public bool FillBuffer(RAudioStream stream, int bufferId) { int readSamples; lock (readMutex) { readSamples = stream.Reader.ReadSamples(readSampleBuffer, 0, BufferSize); CastBuffer(readSampleBuffer, castBuffer, readSamples); } AL.BufferData(bufferId, stream.Reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, castBuffer, readSamples * sizeof(short), stream.Reader.SampleRate); ALHelper.Check(); return(readSamples != BufferSize); }
public void EnsureBuffersFilled() { do { threadLocalStreams.Clear(); lock (iterationMutex) threadLocalStreams.AddRange(streams); foreach (var stream in threadLocalStreams) { lock (stream.prepareMutex) { lock (iterationMutex) if (!streams.Contains(stream)) { continue; } bool finished = false; int queued; AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersQueued, out queued); ALHelper.Check(); int processed; AL.GetSource(stream.alSourceId, ALGetSourcei.BuffersProcessed, out processed); ALHelper.Check(); if (processed == 0 && queued == stream.BufferCount) { continue; } int[] tempBuffers; if (processed > 0) { tempBuffers = AL.SourceUnqueueBuffers(stream.alSourceId, processed); } else { tempBuffers = stream.alBufferIds.Skip(queued).ToArray(); } int bufIdx = 0; for (; bufIdx < tempBuffers.Length; bufIdx++) { finished |= FillBuffer(stream, tempBuffers[bufIdx]); if (finished) { if (stream.IsLooped) { stream.Reader.DecodedTime = TimeSpan.Zero; if (bufIdx == 0) { // we didn't have any buffers left over, so let's start from the beginning on the next cycle... continue; } } else { lock (stream.stopMutex) { stream.NotifyFinished(); } streams.Remove(stream); break; } } } AL.SourceQueueBuffers(stream.alSourceId, bufIdx, tempBuffers); ALHelper.Check(); if (finished && !stream.IsLooped) { continue; } } lock (stream.stopMutex) { if (stream.Preparing) { continue; } lock (iterationMutex) if (!streams.Contains(stream)) { continue; } var state = AL.GetSourceState(stream.alSourceId); if (state == ALSourceState.Stopped) { AL.SourcePlay(stream.alSourceId); ALHelper.Check(); } } } if (UpdateRate > 0) { Thread.Sleep((int)(1000 / UpdateRate)); } }while (underlyingThread != null && !cancelled); }