2

我正在制作一个有趣的 VOIP 程序,而且我大部分时间都在工作。自从我上一个问题以来,又出现了另一个问题。当使用 MixingWaveProvider 通过客户端播放两个或多个声音时,最终混合音频中会出现奇怪的卡顿、咔嗒声、卡顿和静态声音。大多数情况下,它听起来像是某人声音的一部分播放、暂停,然后让另一个人的声音播放一会儿。只要双方都在说话,这种情况就会持续(每个声音似乎“轮流”输出到waveMixer)。

我不会费心发布 Speex 编码/解码代码,因为无论是否使用它都会发生此问题。我通过 WaveInEvent 获得输入,它将信息输入 UDP 网络流。UDP 流将声音数据发送给其他客户端。

这是我用来初始化 WaveOut 和 MixingWaveProvider32 的代码:

waveOut = new DirectSoundOut(settings.GetOutputDevice(), 50);
waveMixer = new MixingWaveProvider32();
waveOut.Init(waveMixer);
waveOut.Play();

当客户端连接时,我将接收到的数据包数据输入到用户的 BufferedWaveProvider 中:

provider = new BufferedWaveProvider(format) { DiscardOnBufferOverflow = true };
wave16ToFloat = new Wave16ToFloatProvider(provider);

之后,我使用此代码将上述 32 位提供程序添加到 MixingWaveProvider32:

waveMixer.AddInputStream(wave16ToFloat);

在将 MixingWaveProvider32 传递给 WaveOut 之前添加的流似乎没有那么严重。但是,我真的需要能够动态添加它们。假设这就是发生这种情况的原因。

这可能与我的网络实现有关,所以如果这里没有找到其他东西,我会调查一下。会不会是每一个语音数据包都阻塞了下一个数据包的读取,从而造成来回的那种声音?如果是这样,我怎样才能在服务器上缓冲更长的数据或等待在客户端发送更大的块?

编辑:

我几乎可以肯定这是由 BufferedWaveProviders 每秒完全耗尽数次引起的。数据包没有足够快地填充它们,它们耗尽,没有任何东西可以传输。正如我上面所问的,有什么方法可以从客户端大块发送它们?或者我可以让缓冲区以某种方式消耗得更慢吗?

编辑2:

我现在已经实现了一个自动暂停缓冲区,以确保它保持填充状态。缓冲区在其内部缓冲区超过 1 秒的声音时取消暂停,并在数据低于 0.5 秒时暂停。但是,缓冲区在声音的 1 秒左右徘徊,我检查过它没有用完/暂停声音中流。虽然这应该是一件好事,但声音失真仍然存在,而且和以前一样糟糕。混音器或我的设置似乎有问题。

4

1 回答 1

1

听起来您已经诊断出问题所在。如果 BufferedWaveProviders 没有填满,那么您将获得沉默。您需要实现某种自动暂停来延迟播放,直到有足够的缓冲音频。一种作弊的方法是在每个缓冲区开始时保持 5 秒的静音,希望在该缓冲区播放完时再接收 5 秒的音频。

于 2013-08-31T20:00:02.283 回答