0

I have a small c# application that uses the waveout interface to periodically call waveoutwrite for writing audio data to the soundcard. I do not use NAudio because I need to use a fixed buffersize of 8192 bytes.

I use the mmdll library in a wrapper class called WaveNative:

// native calls
[DllImport(mmdll)]
public static extern int waveOutGetNumDevs();
[DllImport(mmdll)]
public static extern int waveOutPrepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutUnprepareHeader(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutWrite(IntPtr hWaveOut, ref WaveHdr lpWaveOutHdr, int uSize);
[DllImport(mmdll)]
public static extern int waveOutOpen(out IntPtr hWaveOut, int uDeviceID, WaveFormat lpFormat, WaveDelegate dwCallback, int dwInstance, int dwFlags);
[DllImport(mmdll)]
public static extern int waveOutReset(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutClose(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutPause(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutRestart(IntPtr hWaveOut);
[DllImport(mmdll)]
public static extern int waveOutGetPosition(IntPtr hWaveOut, out int lpInfo, int uSize);
[DllImport(mmdll)]
public static extern int waveOutSetVolume(IntPtr hWaveOut, int dwVolume);
[DllImport(mmdll)]
public static extern int waveOutGetVolume(IntPtr hWaveOut, out int dwVolume);

Now I open the device by calling:

int msg = WaveNative.waveOutOpen(out myWaveOutHandleAsIntPtr, device, waveformatOfAudioFile, callbackDelegate, 0, WaveNative.CALLBACK_FUNCTION);

This works and I can write audio data to the device. BUT: When the sound has finished playing, I wait for the callback method to signal that all my audio buffers (I have 2 of them, each 8192 bytes) have finished playing:

// Inside the callback method:
if (callbackswaiting > 0)
{
    callbackswaiting--;
    if(callbackswaiting == 0)
    {
        WaveNative.waveOutReset(myWaveOutHandleAsIntPtr);
        WaveNative.waveOutClose(myWaveOutHandleAsIntPtr);
    }
}

Now, anytime I try to call the waveOutOpen() method again, my program just hangs. It does not return any error, it just hangs.

What am I doing wrong?

AudioGuy
  • 413
  • 5
  • 18
  • 1
    Closing the waveOut *while* it has an active callback is not very healthy. This invariably works better when you delay the call until the callback is complete. Like using the dispatcher's Begininvoke() method or making the call on an async task. You now get to interlock this yourself, ensure you don't call waveOutOpen until the close call completed. – Hans Passant Dec 16 '17 at 13:20
  • @HansPassant you're completely correct. I now delayed closing the device until after every callback has safely finished. It works like a charm now. – AudioGuy Dec 17 '17 at 16:47

0 Answers0