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