swharden/FftSharp

How to calculate peak frequency

Closed this issue · 1 comments

I jointhe two pieces of code

void WaveIn_DataAvailable (object? sender, NAudio.Wave.WaveInEventArgs e)
{

   int SampleRate = 44100;
   int BufferMilliseconds = 20;
    AudioValues = new double[SampleRate * BufferMilliseconds / 1000];
     for (int i = 0; i <e.Buffer.Length / 2; i ++)
         AudioValues [i] = BitConverter.ToInt16 (e.Buffer, i * 2);

    // get FFT and FFT frequencies
    double [] paddedAudio = FftSharp.Pad.ZeroPad (AudioValues);
    double [] fft = FftSharp.Transform.FFTpower (paddedAudio);
    double fftFreqPeriod = FftSharp.Transform.FFTfreqPeriod (sampleRate, fft.Length);
    double fftFreqSpacing = 1.0 / fftFreqPeriod;
}

// find frequency with the highest FFT power
double peakFrequency = 0;
double peakPower = 0;
for (int i = 0; i < fft.Length; i++)
{
    if (fft[i] > peakPower)
    {
        peakPower = fft[i];
        peakFrequency = i * fftFreqPeriod;
    }
}

i have a tone at 523 Hz.
In this case the peakFrequency is 22050 Hz but the voice sing at 523 Hz I need to find 523 Hz
The F0, it is called fundamental frequency of voice

Thanks
Mimmo

Thanks for sharing this @MimmoGhi! I created a test to demonstrate this concept for future reference:

double sampleRate = 48_000;
double[] signal = FftSharp.SampleData.SampleAudio1(); // 2 kHz peak frequency
double[] fftMag = FftSharp.Transform.FFTmagnitude(signal);
double[] fftFreq = FftSharp.Transform.FFTfreq(sampleRate, fftMag);
int peakIndex = 0;
double peakValue = fftMag[0];
for (int i = 1; i < fftFreq.Length; i++)
{
if (fftMag[i] > peakValue)
{
peakValue = fftMag[i];
peakIndex = i;
}
}
double peakFrequency = fftFreq[peakIndex];
Console.WriteLine($"Peak frequency: {peakFrequency} Hz");