Fast Fourier Transform (FFT) (Part 9)

Part 1234567891011

Here are a few comments on the use of PlainFFT.
First of all: PlainFFT performs in place calculation, which means that the results are recorded within the vectors containing the source data.
“Usable” results are available on completion of the ComplexToReal() execution. Before execution, vReal and vImag vectors contain the transformed results from the FFT. After execution, the vReal vector contains… two times the frequency spectrum in a perfectly symetric way.
The PlainFFT_01.ino skecth example shows

/* Compute magnitudes */
FFT.ComplexToReal(vReal, vImag, samples, FFT_SCL_TYP_AMPLITUDE);

While in fact we could save processing time with

/* Compute magnitudes */
FFT.ComplexToReal(vReal, vImag, samples >> 1, FFT_SCL_TYP_AMPLITUDE);

As long as, in any way the sketch uses

/* Print frequency spectrum */
PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);

for printing the spectrum. CQFD.

The sampling frequency (Let’s call this variable Fs) determines the frequency range of the spectrum while the number of points acquired during signal acquisition (Let’s call this variable N) determines the resolution frequency. As a consequence of that::
– To Increase the frequency range, increase the signal sampling frequency
– To increase the frequency resolution for a given frequency range, increase the number of points acquired at the same sampling frequency.

The result from the FFT can be viewed as a collection of N/2 “bins”. To each bin corresponds a frequency range (or bandwidth), centred on a frequency value, as reported in the vReal vector. The width of each bin (Let’s call this variable Df) is equal to Fs/N. The last bin is centred on the max frequency (Let’s call this variable Fmax) at (Fs/2)-(Fs/N). The first bin is a little bit special: It is centred on 0Hz, so as to say on the DC component of the signal. So that the graphical bin representation should be half the size of the other bins!

All these parameters can be pictured in the following way

Bin 1 Bin 2  Bin 3       Bin N/2
.     .     .     .    // .     .
.     .     .     .   //  .     .
.     .     .     .  //   .     .
.  :  .  :  .  :  . //    .  :  .
|     |     |             |    |
|     |     |             |    -- Nyquist frequency(Fs/2)
|     |     |             ------- Max. Frequency (Fmax)
|     |     --------------------- Df * 2
|     --------------------------- Df * 1
--------------------------------- Df * 0, 0Hz (DC)

In the real world, the amount of signal resulting from:
– Df * 0 +/- Df /2, in other words 0hz, is read from vReal  – Df * 1 +/- Df /2 is read from vReal  – Df * 2 +/- Df /2 is read from vReal  And so on, up to
– Df * N/2 +/- Df /2, so as to say Fmax, is read from vReal [N/2]

Each bin contains the power of one or more signals which frequencies fit in the band bandwith. From this point, it is obvious that the narrower the bin, the better the selectivity of the filter. In some, not to say most, circumstances, the spectrum representation does not exactly looks like pure histograms.

For a given signal characterized by a pure sinusoidal function, the most abundant power is read from the bin which corresponds to the signal frequency, but the adjacent bins may contain some power abundances too. This is due to the frequency leakage. We may use one from the next options to overcome this phenomenon:
– Increase the number of samples (N) in order to improve the selectivity
– Apply appropriate windowing
– Apply spectrum peak interpolation

Peak interpolation helps improving the most accurate peak apex location thanks to some linear (e.g. Quadratic fit) or non-linear (e.g. Gaussian fit). While this interpolation applies to a limited number of consecutive data points, we may apply simplified formula for computing apex locations. Peak interpolation is almost mandatory when all significant peaks from a frequency spectrum must be correlated (e.g. Finding harmonics).

The following pictures illustrate various use cases of PlainFFT for plotting frequency spectrum. In all cases, a Hann window was applied as well as Gaussian peak apex interpolation.

Here is the frequency spectrum from a sinusoidal signal acquired with a sampling rate of 1kHz over 256 samples: Here is the frequency spectrum from a sinusoidal signal acquired with a sampling rate of 1kHz over 32768 samples: Here is the frequency spectrum from a sinusoidal signal acquired with a sampling rate of 500Hz over 256 samples: Note: The peak looks broader than in picture 1, but this feeling is related to the narrower scale!

This is probably on over-simplified explanation, but it is sufficient for using PlainFFT in the most appropriate manner. Feel free to add your comments and suggestions.

Next post on same subject