麦克风停止向 NAudio 提供数据

Posted

技术标签:

【中文标题】麦克风停止向 NAudio 提供数据【英文标题】:Microphone stops providing data with NAudio 【发布时间】: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 设备未断开连接。它是一个带有录音按钮的独立麦克风,响应该按钮按下,上述函数被调用。 【参考方案1】:

USB 麦克风的驱动程序似乎运行不正常。当缓冲区通过 WIM_DATA 消息发送给用户时,它已满。但是,当 waveInUnprepareHeader 被调用时,它仍然在队列中,即使它实际上只是按满的方式传递。所以我认为最终应该归咎于麦克风的驱动程序。

我一直在仔细观察麦克风,似乎这个特定的单元实际上已经损坏了。

【讨论】:

以上是关于麦克风停止向 NAudio 提供数据的主要内容,如果未能解决你的问题,请参考以下文章

naudio 从麦克风录制声音然后保存

使用 NAudio 录制音频并在麦克风输入静音时写入文件

我将如何使用 NAudio 压缩来自麦克风的传入 PCM 数据?

Naudio 录制麦克风 X 秒

NAudio 记录和保存麦克风输入和扬声器输出

无法使用麦克风 c# naudio 捕捉 15k 的音调