private void ClearQueue() { var queued = 0; AL.GetSource(_source, ALGetSourcei.BuffersQueued, out queued); AudioDevice.Check(); for (var i = 0; i < queued; i++) { AL.SourceUnqueueBuffer(_source); } try { AudioDevice.Check(); } catch { //unqueueing buffers can fail } }
private void Empty() { lock (_sync) { AL.SourceStop(_alsourceid); AudioDevice.Check(); AL.GetSource(_alsourceid, ALGetSourcei.BuffersQueued, out int queued); for (int i = 0; i < queued; i++) { AL.SourceUnqueueBuffer(_alsourceid); AudioDevice.Check(); } try { AudioDevice.Check(); } catch { //unqueueing buffers can fail } } }
private void BufferRefiller() { try { while (true) { ALSourceState state; lock (_sync) { state = AL.GetSourceState(_alsourceid); if (state == ALSourceState.Playing) { RefillProcessed(); } else if (_needsrefill) { AL.SourcePlay(_alsourceid); AudioDevice.Check(); } } if (state == ALSourceState.Playing) { Thread.Sleep(1); } else { _event.WaitOne(); _event.Reset(); } } } catch (AudioException ae) { Program.NonFatalError(ae.ToString()); } }
private bool FillAndAddBuffer(int bufnum) { var requestStop = false; var readsamples = _reader.ReadSamples(_samplebuffer, 0, _samplebuffer.Length); for (var i = 0; i < readsamples; i++) { var temp = (int)(32767f * _samplebuffer[i]); if (temp > short.MaxValue) { temp = short.MaxValue; } else if (temp < short.MinValue) { temp = short.MinValue; } _conversionbuffer[i] = (short)temp; } if (_firstbuffer) { var earlysamples = Math.Min(_samplebuffer.Length / 20, readsamples); //10th of a second unless its too much for (var i = 0; i < earlysamples; i++) { var divisor = (20 - (19 * (i / (float)earlysamples))); if (divisor < 1) { divisor = 1; } _conversionbuffer[i] /= (short)divisor; } _firstbuffer = false; } if (readsamples != _samplebuffer.Length) { _endbuffers[bufnum] = true; if (Loop) { _reader.DecodedTime = TimeSpan.FromSeconds(0); // If we previously had no data, try to fill the buffer once again if (readsamples == 0) { return(FillAndAddBuffer(bufnum)); } } else { requestStop = true; } } if (readsamples != 0) { var buffer = _buffers[bufnum]; AL.BufferData(buffer, _format, _conversionbuffer, readsamples * sizeof(short), _reader.SampleRate); AudioDevice.Check(); AL.SourceQueueBuffer(_source, buffer); AudioDevice.Check(); } return(requestStop); }
private void DataStreamProc() { //based on a couple of different audio library playback methods. most notably sfml here. try { var requeststop = false; lock (_threadlock) { if (_threadstartstate == Status.Stopped) { _streaming = false; _continue = true; return; } } AudioDevice.Check(); _buffers = AL.GenBuffers(BufferCount); for (var i = 0; i < BufferCount; i++) { _endbuffers[i] = false; } _firstbuffer = true; requeststop = FillQueue(); bool requirefirstplay = requeststop; _continue = true; AudioDevice.Check(); lock (_threadlock) { if (_threadstartstate == Status.Paused) { AL.SourcePause(_source); AudioDevice.Check(); } } for (;;) { lock (_threadlock) { if (!_streaming) { break; } } if (GetStatus() == Status.Stopped) { if (!requeststop || requirefirstplay) { requirefirstplay = false; AL.Source(_source, ALSourcef.Pitch, _pitch); AL.SourcePlay(_source); } else { lock (_threadlock) { _streaming = false; } } } var processed = 0; AL.GetSource(_source, ALGetSourcei.BuffersProcessed, out processed); AudioDevice.Check(); while (processed-- != 0) { var buffer = AL.SourceUnqueueBuffer(_source); AudioDevice.Check(); var buffernum = 0; for (var i = 0; i < BufferCount; i++) { if (_buffers[i] == buffer) { buffernum = i; break; } } if (_endbuffers[buffernum]) { _reader.DecodedTime = new TimeSpan(0); _endbuffers[buffernum] = false; } else { int size, bits; AL.GetBuffer(buffer, ALGetBufferi.Size, out size); AL.GetBuffer(buffer, ALGetBufferi.Bits, out bits); if (bits == 0) { lock (_threadlock) { _streaming = false; requeststop = true; Program.NonFatalError( "bits in sound stream are 0. Corrupt audio format?"); break; } } } if (!requeststop) { if (FillAndAddBuffer(buffernum)) { requeststop = true; } } } if (GetStatus() != Status.Stopped) { Thread.Sleep(10); } } AL.SourceStop(_source); ClearQueue(); AL.Source(_source, ALSourcei.Buffer, 0); AL.DeleteBuffers(_buffers); } catch (AudioDeviceException) //audiodevice disposed { } Playing = false; }