///Preview timer tick function private void PreviewTimer_Tick(object sender, EventArgs e) { //1 if (m_CurrentAudioPCMFormat == null) { return; } double StepInMs = Math.Abs(4000 * m_FwdRwdRate); //long lStepInBytes = CalculationFunctions.ConvertTimeToByte(StepInMs, (int)mCurrentAudio.getPCMFormat().getSampleRate(), mCurrentAudio.getPCMFormat().getBlockAlign()); long lStepInBytes = m_CurrentAudioPCMFormat.ConvertTimeToBytes(Convert.ToInt64(StepInMs * AudioLibPCMFormat.TIME_UNIT)); int PlayChunkLength = 1200; //long lPlayChunkLength = CalculationFunctions.ConvertTimeToByte(PlayChunkLength, (int)mCurrentAudio.getPCMFormat().getSampleRate(), mCurrentAudio.getPCMFormat().getBlockAlign()); long lPlayChunkLength = m_CurrentAudioPCMFormat.ConvertTimeToBytes(Convert.ToInt64(PlayChunkLength * AudioLibPCMFormat.TIME_UNIT)); if (m_CurrentAudioDataLength < lPlayChunkLength) { lPlayChunkLength = m_CurrentAudioDataLength; PlayChunkLength = Convert.ToInt32(m_CurrentAudioPCMFormat.ConvertBytesToTime(lPlayChunkLength) / AudioLibPCMFormat.TIME_UNIT); } //Console.WriteLine("play chunk length " + PlayChunkLength + " : " + lPlayChunkLength); //lPlayChunkLength = m_CurrentAudioPCMFormat.AdjustByteToBlockAlignFrameSize (PlayChunkLength) ; mPreviewTimer.Interval = PlayChunkLength + REFRESH_INTERVAL_MS; //Console.WriteLine("mPreviewTimer.Interval " + mPreviewTimer.Interval); //System.Media.SystemSounds.Asterisk.Play(); long PlayStartPos = 0; long PlayEndPos = 0; if (m_FwdRwdRate > 0) { //2 //Console.WriteLine("rate is above 0"); //if ((mCurrentAudio.getPCMLength() - (lStepInBytes + m_lChunkStartPosition)) > lPlayChunkLength) //Console.WriteLine("m_CurrentAudioStream.Length " + m_CurrentAudioStream.Length + ", lStepInBytes :" + lStepInBytes + ", m_lChunkStartPosition :" + m_lChunkStartPosition + ", lPlayChunkLength :" + lPlayChunkLength); if ((m_CurrentAudioDataLength - (m_lChunkStartPosition)) >= lPlayChunkLength) { //3 if (m_lChunkStartPosition > 0) { Console.WriteLine("m_lChunkStartPosition , step in bytes : " + m_lChunkStartPosition + " : " + lStepInBytes); m_lChunkStartPosition += lStepInBytes; } else { //m_lChunkStartPosition = mFrameSize; m_lChunkStartPosition = m_CurrentAudioPCMFormat.BlockAlign; } PlayStartPos = m_lChunkStartPosition; PlayEndPos = m_lChunkStartPosition + lPlayChunkLength; //PlayAssetStream(PlayStartPos, PlayEndPos); //Console.WriteLine("play pos " + PlayStartPos + " : " + PlayEndPos); //mEventsEnabled = true; if (CurrentState == State.Playing) { //stopPlayback(); //m_State = State.Paused; } if (CurrentState != State.Playing) { startPlayback(PlayStartPos, PlayEndPos); } //mEventsEnabled = false; //Console.WriteLine(CurrentState); if (m_lChunkStartPosition > m_CurrentAudioStream.Length) { m_lChunkStartPosition = m_CurrentAudioStream.Length; } } //-3 else { //3 Stop(); AudioPlaybackFinishHandler delFinished = AudioPlaybackFinished; if (!mPreviewTimer.Enabled && delFinished != null) { delFinished(this, new AudioPlaybackFinishEventArgs()); //EndOfAudioAsset(this, new Events.Audio.Player.EndOfAudioAssetEventArgs()); } } //-3 } //-2 else if (m_FwdRwdRate < 0) { //2 //if (m_lChunkStartPosition > (lStepInBytes ) && lPlayChunkLength <= m_Asset.getPCMLength () ) //Console.WriteLine("rewind " + m_lChunkStartPosition); if (m_lChunkStartPosition > 0) { //3 if (m_lChunkStartPosition < m_CurrentAudioStream.Length) { m_lChunkStartPosition -= lStepInBytes; if (m_lChunkStartPosition < lPlayChunkLength) { m_lChunkStartPosition = 0; } } else { m_lChunkStartPosition = m_CurrentAudioStream.Length - lPlayChunkLength; } PlayStartPos = m_lChunkStartPosition; PlayEndPos = m_lChunkStartPosition + lPlayChunkLength; //PlayAssetStream(PlayStartPos, PlayEndPos); startPlayback(PlayStartPos, PlayEndPos); if (m_lChunkStartPosition < 0) { m_lChunkStartPosition = 0; } } //-3 else { Stop(); AudioPlaybackFinishHandler delFinished = AudioPlaybackFinished; if (!mPreviewTimer.Enabled && delFinished != null) { delFinished(this, new AudioPlaybackFinishEventArgs()); //EndOfAudioAsset(this, new Events.Audio.Player.EndOfAudioAssetEventArgs()); } } } //-2 } //-1
private void startPlayback(long startPosition, long endPosition) { initializeBuffers(); m_PlaybackStartPositionInCurrentAudioStream = startPosition; m_PlaybackEndPositionInCurrentAudioStream = endPosition == 0 ? m_CurrentAudioDataLength : endPosition; m_CircularBufferWritePosition = 0; //m_CircularBufferFlushTolerance = -1; //m_PredictedByteIncrement = -1; //m_PreviousCircularBufferPlayPosition = -1; //m_CircularBufferTotalBytesPlayed = -1; m_CurrentAudioStream = m_CurrentAudioStreamProvider(); m_CurrentAudioStream.Position = m_PlaybackStartPositionInCurrentAudioStream; int circularBufferLength = m_CircularBuffer. #if USE_SHARPDX Capabilities #else Caps #endif .BufferBytes ; int bytesWrittenToCirularBuffer = transferBytesFromWavStreamToCircularBuffer(circularBufferLength); m_CurrentBytePosition = m_PlaybackStartPositionInCurrentAudioStream; CurrentState = State.Playing; //if (AllowBackToBackPlayback && m_MonitoringTimer != null) m_MonitoringTimer.Start(); try { m_CircularBuffer.Play(0, #if USE_SHARPDX PlayFlags.Looping #else BufferPlayFlags.Looping // this makes it a circular buffer (which we manage manually, by tracking playback versus writing positions) #endif ); if (m_PlaybackStopWatch == null) { m_PlaybackStopWatch = new Stopwatch(); } #if NET4 m_PlaybackStopWatch.Restart(); #else m_PlaybackStopWatch.Stop(); m_PlaybackStopWatch.Reset(); m_PlaybackStopWatch.Start(); #endif //NET4 } catch (Exception) { Debug.Fail("EmergencyStopForSoundBufferProblem !"); CurrentState = State.Stopped; StopForwardRewind(); stopPlayback(); return; } ThreadStart threadDelegate = delegate() { bool endOfAudioStream = false; try { endOfAudioStream = circularBufferRefreshThreadMethod(); } catch (ThreadAbortException ex) { // } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } finally { if (m_PlaybackStopWatch != null) { m_PlaybackStopWatch.Stop(); } if (mPreviewTimer.Enabled) { if (endOfAudioStream || CurrentState == State.Playing) { m_ResumeStartPosition = CurrentBytePosition; CurrentState = State.Paused; // before stopPlayback(), doesn't kill the stream provider } lock (LOCK) { m_CircularBufferRefreshThread = null; } stopPlayback(); } else { if (endOfAudioStream || CurrentState == State.Playing) { CurrentState = State.Stopped; } //if (CurrentState != State.Paused) CurrentState = State.Stopped; lock (LOCK) { m_CircularBufferRefreshThread = null; } StopForwardRewind(); stopPlayback(); if (endOfAudioStream) { AudioPlaybackFinishHandler delFinished = AudioPlaybackFinished; if (delFinished != null && !mPreviewTimer.Enabled) { delFinished(this, new AudioPlaybackFinishEventArgs()); } } } } //Console.WriteLine("Player refresh thread exiting...."); //CurrentState = State.Stopped; //lock (LOCK) //{ // //m_CircularBufferRefreshThreadIsAlive = false; // m_CircularBufferRefreshThread = null; //} //Console.WriteLine("Player refresh thread exit."); }; int count = 0; while (m_CircularBufferRefreshThread != null) { Console.WriteLine(@"------------ m_CircularBufferRefreshThread NOT null!!: " + count++); Thread.Sleep(20); if (count > 10) { Console.WriteLine(@"------------ m_CircularBufferRefreshThread NOT null!! ()BREAK(): " + count++); break; } } if (m_CircularBufferRefreshThread != null) { stopPlayback(); } DebugFix.Assert(m_CircularBufferRefreshThread == null); lock (LOCK) { m_CircularBufferRefreshThread = new Thread(threadDelegate); m_CircularBufferRefreshThread.Name = "Player Refresh Thread"; m_CircularBufferRefreshThread.Priority = ThreadPriority.Normal; m_CircularBufferRefreshThread.IsBackground = true; m_CircularBufferRefreshThread.Start(); } //Console.WriteLine("Player refresh thread start."); }