Comment obtenir la fréquence à partir du résultat fft?

j'ai enregistré un tableau[1024] de données de mon micro sur mon téléphone Android, passé à travers un DFT 1D de données réelles (réglage d'un autre 1024 bits à 0). J'ai sauvé le tableau dans un fichier texte, et répété 8 fois.

j'ai récupéré 16384 résultats. J'ai ouvert le fichier texte dans Excel et j'ai fait un graphique pour voir à quoi il ressemblait(x=index du tableau, y=Taille du nombre retourné). Il y a des pointes massives (à la fois positives et négatives) de magnitude autour de 110, 232, et petites les piques continuent de cette façon jusqu'à ce que vers 1817 et 1941 où les piques grandissent de nouveau, puis tombent à nouveau.

mon problème est que partout où je cherche de l'aide sur le sujet il mentionne gettng les nombres réels et imaginaires, Je n'ai qu'un tableau 1D, que j'ai récupéré de la méthode que J'ai utilisée de la classe de Piotr Wendykier:

DoubleFFT_1D.realForwardFull(audioDataArray); // from the library JTransforms.

ma question Est: Que dois-je faire à ces données pour retourner une fréquence? Le son enregistré était moi jouant un " A " sur la corde inférieure (5ème fret) de ma guitare (à environ 440Hz) .

28
demandé sur Ben Taliadoros 2011-10-06 17:26:07

1 réponses

les données complexes sont entrelacées, avec des composantes réelles à indices pairs et des composantes imaginaires à indices impairs, c'est-à-dire que les composantes réelles sont à l'indice 2*i, les composantes imaginaires sont à l'index 2*i+1.

Pour obtenir de l'ampleur du spectre à l'indice i, vous souhaitez:

re = fft[2*i];
im = fft[2*i+1];
magnitude[i] = sqrt(re*re+im*im);

alors vous pouvez tracer la magnitude[i] pour i = 0 à N / 2 pour obtenir le spectre de puissance. Selon la nature de votre entrée audio vous devriez voir un ou plusieurs pics dans le spectre.

Pour obtenir la fréquence approximative de chaque sommet, vous pouvez convertir l'indice de la pointe, comme suit:

freq = i * Fs / N;

où:

freq = frequency in Hz
i = index of peak
Fs = sample rate (e.g. 44100 Hz or whatever you are using)
N = size of FFT (e.g. 1024 in your case)

Note: Si vous n'avez pas appliqué auparavant un fonction de fenêtre vers les données d'entrée du domaine temporel vous obtiendrez alors une certaine quantité de fuite spectrale et le spectre de puissance cherchera plutôt "barbouillé".


Pour développer sur cette de plus, ici, est pseudo-code pour un exemple complet où nous prenons des données audio et identifions la fréquence du plus grand pic:

N = 1024          // size of FFT and sample window
Fs = 44100        // sample rate = 44.1 kHz
data[N]           // input PCM data buffer
fft[N * 2]        // FFT complex buffer (interleaved real/imag)
magnitude[N / 2]  // power spectrum

capture audio in data[] buffer
apply window function to data[]

// copy real input data to complex FFT buffer
for i = 0 to N - 1
  fft[2*i] = data[i]
  fft[2*i+1] = 0

perform in-place complex-to-complex FFT on fft[] buffer

// calculate power spectrum (magnitude) values from fft[]
for i = 0 to N / 2 - 1
  re = fft[2*i]
  im = fft[2*i+1]
  magnitude[i] = sqrt(re*re+im*im)

// find largest peak in power spectrum
max_magnitude = -INF
max_index = -1
for i = 0 to N / 2 - 1
  if magnitude[i] > max_magnitude
    max_magnitude = magnitude[i]
    max_index = i

// convert index of largest peak to frequency
freq = max_index * Fs / N
46
répondu Paul R 2011-10-06 15:23:57