我有一个播放流式音频数据的应用程序(如聊天客户端)。该工作流程涉及三个简单步骤:
- 首先发送文件头信息(采样率、每个样本的位数和通道数)。
- 音频波形输出设备根据上述参数进行初始化。
- 音频(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());
to s_WaveOut = new DirectSound();
,性能好很多。如果在此之后,我修改 Naudio 源以将播放线程优先级设置为Highest
(默认为“正常”),性能进一步提高,但正如预期的那样,该进程开始消耗大量资源。
谢谢你,
Vikram