public static int Loop(Sound sound, int sourceIndex, Vector2 position, float volume = 1.0f) { if (Disabled) { return(-1); } if (!MathUtils.IsValid(volume)) { volume = 0.0f; } if (sourceIndex < 1 || soundsPlaying[sourceIndex] != sound) { sourceIndex = Play(sound, position, volume, 0.0f, true); } else { UpdateSoundPosition(sourceIndex, position, volume); AL.Source(alSources[sourceIndex], ALSourceb.Looping, true); } ALHelper.Check(); return(sourceIndex); }
public void Dispose() { var state = AL.GetSourceState(alSourceId); if (state == ALSourceState.Playing || state == ALSourceState.Paused) { StopPlayback(); } lock (prepareMutex) { OggStreamer.Instance.RemoveStream(this); if (state != ALSourceState.Initial) { Empty(); } Close(); underlyingStream.Dispose(); } AL.DeleteSource(alSourceId); AL.DeleteBuffers(alBufferIds); /*if (ALHelper.Efx.IsInitialized) * ALHelper.Efx.DeleteFilter(alFilterId);*/ ALHelper.Check(); }
public OggStream(Stream stream, int bufferCount = DefaultBufferCount) { BufferCount = bufferCount; alBufferIds = AL.GenBuffers(bufferCount); alSourceId = AL.GenSource(); if (ALHelper.XRam.IsInitialized) { ALHelper.XRam.SetBufferMode(BufferCount, ref alBufferIds[0], XRamExtension.XRamStorage.Hardware); ALHelper.Check(); } if (ALHelper.Efx.IsInitialized) { //alFilterId = ALHelper.Efx.GenFilter(); //ALHelper.Efx.Filter(alFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass); //ALHelper.Efx.Filter(alFilterId, EfxFilterf.LowpassGain, 1); //ALHelper.Efx.BindFilterToSource(alSourceId, alFilterId); //LowPassHFGain = 1; } underlyingStream = stream; IsLooped = true; }
public void Resume() { if (AL.GetSourceState(alSourceId) != ALSourceState.Paused) { return; } OggStreamer.Instance.AddStream(this); AL.SourcePlay(alSourceId); ALHelper.Check(); }
public void Pause() { if (AL.GetSourceState(alSourceId) != ALSourceState.Playing) { return; } OggStreamer.Instance.RemoveStream(this); AL.SourcePause(alSourceId); ALHelper.Check(); }
//public bool IsLooped { get; set; } public static OggSound Load(string oggFile, int bufferCount = DefaultBufferCount) { OggSound sound = new OggSound(); sound.file = oggFile; using (VorbisReader reader = new VorbisReader(oggFile)) { int bufferSize = (int)reader.TotalSamples * reader.Channels; float[] buffer = new float[bufferSize]; sound.castBuffer = new short[bufferSize]; int readSamples = reader.ReadSamples(buffer, 0, bufferSize); CastBuffer(buffer, sound.castBuffer, readSamples); sound.alBufferId = AL.GenBuffer(); sound.format = reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16; sound.sampleRate = reader.SampleRate; ALHelper.Check(); //alSourceId = AL.GenSource(); AL.BufferData(sound.alBufferId, reader.Channels == 1 ? ALFormat.Mono16 : ALFormat.Stereo16, sound.castBuffer, readSamples * sizeof(short), reader.SampleRate); ALHelper.Check(oggFile); } //AL.Source(alSourceId, ALSourcei.Buffer, alBufferId); //if (ALHelper.XRam.IsInitialized) //{ // ALHelper.XRam.SetBufferMode(bufferCount, ref alBufferId, XRamExtension.XRamStorage.Hardware); // ALHelper.Check(); //} //Volume = 1; //if (ALHelper.Efx.IsInitialized) //{ // alFilterId = ALHelper.Efx.GenFilter(); // ALHelper.Efx.Filter(alFilterId, EfxFilteri.FilterType, (int)EfxFilterType.Lowpass); // ALHelper.Efx.Filter(alFilterId, EfxFilterf.LowpassGain, 1); // LowPassHFGain = 1; //} return(sound); }
public void Dispose() { //var state = AL.GetSourceState(alSourceId); //if (state == ALSourceState.Playing || state == ALSourceState.Paused) // Stop(); System.Diagnostics.Debug.WriteLine(alBufferId); //AL.DeleteSource(alSourceId); AL.DeleteBuffer(alBufferId); //if (ALHelper.Efx.IsInitialized) // ALHelper.Efx.DeleteFilter(alFilterId); ALHelper.Check(); }
public void Dispose() { System.Diagnostics.Debug.WriteLine(alBufferId); if (alBufferId > 0) { AL.DeleteBuffer(alBufferId); alBufferId = 0; } //if (ALHelper.Efx.IsInitialized) // ALHelper.Efx.DeleteFilter(alFilterId); ALHelper.Check(); }
public bool FillBuffer(OggStream 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 static void Resume(int sourceIndex) { if (Disabled) { return; } if (AL.GetSourceState(alSources[sourceIndex]) != ALSourceState.Paused) { return; } AL.SourcePlay(alSources[sourceIndex]); ALHelper.Check(); }
public static void Pause(int sourceIndex) { if (Disabled) { return; } if (AL.GetSourceState(alSources[sourceIndex]) != ALSourceState.Playing) { return; } AL.SourcePause(alSources[sourceIndex]); ALHelper.Check(soundsPlaying[sourceIndex]?.FilePath); }
internal void Open(bool precache = false) { underlyingStream.Seek(0, SeekOrigin.Begin); Reader = new VorbisReader(underlyingStream, false); if (precache) { // Fill first buffer synchronously OggStreamer.Instance.FillBuffer(this, alBufferIds[0]); AL.SourceQueueBuffer(alSourceId, alBufferIds[0]); ALHelper.Check(); // Schedule the others asynchronously OggStreamer.Instance.AddStream(this); } Ready = true; }
public static OggStream StartStream(string file, float volume = 1.0f) { if (Disabled) { return(null); } if (oggStreamer == null) { oggStreamer = new OggStreamer(); } oggStream = new OggStream(file); oggStreamer.AddStream(oggStream); oggStream.Play(volume); ALHelper.Check(); return(oggStream); }
public static void Dispose() { if (Disabled) { return; } if (ALHelper.Efx.IsInitialized) { ALHelper.Efx.DeleteFilter(lowpassFilterId); } for (int i = 0; i < DefaultSourceCount; i++) { var state = OpenTK.Audio.OpenAL.AL.GetSourceState(alSources[i]); if (state == OpenTK.Audio.OpenAL.ALSourceState.Playing || state == OpenTK.Audio.OpenAL.ALSourceState.Paused) { Stop(i); } OpenTK.Audio.OpenAL.AL.DeleteSource(alSources[i]); ALHelper.Check(); } if (oggStream != null) { oggStream.Stop(); oggStream.Dispose(); oggStream = null; } if (oggStreamer != null) { oggStreamer.Dispose(); oggStreamer = null; } }
void Empty() { int queued; AL.GetSource(alSourceId, ALGetSourcei.BuffersQueued, out queued); ALHelper.Check(); if (queued > 0) { try { AL.SourceUnqueueBuffers(alSourceId, queued); if (AL.GetError() != ALError.NoError) { throw new InvalidOperationException(); } } catch (InvalidOperationException) { // This is a bug in the OpenAL implementation // Salvage what we can int processed; AL.GetSource(alSourceId, ALGetSourcei.BuffersProcessed, out processed); var salvaged = new int[processed]; if (processed > 0) { AL.SourceUnqueueBuffers(alSourceId, processed, salvaged); ALHelper.Check(); } // Try turning it off again? AL.SourceStop(alSourceId); ALHelper.Check(); Empty(); } } }
public void Play(float volume) { var state = AL.GetSourceState(alSourceId); switch (state) { case ALSourceState.Playing: return; case ALSourceState.Paused: Resume(); return; } Prepare(); AL.SourcePlay(alSourceId); this.Volume = volume; ALHelper.Check(); Preparing = false; OggStreamer.Instance.AddStream(this); }
public static void UpdateSoundPosition(int sourceIndex, Vector2 position, float baseVolume = 1.0f) { if (sourceIndex < 1 || Disabled) { return; } if (!MathUtils.IsValid(position)) { position = Vector2.Zero; } position /= 1000.0f; OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSourcef.Gain, baseVolume * MasterVolume); OpenTK.Audio.OpenAL.AL.Source(alSources[sourceIndex], OpenTK.Audio.OpenAL.ALSource3f.Position, position.X, position.Y, 0.0f); float lowPassGain = lowPassHfGain / Math.Max(position.Length() * 5.0f, 1.0f); ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilterf.LowpassGainHF, lowPassGain); ALHelper.Efx.BindFilterToSource(alSources[sourceIndex], lowpassFilterId); ALHelper.Check(); }
public static void Init() { var availableDevices = AudioContext.AvailableDevices; if (availableDevices.Count == 0) { DebugConsole.ThrowError("No audio devices found. Disabling audio playback."); Disabled = true; return; } try { AC = new AudioContext(); ALHelper.Check(); } catch (DllNotFoundException) { Program.CrashMessageBox("OpenAL32.dll not found"); throw; } for (int i = 0; i < DefaultSourceCount; i++) { alSources.Add(OpenTK.Audio.OpenAL.AL.GenSource()); } ALHelper.Check(); if (ALHelper.Efx.IsInitialized) { lowpassFilterId = ALHelper.Efx.GenFilter(); //alFilters.Add(alFilterId); ALHelper.Efx.Filter(lowpassFilterId, OpenTK.Audio.OpenAL.EfxFilteri.FilterType, (int)OpenTK.Audio.OpenAL.EfxFilterType.Lowpass); LowPassHFGain = 1.0f; } }
void StopPlayback() { AL.SourceStop(alSourceId); ALHelper.Check(); }
void EnsureBuffersFilled() { while (!cancelled) { Thread.Sleep((int)(1000 / UpdateRate)); if (cancelled) { break; } 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(); } for (int i = 0; i < tempBuffers.Length; i++) { finished |= FillBuffer(stream, tempBuffers[i]); if (finished) { if (stream.IsLooped) { stream.Reader.DecodedTime = TimeSpan.Zero; } else { streams.Remove(stream); i = tempBuffers.Length; } } } AL.SourceQueueBuffers(stream.alSourceId, tempBuffers.Length, 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(); } } } } }