如何使用AsioOut使用NAudio录制和播放

我正在尝试使用C# 直接 获得声音输入并以较少的延迟发送输出

我正在使用支持ASIO的库NAudio以获得更好的延迟。

特别是,我使用AsioOut对象进行录制,另一个用于使用BufferedWaveProvider初始化的回放, BufferedWaveProvider填充了一个回调函数: OnAudioAvailable ,它允许我使用ASIO缓冲区。

问题是我听到了各种故障延迟的声音。 我认为问题在于OnAudioAvailable函数,其中缓冲区充满了从声卡输入的数据。

声明:

NAudio.Wave.AsioOut playAsio; NAudio.Wave.AsioOut recAsio; NAudio.Wave.BufferedWaveProvider buffer; 

播放程序:

 if (sourceList.SelectedItems.Count == 0) return; int deviceNumber = sourceList.SelectedItems[0].Index; recAsio = new NAudio.Wave.AsioOut(deviceNumber); recAsio.InitRecordAndPlayback(null, 2, 44100); //rec channel = 1 NAudio.Wave.WaveFormat formato = new NAudio.Wave.WaveFormat(); buffer = new NAudio.Wave.BufferedWaveProvider(formato); recAsio.AudioAvailable += new EventHandler(OnAudioAvailable); //Collego l'output col buffer playAsio = new NAudio.Wave.AsioOut(deviceNumber); playAsio.Init(buffer); //Registro recAsio.Play(); //Playback playAsio.Play(); 

OnAudioAvailable():

 //Callback private unsafe void OnAudioAvailable(object sender, NAudio.Wave.AsioAudioAvailableEventArgs e) { //Copio tutti gli elementi di InputBuffers in buf e li aggiungo in coda al buffer byte[] buf = new byte[e.SamplesPerBuffer]; for (int i = 0; i < e.InputBuffers.Length; i++) { Marshal.Copy(e.InputBuffers[i], buf, 0, e.SamplesPerBuffer); //Aggiungo in coda al buffer buffer.AddSamples(buf, 0, buf.Length); } } 

AsioAudioAvailableEventArgs定义:

 public AsioAudioAvailableEventArgs(IntPtr[] inputBuffers, int samplesPerBuffer, AsioSampleType asioSampleType); public float[] GetAsInterleavedSamples(); 

有谁知道如何修理它? 谢谢你们。

您不应该为同一设备使用两个AsioOut实例。 我很惊讶这种作品。 只需使用InitRecordAndPlayback

对于传递监视的绝对最小延迟,在AudioAvailableEvent ,直接复制到OutputBuffers ,并设置WrittenToOutputBuffers = true 。 这意味着您不需要BufferedWaveProvider

还要记住,任何故障都只是因为您没有足够快地处理AudioAvailable事件。 当您使用ASIO时,您可以处于非常低的延迟(例如,低于10ms),并且可以处理大量数据(例如96kHz采样率,8个输入和输出通道)。 因此,您需要在短时间内完成大量数据移动。 使用.NET,您必须考虑垃圾收集器可能随时启动并导致您不时错过缓冲区的不幸事实。