流音频播放中的延迟(大约200毫秒)

本文关键字:大约 200毫秒 延迟 音频 播放 | 更新日期: 2023-09-27 18:19:00

我有一个应用程序播放流音频数据(如聊天客户端)。该工作流包括三个简单的步骤:

  1. 首先发送文件头信息(采样率,每采样位和通道数)。
  2. 根据上述参数初始化音频波形设备。
  3. 音频(pcm)数据在上述设备上发送和播放。

数据接收代码为本机(C代码)。它读取套接字上的数据。然后调用托管c#代码,该代码使用Naudio库初始化设备并播放音频。

现在的问题是,我看到一些音频播放延迟。我已经检测了我的代码的其余部分(具体来说:在套接字上传输数据并将其传递回托管代码),这似乎是好的。整个传输过程大约需要600微秒,但在我将缓冲区分配给Naudio之后,它似乎在一段时间(大约200-250毫秒)后开始播放它。

这是我的c#类处理音频播放部分:

class foo
{
    static  IWavePlayer     s_WaveOut;
    static  WaveFormat      s_WaveOutFormat;
    static  BufferedWaveProvider    s_WaveProvider;
    static  byte[]          s_Samples       = new byte[10000];
    // called from native code to init deivce with specified sample rate and num of channels
    private static void DeviceInit(int rate, int bits, int channels)
    {
        s_WaveOut   = new WaveOut(WaveCallbackInfo.FunctionCallback());
        s_WaveOutFormat = new WaveFormat(rate, bits, channels);
        s_WaveProvider  = new BufferedWaveProvider(s_WaveOutFormat);
        s_WaveProvider.DiscardOnBufferOverflow      = true;
        s_WaveProvider.BufferLength         = 5 * 1024 * 1024;
        s_WaveOut.Init(s_WaveProvider);
        s_WaveOut.Play();
    }
    // called from native 'C' code upon receiving audio packates
    private unsafe static void PlayDataCallback(
        IntPtr buff,
        Int32 size) 
    {
        Marshal.Copy(buff, s_Samples, 0, size);
        s_WaveProvider.AddSamples(s_Samples, 0, size);
    }
}

有没有人知道是什么原因导致了延迟,或者是我用了错误的方式使用它(Naudio)。

我尝试了相同的Naudio库来播放wav文件,这似乎工作完美,只有当我在初始化设备后添加样本时,问题才会出现。

[update]如果我将s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());改为s_WaveOut = new DirectSound();,性能会好得多。如果在此之后,我修改Naudio源以将播放线程优先级设置为Highest(默认为Normal),则性能进一步提高,但正如预期的那样,该进程开始消耗高资源。

谢谢你,

Vikram

流音频播放中的延迟(大约200毫秒)

我还使用NAudio开发音频流应用程序。我们也有延迟问题。达到300毫秒

捕获每秒发生10次(100毫秒一次)。

使用Vikram.exe的建议使用DirectSoundOut而不是WaveOut有一点帮助。延迟减少了50或100毫秒,但前提是我将Desired latency设置为50毫秒

new DirectSoundOut(guid, 50);

另一个技巧将延迟降低了100或200毫秒。我们检查是否有声音正在播放,如果有,则跳过新帧。

if (s_WaveProvider.BufferedDuration <= 100)
    s_WaveProvider.AddSamples(s_Samples, 0, size);

在声音平滑方面仍有一些工作要做,但通常我们现在没有延迟。

音频播放总是会引入延迟。对于WaveOut,您可以指定缓冲区的数量和所需的总体延迟。您还可以为其他驱动程序模型指定缓冲区大小。对于大多数回放场景,每个100ms的两个缓冲区是理想的,因为它具有合理的响应性,除非在极端负载下,否则不会出现卡顿。但是,如果需要的话,可以降低,但是要冒无法及时填充下一个缓冲区的风险。不要指望NAudio的延迟会像DAW那样低(例如5毫秒),它没有经过高度优化,而且由于垃圾收集器的原因,. net框架并不特别适合这种应用程序。

下面是设置WaveOut输出延迟的示例:

var waveOut = new WaveOut();
waveout.DesiredLatency = 50; // 50ms latency