I have an application which plays the streamed audio data (like a chat client). The workflow involves three simple steps:
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.