2016-06-29 1 views
1

J'ai besoin de transformer un tableau avec des valeurs entières en domaine fréquentiel (afin de le multiplier par un autre plus tard). Le tableau de sortie doit avoir la taille de 44100 mais le tableau d'entrée variera. Je pense que fftw3 est un bon outil pour cela. Mais comment puis-je créer un «plan» avec différentes tailles de tableaux pour l'entrée et la sortie?C++: comment transformer un tableau en un autre tableau de taille différente en utilisant fftw3

est ici la fonction que j'ai écrit:

fftw_complex* fourier(int* samples, int numberOfSamples){ 

    fftw_complex* input; 
    fftw_complex* output; 
    fftw_plan plan; 
    input = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*numberOfSamples); 
    output = (fftw_complex*)fftw_malloc(sizeof(fftw_complex)*44100);     //cd-quality 

    plan = fftw_plan_dft_1d(44100, input, output, FFTW_FORWARD, FFTW_ESTIMATE); 
    // here is the problem because ^this 
    // array has a different size than 
    //          ^this array 

    for(size_t index = 0; index < numberOfSamples; index++){ 
     input[index][0] = (double)(samples[index]); 
     input[index][1] = 0; 
    } 
    fftw_execute(plan); 
    fftw_destroy_plan(plan); 
    fftw_free(input); 
    return output; 
} 

merci beaucoup pour répondre à

+2

'44100' ressemble à une sorte de taux d'échantillonnage audio. Normalement, les tailles de tableaux 'fft' n'ont rien à voir avec les taux d'échantillonnage et sont de puissance de deux. Habituellement, les tailles des tableaux d'entrée et de sortie correspondent en raison de l'exigence mathématique. Si la taille des données d'entrée réelles ne correspond pas à la taille du tableau, il existe des techniques de fenêtrage et de remplissage nul pour résoudre ce problème. Il y a assez de bonne littérature sur ce sujet. – user3078414

+1

autres ont déjà mentionné que la longueur d'entrée et de sortie doit correspondre. Peut-être pourriez-vous donner un peu plus de contexte sur ce que vous essayez de faire. basé sur ce nombre magique, il semble que vous essayez d'estimer le spectre de puissance avec 1 bin par Hz (probablement). Si c'est le cas, vous avez juste besoin de mettre à zéro votre entrée jusqu'à 44100 échantillons et d'appliquer une fonction de fenêtre (essayez hanning) au bloc d'entrée que vous avez pour lisser le spectre. –

Répondre

3

La transformée de Fourier discrète sera toujours produire une sortie avec la même taille que son entrée, en tant que principe mathématique de base l'algorithme, et cela est reflété dans FFTW en prenant seulement dans un paramètre de taille. En effet, pour un tableau de N valeurs discrètes dans le domaine temporel, il y a exactement N fréquences uniques possibles en jeu, de 0 à N-1 cycles par unité de temps (cette unité étant la durée de votre entrée).

Vous pouvez augmenter ou réduire la taille de votre entrée à 44100 valeurs, en étirant essentiellement l'entrée et en interpolant ses valeurs pour créer une nouvelle matrice qui correspond à la longueur requise, puis effectuer la transformée de Fourier. Je vous recommande d'effectuer cet étirement sur le domaine de temps d'entrée et non sur le domaine fréquentiel pour éviter les artefacts indésirables.

+1

Une interpolation linéaire est-elle la meilleure chose à faire? Je veux dire, supposons que vous preniez les échantillons, produisiez une somme de sinusodiaux qui se rapprochaient le plus du signal, puis utilisiez cela pour interpoler? Cela correspond à une transformation relativement simple dans le domaine fréquentiel, et pourrait être une meilleure méthode? – Yakk

+0

@Yakk ne ferait-il pas la même chose, mais pas en n * log (n)? –

+2

vous ne pouvez pas simplement étirer l'entrée, ce qui provoquera des artefacts évidents. si vous avez réellement besoin d'interpoler (je ne vois pas pourquoi vous feriez ça du tout ici, étant donné que cela change complètement la signification de la corbeille), vous devriez le faire contre une forme d'impulsion limitée de nyquist. Si vous vous souciez de la performance, vous devriez le faire dans le domaine fréquentiel, car c'est moins cher (un seul robinet). Si vous êtes vraiment inquiet à propos des artefacts dans le domaine fréquentiel, remplacez la transformation pour transformer la circonvolution circulaire en une normale, même que la méthode chevauchement et sauvegarde –