带 NAudio 的音频中继器
我正在实现一个程序,该程序从输入设备读取音频流并使用 NAudio 将其发送到输出设备。为此,我使用 WaveIn
及其 DataAvailable
事件从输入流获取数据。为了写入数据,我将使用 WaveOut
,这也意味着我需要使用 IWaveProvider
的某些实现。使用队列来满足我的需求似乎非常简单。除了一件事:当队列为空并且调用 Read() 方法时会发生什么?我在文档中没有找到任何与此相关的内容。我认为我有的选项:
- 该方法应该阻塞,直到一些数据可用。
- 该方法立即返回 0,表示当前没有可用数据。
- 用零填充缓冲区。
我正在考虑使用选项 1 或 2,但后来我发现 BufferedWaveProvider
(以及内部使用 BufferedWaveProvider
的 WaveInProvider
)使用选项 3。由此,我推断选项 3 是首选选项。
问题是,我的推断正确吗?我应该使用选项 3 吗?如果我使用选项 1 或 2 会发生什么?这还能用吗?
I'm implementing a program that reads an audio stream from an input device and sends it to an output device using NAudio. To do that, I get the data from the input stream using WaveIn
and its DataAvailable
event. To write the data, I am about to use WaveOut
, which also means I need to use some implementation of IWaveProvider
. Implementing that for my needs seems quite straightforward using a queue. Except for one thing: what should happen when the queue is empty and the Read()
method is called? I didn't find anything about this in the documentation. Options I think I have:
- The method should block, until some data are available.
- The method immediately returns 0, indicating no data are currently available.
- Fill the buffer with zeroes.
I was thinking about using option 1 or 2, but then I found BufferedWaveProvider
(and WaveInProvider
, that uses BufferedWaveProvider
internally) that uses option 3. From that, I inferred that option 3 is the preferred one.
The question is, did I infer that right and should I use option 3? What would happen if I used options 1 or 2? Would that even work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当声卡需要更多数据来播放时,将调用 Read 方法。阻塞通常不是一个好的选择,因为您可能位于驱动程序本身内部的线程上(如具有函数回调的 ASIO 或 WaveOut),或者您可能位于 GUI 线程上(如具有 Windows 消息回调的 WaveOut)。
从 Read 方法返回 0 意味着“这是音频数据的结尾”,因此返回 0 将导致播放停止。
因此,选项三是不阻塞不应阻塞的线程并允许继续播放的最佳选择。
例如,如果 Read 方法的使用者是 WaveFileWriter,则选项 1 就可以了(选项 2 可能取决于您如何确定何时停止写入 WAV 文件)。
The Read method is called when the soundcard is in need of more data to play. Blocking is not usually a good option because you might be on a thread from within the driver itself (as with ASIO or WaveOut with function callbacks), or you might be on the GUI thread (as with WaveOut with windows message callbacks).
Returning 0 from the Read method means "this is the end of the audio data", so returning 0 would result in playback stopping.
So option three is the best choice to not block on threads you shouldn't be blocking on and to allow playback to continue.
If the consumer of your Read method was for example a WaveFileWriter, option 1 would be fine, (and option 2 might be depending on how you determine when to stop writing to the WAV file).