我正在创建一个客户端/服务器音频系统,它可以通过网络任意传输音频。一个中央服务器泵出音频流,x个客户端接收音频数据并播放它。到目前为止还没有任何魔法需要,我甚至可以将这个场景与开箱即用的VLC媒体播放器配合使用。
然而,棘手的部分似乎是同步音频播放,以便所有客户端都处于可听见的同步状态(只要感知人类听众同步,就可以允许实际延迟)。
我的问题是,如果有任何已知的方法或算法用于此类同步问题(视频可能以相同的方式解决)。我最初的想法是围绕物理机器之间的时钟同步,从而创建一个虚拟的“主计时器”,并以某种方式将音频数据包与它对齐。
有些产品已经解决了这个问题(但对我的整体用例来说还不够):
欢迎提出任何指示。 感谢。
PS:This related question似乎很久以前就已经死了。
答案 0 :(得分:30)
Ryan Barrett在his blog上写下了他的发现。
他的解决方案涉及使用NTP作为一种方法来保持所有时钟同步:
但是,说真的,只有一个 p4sync的技巧,就是这样 使用NTP。一台主机充当p4sync 服务器。其他p4sync客户端 将它们的系统时钟同步到 服务器的时钟,使用SNTP。当。。。的时候 服务器开始播放一首歌吧 记录时间,到毫秒。 然后客户端检索它 时间戳,计算差异 在当前时间之间 时间戳,并向前迈进 进入歌曲。
答案 1 :(得分:10)
查看Microsoft Research的Tom Blank撰写的论文An Internet Protocol Sound System。他解决了你正在处理的确切问题。他的解决方案包括在机器之间同步时钟并使用时间戳让它们同时播放。这种方法的缺点是延迟。要使所有时钟同步,需要在网络上以最大延迟标记时间。
答案 2 :(得分:9)
难题,但可能。
使用NTP或tictoc为您自己建立一个具有系统时间源已知速率的同步时钟。
同时保持估算器运行时钟的速率;通常的做法是使用正在播放的相同声音设备进行录制,在预装有幻数的缓冲区上进行录制,并通过同步时钟查看声卡在测量时间内到达的位置(反之亦然,请参阅在同步时钟上执行已知数量的样本需要多长时间。你需要继续这样做,时钟会相对于网络时间漂移。
所以现在您确切地知道您需要输出的声卡时钟每秒有多少样本以匹配同步时钟的速率。因此,您然后以该速率插入从网络接收的样本,加上或减去校正,如果您需要从最后一个缓冲区的位置赶上或回落一点。你需要非常小心地进行这种插值,使其不会引入音频伪像。有一些示例代码here用于您需要的算法,但在您加快速度之前,它将会进行相当多的阅读。
如果您的来源是实时录制,当然,您必须在发送之前测量该声卡的采样率并插入网络时间样本。
答案 3 :(得分:6)
根据场地的大小和形状,将所有内容与 同步是一件容易的事,让声音正确的一切都是艺术形式本身,如果可能的话。从技术方面来说,最困难的部分是找出从同步时间线到实际声音输出的延迟。具有相同的硬件和低延迟软件框架(ASIO,JACK)肯定有帮助,校准也是如此。提前或活跃。否则,它只是将时间线与NTP同步,并使用闭环反馈到音频音调,以使输出与约定的时间线同步。
更大的问题是声音需要相当长的时间才能传播。距离差10m已经是30ms的延迟 - 足以搞定声音定位。加倍,你进入烦人的回声领域。专业音频设置实际上有目的地引入延迟,使用更多数量的高频扬声器并播放混响,以避免让听众感到厌恶的回声。
答案 4 :(得分:0)
“...只要它被人类听众认为是同步的” - 很难做到因为耳朵比眼睛更不宽容。特别是如果你想通过无线网络这样做。
我会首先尝试使用基于网络的技术,远程控制闪存音频播放器 由服务器通过Javascript。
如果这会产生不好的结果,那么我会尝试通过使用python(使用pygame)来获得更多控制。
如果正在取得进展,我也会尝试使用ChucK并尝试使用ALSA音频库进行低级编程。
如果没有任何令人满意的结果,我会来重新审视这篇文章,实际上是由专业的音频编程大师阅读一些明智的东西,如果我的生活依赖于它,可能最终会为商业NetChorus应用程序分配14英镑类似。