private void PlaybackProc(object o) { var waitHandle = o as EventWaitHandle; WaitHandle[] waitHandles = null; Exception exception = null; try { //004 //bool flag = true; int bufferSize = _secondaryBuffer.BufferCaps.BufferBytes; var latencyBytes = (int)_source.WaveFormat.MillisecondsToBytes(_latency); var buffer = new byte[bufferSize]; _primaryBuffer.Play(DSBPlayFlags.Looping); //default flags: looping //003 /*if (flag) //could refill buffer * {*/ /* * Setup notify */ var waitHandleNull = new EventWaitHandle(false, EventResetMode.AutoReset); var waitHandle0 = new EventWaitHandle(false, EventResetMode.AutoReset); var waitHandleEnd = new EventWaitHandle(false, EventResetMode.AutoReset); waitHandles = new WaitHandle[] { waitHandleNull, waitHandle0, waitHandleEnd }; _directSoundNotify = _secondaryBuffer.QueryInterface <DirectSoundNotify>(); DSBPositionNotify[] positionNotifies = { new DSBPositionNotify { Offset = DSBPositionNotify.OffsetZero, EventNotifyHandle = waitHandleNull.SafeWaitHandle.DangerousGetHandle() }, new DSBPositionNotify { Offset = (int)_source.WaveFormat.MillisecondsToBytes(_latency), EventNotifyHandle = waitHandle0.SafeWaitHandle.DangerousGetHandle() }, new DSBPositionNotify { Offset = DSBPositionNotify.OffsetStop, EventNotifyHandle = waitHandleEnd.SafeWaitHandle.DangerousGetHandle() } }; _directSoundNotify.SetNotificationPositions(positionNotifies); int waitHandleTimeout = waitHandles.Length * _latency; //001 /*if (PlaybackState == SoundOut.PlaybackState.Stopped) * { * _secondaryBuffer.SetCurrentPosition(0); * flag = RefillBuffer(buffer, 0, bufferSize); * }*/ //002 _secondaryBuffer.SetCurrentPosition(0); _secondaryBuffer.Play(DSBPlayFlags.Looping); //default flags: looping _playbackState = PlaybackState.Playing; if (waitHandle != null) { waitHandle.Set(); } while (PlaybackState != PlaybackState.Stopped) { int waitHandleIndex = WaitHandle.WaitAny(waitHandles, waitHandleTimeout, true); bool isTimeOut = waitHandleIndex == WaitHandle.WaitTimeout; //dsound stopped //case of end of buffer or Stop() called: http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.dsbpositionnotify(v=vs.85).aspx bool isBufferStopped = waitHandleIndex == (waitHandles.Length - 1); int sampleOffset = (waitHandleIndex == 0 ? 1 : 0) * latencyBytes; //bug: sampleOffset = count if (isTimeOut == false && isBufferStopped == false) { /* * Refill the buffer */ if (RefillBuffer(buffer, sampleOffset, latencyBytes) == false) { _playbackState = PlaybackState.Stopped; } } else { _playbackState = PlaybackState.Stopped; } } /*} * else * { * _playbackState = SoundOut.PlaybackState.Stopped; * }*/ } catch (Exception ex) { exception = ex; } finally { if (_directSoundNotify != null) { _directSoundNotify.Dispose(); _directSoundNotify = null; } if (_secondaryBuffer != null) { _secondaryBuffer.Stop(); } if (_primaryBuffer != null) { _primaryBuffer.Stop(); } if (waitHandles != null) { foreach (WaitHandle waitHandle1 in waitHandles) { var wh = (EventWaitHandle)waitHandle1; wh.Close(); } } RaiseStopped(exception); } }