2012-08-08 42 views
2


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

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

我与waveOutXXX多次编程,没有任何问题,我知道它好,但我解决不了我的动态重采样

+0

另外,网络数据缓冲也可能会产生影响,使得网络堆栈首先尝试预缓冲数据(以便更有效地以更大的块形式发送),从而导致罕见地发送小块数据和间隙在接收方。 – 2012-08-08 14:53:56

+0

这是一个很好的说明,但由于我有一个连续的数据(每秒16K)是否真的影响网络的缓冲?并且我缓冲了1秒钟的数据,所以指定的问题不应该是可以在我的回放系统中产生空隙的东西 – BigBoss 2012-08-09 20:23:57

+0

我认为最好的做法是做一个测试,看看发生了什么。 – 2012-08-09 20:27:29

回答

1

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

现在,在很长一段时间内,记录端的时钟和播放端的时钟可能会漂移得足够远,以至于300ms的缓冲区已经不够用了。我会建议,不要重新采样这样一个可能会引入伪像的小差异,只需在编码端添加样本即可。你仍然可以以8kHz记录,但你可能会每秒钟增加一个或两个样本,以达到8.001kHz左右。简单地将现有样本中的一个样本加倍(甚至是一个样本与下一个样本之间的简单平均值)将不会被听到。根据您的应用需要进行调整。

+0

感谢Brad对你的回应。但我使用了一个不是300毫秒的1秒缓冲区,而且我仍然有问题。我说我已经播放了很多波形文件,没有任何问题,所以我知道我应该在哪里添加缓冲区,但是在播放的一面添加一个或多个样本的想法看起来很有道理。如果玩边比录音边快,我该怎么办?以及为什么我有这么大的缓冲区(1秒)的错误 – BigBoss 2012-08-09 20:17:04

+0

@BigBoss,我认为这个问题不是专门缓冲,而是在你的代码或方法中有错误。您需要生成稳定的数据流才能发送到声卡,就好像您正在播放一个长WAV文件一样。您不能发送一个缓冲区,然后再发送另一个缓冲区,然后发送另一个您需要编程连接这些缓冲区并稳定地将它们发送到声卡的缓冲区。添加样本可以修复播放端比录制端更快的问题。如果你添加了太多的样本,你可以做相反的事情。远程缓冲区上的遥测将很有用。 – Brad 2012-08-09 20:22:56

+0

让我解释一下我的程序。我从我的服务器接收数据。我会将它分成固定的声音块并缓冲它们长达1秒,然后开始播放,将所有准备好的波形标题写入声卡,然后在从服务器接收到数据时,数据的大小与我的一样多固定长度,我添加一个新的缓冲区声卡(如果我有一个返回的波头)或我下次缓冲数据窗口通知我的WOM_DONE。 – BigBoss 2012-08-09 20:32:22

1

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

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

我解决这个问题的方法是先让音频缓冲区变长。然后,每当收到一个新的音频块时,我检查了缓冲区是多么充分。如果它还不到20%,我会写一些沉默,使其达到60%左右。

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

当缓冲区开始变空时,但在实际执行之前写入静音,以确保缓冲区总是有一些数据可用,以便处理稍后。而且,与许多周期性间隙相比,播放中的单个小间隙很难被注意到。

我不知道这是否适用于您,但它应该很容易实施并尝试。

+0

正如你所说,易于实施和测试,我会明天检查它并让你知道结果 – BigBoss 2012-08-09 20:26:40