如何延迟音频播放与FFT同步

时间:2017-10-21 05:00:48

标签: c# wpf fft naudio

我正在使用C#WPF进行实时FFT。

我正在使用NAudio的WaveIn和BufferedWaveProvider来捕捉Stereo Mix录制的任何声音。我每秒多次使用缓冲区的FFT并使用位图显示它,以便显示屏显示通过扬声器播放的任何音频的实时傅里叶变换。

我的问题是,正如预期的那样,显示的FFT落后于来自扬声器的音频少量(可能是200 ms)。

有没有什么方法可以录制应该从扬声器播放的当前音频,以便我可以对它进行FFT,然后在静音后再播放一小段时间(例如200 ms)原始的实时音频。

最终结果只是从显示的FFT中有效地消除感知的延迟。例如,当我的程序运行时,来自youtube视频的音频会略微落后于视频。

以下是我现在的相关方法:

    public MainWindow()
    {
        sampleSize = (int)Math.Pow(2, 13);
        BUFFERSIZE = sampleSize * 2;

        InitializeComponent();

        // get the WaveIn class started
        WaveIn wi = new WaveIn();
        wi.DeviceNumber = deviceNo;
        wi.WaveFormat = new NAudio.Wave.WaveFormat(RATE, WaveIn.GetCapabilities(wi.DeviceNumber).Channels);

        // create a wave buffer and start the recording
        wi.DataAvailable += new EventHandler<WaveInEventArgs>(wi_DataAvailable);
        bwp = new BufferedWaveProvider(wi.WaveFormat);

        bwp.BufferLength = BUFFERSIZE; //each sample is 2 bytes
        bwp.DiscardOnBufferOverflow = true;
        wi.StartRecording();
    }

    public void UpdateFFT()
    {
        // read the bytes from the stream            
        byte[] buffer = new byte[BUFFERSIZE];
        bwp.Read(buffer, 0, BUFFERSIZE);
        if (buffer[BUFFERSIZE - 2] == 0) return;

        Int32[] vals = new Int32[sampleSize];
        Ys = new double[sampleSize];
        for (int i = 0; i < vals.Length; i++)
        {
            // bit shift the byte buffer into the right variable format
            byte hByte = buffer[i * 2 + 1];
            byte lByte = buffer[i * 2 + 0];
            vals[i] = (short)((hByte << 8) | lByte);
            Ys[i] = vals[i];
        }

            FFT(Ys);
    }

我还是音频处理的新手 - 任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

延迟的原因是WaveIn的延迟,默认情况下约为200毫秒。你可以减少这种情况,但有辍学的风险。

虽然您可以使用WasapiCapture捕获系统播放的音频,但无法使用NAudio更改音频或延迟播放。