我有一个C#项目,用于播放RSS订阅的莫尔斯电码。我使用了Managed DirectX编写它,但发现Managed DirectX已经过时并被废弃。我的任务是播放与沉默周期(代码)精确定时其持续时间的纯正正弦波间隔。我需要能够调用一个函数,播放纯音调一段时间,然后Thread.Sleep(),然后再播放另一个,依此类推。在最快的情况下,音调和空格可以短至40毫秒。
在Managed DirectX中工作得非常好。为了获得精确定时的音调,我创建了1秒钟的正弦波到辅助缓冲区中,然后为了播放一定持续时间的音调,我向前搜索到缓冲区末尾x毫秒的位置,然后播放。
我尝试了System.Media.SoundPlayer。它很糟糕[编辑-请参见下面我的答案],因为您必须Play(),Sleep(),然后Stop()以获取任意音调长度。结果是一个声音太长,由CPU负载变化不定。实际停止音调需要不确定的时间。
然后我开始尝试使用NAudio 1.3。我最终使用一个内存常驻流提供音调数据,并再次向前搜索使所需长度的音调保留在流中,然后播放。这在DirectSoundOut类上效果还可以一段时间(见下文),但WaveOut类很快就会出现内部断言说缓冲区仍在队列中,尽管PlayerStopped = true。这很奇怪,因为我在播放到末尾后,将等待相同持续时间在音调结束和下一次开始之间。您认为在开始播放40毫秒音调的80毫秒后,它不会在队列中具有缓冲区。
DirectSoundOut 一开始表现良好,但它存在一个问题,即对于每个音调突发 Play() 它都会启动一个单独的线程。最终(大约 5 分钟左右)它就会停止工作。在 VS2008 IDE 中运行项目时,在输出窗口中可以看到一个又一个线程退出。我在播放过程中没有创建新对象,只是 Seek() 音频流然后反复调用 Play(),因此我不认为这是孤立缓冲区或其他累积导致堵塞的问题。
对于这个问题我已经失去了耐心,所以我希望在这里询问是否有人面临过类似的要求,并能指引我朝着可能的解决方向前进。