naudio / NAudio

Audio and MIDI library for .NET
MIT License
5.56k stars 1.1k forks source link

WaveIn - StartRecording ends up with NAudio.MmException #692

Open Jigfreed opened 4 years ago

Jigfreed commented 4 years ago

When I disable and re-enable microphone on system level the next one calling of WaveIn.StartRecording ends up with MmException: NoDriver calling waveInPrepareHeader.

NAudio.MmException: NoDriver calling waveInPrepareHeader
   v NAudio.Wave.WaveInBuffer.Reuse()
   v NAudio.Wave.WaveIn.Callback(IntPtr waveInHandle, WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)    v NAudio.Wave.WaveInBuffer.Reuse()
   v NAudio.Wave.WaveIn.Callback(IntPtr waveInHandle, WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)

My simplified WaveIn initialization looks like:

micRecording = new WaveIn { WaveFormat = new WaveFormat(8000, 1) }; 
micRecording.DataAvailable += WaveSource_DataAvailable;
micRecording.RecordingStopped += WaveSource_RecordingStopped;
micRecording.StartRecording();

Note that the exception is not thrown when the recording was not started previously in past.

Sometimes the StartRecording will pass correctly, but recording will stop immediately with similar exception:

NAudio.MmException: NoDriver calling waveInAddBuffer
   v NAudio.Wave.WaveInBuffer.Reuse()
   v NAudio.Wave.WaveIn.Callback(IntPtr waveInHandle, WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)    v NAudio.Wave.WaveInBuffer.Reuse()
   v NAudio.Wave.WaveIn.Callback(IntPtr waveInHandle, WaveMessage message, IntPtr userData, WaveHeader waveHeader, IntPtr reserved)

The only walkaround I found is to call StartRecording again when MmException is thrown - the next try will be ok in most cases but I cannot use this walkaround when recording starts correctly but then stops on exception immediately.

WasapiCapture does not have this bug but needs some extra resamling in my case so I would prefer the WaveIn.

markheath commented 3 years ago

I suggest you try using WaveInEvent instead. Uses a more reliable callback mechanism