Audio 快速音频输入/输出

Audio 快速音频输入/输出,audio,javasound,low-latency,Audio,Javasound,Low Latency,以下是我想做的: 我想让用户给我的程序一些声音数据(通过麦克风输入),然后保持250毫秒,然后通过扬声器输出 我已经使用Java声音API完成了这项工作。问题是它有点慢。从发出声音到从扬声器中再次听到声音至少需要1-2秒,我甚至还没有尝试实现延迟逻辑。理论上不应该有任何拖延,但确实有。我知道你必须等待声卡填满它的缓冲区或其他东西,样本大小和采样率与此有关 我的问题是:我是否应该继续沿着Java路径尝试这样做?如果可能的话,我想把延迟降低到100ms左右。有没有人有在Java中使用ASIO驱动程序

以下是我想做的:

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

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

我的问题是:我是否应该继续沿着Java路径尝试这样做?如果可能的话,我想把延迟降低到100ms左右。有没有人有在Java中使用ASIO驱动程序的经验?应该会更快


而且,我是一个.NET的人。用.NET代替它有意义吗?C++怎么样?我在这里寻找合适的技术,也许是一个很好的例子,说明如何使用您建议的技术平台读取/写入音频输入/输出流。谢谢你的帮助

我过去使用过JavaSound,发现它非常脆弱(而且在VM版本之间不断变化)。如果您喜欢C#,使用它,只需使用DirectX API即可。下面是一个使用DirectSound和C#实现某种目的的示例。你可以使用特效插件来执行250毫秒的回音

您可能需要研究一种专为低延迟声音处理而设计的音频API。此外,Google还提供了一个关于将JACK与Java结合使用的[PDF]

理论上不应该有任何拖延,但确实有

嗯,零延迟是不可能的。你所能期望的最好结果就是一个不可察觉的延迟(就人类感知而言)。如果你描述一下你读写声音数据的基本算法,这可能会有所帮助,这样人们就可以发现可能的问题


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

如果选择C/C++路径,我强烈建议使用PortAudio()。它可以在多个平台上处理几乎所有的事情,它可以让您对声音驱动程序进行低级别的控制,而无需实际处理各种各样的声音驱动技术


我在多个项目中使用过PortAudio,使用它真是一件乐事。而且许可证是允许的。

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


是一个用于实时音频输入和输出的低级C库。它甚至配备了一个完全可以实现您所需的功能的接口,即将麦克风输入传输到扬声器输出。

使用JavaSound可以在100-150毫秒的范围内获得端到端延迟

  • 延迟的主要原因是捕获和回放线路的缓冲区大小。打开行时设置大小:

    • 捕获:
      TargetDataLine#打开(音频格式,int-bufferSize)
    • 播放:
      SourceDataLine#打开(音频格式,int-bufferSize)
  • 如果缓冲区太大,则会导致延迟过长,但如果缓冲区太小,则会导致播放不连贯。因此,您需要在应用程序需求和计算能力之间找到平衡

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

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

  • 音频延迟的第二个也是经常被忽略的原因是在捕获或播放线程中执行的任何其他活动。例如,将消息记录到控制台可能会带来10毫秒的延迟。把它关掉

  • 它可以是低延迟。延迟部分取决于您的硬件。在这些限制范围内,您可以控制如何设置它,接收回调的块大小是多少,等等。很好,问题。。。我也在寻找合适的技术。:)我对多个
    SourceDataLine
    有问题,我想同步它们,但我认为存在GC问题,因为我的延迟超过8秒。开始时接近400毫秒,延迟开始逐渐增加。