private void MediaEngine_MediaStateChanged(MediaState state) { switch (state) { case MediaState.Loading: this.PlaybackState = PlaybackState.Loading; break; case MediaState.Stopped: this.PlaybackState = PlaybackState.Paused; break; case MediaState.Playing: this.PlaybackState = PlaybackState.Playing; break; case MediaState.Error: this.PlaybackState = PlaybackState.Error_MediaInvalid; break; case MediaState.Ended: this.PlaybackState = PlaybackState.Ended; break; } }
public MediaStateChangedEventArgs(BufferState bufferState, NetworkState networkState, PlaybackState playbackState, SeekState seekState) { this.bufferState = bufferState; this.networkState = networkState; this.playbackState = playbackState; this.seekState = seekState; }
public Form1() { InitializeComponent(); m_state = PlaybackState.Closed; m_pPlayer = new DShowPlayer(panVideoWin, Handle, WM_GRAPH_EVENT); m_bDrag = false; }
public static PlayerState? Convert(PlaybackState? inState) { if(!inState.HasValue) { return null; } else { return Convert(inState.Value); } }
public MediaNotificationManager(MusicService serv) { service = serv; UpdateSessionToken(); notificationColor = ResourceHelper.GetThemeColor(service, Android.Resource.Attribute.ColorPrimary, Color.DarkGray); notificationManager = (NotificationManager) service .GetSystemService(Context.NotificationService); string pkg = service.PackageName; pauseIntent = PendingIntent.GetBroadcast(service, RequestCode, new Intent(ActionPause).SetPackage(pkg), PendingIntentFlags.CancelCurrent); playIntent = PendingIntent.GetBroadcast(service, RequestCode, new Intent(ActionPlay).SetPackage(pkg), PendingIntentFlags.CancelCurrent); previousIntent = PendingIntent.GetBroadcast(service, RequestCode, new Intent(ActionPrev).SetPackage(pkg), PendingIntentFlags.CancelCurrent); nextIntent = PendingIntent.GetBroadcast(service, RequestCode, new Intent(ActionNext).SetPackage(pkg), PendingIntentFlags.CancelCurrent); notificationManager.CancelAll (); mCb.OnPlaybackStateChangedImpl = (state) => { playbackState = state; LogHelper.Debug (Tag, "Received new playback state", state); if (state != null && (state.State == PlaybackStateCode.Stopped || state.State == PlaybackStateCode.None)) { StopNotification (); } else { Notification notification = CreateNotification (); if (notification != null) { notificationManager.Notify (NotificationId, notification); } } }; mCb.OnMetadataChangedImpl = (meta) => { metadata = meta; LogHelper.Debug (Tag, "Received new metadata ", metadata); Notification notification = CreateNotification (); if (notification != null) { notificationManager.Notify (NotificationId, notification); } }; mCb.OnSessionDestroyedImpl = () => { LogHelper.Debug (Tag, "Session was destroyed, resetting to the new session token"); UpdateSessionToken (); }; }
private void PlaybackThread() { Exception exception = null; try { DoPlayback(); } catch (Exception e) { exception = e; } finally { playbackState = PlaybackState.Stopped; // we're exiting our background thread RaisePlaybackStoppedEvent(exception); } }
/// <summary> /// Resume playing after a pause from the same position /// </summary> private void Resume() { if (m_PlaybackState != PlaybackState.Paused) { return; } MmResult result; lock (WaveOutLock) result = WaveInterop.NativeMethods.waveOutRestart(DeviceHandle); if (result != MmResult.NoError) { throw new MmException(result, nameof(WaveInterop.NativeMethods.waveOutRestart)); } m_PlaybackState = PlaybackState.Playing; }
private void FillBuffer(IWaveProvider playbackProvider, int frameCount) { IntPtr buffer = renderClient.GetBuffer(frameCount); int readLength = frameCount * bytesPerFrame; int read = playbackProvider.Read(readBuffer, 0, readLength); if (read == 0) { playbackState = PlaybackState.Stopped; } Marshal.Copy(readBuffer, 0, buffer, read); int actualFrameCount = read / bytesPerFrame; /*if (actualFrameCount != frameCount) * { * Debug.WriteLine(String.Format("WASAPI wanted {0} frames, supplied {1}", frameCount, actualFrameCount )); * }*/ renderClient.ReleaseBuffer(actualFrameCount, AudioClientBufferFlags.None); }
/// <summary> /// Closes the wave device. /// </summary> private void CloseWaveOut() { if (CallbackEvent != null) { m_PlaybackState = PlaybackState.Stopped; CallbackEvent.Set(); CallbackEvent.Close(); CallbackEvent = null; } lock (WaveOutLock) { if (DeviceHandle != IntPtr.Zero) { WaveInterop.NativeMethods.waveOutClose(DeviceHandle); DeviceHandle = IntPtr.Zero; } } }
/// <summary> /// Initializes the specified wave provider. /// </summary> /// <param name="waveProvider">The wave provider.</param> /// <exception cref="System.InvalidOperationException">Can't re-initialize during playback</exception> public void Init(IWaveProvider waveProvider) { if (m_PlaybackState != PlaybackState.Stopped) { throw new InvalidOperationException("Can't re-initialize during playback"); } if (DeviceHandle != IntPtr.Zero) { // normally we don't allow calling Init twice, but as experiment, see if we can clean up and go again // try to allow reuse of this waveOut device // n.b. risky if Playback thread has not exited DisposeBuffers(); CloseWaveOut(); } CallbackEvent = new AutoResetEvent(false); WaveStream = waveProvider; var bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult result; lock (WaveOutLock) { result = WaveInterop.NativeMethods.waveOutOpenWindow( out DeviceHandle, DeviceNumber, WaveStream.WaveFormat, CallbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); } MmException.Try(result, nameof(WaveInterop.NativeMethods.waveOutOpen)); Buffers = new WaveOutBuffer[NumberOfBuffers]; m_PlaybackState = PlaybackState.Stopped; for (var n = 0; n < NumberOfBuffers; n++) { Buffers[n] = new WaveOutBuffer(DeviceHandle, bufferSize, WaveStream, WaveOutLock); } }
/// <summary> /// Begin playback /// </summary> public void Play() { if (playbackState == PlaybackState.Stopped) { // ------------------------------------------------------------------------------------- // Thread that process samples // ------------------------------------------------------------------------------------- notifyThread = new Thread(new ThreadStart(PlaybackThreadFunc)); // put this back to highest when we are confident we don't have any bugs in the thread proc notifyThread.Priority = ThreadPriority.Normal; notifyThread.IsBackground = true; notifyThread.Start(); } lock (m_LockObject) { playbackState = PlaybackState.Playing; } }
// made non-static so that playing can be stopped here private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved) { if (uMsg == WaveInterop.WaveMessage.WaveOutDone) { GCHandle hBuffer = (GCHandle)wavhdr.userData; WaveOutBuffer buffer = (WaveOutBuffer)hBuffer.Target; // check that we're not here through pressing stop if (PlaybackState == PlaybackState.Playing) { if (!buffer.OnDone()) { playbackState = PlaybackState.Stopped; RaisePlaybackStoppedEvent(); } } // n.b. this was wrapped in an exception handler, but bug should be fixed now } }
/// <summary> /// Set the playback state. /// </summary> /// <param name="state"></param> /// <returns></returns> public static async Task <bool> SetState(PlaybackState state) { var request = JsonRpcFactory.CreateRequest( Playback.MethodSetState, new { new_state = state } ); var response = await Playback._query.Exec(request); if (response.Error != null) { return(false); } return(true); }
/// <summary> /// Begin Playback /// </summary> async public void Play() { if (this.playbackState != PlaybackState.Playing) { if (this.playbackState == PlaybackState.Stopped) { this.EventWriterDLL.FlushBuildString(EventWriterDLL.SeverityTypes.Information, 0x01); this.playbackState = PlaybackState.Playing; await Task.Delay(10); await Task.Run(() => PlayThread()); } else { this.playbackState = PlaybackState.Playing; } } }
public void Resume() { switch (_playbackState) { case PlaybackState.Playing: return; case PlaybackState.Paused: _playbackState = PlaybackState.Playing; return; case PlaybackState.Stopped: if (_client.Start()) { _playbackState = PlaybackState.Playing; } break; } }
/// <summary> /// Initialises the WaveOut device /// </summary> /// <param name="waveProvider">WaveProvider to play</param> public void Init(IWaveProvider waveProvider) { this.waveStream = waveProvider; int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); } MmException.Try(result, "waveOutOpen"); buffers = new WaveOutBuffer[NumberOfBuffers]; playbackState = PlaybackState.Stopped; for (int n = 0; n < NumberOfBuffers; n++) { buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock); } }
/// <summary> /// Pause the audio /// </summary> public void Pause() { if (_playbackState != PlaybackState.Playing) { return; } MmResult result; _playbackState = PlaybackState.Paused; // set this here, to avoid a deadlock with some drivers lock (_waveOutLock) { result = WaveInterop.waveOutPause(_hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutPause"); } }
/// <summary> /// Public method called by the main view to start playing the playlist /// </summary> public void play() { // If there is no backgroundworker initialized, do that if (playerThread == null) { playerThread = new BackgroundWorker(); playerThread.DoWork += new DoWorkEventHandler(playerThread_DoWork); playerThread.ProgressChanged += new ProgressChangedEventHandler(playerThread_ProgressChanged); playerThread.RunWorkerCompleted += new RunWorkerCompletedEventHandler(playerThread_RunWorkerCompleted); playerThread.WorkerReportsProgress = true; } // Set state to playing this.playState = PlaybackState.Playing; // start playing the entire queue playQueue(); }
/// <summary> /// Resume playing after a pause from the same position /// </summary> public void Resume() { if (_playbackState != PlaybackState.Paused) { return; } MmResult result; lock (_waveOutLock) { result = WaveInterop.waveOutRestart(_hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutRestart"); } _playbackState = PlaybackState.Playing; }
/// <summary> /// Begin playback /// </summary> public void Play() { if (playbackState == PlaybackState.Stopped) { // ------------------------------------------------------------------------------------- // Thread that process samples // ------------------------------------------------------------------------------------- notifyThread = new Thread(new ThreadStart(processSamples)); // put this back to highest when we are confident we don't have any bugs in the thread proc notifyThread.Priority = ThreadPriority.Normal; notifyThread.IsBackground = true; notifyThread.Start(); } lock (m_LockObject) { playbackState = PlaybackState.Playing; } }
void SetPlaybackState(PlaybackState ps) { foreach (GameObject g in playGraphics) { g.SetActive(false); } foreach (GameObject g in pauseGraphics) { g.SetActive(false); } foreach (GameObject g in stopGraphics) { g.SetActive(false); } switch (ps) { case PlaybackState.play: foreach (GameObject g in playGraphics) { g.SetActive(true); } break; case PlaybackState.pause: foreach (GameObject g in pauseGraphics) { g.SetActive(true); } break; case PlaybackState.stop: foreach (GameObject g in stopGraphics) { g.SetActive(true); } break; default: break; } }
/// <summary> /// Initialises the WaveOut device /// </summary> /// <param name="waveProvider">WaveProvider to play</param> public void Init(IWaveProvider waveProvider) { _waveStream = waveProvider; var bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult result; lock (_waveOutLock) { result = _callbackInfo.WaveOutOpen(out _hWaveOut, DeviceNumber, _waveStream.WaveFormat, _callback); } MmException.Try(result, "waveOutOpen"); _buffers = new WaveOutBuffer[NumberOfBuffers]; _playbackState = PlaybackState.Stopped; for (var n = 0; n < NumberOfBuffers; n++) { _buffers[n] = new WaveOutBuffer(_hWaveOut, bufferSize, _waveStream, _waveOutLock); } }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { PlaybackState state = (PlaybackState)value; string imagepath; switch (state) { case PlaybackState.Playing: imagepath = "/Resources/MediaIcons/ThumbButtons/play.png"; break; case PlaybackState.Paused: imagepath = "/Resources/MediaIcons/ThumbButtons/pause.png"; break; default: return(null); } return(imagepath); }
private void EnqueueBuffers() { for (int n = 0; n < NumberOfBuffers; n++) { if (!buffers[n].InQueue) { if (buffers[n].OnDone()) { Interlocked.Increment(ref queuedBuffers); } else { playbackState = PlaybackState.Stopped; break; } //Debug.WriteLine(String.Format("Resume from Pause: Buffer [{0}] requeued", n)); } // ReSharper disable once RedundantIfElseBlock } }
/// <summary> /// 停止します /// </summary> public void Stop() { if (this.music == null) { throw new NotMusicException(); } this.timer.Stop(); try { if (this.music != null) { this.music.Stop(); } } catch (MmException) { throw; } this.position = 0; this.playState = PlaybackState.Stopped; }
private void _audioPlayer_PlaybackStopped() { _playbackState = PlaybackState.Stopped; PlayPauseImageSource = "../Images/play.png"; CommandManager.InvalidateRequerySuggested(); CurrentTrackPosition = 0; if (_audioPlayer.PlaybackStopType == AudioPlayer.PlaybackStopTypes.PlaybackStoppedReachingEndOfFile) { CurrentlySelectedTrack = Playlist.NextItem(CurrentlyPlayingTrack); StartPlayback(null); } else if (_audioPlayer.PlaybackStopType == AudioPlayer.PlaybackStopTypes.PlaybackStoppedByUser) { if (CurrentlySelectedTrack != CurrentlyPlayingTrack) { StartPlayback(null); } } }
private void PlaybackThread() { Exception exception = null; try { DoPlayback(); } catch (Exception e) { NAudioLogger.Instance.LogError(e.Message); exception = e; } finally { playbackState = PlaybackState.Stopped; // we're exiting our background thread RaisePlaybackStoppedEvent(exception); } }
/// <summary> /// Start playing the audio from the WaveStream /// </summary> public void Play() { if (playbackState == PlaybackState.Stopped) { playbackState = PlaybackState.Playing; for (int n = 0; n < NumberOfBuffers; n++) { System.Diagnostics.Debug.Assert(buffers[n].InQueue == false, "Adding a buffer that was already queued on play"); if (!buffers[n].OnDone()) { playbackState = PlaybackState.Stopped; } } } else if (playbackState == PlaybackState.Paused) { Resume(); playbackState = PlaybackState.Playing; } }
/// <summary> /// Resume playing after a pause from the same position /// </summary> public void Resume() { if (Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId) { lock (actionQueue) { actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Resume, null)); workAvailable.Set(); } return; } MmResult result = WaveInterop.waveOutRestart(hWaveOut); if (result != MmResult.NoError) { throw new MmException(result, "waveOutRestart"); } playbackState = PlaybackState.Playing; }
public void TogglePaused() { switch (playbackState) { case PlaybackState.Paused: playbackState = PlaybackState.Playing; waveOut1?.Play(); waveOut2?.Play(); break; case PlaybackState.Playing: playbackState = PlaybackState.Paused; waveOut1?.Pause(); waveOut2?.Pause(); break; default: break; } }
/// <summary> /// Stop and reset the WaveOut device /// </summary> public void Stop() { if (playbackState != PlaybackState.Stopped) { // in the call to waveOutReset with function callbacks // some drivers will block here until OnDone is called // for every buffer playbackState = PlaybackState.Stopped; // set this here to avoid a problem with some drivers whereby MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutReset(hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutReset"); } callbackEvent.Set(); // give the thread a kick, make sure we exit } }
/// <summary> /// Initialises the WaveOut device /// </summary> /// <param name="waveProvider">WaveProvider to play</param> public void Init(IWaveProvider waveProvider) { this.waveStream = waveProvider; int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult result; lock (waveOutLock) { result = callbackInfo.WaveOutOpen(out hWaveOut, DeviceNumber, waveStream.WaveFormat, callback); } MmException.Try(result, "waveOutOpen"); buffers = new WaveOutBuffer[NumberOfBuffers]; playbackState = PlaybackState.Stopped; for (int n = 0; n < NumberOfBuffers; n++) { buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock); } }
/// <summary> /// Stop and reset the WaveOut device /// </summary> public void Stop() { if (Thread.CurrentThread.ManagedThreadId != waveOutThread.ManagedThreadId) { lock (actionQueue) { actionQueue.Enqueue(new WaveOutAction(WaveOutFunction.Stop, null)); workAvailable.Set(); } return; } playbackState = PlaybackState.Stopped; buffersQueued = false; MmResult result = WaveInterop.waveOutReset(hWaveOut); if (result != MmResult.NoError) { throw new MmException(result, "waveOutReset"); } }
public async Task trackAudio() { bool playMedia = true; PlaybackState statePlayback = playerMedia.getPlaybackState(); while (playMedia) { if (statePlayback == PlaybackState.Playing) { await Task.Delay(1000); TimeSpan currentAudio = playerMedia.getCurrentTime(); Item item = getTextFromSpeach(currentAudio); await Controller.displayParametersCurrents(currentAudio, item); } else if (statePlayback == PlaybackState.Paused) { await Task.Delay(2000); } } }
public override bool UpdateSubTree() { state = frameStableClock.IsPaused.Value ? PlaybackState.NotValid : PlaybackState.Valid; int loops = MaxCatchUpFrames; while (state != PlaybackState.NotValid && loops-- > 0) { updateClock(); if (state == PlaybackState.NotValid) { break; } base.UpdateSubTree(); UpdateSubTreeMasking(this, ScreenSpaceDrawQuad.AABBFloat); } return(true); }
/// <summary> /// Starts the playback thread. /// </summary> private void StartPlaybackThread() { try { PerformContinuousPlayback(); } catch (MmException mex) when(mex.Result == MmResult.WaveHeaderUnprepared) { Renderer?.MediaCore?.Log(MediaLogMessageType.Debug, $"{nameof(AudioPlaybackTask)} forced exit requested. {mex.Message}."); return; } catch (Exception e) { Renderer?.MediaCore?.Log(MediaLogMessageType.Error, $"{nameof(AudioPlaybackTask)} exiting. {e.Message}. Stack Trace:\r\n{e.StackTrace}"); } finally { try { CallbackEvent?.Set(); } catch { } m_PlaybackState = PlaybackState.Stopped; } }
/// <summary> /// Begin Playback /// </summary> public void Play() { switch (playbackState) { case PlaybackState.Playing: return; case PlaybackState.Paused: playbackState = PlaybackState.Playing; return; case PlaybackState.Stopped: playbackState = PlaybackState.Playing; //playThread = new Thread(new ThreadStart(PlayThread)); //playThread.Priority = ThreadPriority.Highest; //playThread.IsBackground = true; //playThread.Name = "Pro Audio"; //playThread.Start(); return; } }
private void EnqueueBuffers() { for (int n = 0; n < NumberOfBuffers; n++) { if (!buffers[n].InQueue) { if (buffers[n].OnDone()) { Interlocked.Increment(ref queuedBuffers); } else { playbackState = PlaybackState.Stopped; break; } //Debug.WriteLine(String.Format("Resume from Pause: Buffer [{0}] requeued", n)); } else { //Debug.WriteLine(String.Format("Resume from Pause: Buffer [{0}] already queued", n)); } } }
/// <summary> /// Stop playback and flush buffers /// </summary> public void Stop() { if (playbackState != PlaybackState.Stopped) { playbackState = PlaybackState.Stopped; playThread.Join(); playThread = null; } }
/// <summary> /// Begin Playback /// </summary> public void Play() { if (playbackState != PlaybackState.Playing) { if (playbackState == PlaybackState.Stopped) { playThread = new Thread(new ThreadStart(PlayThread)); playbackState = PlaybackState.Playing; playThread.Start(); } else { playbackState = PlaybackState.Playing; } } }
/// <summary> /// Initialises the WaveOut device /// </summary> /// <param name="waveProvider">WaveProvider to play</param> public void Init(IWaveProvider waveProvider) { if (playbackState != PlaybackState.Stopped) { throw new InvalidOperationException("Can't re-initialize during playback"); } if (hWaveOut != IntPtr.Zero) { // normally we don't allow calling Init twice, but as experiment, see if we can clean up and go again // try to allow reuse of this waveOut device // n.b. risky if Playback thread has not exited DisposeBuffers(); CloseWaveOut(); } this.callbackEvent = new AutoResetEvent(false); this.waveStream = waveProvider; int bufferSize = waveProvider.WaveFormat.ConvertLatencyToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutOpenWindow(out hWaveOut, (IntPtr)DeviceNumber, waveStream.WaveFormat, callbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); } MmException.Try(result, "waveOutOpen"); buffers = new WaveOutBuffer[NumberOfBuffers]; playbackState = PlaybackState.Stopped; for (int n = 0; n < NumberOfBuffers; n++) { buffers[n] = new WaveOutBuffer(hWaveOut, bufferSize, waveStream, waveOutLock); } }
/// <summary> /// Resume playing after a pause from the same position /// </summary> private void Resume() { if (playbackState == PlaybackState.Paused) { MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutRestart(hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutRestart"); } playbackState = PlaybackState.Playing; } }
/// <summary> /// Stop playback without flushing buffers /// </summary> public void Pause() { if (playbackState == PlaybackState.Playing) { playbackState = PlaybackState.Paused; } }
/// <summary> /// Stop playback /// </summary> public void Stop() { // Try and tidy up nicely if (Monitor.TryEnter(m_LockObject, 50)) { playbackState = PlaybackState.Stopped; Monitor.Exit(m_LockObject); } else { // No joy - abort the thread! if (notifyThread != null) { notifyThread.Abort(); notifyThread = null; } } }
/// <summary> /// Begin Playback /// </summary> public void Play() { if (playbackState != PlaybackState.Playing) { if (playbackState == PlaybackState.Stopped && !preventNewPlayTaskCreation) { playbackState = PlaybackState.Playing; playTask = Task.Run((Action)PlayThread); } else { playbackState = PlaybackState.Playing; } } }
public void RefreshPlaybackState() { PlaybackState nextPlaybackState = playbackState; if (sound != null) { if (sound.CurrentSubSoundIndex != -1 && sound.CurrentSubSound != null) { if (sound.CurrentSubSound.Channel.IsPlaying) { if (sound.CurrentSubSound.Channel.Paused) nextPlaybackState = PlaybackState.Paused; else nextPlaybackState = PlaybackState.Playing; } else nextPlaybackState = PlaybackState.Stopped; } else { if (sound.Channel != null) { if (sound.Channel.IsPlaying) { if (sound.Channel.Paused) nextPlaybackState = PlaybackState.Paused; else nextPlaybackState = PlaybackState.Playing; } else nextPlaybackState = PlaybackState.Stopped; } else nextPlaybackState = PlaybackState.None; } } else nextPlaybackState = PlaybackState.None; if (playbackState != nextPlaybackState) { playbackState = nextPlaybackState; if (PlaybackStateChanged != null) PlaybackStateChanged(this, new MediaStateChangedEventArgs(BufferState, NetworkState, PlaybackState, SeekState)); } }
// made non-static so that playing can be stopped here private void Callback(IntPtr hWaveOut, WaveInterop.WaveMessage uMsg, IntPtr dwInstance, WaveHeader wavhdr, IntPtr dwReserved) { if (uMsg == WaveInterop.WaveMessage.WaveOutDone) { GCHandle hBuffer = (GCHandle)wavhdr.userData; WaveOutBuffer buffer = (WaveOutBuffer)hBuffer.Target; Interlocked.Decrement(ref queuedBuffers); Exception exception = null; // check that we're not here through pressing stop if (PlaybackState == PlaybackState.Playing) { // to avoid deadlocks in Function callback mode, // we lock round this whole thing, which will include the // reading from the stream. // this protects us from calling waveOutReset on another // thread while a WaveOutWrite is in progress lock (waveOutLock) { try { if (buffer.OnDone()) { Interlocked.Increment(ref queuedBuffers); } } catch (Exception e) { // one likely cause is soundcard being unplugged exception = e; } } } if (queuedBuffers == 0) { if (callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback && playbackState == PlaybackState.Stopped) { // the user has pressed stop // DO NOT raise the playback stopped event from here // since on the main thread we are still in the waveOutReset function // Playback stopped will be raised elsewhere } else { playbackState = PlaybackState.Stopped; // set explicitly for when we reach the end of the audio RaisePlaybackStoppedEvent(exception); } } } }
/// <summary> /// Stop and reset the WaveOut device /// </summary> public void Stop() { if (playbackState != PlaybackState.Stopped) { // in the call to waveOutReset with function callbacks // some drivers will block here until OnDone is called // for every buffer playbackState = PlaybackState.Stopped; // set this here to avoid a problem with some drivers whereby MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutReset(hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutReset"); } // with function callbacks, waveOutReset will call OnDone, // and so PlaybackStopped must not be raised from the handler // we know playback has definitely stopped now, so raise callback if (callbackInfo.Strategy == WaveCallbackStrategy.FunctionCallback) { RaisePlaybackStoppedEvent(null); } } }
/// <summary> /// Start playing the audio from the WaveStream /// </summary> public void Play() { if (playbackState == PlaybackState.Stopped) { playbackState = PlaybackState.Playing; Debug.Assert(queuedBuffers == 0, "Buffers already queued on play"); EnqueueBuffers(); } else if (playbackState == PlaybackState.Paused) { EnqueueBuffers(); Resume(); playbackState = PlaybackState.Playing; } }
private void FillBuffer(IWaveProvider playbackProvider, int frameCount) { IntPtr buffer = renderClient.GetBuffer(frameCount); int readLength = frameCount*bytesPerFrame; int read = playbackProvider.Read(readBuffer, 0, readLength); if (read == 0) { playbackState = PlaybackState.Stopped; } Marshal.Copy(readBuffer, 0, buffer, read); int actualFrameCount = read/bytesPerFrame; /*if (actualFrameCount != frameCount) { Debug.WriteLine(String.Format("WASAPI wanted {0} frames, supplied {1}", frameCount, actualFrameCount )); }*/ renderClient.ReleaseBuffer(actualFrameCount, AudioClientBufferFlags.None); }
/// <summary> /// Start playing the audio from the WaveStream /// </summary> public void Play() { if (this.buffers == null || this.waveStream == null) { throw new InvalidOperationException("Must call Init first"); } if (playbackState == PlaybackState.Stopped) { playbackState = PlaybackState.Playing; callbackEvent.Set(); // give the thread a kick ThreadPool.QueueUserWorkItem((state) => PlaybackThread(), null); } else if (playbackState == PlaybackState.Paused) { Resume(); callbackEvent.Set(); // give the thread a kick } }
/// <summary> /// Stop playback and flush buffers /// </summary> public void Stop() { if (playbackState != PlaybackState.Stopped) { playbackState = PlaybackState.Stopped; } }
/// <summary> /// Pause Playback /// </summary> public void Pause() { lock (m_LockObject) { playbackState = PlaybackState.Paused; } }
private void DoPlayback() { while (playbackState != PlaybackState.Stopped) { if (!callbackEvent.WaitOne(DesiredLatency)) Debug.WriteLine("WARNING: WaveOutEvent callback event timeout"); // requeue any buffers returned to us if (playbackState == PlaybackState.Playing) { int queued = 0; foreach (var buffer in buffers) { if (buffer.InQueue || buffer.OnDone()) { queued++; } } if (queued == 0) { // we got to the end this.playbackState = PlaybackState.Stopped; callbackEvent.Set(); } } } }
/// <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) Debug.WriteLine(e.ToString()); exception = e; } finally { if (!lPlaybackHalted) { try { StopPlayback(); } catch (Exception e) { Debug.WriteLine(e.ToString()); // 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); } }
/// <summary> /// Pause the audio /// </summary> public void Pause() { if (playbackState == PlaybackState.Playing) { MmResult result; lock (waveOutLock) { result = WaveInterop.waveOutPause(hWaveOut); } if (result != MmResult.NoError) { throw new MmException(result, "waveOutPause"); } playbackState = PlaybackState.Paused; } }