0

我将NAudioWasapiLoopbackCaptureWaveOut结合使用,以创建全局回声效果,即影响当前音频输出。

然而,我的实现,对我来说似乎很糟糕,根本无法正常工作。在每台机器上听起来都不一样,有时甚至会崩溃。

这是我想出的代码。它记录音频输出,每 75 毫秒使用WaveOut播放录制的流。

我在这里做错了什么,如何改进?

private static void CreateReverb()
{
    MemoryStream loopbackWave = new MemoryStream();
    DateTime lastEcho = DateTime.Now;

    WasapiLoopbackCapture waveIn = new WasapiLoopbackCapture();
    waveIn.StartRecording();
    waveIn.DataAvailable += delegate(object sender, WaveInEventArgs e)
    {
        loopbackWave.Write(e.Buffer, 0, e.BytesRecorded);
        if ((DateTime.Now - lastEcho).TotalMilliseconds > 75)
        {
            lastEcho = DateTime.Now;
            byte[] loopbackBytes = loopbackWave.ToArray();
            loopbackWave.Dispose();
            loopbackWave = new MemoryStream();

            using (MemoryStream waveStream = new MemoryStream())
            {
                using (WaveFileWriter waveFileWriter = new WaveFileWriter(waveStream, waveIn.WaveFormat))
                {
                    waveFileWriter.Write(loopbackBytes, 0, loopbackBytes.Length);
                }
                loopbackBytes = waveStream.ToArray();
            }

            for (int i = 0; i < 3; i++)
            {
                ThreadPool.QueueUserWorkItem(delegate
                {
                    try
                    {
                        WaveOut waveOut = new WaveOut();
                        waveOut.Init(new WaveFileReader(new MemoryStream(loopbackBytes)));
                        waveOut.Volume = ReverbIntensity * .5f;
                        waveOut.Play();
                        Thread.Sleep(200);
                        waveOut.Dispose();
                    }
                    catch { }
                });
            }
        }
    };
}

编辑:第二次尝试:

这一次,我尝试BufferedWaveProvider按照 Mark 的建议使用。问题是播放没有延迟,因此创建了反馈循环而不是回声。输出必须.5f在音量上并且必须有大约 75 毫秒的延迟才能使其工作。

private static void CreateReverb()
{
    DateTime lastEcho = DateTime.Now;

    WasapiLoopbackCapture waveIn = new WasapiLoopbackCapture();
    BufferedWaveProvider bufferedWaveProvider = new BufferedWaveProvider(waveIn.WaveFormat);
    WasapiOut wasapiOut = new WasapiOut(AudioClientShareMode.Shared, 0);

    bufferedWaveProvider.DiscardOnBufferOverflow = true;
    wasapiOut.Init(bufferedWaveProvider);
    wasapiOut.Play();
    waveIn.StartRecording();

    waveIn.DataAvailable += delegate(object sender, WaveInEventArgs e)
    {
        bufferedWaveProvider.AddSamples(e.Buffer, 0, e.BytesRecorded);
    };
}
4

1 回答 1

1

不要一直打开数百个WaveOut. 您应该只有一个 的实例WaveOut,即从以录制的音频开始的自定义流播放(aBufferedWaveProvider将是一个很好的起点),然后将其传递给您的效果。ISampleProvider最好的方法是在其从源提供程序读取的方法中创建一个实现Read,然后执行效果。

最后,您正在使用环回音频捕获声音,然后在同一设备上播放它,这本身很可能会创建一个令人讨厌的反馈循环。

于 2015-03-12T21:12:29.593 回答