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); } }
private void CleanupResources() { if (_directSoundNotify != null) { _directSoundNotify.Dispose(); _directSoundNotify = null; } if (_secondaryBuffer != null) { _secondaryBuffer.Stop(); _secondaryBuffer.Dispose(); _secondaryBuffer = null; } if (_primaryBuffer != null) { _primaryBuffer.Stop(); _primaryBuffer.Dispose(); _primaryBuffer = null; } if (_directSound != null) { _directSound.Dispose(); _directSound = null; } _isInitialized = false; }