这就是我想做的:

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

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

我的问题是这样的:我应该继续沿着 Java 路径尝试做到这一点吗?如果可能的话,我希望将延迟降低到 100 毫秒左右。有人有在 Java 中使用 ASIO 驱动程序的经验吗?据说还比较快..

另外,我是一个 .NET 人。这对于 .NET 有意义吗?那么 C++ 呢?我正在寻找在这里使用的正确技术,也许是如何使用您建议的技术平台读取/写入音频输入/输出流的一个很好的例子。感谢您的帮助!

有帮助吗?

解决方案

我过去使用过 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

其他提示

您可能想看看 JACK ,音频API设计的低延迟无害化处理。此外,谷歌变成了这个漂亮 [PDF]演示如何使用JACK与Java

  

理论上应该没有延迟,但有

好了,这是不可能具有零延迟。你可以期望的最好是不易察觉的延迟(在人类感知的方面)。如果你描述你的阅读和写作的声音数据的基本算法,它可能会帮助,使人们可以识别可能的问题。

通过使用垃圾回收的语言如Java的一个潜在的问题是,GC会定期运行,打断你的处理一定的时间任意数量。不过,我会感到惊讶,如果它>在正常使用100毫秒。如果GC是一个问题,多数JVM提供替代收集算法可以试试。

如果您选择走下来的C / C ++的路,我强烈建议使用PortAudio( http://portaudio.com/ )。它与在多个平台上几乎所有的东西,它给你的声卡驱动程序的低级别的控制,而不必实际处理各种声音驱动技术,它环绕。

我用PortAudio多个项目,这是一个真正的快乐使用。和许可证是许可。

如果低延迟是你的目标,你不能击败℃。

libsoundio 是用于实时音频输入和输出低电平的C库。它甚至还带有一个例如计划,你想要做什么 - 管道麦克风输入到扬声器输出

这当然是可以实现的 Java声音 获得大约 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. 音频延迟的第二个且经常被忽视的原因是捕获或播放线程中正在进行的任何其他活动。例如,将消息记录到控制台可能会导致数十毫秒的延迟。把它关掉。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top