问题描述
我有一个播放流音频数据的应用程序(如聊天客户端).工作流程包括三个简单步骤:
- 文件头信息(采样率,每个样本的位数和通道数)首先发送.
- 基于上述参数初始化音频波形输出设备.
- 已发送音频(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文件,并且看起来很完美,问题只有在我自己初始化设备后添加样本时才会出现.
[更新] 如果将s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
更改为s_WaveOut = new DirectSound();
,性能会更好.如果在此之后,我修改了Naudio信号源,以将播放线程优先级设置为Highest
(默认值为正常"),性能会进一步提高,但是正如预期的那样,该过程开始消耗大量资源.
谢谢
维克拉姆
我还使用NAudio开发音频流应用程序.我们也有延迟问题.达到300毫秒.
每秒捕获10次(一次100毫秒).
使用Vikram.exe的建议使用DirectSoundOut代替WaveOut有所帮助.延迟减少了50或100毫秒,但前提是我将所需延迟"设置为50毫秒.
new DirectSoundOut(guid, 50);
另一个技巧已将延迟降低了100或200毫秒.我们检查是否正在播放声音,如果有,则跳过新的帧.
if (s_WaveProvider.BufferedDuration <= 100)
s_WaveProvider.AddSamples(s_Samples, 0, size);
关于声音的平滑度,还有一些工作要做,但是现在我们通常没有等待时间了.
I have an application which plays the streamed audio data (like a chat client). The workflow involves three simple steps:
- The file header info (sample rate, bits per sample and num of channels) is sent first.
- Audio waveout device is initialized based on the above parameters.
- Audio (pcm) data is sent and is played on the above device.
The data receiving code is native (C code). and it reads data on a socket. Then it calls the managed C# code, which uses Naudio library to initialize device and play audio.
Now the problem is that, I am seeing some delay in audio playback. I have already instrumented the rest of my code (specifically: transferring data on socket and passing it back to managed code) and that seems to be okay. The whole transfer process is taking around 600 micro seconds, but after I assign the buffer to Naudio
, it seems to start playing it after some time (around 200-250 milliseconds).
Here is my C# class that handles the audio playing part:
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);
}
}
Anyone has any idea on what might be causing the delay or am I using it (Naudio) in some wrong way.
I tried the same Naudio library to play a wav file and that seems to work perfect, the problem is coming only when I am adding samples after initialing the device myself.
[update] If I change s_WaveOut = new WaveOut(WaveCallbackInfo.FunctionCallback());
to s_WaveOut = new DirectSound();
, the performance is much better. If after this, I modify the Naudio source to set playback thread priority to Highest
(default is Normal), the performace improves further, but as expected, the process starts consuming high resources.
Thank you,
Vikram
I also develop audio streaming application using NAudio. We also have latency issue. It reaches 300 ms.
The capture happens 10 times per second (once a 100 ms).
Using the advice of Vikram.exe to use DirectSoundOut instead of WaveOut helped a bit. The latency decreased by 50 or 100 ms, but only if I set Desired Latency to 50 ms.
new DirectSoundOut(guid, 50);
One more trick has lowered the latency by 100 or 200 ms. We check if there is a sound being played and skip new frames if it is.
if (s_WaveProvider.BufferedDuration <= 100)
s_WaveProvider.AddSamples(s_Samples, 0, size);
There is still some work to be done in regards of sound smoothness, but generally we have no latency now.
这篇关于流式音频播放的延迟(大约200毫秒)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!