首页 > 解决方案 > C# 中 FFT 的音高检测

问题描述

我正在制作一个程序来调整铜管乐队。我开始用麦克风录音。

public void StartMicListening()
    {
        int audioDevNumber = 0;
        WaveInEvent wIN = new WaveInEvent();
        wIN.DeviceNumber = audioDevNumber;
        wIN.WaveFormat = new NAudio.Wave.WaveFormat(RATE, 1);
        wIN.BufferMilliseconds = (int)((double)BUFFERSIZE / (double)RATE * 1000.0);
        wIN.DataAvailable += new EventHandler<WaveInEventArgs>(AudioDataAvailable);
        bwp = new BufferedWaveProvider(wIN.WaveFormat);
        bwp.BufferLength = BUFFERSIZE * 2;
        bwp.DiscardOnBufferOverflow = true;
        try
        {
            wIN.StartRecording();
        }
        catch
        {
            Console.WriteLine("Can't see device");
        }

        //Console.WriteLine("Recording");
    }

接下来我要计算 FFT

public void calculateFFT()
    {
        var audioBytes = new byte[BUFFERSIZE];
        bwp.Read(audioBytes, 0, BUFFERSIZE);
        int pointCount = audioBytes.Length / 2;
        double[] pcm = new double[pointCount];
        double[] fft = new double[pointCount];
        double[] fftReal = new double[pointCount/2];


        for (int i = 0; i < pointCount; i++)
        {
            // read the int16 from the two bytes
            Int16 val = BitConverter.ToInt16(audioBytes, i * 2);

            // store the value in Ys as a percent (+/- 100% = 200%)
            pcm[i] = (double)(val) / Math.Pow(2, 18) * 200.0;
        }
        fft = FFT(pcm);
        Array.Copy(fft, fftReal, fftReal.Length);

    }

当我使用 440 Hz 音调的音调发生器 ( https://www.szynalski.com/tone-generator/ ) 测试此代码时,我从 fftReal 获得最大值,它运行良好。但是当我将它与萨克斯管的声音一起使用时,我从 fftReal 中获得最大值,我检测到有时是 440Hz,有时是 880Hz,有时是 1320Hz。880 Hz 和 1320 Hz 是 A 音调(440 Hz)的等分,但我只需要检测频谱的第一个音高(440 Hz)。有什么解决办法吗?Mayba 你们中的一些人已经用 C# 完成了它,可以分享给我。

标签: c#fftpitch

解决方案


推荐阅读