private void PlaybackProc(object o) { EventWaitHandle waitHandle = o as EventWaitHandle; EventWaitHandle[] waitHandles = null; try { //004 //bool flag = true; int bufferSize = _secondaryBuffer.BufferCaps.dwBufferBytes; int latencyBytes = (int)_source.WaveFormat.MillisecondsToBytes(_latency); byte[] buffer = new byte[bufferSize]; _primaryBuffer.Play(DSBPlayFlags.DSBPLAY_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 EventWaitHandle[]{ waitHandleNull, waitHandle0, waitHandleEnd }; _directSoundNotify = _secondaryBuffer.QueryInterface<DirectSoundNotify>(); DSBPositionNotify[] positionNotifies = { new DSBPositionNotify() { dwOffset = DSBPositionNotify.OffsetZero, hEventNotify = waitHandleNull.SafeWaitHandle.DangerousGetHandle() }, new DSBPositionNotify() { dwOffset = (uint)_source.WaveFormat.MillisecondsToBytes(_latency), hEventNotify = waitHandle0.SafeWaitHandle.DangerousGetHandle() }, new DSBPositionNotify() { dwOffset = DSBPositionNotify.OffsetEnd, hEventNotify = 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.DSBPLAY_LOOPING); //default flags: looping _playbackState = SoundOut.PlaybackState.Playing; if (waitHandle != null) waitHandle.Set(); while (PlaybackState != SoundOut.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 = SoundOut.PlaybackState.Stopped; } } else { _playbackState = SoundOut.PlaybackState.Stopped; } } /*} else { _playbackState = SoundOut.PlaybackState.Stopped; }*/ } finally { if (_directSoundNotify != null) { _directSoundNotify.Dispose(); _directSoundNotify = null; } if (_secondaryBuffer != null) { _secondaryBuffer.Stop(); } if (_primaryBuffer != null) { _primaryBuffer.Stop(); } if (waitHandles != null) { foreach (var wh in waitHandles) { wh.Close(); } } RaiseStopped(); } }
private void CleanupRessources() { 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; }