private void PlaybackProc(object playbackStartedEventWaithandle) { try { int bufferSize; int frameSize; byte[] buffer; int eventWaitHandleIndex; WaitHandle[] eventWaitHandleArray; bufferSize = _audioClient.BufferSize; frameSize = _outputFormat.Channels * _outputFormat.BytesPerSample; buffer = new byte[bufferSize * frameSize]; eventWaitHandleIndex = WaitHandle.WaitTimeout; eventWaitHandleArray = new WaitHandle[] { _eventWaitHandle }; //001 /*if (!FeedBuffer(_renderClient, buffer, bufferSize, frameSize)) //todo: might cause a deadlock: play() is waiting on eventhandle but FeedBuffer got already called * { * _playbackState = PlaybackState.Stopped; * if (playbackStartedEventWaithandle is EventWaitHandle) * { * ((EventWaitHandle)playbackStartedEventWaithandle).Set(); * playbackStartedEventWaithandle = null; * } * } * else * {*/ _audioClient.Start(); _playbackState = SoundOut.PlaybackState.Playing; if (playbackStartedEventWaithandle is EventWaitHandle) { ((EventWaitHandle)playbackStartedEventWaithandle).Set(); playbackStartedEventWaithandle = null; } while (PlaybackState != PlaybackState.Stopped) { if (_eventSync) //based on the "RenderSharedEventDriven"-Sample: http://msdn.microsoft.com/en-us/library/dd940520(v=vs.85).aspx { eventWaitHandleIndex = WaitHandle.WaitAny(eventWaitHandleArray, 3 * _latency, false); //3 * latency = see msdn: recommended timeout if (eventWaitHandleIndex == WaitHandle.WaitTimeout) { continue; } } else //based on the "RenderSharedTimerDriven"-Sample: http://msdn.microsoft.com/en-us/library/dd940521(v=vs.85).aspx { Thread.Sleep(_latency / 8); } if (PlaybackState == PlaybackState.Playing) { int padding; if (_eventSync && _shareMode == AudioClientShareMode.Exclusive) { padding = 0; } else { padding = _audioClient.GetCurrentPadding(); } int framesReadyToFill = bufferSize - padding; if (framesReadyToFill > 5 && !(_source is DmoResampler && ((DmoResampler)_source).OutputToInput(framesReadyToFill * frameSize) <= 0)) //avoid conversion errors { if (!FeedBuffer(_renderClient, buffer, framesReadyToFill, frameSize)) { _playbackState = PlaybackState.Stopped; //TODO: Fire Stopped-event here? } } } } Thread.Sleep(_latency / 2); _audioClient.Stop(); _audioClient.Reset(); //} } finally { //CleanupResources(); if (playbackStartedEventWaithandle is EventWaitHandle) { ((EventWaitHandle)playbackStartedEventWaithandle).Set(); } RaiseStopped(); } }