【发布时间】:2015-01-23 10:59:03
【问题描述】:
我正在使用NAudio 中的WaveInEvent 来记录麦克风数据。它可以正常工作一段时间,但几次后,它会停止提供输入数据 - 永远不会使用新数据调用 DataAvailable 回调。
我每次都尝试创建一个新的WaveInEvent,但这并没有解决问题。我也尝试过使用 WASAPI 输入,它始终称为 DataAvailable - 数据字节为零。
如何使用NAudio 可靠地从麦克风录制音频?
目前,我的代码如下所示:
StartRecording() {
microphone = new WaveInEvent();
microphone.DeviceNumber = 0;
microphone.WaveFormat = outformat;
microphone.BufferMilliseconds = 50;
microphone.DataAvailable += (_, recArgs) =>
{
session.OnAudioData(recArgs.Buffer, recArgs.BytesRecorded);
};
microphone.StartRecording();
}
StopRecording() {
if (microphone != null)
{
microphone.StopRecording();
microphone.Dispose();
microphone = null;
}
}
项目中除了使用 WaveFormat 来描述波形格式外,没有其他 naudio 代码。
NAudio 在尝试从线程池工作程序调用 WaveInBuffer.Reuse() 时抛出访问冲突异常。我不知道为什么这不会做比丢弃音频数据更严重的事情。
对于我没有重新创建 WaveInEvent 的情况,我得到了一个 MmException - 在同一个地方调用 waveInPrepareHeader 的无效句柄。
坦率地说,我得到不同的结果这一事实在很大程度上意味着 NAudio 正在做一些不应该在实例之间共享状态的时髦的事情,并且查看 Codeplex 上的源代码,我不确定 WTF 是否正在继续。
【问题讨论】:
-
你能添加一些代码吗?
-
您是否在 RecordingStopped 事件中遇到异常?另外,这是USB捕获设备吗?如果是Realtek板载声卡,你更新驱动了吗?
-
@MarkHeath:我确实在 RecordingStopped 中遇到了异常,它是一个 USB 捕获设备。
-
我之前见过 NAudio 访问冲突,当某些应该固定的东西没有被固定并且 GC 移动它时。但我认为我们很久以前就已经解决了所有这些问题。也可能是不可靠的驱动程序问题,当然 USB 设备在使用时可能会断开连接。异常的堆栈跟踪是否指向产生访问冲突的 waveIn API 调用?
-
@MarkHeath:这是 StartRecording 的 lambda -> RecordThread() -> DoRecording() -> WaveInBuffer.Reuse()。如果您不希望 GC 移动内存缓冲区,那么简单地使用像 heapalloc/heapfree 这样的本机分配器来分配它会更容易吗? USB 设备未断开连接。它是一个带有录音按钮的独立麦克风,响应该按钮按下,上述函数被调用。