/// <summary> /// Processes the samples in a separate thread. /// </summary> private void processSamples() { // Used to determine if playback is halted bool lPlaybackHalted = false; // Incase the thread is killed try { InitialiseDirectSound(); int lResult = 1; if (PlaybackState == PlaybackState.Stopped) { secondaryBuffer.SetCurrentPosition(0); nextSamplesWriteIndex = 0; lResult = Feed(samplesTotalSize); } // Incase the previous Feed method returns 0 if (lResult > 0) { lock (m_LockObject) { playbackState = PlaybackState.Playing; } secondaryBuffer.Play(0, 0, DirectSoundPlayFlags.DSBPLAY_LOOPING); WaitHandle[] waitHandles = new WaitHandle[] { frameEventWaitHandle1, frameEventWaitHandle2, endEventWaitHandle }; bool lContinuePlayback = true; while (PlaybackState != PlaybackState.Stopped && lContinuePlayback) { // Wait for signals on frameEventWaitHandle1 (Position 0), frameEventWaitHandle2 (Position 1/2) int indexHandle = WaitHandle.WaitAny(waitHandles, 3 * desiredLatency, false); // TimeOut is ok if (indexHandle != WaitHandle.WaitTimeout) { // Buffer is Stopped if (indexHandle == 2) { // (Gee) - Not sure whether to stop playback in this case or not! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } else { indexHandle = (indexHandle == 0) ? 1 : 0; nextSamplesWriteIndex = indexHandle * samplesFrameSize; // Only carry on playing if we can! if (Feed(samplesFrameSize) == 0) { StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } } } else { // Timed out! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } } } } catch (Exception) { // Do nothing! } finally { if (!lPlaybackHalted) { StopPlayback(); } lock (m_LockObject) { playbackState = PlaybackState.Stopped; } // Fire playback stopped event if (PlaybackStopped != null) { PlaybackStopped(this, EventArgs.Empty); } } }
/// <summary> /// Processes the samples in a separate thread. /// </summary> private void PlaybackThreadFunc() { // Used to determine if playback is halted bool lPlaybackHalted = false; Exception exception = null; // Incase the thread is killed try { InitializeDirectSound(); int lResult = 1; if (PlaybackState == PlaybackState.Stopped) { secondaryBuffer.SetCurrentPosition(0); nextSamplesWriteIndex = 0; lResult = Feed(samplesTotalSize); } // Incase the previous Feed method returns 0 if (lResult > 0) { lock (m_LockObject) { playbackState = PlaybackState.Playing; } secondaryBuffer.Play(0, 0, DirectSoundPlayFlags.DSBPLAY_LOOPING); WaitHandle[] waitHandles = new WaitHandle[] { frameEventWaitHandle1, frameEventWaitHandle2, endEventWaitHandle }; bool lContinuePlayback = true; while (PlaybackState != PlaybackState.Stopped && lContinuePlayback) { // Wait for signals on frameEventWaitHandle1 (Position 0), frameEventWaitHandle2 (Position 1/2) int indexHandle = WaitHandle.WaitAny(waitHandles, 3 * desiredLatency, false); // TimeOut is ok if (indexHandle != WaitHandle.WaitTimeout) { // Buffer is Stopped if (indexHandle == 2) { // (Gee) - Not sure whether to stop playback in this case or not! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } else { indexHandle = (indexHandle == 0) ? 1 : 0; nextSamplesWriteIndex = indexHandle * samplesFrameSize; // Only carry on playing if we can! if (Feed(samplesFrameSize) == 0) { StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } } } else { // Timed out! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; // report this as an error in the Playback Stopped // seems to happen when device is unplugged throw new Exception("DirectSound buffer timeout"); } } } } catch (Exception e) { // Do nothing (except report error) Debug.WriteLine(e.ToString()); exception = e; } finally { if (!lPlaybackHalted) { StopPlayback(); } lock (m_LockObject) { playbackState = PlaybackState.Stopped; } // Fire playback stopped event RaisePlaybackStopped(exception); } }
/// <summary> /// Processes the samples in a separate thread. /// </summary> private void PlaybackThreadFunc() { // Used to determine if playback is halted bool lPlaybackHalted = false; bool firstBufferStarted = false; bytesPlayed = 0; Exception exception = null; // Incase the thread is killed try { InitializeDirectSound(); int lResult = 1; if (PlaybackState == PlaybackState.Stopped) { secondaryBuffer.SetCurrentPosition(0); nextSamplesWriteIndex = 0; lResult = Feed(samplesTotalSize); } // Incase the previous Feed method returns 0 if (lResult > 0) { lock (m_LockObject) { playbackState = PlaybackState.Playing; } secondaryBuffer.Play(0, 0, DirectSoundPlayFlags.DSBPLAY_LOOPING); var waitHandles = new WaitHandle[] { frameEventWaitHandle1, frameEventWaitHandle2, endEventWaitHandle }; bool lContinuePlayback = true; while (PlaybackState != PlaybackState.Stopped && lContinuePlayback) { // Wait for signals on frameEventWaitHandle1 (Position 0), frameEventWaitHandle2 (Position 1/2) int indexHandle = WaitHandle.WaitAny(waitHandles, 3 * desiredLatency, false); // TimeOut is ok if (indexHandle != WaitHandle.WaitTimeout) { // Buffer is Stopped if (indexHandle == 2) { // (Gee) - Not sure whether to stop playback in this case or not! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } else { if (indexHandle == 0) { // we're at the beginning of the buffer... if (firstBufferStarted) { // because this notification is based on the *playback" cursor, this should be reasonably accurate bytesPlayed += samplesFrameSize * 2; } } else { firstBufferStarted = true; } indexHandle = (indexHandle == 0) ? 1 : 0; nextSamplesWriteIndex = indexHandle * samplesFrameSize; // Only carry on playing if we can! if (Feed(samplesFrameSize) == 0) { StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; } } } else { // Timed out! StopPlayback(); lPlaybackHalted = true; lContinuePlayback = false; // report this as an error in the Playback Stopped // seems to happen when device is unplugged throw new Exception("DirectSound buffer timeout"); } } } } catch (Exception e) { // Do nothing (except report error) NAudioLogger.Instance.LogError(e.Message); exception = e; } finally { if (!lPlaybackHalted) { try { StopPlayback(); } catch (Exception e) { NAudioLogger.Instance.LogError(e.Message); // don't overwrite the original reason we exited the playback loop if (exception == null) { exception = e; } } } lock (m_LockObject) { playbackState = PlaybackState.Stopped; } bytesPlayed = 0; // Fire playback stopped event RaisePlaybackStopped(exception); } }