/// <summary> /// Get the number of processed buffers. /// </summary> public int ProcessedBuffers() { CheckDisposed(); Context.MakeCurrent(); AL10.alGetSourcei(Name, AL10.AL_BUFFERS_PROCESSED, out var processed); AlHelper.AlCheckError("Failed to get number of processed buffers."); return(processed); }
protected void StopSource() { AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out var state); if (state == AL10.AL_PLAYING || state == AL10.AL_PAUSED) { AL10.alSourceStop(Source); } }
internal bool Update() { if (State == SoundState.Stopped) { /* If we've stopped, remove ourselves from the list. * Do NOT do anything else, Play/Stop/Dispose do this! * -flibit */ return(false); } // Get the processed buffers. int finishedBuffers; AL10.alGetSourcei( INTERNAL_alSource, AL10.AL_BUFFERS_PROCESSED, out finishedBuffers ); if (finishedBuffers == 0) { // Nothing to do... yet. return(true); } uint[] bufs = new uint[finishedBuffers]; AL10.alSourceUnqueueBuffers( INTERNAL_alSource, (IntPtr)finishedBuffers, bufs ); PendingBufferCount -= finishedBuffers; if (BufferNeeded != null) { // PendingBufferCount changed during playback, trigger now! BufferNeeded(this, null); } // Error check our queuedBuffers list. for (int i = 0; i < finishedBuffers; i += 1) { uint newBuf = queuedBuffers.Dequeue(); if (newBuf != bufs[i]) { throw new Exception("Buffer desync!"); } availableBuffers.Enqueue(newBuf); } // Notify the application that we need moar buffers! if (PendingBufferCount <= 2 && BufferNeeded != null) { BufferNeeded(this, null); } return(true); }
public int CheckProcessedBuffers(IALSource source) { int result; AL10.alGetSourcei( (source as OpenALSource).Handle, AL10.AL_BUFFERS_PROCESSED, out result ); return(result); }
public void StopAllSounds() { foreach (var key in sourcePool.Keys) { int state; AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state); if (state == AL10.AL_PLAYING || state == AL10.AL_PAUSED) { AL10.alSourceStop(key); } } }
private void alSourcePlay() { int state = AL10.alGetSourcei(alSource, AL10.AL_SOURCE_STATE); if (state != AL10.AL_PLAYING) { if (minimumNumberBuffers <= 0 || WaitingBuffers >= minimumNumberBuffers) { AL10.alSourcePlay(alSource); } } }
public int CheckProcessedBuffers(IALSource source) { int result; AL10.alGetSourcei( (source as OpenALSource).Handle, AL10.AL_BUFFERS_PROCESSED, out result ); #if VERBOSE_AL_DEBUGGING CheckALError(); #endif return(result); }
public void SetSoundVolume(float volume, ISound music, ISound video) { var sounds = sourcePool.Keys.Where(key => { AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out var state); return((state == AL10.AL_PLAYING || state == AL10.AL_PAUSED) && (music == null || key != ((OpenAlSound)music).Source) && (video == null || key != ((OpenAlSound)video).Source)); }); foreach (var s in sounds) { AL10.alSourcef(s, AL10.AL_GAIN, volume); } }
public void StopSound(ISound sound) { if (sound == null) { return; } var key = ((OpenAlSound)sound).Source; int state; AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state); if (state == AL10.AL_PLAYING || state == AL10.AL_PAUSED) { AL10.alSourceStop(key); } }
public void SetAllSoundsPaused(bool paused) { foreach (var key in sourcePool.Keys) { int state; AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state); if (state == AL10.AL_PLAYING && paused) { AL10.alSourcePause(key); } else if (state == AL10.AL_PAUSED && !paused) { AL10.alSourcePlay(key); } } }
public virtual void checkFreeBuffers(int alSource) { while (true) { int processedBuffers = AL10.alGetSourcei(alSource, AL10.AL_BUFFERS_PROCESSED); if (processedBuffers <= 0) { break; } int alBuffer = AL10.alSourceUnqueueBuffers(alSource); //if (log.DebugEnabled) { Console.WriteLine(string.Format("free buffer {0:D}", alBuffer)); } freeBuffers.Push(alBuffer); } }
public SoundState GetSourceState(IALSource source) { int state; AL10.alGetSourcei( (source as OpenALSource).Handle, AL10.AL_SOURCE_STATE, out state ); if (state == AL10.AL_PLAYING) { return(SoundState.Playing); } else if (state == AL10.AL_PAUSED) { return(SoundState.Paused); } return(SoundState.Stopped); }
public void PauseSound(ISound sound, bool paused) { if (sound == null) { return; } var key = ((OpenAlSound)sound).Source; int state; AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state); if (state == AL10.AL_PLAYING && paused) { AL10.alSourcePause(key); } else if (state == AL10.AL_PAUSED && !paused) { AL10.alSourcePlay(key); } }
bool TryGetSourceFromPool(out uint source) { foreach (var kvp in sourcePool) { if (!kvp.Value.IsActive) { sourcePool[kvp.Key].IsActive = true; source = kvp.Key; return(true); } } var freeSources = new List <uint>(); foreach (var key in sourcePool.Keys) { int state; AL10.alGetSourcei(key, AL10.AL_SOURCE_STATE, out state); if (state != AL10.AL_PLAYING && state != AL10.AL_PAUSED) { freeSources.Add(key); } } if (freeSources.Count == 0) { source = 0; return(false); } foreach (var i in freeSources) { sourcePool[i].IsActive = false; } sourcePool[freeSources[0]].IsActive = true; source = freeSources[0]; return(true); }
public SoundState GetSourceState(IALSource source) { int state; AL10.alGetSourcei( (source as OpenALSource).Handle, AL10.AL_SOURCE_STATE, out state ); #if VERBOSE_AL_DEBUGGING CheckALError(); #endif if (state == AL10.AL_PLAYING) { return(SoundState.Playing); } else if (state == AL10.AL_PAUSED) { return(SoundState.Paused); } return(SoundState.Stopped); }
void PauseSound(uint source, bool paused) { AL10.alGetSourcei(source, AL10.AL_SOURCE_STATE, out var state); if (paused) { if (state == AL10.AL_PLAYING) { AL10.alSourcePause(source); } else if (state == AL10.AL_INITIAL) { // If a sound hasn't started yet, // we indicate it should not play be transitioning it to the stopped state. AL10.alSourcePlay(source); AL10.alSourceStop(source); } } else if (!paused && state != AL10.AL_PLAYING) { AL10.alSourcePlay(source); } }
public void GetBufferData( IALSource source, IALBuffer[] buffer, IntPtr samples, int samplesLen, AudioChannels channels ) { int copySize1 = samplesLen / (int)channels; int copySize2 = 0; // Where are we now? int offset; AL10.alGetSourcei( (source as OpenALSource).Handle, AL11.AL_SAMPLE_OFFSET, out offset ); // Is that longer than what the active buffer has left...? uint buf = (buffer[0] as OpenALBuffer).Handle; int len; AL10.alGetBufferi( buf, AL10.AL_SIZE, out len ); len /= 2; // FIXME: Assuming 16-bit! len /= (int)channels; if (offset > len) { copySize2 = copySize1; copySize1 = 0; offset -= len; } else if (offset + copySize1 > len) { copySize2 = copySize1 - (len - offset); copySize1 = (len - offset); } // Copy! if (copySize1 > 0) { ALEXT.alGetBufferSamplesSOFT( buf, offset, copySize1, channels == AudioChannels.Stereo ? ALEXT.AL_STEREO_SOFT : ALEXT.AL_MONO_SOFT, ALEXT.AL_FLOAT_SOFT, samples ); offset = 0; } if (buffer.Length > 1 && copySize2 > 0) { ALEXT.alGetBufferSamplesSOFT( (buffer[1] as OpenALBuffer).Handle, 0, copySize2, channels == AudioChannels.Stereo ? ALEXT.AL_STEREO_SOFT : ALEXT.AL_MONO_SOFT, ALEXT.AL_FLOAT_SOFT, samples + (copySize1 * (int)channels) ); } }
public OpenAlAsyncLoadSound(uint source, bool looping, bool relative, WPos pos, float volume, int channels, int sampleBits, int sampleRate, Stream stream) : base(source, looping, relative, pos, volume, sampleRate) { // Load a silent buffer into the source. Without this, // attempting to change the state (i.e. play/pause) the source fails on some systems. var silentSource = new OpenAlSoundSource(SilentData, SilentData.Length, channels, sampleBits, sampleRate); AL10.alSourcei(source, AL10.AL_BUFFER, (int)silentSource.Buffer); playTask = Task.Run(async() => { MemoryStream memoryStream; using (stream) { try { memoryStream = new MemoryStream((int)stream.Length); } catch (NotSupportedException) { // Fallback for stream types that don't support Length. memoryStream = new MemoryStream(); } try { await stream.CopyToAsync(memoryStream, 81920, cts.Token); } catch (TaskCanceledException) { // Sound was stopped early, cleanup the unused buffer and exit. AL10.alSourceStop(source); AL10.alSourcei(source, AL10.AL_BUFFER, 0); silentSource.Dispose(); return; } } var data = memoryStream.GetBuffer(); var dataLength = (int)memoryStream.Length; var bytesPerSample = sampleBits / 8f; var lengthInSecs = dataLength / (channels * bytesPerSample * sampleRate); using (var soundSource = new OpenAlSoundSource(data, dataLength, channels, sampleBits, sampleRate)) { // Need to stop the source, before attaching the real input and deleting the silent one. AL10.alSourceStop(source); AL10.alSourcei(source, AL10.AL_BUFFER, (int)soundSource.Buffer); silentSource.Dispose(); lock (cts) { if (!cts.IsCancellationRequested) { // TODO: A race condition can happen between the state check and playing/rewinding if a // user pauses/resumes at the right moment. The window of opportunity is small and the // consequences are minor, so for now we'll ignore it. int state; AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out state); if (state != AL10.AL_STOPPED) { AL10.alSourcePlay(source); } else { // A stopped sound indicates it was paused before we finishing loaded. // We don't want to start playing it right away. // We rewind the source so when it is started, it plays from the beginning. AL10.alSourceRewind(source); } } } while (!cts.IsCancellationRequested) { // Need to check seek before state. Otherwise, the music can stop after our state check at // which point the seek will be zero, meaning we'll wait the full track length before seeing it // has stopped. var currentSeek = SeekPosition; int state; AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out state); if (state == AL10.AL_STOPPED) { break; } try { // Wait until the track is due to complete, and at most 60 times a second to prevent a // busy-wait. var delaySecs = Math.Max(lengthInSecs - currentSeek, 1 / 60f); await Task.Delay(TimeSpan.FromSeconds(delaySecs), cts.Token); } catch (TaskCanceledException) { // Sound was stopped early, allow normal cleanup to occur. } } AL10.alSourcei(Source, AL10.AL_BUFFER, 0); } }); }