2


我正在该服务器中编写一个客户端/服务器应用程序,发送实时音频数据,捕获从某些外部设备(例如麦克风)捕获的音频样本并将其发送到客户端。然后客户想要播放这些样本。我的应用程序将在本地网络上运行,所以我的带宽没有问题(我的声音是 8k,8bit 立体声,而我的网卡是 1000Mb)。在客户端中,我将数据缓冲一小段时间,然后开始播放。当数据从服务器到达时,我将它们发送到声卡。这似乎工作正常,但有一个问题:
当我在客户端的缓冲区完成时,我会遇到播放声音的间隙。
我认为这是因为服务器和客户端的采样时间不同,这意味着服务器上的 8K 与客户端上的 8K 不同。
我可以通过再次暂停客户端的播放和缓冲来解决这个问题,但我的老板不接受,因为我有适当的带宽,我应该能够播放声音而没有间隙或暂停。
所以我决定在客户端动态改变播放速度,但我不知道怎么做。

我在 Windows(本机)中编程,目前使用 waveOutXXX 播放声音。我可以使用任何其他本机库(DirectX/DirectSound、Jack 或 ...),但它们应该在客户端提供流畅的播放。

我已经用 waveOutXXX 编程了很多次,没有任何问题,我知道它很好,但我无法解决我的动态重采样问题

4

2 回答 2

1

我在我处理的应用程序中遇到了类似的问题。它不涉及网络,但它确实涉及以一定的固定采样率实时捕获源数据,大量的信号处理,最后以固定的速率输出到声卡。和你一样,我在缓冲区边界的播放中也有间隙。

在我看来,问题在于正在完成的处理导致音频数据以非常生涩的方式进入声卡。也就是说,它会得到一个很大的块,然后需要很长时间才能得到另一个块。总体吞吐量是正确的,但是这种延迟导致声卡经常缺乏数据。我想你的系统中的网络部分可能有同样的情况。

我解决它的方法是首先使音频缓冲区更长。然后,每次收到新的音频块时,我都会检查缓冲区的满载情况。如果它不到 20% 满,我会写一些静默,让它大约 60% 满。

您可能会认为这不利于减少播放中的间隙,因为它实际上是在增加间隙,但它确实有帮助。我遇到的问题是,即使我有一个非常大的音频缓冲区,我总是处于它为空的边缘。由于系统中的其他延迟,这导致几乎每个缓冲区的播放间隙。

当缓冲区开始变空时写入静默,但在它真正变空之前,确保缓冲区总是有一些数据可以在处理落后一点时保留。此外,与许多周期性间隙相比,播放中只有一个小间隙很难注意到。

我不知道这是否对你有用,但它应该很容易实现和试用。

于 2012-08-08T14:09:16.660 回答
1

我建议您的问题不太可能是由于采样率不匹配,而是与您的缓冲有关。您应该不断地将数据转储到声卡,并不断填充缓冲区。使用合理的缓冲区大小......对于大多数应用程序来说,300 毫秒应该足够了。

现在,在很长一段时间内,录制端的时钟和播放端的时钟可能会偏离得足够远,以至于 300 毫秒的缓冲区不再足够。我建议不要以可能引入伪影的如此小的差异重新采样,而只需在编码端添加样本。您仍然以 8kHz 录制,但您可能每秒添加一两个样本,以达到 8.001kHz 左右。简单地将现有样本之一加倍(或者甚至是一个样本与下一个样本之间的简单平均值)将听不见。根据您的应用程序的需要进行调整。

于 2012-08-08T14:39:39.933 回答