private void DisposeWave() { lock (mutex) { if (dataStream != null) { dataStream.Dispose(); dataStream = null; } if (audioBuffer != null) { audioBuffer.Dispose(); audioBuffer = null; } if (sourceVoice != null) { if (currentStream != null) { sourceVoice.BufferEnd -= bufferEndCallback; } sourceVoice.Stop(); sourceVoice.FlushSourceBuffers(); sourceVoice.Dispose(); sourceVoice = null; } current = null; currentStream = null; } }
private bool FillBuffer(int bufferIdx, IPlayableStream stream) { AudioBuffer buffer = this.streamBuffers[bufferIdx]; byte[] byteBuffer = this.byteBuffers[bufferIdx]; bool isDone; var dataRead = stream.GetWaveData(byteBuffer, StreamingBufferSize); if (dataRead > 0) { streamBuffered += dataRead; isDone = (streamBuffered >= streamLength); buffer.Flags = isDone ? BufferFlags.EndOfStream : BufferFlags.None; buffer.AudioBytes = dataRead; buffer.Context = (IntPtr)bufferIdx; sourceVoice.SubmitSourceBuffer(buffer); bufferStatus.Set(bufferIdx, true); } else { isDone = true; } return(isDone); }
private void DecoderThread(object wave) { IPlayableStream stream = wave as IPlayableStream; lock (mutex) { while (true) { if (current != wave) { return; } // Fill any unfilled buffers for (var i = 0; i < bufferStatus.Count; i++) { if (bufferStatus.Get(i) == false) { bool isDone = FillBuffer(i, stream); if (isDone) { return; } } } // Wait to be signalled that a buffer is empty System.Threading.Monitor.Wait(mutex); } } }
public void Play(IPlayable wave) { lock (mutex) { if (wave == current) { if (isPaused) { sourceVoice.Start(); isPaused = false; return; } } DisposeWave(); xaudio.CommitChanges(); isPaused = false; current = wave; currentStream = wave as IPlayableStream; if (decodeThread != null) { System.Threading.Monitor.Pulse(mutex); decodeThread = null; } if (currentStream == null) { sourceVoice = new SourceVoice(xaudio, wave.WaveFormat); dataStream = new SlimDX.DataStream(wave.WaveData, true, false); audioBuffer = new SlimDX.XAudio2.AudioBuffer(); audioBuffer.AudioData = dataStream; audioBuffer.AudioBytes = wave.WaveData.Length; audioBuffer.Flags = BufferFlags.EndOfStream; sourceVoice.SubmitSourceBuffer(audioBuffer); sourceVoice.Start(); } else { streamLength = currentStream.StreamLength; streamBuffered = 0; sourceVoice = new SourceVoice(xaudio, wave.WaveFormat); sourceVoice.BufferEnd += bufferEndCallback; // Fill buffers initially bool isDone = false; for (var i = 0; i < NumStreamingBuffers; i++) { isDone = FillBuffer(i, currentStream); if (isDone) { break; } } sourceVoice.Start(); if (!isDone) { System.Threading.ParameterizedThreadStart threadProc = DecoderThread; decodeThread = new System.Threading.Thread(threadProc); decodeThread.Name = "Vorbis Decoder Thread"; decodeThread.Start(currentStream); } } } }
private bool FillBuffer(int bufferIdx, IPlayableStream stream) { AudioBuffer buffer = this.streamBuffers[bufferIdx]; byte[] byteBuffer = this.byteBuffers[bufferIdx]; bool isDone; var dataRead = stream.GetWaveData(byteBuffer, StreamingBufferSize); if (dataRead > 0) { streamBuffered += dataRead; isDone = (streamBuffered >= streamLength); buffer.Flags = isDone ? BufferFlags.EndOfStream : BufferFlags.None; buffer.AudioBytes = dataRead; buffer.Context = (IntPtr)bufferIdx; sourceVoice.SubmitSourceBuffer(buffer); bufferStatus.Set(bufferIdx, true); } else { isDone = true; } return isDone; }