Fast Fourier Transform (FFT) (Part 5)

Part 1234567891011

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);
}

Next post on same subject

1. paulcardno says:

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

2. Didier says:

My last post http://didier.longueville.free.fr/arduinoos/?p=3272 should answer most of your questions regarding fequency spectra obtained with PlainFFT!

3. kevin says:

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”??