b02laire
b02laire

Reputation: 1

Extract fundamental frequency from FFT

I'm coding a guitar tuner in c#. Using the NAudio library, I can compute an FFT of my microphone's data in real time. The FFT works well when i visualize it, but when I try to extract the fundamental frequency, I only get results far from what i'm supposed to have. I suppose this has to do with my rather simple way to research peaks in my fourier data:

//fft_size=size of the array containing the processed FFT
//Xs is the frequency axis of my computed FFT (double array)
//Ys is the amplitude axis of my computed FFT (double array)



int pk=0;
for (int p = 0; p < fft_size; p++) 

        {
            if (Ys[p] > Ys[pk])
            {
                pk = p;
            }
        }

labelfrequency.Text=Xs[pk].ToString();

Then the frequency is displayed on the windows form

Upvotes: 0

Views: 1823

Answers (2)

hotpaw2
hotpaw2

Reputation: 70743

Peak FFT magnitude won't work. There is a big difference between FFT peak magnitude frequency and musical pitch.

Musical pitch is a psycho-acoustic phenomena, only loosely related to the largest sinusoidal component of a Fourier decomposition. This is especially important for guitar sounds, where the pitch sound can have a weak or missing fundamental frequency component, and stronger overtones. Thus, using a bare FFT magnitude will make a very poor and unreliable guitar tuner.

Even if the fundamental pitch is represented by the FFT magnitude peak, it could end up partially in-between FFT result bins, which can be spaced as far or farther apart than half a semi-tone for very low notes in short FFTs. Thus, the peak bin center frequency will be way off the actual pitch frequency, in terms of "cents" pitch measurement accuracy.

Instead you need to try using one of the many pitch detection/estimation algorithms (in the family of: weighted autocorrelation, ASDF, AMDF, Cepstral analysis, harmonic product spectrum, YAPT/YIN, trained-DNNs, and etc.), and perhaps use high-quality interpolation as well.

Upvotes: 1

Riccardo Bettati
Riccardo Bettati

Reputation: 66

Unfortunately, fundamental-frequency detection (more commonly known as "pitch detection") is somewhat harder than just doing an FFT, for two reasons. First, the FFT is often too coarse (due to the discretization) to give you the actual frequency. So you need to to some post-processing to find the actual peak from the discrete FFT data. This is not hard to do. Second, it is sometimes hard to pick the correct peak. Often, the peak for the fundamental frequency is much weaker than that of one of the overtones.

No need to despair. There is lots of work on pitch detection, which is enumerated in this wikipedia article. YIN is an example of an effective and rather simple algorithm that handles both of the problems listed above. There are lots of implementations of YIN available on the Web. You may need to be careful when you use this algorithm, as you may run into intellectual property issues. This algorithm may have been patented.

As a side note, we have been working on pitch detection for violins and such, and we are having difficulties with pitch detection during periods of low energy (at the beginning of the bow movement and when the sound is dissipating). I have been even thinking about using deep learning to tease out the pitch in these situations...

Much luck with your project!

Upvotes: 3

Related Questions