159
votes

I have an FFT result. These are stored in two double arrays: a real part array and an imaginary part array. How do I determine the frequencies that correspond to each element in these arrays?

In other words, I would like have create an array that stores the frequencies for each real and imaginary component of my FFT.

5
I do it in C#.net. Can you help me?Rango
If you don't understand the relevance of the real and imaginary parts of an FFT then you aren't going to get any meaningful results, so you should hunt out some FFT and signal processing tutorials to understand how to interpret the results. I think it's quite likely that whatever you're using it for, you are wanting the magnitude of the FFT or the Power Spectral Density.the_mandrill
Thank you! I want to get peak frequencies of each frame (frame length depend in Window Length and Shift Length)Rango

5 Answers

378
votes

The first bin in the FFT is DC (0 Hz), the second bin is Fs / N, where Fs is the sample rate and N is the size of the FFT. The next bin is 2 * Fs / N. To express this in general terms, the nth bin is n * Fs / N.

So if your sample rate, Fs is say 44.1 kHz and your FFT size, N is 1024, then the FFT output bins are at:

  0:   0 * 44100 / 1024 =     0.0 Hz
  1:   1 * 44100 / 1024 =    43.1 Hz
  2:   2 * 44100 / 1024 =    86.1 Hz
  3:   3 * 44100 / 1024 =   129.2 Hz
  4: ...
  5: ...
     ...
511: 511 * 44100 / 1024 = 22006.9 Hz

Note that for a real input signal (imaginary parts all zero) the second half of the FFT (bins from N / 2 + 1 to N - 1) contain no useful additional information (they have complex conjugate symmetry with the first N / 2 - 1 bins). The last useful bin (for practical aplications) is at N / 2 - 1, which corresponds to 22006.9 Hz in the above example. The bin at N / 2 represents energy at the Nyquist frequency, i.e. Fs / 2 ( = 22050 Hz in this example), but this is in general not of any practical use, since anti-aliasing filters will typically attenuate any signals at and above Fs / 2.

55
votes

Take a look at my answer here.

Answer to comment:

The FFT actually calculates the cross-correlation of the input signal with sine and cosine functions (basis functions) at a range of equally spaced frequencies. For a given FFT output, there is a corresponding frequency (F) as given by the answer I posted. The real part of the output sample is the cross-correlation of the input signal with cos(2*pi*F*t) and the imaginary part is the cross-correlation of the input signal with sin(2*pi*F*t). The reason the input signal is correlated with sin and cos functions is to account for phase differences between the input signal and basis functions.

By taking the magnitude of the complex FFT output, you get a measure of how well the input signal correlates with sinusoids at a set of frequencies regardless of the input signal phase. If you are just analyzing frequency content of a signal, you will almost always take the magnitude or magnitude squared of the complex output of the FFT.

19
votes

I have used the following:

public static double Index2Freq(int i, double samples, int nFFT) {
  return (double) i * (samples / nFFT / 2.);
}

public static int Freq2Index(double freq, double samples, int nFFT) {
  return (int) (freq / (samples / nFFT / 2.0));
}

The inputs are:

  • i: Bin to access
  • samples: Sampling rate in Hertz (i.e. 8000 Hz, 44100Hz, etc.)
  • nFFT: Size of the FFT vector
14
votes

The FFT output coefficients (for complex input of size N) are from 0 to N - 1 grouped as [LOW,MID,HI,HI,MID,LOW] frequency.

I would consider that the element at k has the same frequency as the element at N-k since for real data, FFT[N-k] = complex conjugate of FFT[k].

The order of scanning from LOW to HIGH frequency is

0,

 1,
 N-1,

 2,
 N-2

 ...

 [N/2] - 1,
 N - ([N/2] - 1) = [N/2]+1,

 [N/2]

There are [N/2]+1 groups of frequency from index i = 0 to [N/2], each having the frequency = i * SamplingFrequency / N

So the frequency at bin FFT[k] is:

if k <= [N/2] then k * SamplingFrequency / N
if k >= [N/2] then (N-k) * SamplingFrequency / N
5
votes

Your kth FFT result's frequency is 2*pi*k/N.