This project has moved. For the latest updates, please go here.

Stop or Dispose methods hang if USB device undocked while playing wav file

Dec 2, 2011 at 9:36 AM

We are using NAudio to play sound through a USB device and have a problem where the Stop or Dispose methods for out WaveOut object hangs. It seems the problem only happens if the user undocks the USB device while WaveOut is playing a wav file. We are getting no exceptions being throw for us to catch and handle this event.

We have simplified our threading model, but this has not solved anything and still find that NAudio deadlocks on us, with the callback method holding onto a lock. It seems to hold onto the lock because its call to the winmm.dll waveOutWrite method call hangs, or never returns, or throws an exception because the device is not there anymore.

Any suggestions would be appreciated.

Mark

Coordinator
Dec 2, 2011 at 9:39 AM

are you using function callbacks? and are you using the very latest NAudio (build from source)?

I fixed a deadlock with function callbacks a while back, and there is also WaveOutEvent which is the preferred option going forwards instead of function callbacks

 

Mark

Dec 2, 2011 at 10:03 AM

Mark,

 

We have a version on the DLL of 1.5.3.0 and the following code causes the problem we have...

 

 

ManualResetEvent stopped = new ManualResetEvent(false);

 

private void playsound(string fileName)

{ 

 

  using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))

  {

 

 

 

 

 

 

 

  waveOut.PlaybackStopped += new EventHandler(waveOut_PlaybackHasStopped);

  waveOut.DeviceNumber = 0;

  waveOut.DesiredLatency = 200;

  waveOut.Init(inputStream);

  waveOut.Play(); 

 

  for (; ; )

 

 

      break;

    if (maxPlaySeconds > 0 && DateTime.Now.CompareTo(quitTime) >= 0)

     }

   }

 

  }

// DeadLock at this point. 

} 

 

 

private void waveOut_PlaybackHasStopped(object sender, EventArgs e)

{

  stop.Set();

}

 

 -mjl

    {

       break;

  { 

 

 

    if(stop.WaitOne(100))

Dec 2, 2011 at 1:59 PM

I got my solution to work. Changed from the WaveOut class to the WaveOutEvent class, in the WaveOutEvent class the call to the WinMM.Dll waveOutWrite method would throw and exception instead of deadlocking. I ammended the code for WaveOutEvent to catch the MMException being thrown, this catch is in the PlaybackThread method and the handler has the following

catch(MmException ex)

{

buffer = null;

playbackState = PlaybackState.Stopped;

System.Diagnostics.Debug.WrtieLine(ex); // so a debugger can view this is happend and to be able to log using trace listeners.

}

 

If I did not catch the exception there I would get an unhandled error which is not caught by the application general exception error and my appliation would crash and be unloaded from memory.

 

Mark

Feb 2, 2012 at 9:28 PM

Just wanted to post in case it is useful to other users.  Replacing WaveOut with WaveOutEvent in one of our classes fixed a similar deadlock situation we were experiencing when playing a wav file repeatedly in the same run of the application.  The first play would be successful then subsequent attempts would lock the application.  Quite literally all we had to do was swap the classes and the problem cleared.  Thanks Mr. Heath, extraordinarily useful project!

Coordinator
Feb 6, 2012 at 12:53 PM

glad you got it working in the end. the function callbacks have been nothing but trouble and I may even depracate them in the future

Jul 26, 2012 at 12:56 AM

Thanks for this post folks.

I ran into a similiar problem this evening.  I noticed whenever I unplugged my headphones my waveout device would stop reading the input stream.  I put in a timeout that would throw an exception and try to dispose of the waveout device.  The dispose method would hang.

I switched to the WaveOutEvent class and everything is happy again.