Fast Fourier Transform (FFT) (Part 5)
Part 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
So far so good, we got our magnitude spectrum. We may now analyze it just like any other spectrum in order to get meaningful information. In our case, we may want to identify the main frequencies from the spectrum. Firstly we will run a peak picking algorithm in order to locate major peaks, and then keep the most intense one. Those who want to perform spectral comparison will have to keep all significant peaks.
There are lots of peak picking algorithm! But the one we need has to be small and fast. This one is pretty trivial but it works great.
Secondly, because of the poor peak shapes (lack of large vectors of data) we need to interpolate the peak apex in order to get an accurate frequency. I am using a non iterative quadratic interpolation which gives good results too.
Both routines are merged in one function
double majorPeak(double *vD, uint8_t samples) { double maxY = 0; uint8_t IndexOfMaxY = 0; for (uint8_t i = 1; i < (samples - 1); i++) { if ((vD[i-1] < vD[i]) && (vD[i] > vD[i+1])) { if (vD[i] > maxY) { maxY = vD[i]; IndexOfMaxY = i; } } } double delta = 0.5 * ((vD[IndexOfMaxY-1] - vD[IndexOfMaxY+1]) / (vD[IndexOfMaxY-1] - (2.0 * vD[IndexOfMaxY]) + vD[IndexOfMaxY+1])); double interpolatedX = (IndexOfMaxY + delta) / samplingDuration; return(interpolatedX); }
Links:
Hi Didier
I’m wanting to be able to look at each of the different frequencies that have been calculated in *vD, can you tell me how I calculate the frequency for each of these values.
thanks Paul
My last post http://didier.longueville.free.fr/arduinoos/?p=3272 should answer most of your questions regarding fequency spectra obtained with PlainFFT!
why the function “majorPeak(double *vD, uint8_t samples)” is different with example code in part6?
the function in part6 is “double x = FFT.majorPeak(vReal, samples, samplingFrequency);” it has “samplingFrequency”??