private void OnBufferDone(WaveOutBuffer buffer) { if (playbackState == PlaybackState.Playing) { if (!buffer.OnDone()) { playbackState = PlaybackState.Stopped; RaisePlaybackStopped(); } } }
/// <summary> /// Made non-static so that playing can be stopped here /// </summary> /// <param name="hWaveOut"></param> /// <param name="uMsg"></param> /// <param name="dwInstance"></param> /// <param name="wavhdr"></param> /// <param name="dwReserved"></param> private void Callback(IntPtr hWaveOut, WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved) { if (uMsg == WaveMessage.WaveOutDone) { GCHandle hBuffer = (GCHandle)wavhdr.userData; WaveOutBuffer buffer = (WaveOutBuffer)hBuffer.Target; Interlocked.Decrement(ref _queuedBuffers); Exception exception = null; // check that we're not here through pressing stop if (PlaybackState == PlaybackState.Playing) { // to avoid deadlocks in Function callback mode, // we lock round this whole thing, which will include the // reading from the stream. // this protects us from calling waveOutReset on another // thread while a WaveOutWrite is in progress lock (_waveOutLock) { try { if (buffer.OnDone()) { Interlocked.Increment(ref _queuedBuffers); } } catch (Exception e) { // one likely cause is soundcard being unplugged exception = e; } } } if (_queuedBuffers == 0) { if (_callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback && _playbackState == PlaybackState.Stopped) { // the user has pressed stop // DO NOT raise the playback stopped event from here // since on the main thread we are still in the waveOutReset function // Playback stopped will be raised elsewhere } else { // set explicitly for when we reach the end of the audio. _playbackState = PlaybackState.Stopped; RaisePlaybackStoppedEvent(exception, (_pressStop ? false : true)); } } } }