/// <summary> /// Playing process /// </summary> private void PlaybackThread() { bool Running = true; while (Running) { if (m_SeekRequested) { Thread.Sleep(10); continue; } if (m_StopRequested) { Running = false; continue; } if (m_PlayerState == OggPlayerStatus.Error) { Running = false; continue; } if (m_PauseRequested) { Thread.Sleep(10); continue; } // Check currently queued buffers int QueuedBuffers; AL.GetSource(m_Source, ALGetSourcei.BuffersQueued, out QueuedBuffers); // Check for underruns/playback complete // We're using -two- 'cos it doesn't seem to handle the last buffer properly (and the last 2 on windows systems // (not sure why yet - need to do some investigatling). This shouldn't cause any problems unless a large Buffer_Size is set // Anyway: Fear the evil magic hack 'cos this should really be if (QueuedBuffers<=0) if (QueuedBuffers <= 2) { if (m_ReachedEOF) { if (AL.GetSourceState(m_Source) != ALSourceState.Stopped) { AL.SourceStop(m_Source); } Playback_Stop(true); StateChange(OggPlayerStatus.Stopped, OggPlayerStateChanger.EndOfFile); SendMessage(OggPlayerMessageType.PlaybackEndOfFile); Running = false; } else { SendMessage(OggPlayerMessageType.BufferUnderrun); if (!BufferThread.IsAlive) { BufferThread.Start(); } Thread.Sleep(m_PrebufferDelay); } continue; } // See if we're playing if (AL.GetSourceState(m_Source) != ALSourceState.Playing) { lock (OALLocker) { AL.SourcePlay(m_Source); } #if (DEBUG) Console.WriteLine("Source restarted"); #endif } // Count processed buffers int ProcessedBuffers; AL.GetSource(m_Source, ALGetSourcei.BuffersProcessed, out ProcessedBuffers); if (ProcessedBuffers > 0) { // We've got some buffers to desclurple lock (OALLocker) { while (ProcessedBuffers > 0) { // Unqueue the first buffer from the source AL.SourceUnqueueBuffer((int)m_Source); // De-allocate the buffer from memory if (m_BufferRefs.Count > 0) { uint BufferRef = (uint)m_BufferRefs.Dequeue(); if (!AL.IsBuffer(BufferRef)) { SendMessage(OggPlayerMessageType.BufferAnomaly); } AL.DeleteBuffer(ref BufferRef); } else { SendMessage(OggPlayerMessageType.BufferHeapAnomaly); } // Update the internal quantity tracking m_BufferedSizeHeap.Pop(); m_PlayingOffset += m_BufferedTimeHeap.Pop(); // Decrement processed buffers & loop ProcessedBuffers--; } } // Check tick events if (m_PlayingOffset >= m_LastTick + m_TickInterval) { m_LastTick = m_PlayingOffset; if (TickEnabled) { SendTick(m_PlayingOffset, m_BufferOffset); } } } else { Thread.Sleep(10); } if (m_UpdateDelay > 0) { Thread.Sleep(m_UpdateDelay); } } }