这就是我想要做的事情:
我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持250ms,然后通过扬声器将其输出。
我已经使用Java Sound API完成了这项工作。问题是它有点慢。从发出声音到再次从扬声器听到声音的时间至少需要1-2秒,我甚至还没有尝试实现延迟逻辑。理论上应该没有延迟,但有。我知道你必须等待声卡填满其缓冲区或其他任何东西,样本大小和采样率与此有关。
我的问题是:我应该继续沿着Java路径尝试这样做吗?如果可能的话,我希望将延迟降低到100毫秒。有没有人有使用Java的ASIO驱动程序的经验?据说它更快......
另外,我是一个.NET家伙。这对.NET来说有意义吗?那么C ++呢?我正在寻找在这里使用的正确技术,也许是如何使用您建议的技术平台读/写音频输入/输出流的一个很好的例子。谢谢你的帮助!
答案 0 :(得分:3)
我过去曾使用过JavaSound,发现它非常不稳定(并且它在VM发布之间不断变化)。如果您喜欢C#,请使用它,只需使用DirectX API即可。这是一个使用DirectSound和C#做你想做的事情的例子。您可以使用效果插件执行250毫秒回声。
答案 1 :(得分:3)
您可能需要查看专为低延迟声音处理而设计的音频API JACK。此外,谷歌提出了关于将JACK与Java一起使用的nifty presentation [PDF]。
理论上应该没有延迟,但有。
嗯,零延迟是不可能的。你可以期待的最好的是一个不明显的延迟(就人类的感知而言)。如果您描述阅读和阅读的基本算法,它可能会有所帮助。写出声音数据,这样人们就可以发现可能的问题。
使用像Java这样的垃圾收集语言的一个潜在问题是GC会定期运行,在一段任意时间内中断处理。但是,如果在正常使用情况下> 100毫秒,我会感到惊讶。如果GC出现问题,大多数JVM都会提供您可以尝试的备用收集算法。
答案 2 :(得分:3)
如果您选择沿着C / C ++路径前进,我强烈建议您使用PortAudio(http://portaudio.com/)。它适用于多个平台上的几乎所有内容,它可以让您对声音驱动程序进行低级控制,而无需实际处理周围的各种声音驱动程序技术。
我在多个项目中使用过PortAudio,使用起来非常愉快。许可证是宽容的。
答案 3 :(得分:1)
如果低延迟是您的目标,那么您就无法击败C.
libsoundio是一个用于实时音频输入和输出的低级C库。它甚至带有一个example program,可以完全按照您的要求进行操作 - 将麦克风输入连接到扬声器输出。
答案 4 :(得分:0)
使用 JavaSound 可以实现100-150毫秒的端到端延迟。</ p>
延迟的主要原因是捕获和回放行的缓冲区大小。打开行时设置大小:
TargetDataLine#open(AudioFormat format, int bufferSize)
SourceDataLine#open(AudioFormat format, int bufferSize)
如果缓冲区太大会导致延迟时间过长,但如果缓冲区太小则会导致恶意播放。因此,您需要为应用程序需求和计算能力找到平衡点。
调用DataLine#getBufferSize
时,可以使用#open(AudioFormat format)
检查默认缓冲区大小。默认大小将根据AudioFormat
而变化,并且似乎适用于高延迟,无间断的播放应用(例如互联网流媒体)。如果您正在开发低延迟应用程序,则默认缓冲区大小太大而且应该更改。
在我使用16位PCM AudioFormat
的测试中,1024字节的缓冲区大小非常接近低延迟的理想状态。