我正在该服务器中编写客户端/服务器应用程序发送实时音频数据,捕获从某些外部设备(例如麦克风)捕获的音频样本并将其发送到客户端。然后客户想要播放这些样本。我的应用程序将在本地网络上运行,所以我没有带宽问题(我的声音是8k,8位立体声,而我的网卡1000Mb)。在客户端I缓冲数据一小段时间,然后开始播放。当数据从服务器到达时,我将它们发送到声卡。这似乎工作正常,但有一个问题:
当我在客户端的缓冲区完成时,我会遇到播放声音的差距
我认为这是因为服务器和客户端的采样时间不同,这意味着服务器上的8K与客户端上的8K不同。
我可以通过再次暂停客户端的播放和缓冲来解决这个问题,但我的老板不接受它,因为我有适当的带宽,我应该能够播放无间隙或暂停的声音。
所以我决定动态改变客户端的播放速度,但我不知道如何。
我在Windows(本机)编程,我目前使用waveOutXXX播放声音。我可以使用任何其他本机库(DirectX / DirectSound,Jack或......),但它们应该在客户端提供流畅的播放。
我已经使用waveOutXXX多次编程没有任何问题,我知道它很好,但我无法解决我的动态重采样问题
答案 0 :(得分:1)
我在我工作的应用程序中遇到了类似的问题。它不涉及网络,但确实涉及以一定的固定采样率实时捕获源数据,大量信号处理,最后以固定速率输出到声卡。和你一样,我在缓冲区边界的播放中有间隙。
在我看来,问题是正在进行的处理导致音频数据以非常不稳定的方式进入声卡。也就是说,它会获得一大块,然后在它获得另一块之前需要很长时间。整体吞吐量是正确的,但这种延迟导致声卡经常缺乏数据。我想你的系统中的网络部分可能会有相同的情况。
我解决它的方法是首先使音频缓冲区更长。然后,每次收到新的音频块时,我都检查了缓冲区的填充程度。如果它不到20%满,我会写一些沉默,使其大约60%满。
你可能认为这不利于减少回放中的差距,因为它实际上增加了一个差距,但实际上它有所帮助。我遇到的问题是即使我有一个非常大的音频缓冲区,我总是处于空洞的边缘。由于系统中存在其他延迟,因此几乎每个缓冲区都会出现回放间隙。
当缓冲区开始变空时写入静音,但在它实际发生之前,确保缓冲区总是有一些数据可用,如果处理稍微落后。此外,与许多周期性间隙相比,回放中只有一个小差距很难被注意到。
我不知道这是否适合您,但它应该易于实施和试用。
答案 1 :(得分:1)
我建议您的问题可能不是由于错误匹配的采样率,而是与您的缓冲有关。您应该不断地将数据转储到声卡,并不断填充缓冲区。使用合理的缓冲区大小......对于大多数应用程序来说,300毫秒就足够了。
现在,在很长一段时间内,录制侧的时钟和播放侧的时钟可能会分开,足以使300ms缓冲区不再足够。我建议不要在如此小的差异上重新采样,这可能会引入伪像,只需在编码端添加样本即可。您仍然以8kHz的速度录制,但是您可以每秒添加一两个样本,以达到8.001kHz左右。简单地将现有样本中的一个加倍(或者甚至是一个样本与下一个样本之间的简单平均值)将是听不见的。根据您的应用需要进行调整。