4

这是我想要做的:

我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持 250 毫秒,然后通过扬声器输出回来。

我已经使用 Java Sound API 完成了这项工作。问题是它有点慢。从发出声音到再次从扬声器中听到声音的时间至少需要 1-2 秒,我什至还没有尝试实现延迟逻辑。理论上应该没有延迟,但确实存在。我知道您必须等待声卡填满其缓冲区或其他任何东西,并且样本大小和采样率与此有关。

我的问题是:我应该继续沿着 Java 路径尝试这样做吗?如果可能的话,我想将延迟降低到 100 毫秒。有没有人有使用 Java 的 ASIO 驱动程序的经验?应该是更快了。。

另外,我是一个 .NET 人。这是否与 .NET 相关?C++呢?我正在寻找合适的技术在这里使用,也许是如何使用您建议的技术平台读/写音频输入/输出流的一个很好的例子。谢谢你的帮助!

4

5 回答 5

3

我过去使用过 JavaSound,发现它非常不稳定(并且它在 VM 版本之间不断变化)。如果您喜欢 C#,请使用它,只需使用 DirectX API。这是一个使用 DirectSound 和 C# 做一些你想做的事情的例子。您可以使用效果插件来执行您的 250 毫秒回声。

http://blogs.microsoft.co.il/blogs/tamir/archive/2008/12/25/capturing-and-streaming-sound-by-using-directsound-with-c.aspx

于 2009-05-11T03:19:36.223 回答
3

您可能想查看JACK,这是一种专为低延迟声音处理而设计的音频 API。此外,Google 还提供了这个关于将 JACK 与 Java 结合使用的精彩演示文稿[PDF]。

理论上应该没有延迟,但确实存在。

那么,零延迟是不可能的。您可以期望的最好结果是不明显的延迟(就人类感知而言)。如果您描述读取和写入声音数据的基本算法可能会有所帮助,以便人们可以识别可能的问题。

使用像 Java 这样的垃圾收集语言的一个潜在问题是 GC 会定期运行,从而在任意时间内中断您的处理。但是,如果它在正常使用中大于 100 毫秒,我会感到惊讶。如果 GC 是个问题,大多数 JVM 都提供了可供您尝试的替代收集算法。

于 2009-05-13T00:04:50.343 回答
3

如果您选择走 C/C++ 路径,我强烈建议您使用 PortAudio ( http://portaudio.com/ )。它适用于多个平台上的几乎所有东西,它使您可以对声音驱动程序进行低级控制,而无需实际处理周围的各种声音驱动程序技术。

我在多个项目中使用过 PortAudio,使用起来真的很开心。并且许可证是允许的。

于 2009-05-13T20:41:32.863 回答
1

如果低延迟是您的目标,那么您无法击败 C。

libsoundio是一个用于实时音频输入和输出的低级 C 库。它甚至还附带了一个示例程序,可以完全满足您的要求 - 将麦克风输入连接到扬声器输出。

于 2015-10-24T19:34:29.713 回答
0

使用JavaSound在 100-150 毫秒的范围内获得端到端延迟当然是可以实现的。

  1. 延迟的主要原因是捕获和播放线的缓冲区大小。打开线条时设置大小:

    • 捕获:TargetDataLine#open(AudioFormat format, int bufferSize)
    • 回放:SourceDataLine#open(AudioFormat format, int bufferSize)

如果缓冲区太大,则会导致延迟过长,但如果缓冲区太小,则会导致播放卡顿。因此,您需要在应用程序需求和计算能力之间找到平衡点。

DataLine#getBufferSize调用时可以检查默认缓冲区大小#open(AudioFormat format)。默认大小将根据不同而有所不同,AudioFormat并且似乎适用于高延迟、无卡顿的播放应用程序(例如互联网流媒体)。如果您正在开发低延迟应用程序,则默认缓冲区大小太大,应该更改。

在我使用 16 位 PCM 进行的测试中AudioFormat,1024 字节的缓冲区大小已经非常接近低延迟的理想值。

  1. 音频延迟的第二个也是经常被忽视的原因是在捕获或播放线程中执行的任何其他活动。例如,将消息记录到控制台可能会引入 10 毫秒的延迟。把它关掉。
于 2016-02-22T04:12:29.923 回答