来自网络的多个音频流的软件混合

信息处理 音频处理 pcm
2022-02-03 00:23:31

TLDR:当流可能不可靠时,如何混合网络流?

我正在开展一个项目,该项目将允许音乐家通过互联网以低延迟一起练习/表演。(想想 JackTrip,但对用户更友好)。

我通过网络上的 UDP 接收原始 PCM 音频数据。当这些进来时,我确定发送者是谁,并将该流传输到该特定人的缓冲区中。我对每个参与的人都有一个单独的缓冲区。

然后我定期从每个缓冲区中一次取一个“块”,将它们混合在一起并输出到设备的扬声器。

我遇到的问题是知道什么时候拿那个“块”。一些客户端离线并且他们的缓冲区空了。我不能只是等待他们的缓冲区重新填充,因为这会减慢其他客户端的速度。

我的想法是查看特定时间点的所有缓冲区,并且仅在填充了至少一半的缓冲区时才处理一个块。

有任何想法吗?

其他详情:

  • 我的缓冲区有 128 个样本。
  • 我正在使用 44100 的采样率
  • 我正在使用 16 位有符号整数 pcm
  • 流是单声道
  • 我正在使用PortAudio和 C++。
  • 我正在使用 ASIO 音频驱动程序。
1个回答

通常,您将需要某种排序时间同步协议。

通常,您希望为每个网络通道在本地创建一个循环缓冲区。一旦数据包进来,您就将其推入循环缓冲区或写入位置的该通道。

播放由您当地的 D/A 时钟计时。一旦 D/A 缓冲区为空,您就从当前读取位置的所有客户端循环缓冲区中抓取一帧,将它们混合在一起并将它们放入 D/A 缓冲区。

您需要管理两件事。

  1. 丢弃:如果您需要一个新的播放帧并且客户端的循环缓冲区为空或数据包被丢弃(它们应该被编号以检测这一点),就会发生这种情况。你无能为力。您可以玩零或尝试从先前的缓冲区推断 丢失意味着您的网络无法跟上。
  2. 时钟漂移。即使每个人都在名义上以 44.1kHz 播放,也没有两个时钟是相同的,并且随着时间的推移它们会分开。要解决这些问题,您需要 a) 测量时钟漂移并 b) 纠正它。a) 可以通过全局时间参考(类似于 NTP)、通过平均数据包到达时间或监控缓冲区级别来完成。b)将需要某种采样率转换:最粗略的选择是偶尔丢帧插入零帧。

这是一个古老的权衡:延迟越低,退出率就越高。因此,“最佳”拨号是这里的关键。调整起来很容易:只需使您的循环缓冲区更小/更大。然而,找到最优值是困难的,因为它在很大程度上取决于当前的网络条件,所以在实践中这确实应该是自适应的。