/// <summary> /// Fills the buffer. /// </summary> /// <param name="target">The OpenALDataBuffer.</param> private void FillBuffer(OpenALDataBuffer target) { lock (_locker) { var unqueueBuffer = new uint[1]; OpenAL.alSourceUnqueueBuffers(_source.SourceId, 1, unqueueBuffer); var data = new byte[_bufferSize]; var datalength = _bufferSize; if (_bufferSize > _audioData.Length - _processedBytes) { Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _audioData.Length - _processedBytes); datalength = _audioData.Length - _processedBytes; _processedBytes += datalength; } else { Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _bufferSize); _processedBytes += _bufferSize; } _audioMixer.ApplyEffects(data, WaveFormat); OpenAL.alBufferData(target.Id, Format, data, datalength, SampleRate); OpenAL.alSourceQueueBuffers(_source.SourceId, 1, new[] { target.Id }); } }
/// <summary> /// Fills the buffer. /// </summary> /// <param name="target">The OpenALDataBuffer.</param> private void FillBuffer(OpenALDataBuffer target) { lock (_locker) { var unqueueBuffer = new uint[1]; OpenAL.alSourceUnqueueBuffers(_source.SourceId, 1, unqueueBuffer); var data = new byte[_bufferSize]; var datalength = _bufferSize; if (_bufferSize > _audioData.Length - _processedBytes) { Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _audioData.Length - _processedBytes); datalength = _audioData.Length - _processedBytes; _processedBytes += datalength; } else { Buffer.BlockCopy(_audioData, _processedBytes, data, 0, _bufferSize); _processedBytes += _bufferSize; } _audioMixer.ApplyEffects(data, WaveFormat); OpenAL.alBufferData(target.Id, Format, data, datalength, SampleRate); OpenAL.alSourceQueueBuffers(_source.SourceId, 1, new[] {target.Id}); } }
/// <summary> /// Starts the playback. /// </summary> private void StartPlayback() { if (PlaybackState == PlaybackState.Stopped) { PlaybackState = PlaybackState.Playing; RaisePlaybackChanged(); _processedBytes = 0; _playbackThread = new Task(() => { OpenALDataBuffer buffer1; OpenALDataBuffer buffer2; OpenALDataBuffer buffer3; lock (_locker) { Owner.Context.MakeCurrent(); buffer1 = OpenALDataBuffer.CreateBuffer(); buffer2 = OpenALDataBuffer.CreateBuffer(); buffer3 = OpenALDataBuffer.CreateBuffer(); } buffer1.Next = buffer2; buffer2.Next = buffer3; buffer3.Next = buffer1; OpenALDataBuffer currentBuffer = buffer1; FillBuffer(currentBuffer); currentBuffer = currentBuffer.Next; FillBuffer(currentBuffer); currentBuffer = currentBuffer.Next; FillBuffer(currentBuffer); lock (_locker) { OpenAL.alSourcePlay(_source.SourceId); } while (_processedBytes < _audioData.Length) { if (_beginDispose) { return; } switch (PlaybackState) { case PlaybackState.Paused: _playbackThread.Wait(Latency); continue; case PlaybackState.Stopped: return; } int finishedBuffers; lock (_locker) { OpenAL.alGetSourcei(_source.SourceId, SourceProperty.AllBuffersProcessed, out finishedBuffers); } if (finishedBuffers == 0) { _playbackThread.Wait(Latency); } while (finishedBuffers > 0) { finishedBuffers--; currentBuffer = currentBuffer.Next; FillBuffer(currentBuffer); } Position = _processedBytes / WaveFormat.AvgBytesPerSec * 1000; //if the audio stops where it should not, restart playback lock (_locker) { int sourceState; OpenAL.alGetSourcei(_source.SourceId, SourceProperty.SourceState, out sourceState); if ((SourceState)sourceState == SourceState.Stopped) { OpenAL.alSourcePlay(_source.SourceId); } } } PlaybackState = PlaybackState.Stopped; var queuedBuffers = new uint[3]; RaisePlaybackChanged(); lock (_locker) { OpenAL.alSourceUnqueueBuffers(_source.SourceId, 3, queuedBuffers); OpenAL.alDeleteBuffers(3, queuedBuffers); } }); _playbackThread.Start(); } }