void UpdateThread() { //Init context IntPtr dev = Alc.alcOpenDevice(null); IntPtr ctx = Alc.alcCreateContext(dev, IntPtr.Zero); Alc.alcMakeContextCurrent(ctx); for (int i = 0; i < MAX_SOURCES; i++) { freeSources.Enqueue(Al.GenSource()); } for (int i = 0; i < MAX_BUFFERS; i++) { Buffers.Enqueue(Al.GenBuffer()); } uint musicSource; for (int i = 0; i < 2; i++) { while (!freeSources.TryDequeue(out musicSource)) { } streamingSources.Enqueue(musicSource); } FLLog.Debug("Audio", "Audio initialised"); Ready = true; while (running) { //insert into items to update while (toAdd.Count > 0) { SoundEffectInstance item; if (toAdd.TryDequeue(out item)) { sfxInstances.Add(item); } } Action toRun; if (Actions.TryDequeue(out toRun)) { toRun(); } //update SFX for (int i = sfxInstances.Count - 1; i >= 0; i--) { int state; Al.alGetSourcei(sfxInstances[i].ID, Al.AL_SOURCE_STATE, out state); if (state != Al.AL_PLAYING) { if (sfxInstances[i].Dispose != null) { sfxInstances[i].Dispose.Dispose(); } freeSources.Enqueue(sfxInstances[i].ID); sfxInstances.RemoveAt(i); i--; } } //update Streaming foreach (var item in activeStreamers) { item.Update(); } foreach (var item in toRemove) { activeStreamers.Remove(item); if (item.Stopped != null) { item.OnStopped(); } } Thread.Sleep(5); } //Delete context Alc.alcMakeContextCurrent(IntPtr.Zero); Alc.alcDestroyContext(ctx); Alc.alcCloseDevice(ctx); }
void UpdateThread() { audioThreadId = Thread.CurrentThread.ManagedThreadId; //Init context IntPtr dev = Alc.alcOpenDevice(null); IntPtr ctx = Alc.alcCreateContext(dev, IntPtr.Zero); Alc.alcMakeContextCurrent(ctx); Al.CheckErrors(); for (int i = 0; i < MAX_SOURCES; i++) { freeSources.Enqueue(Al.GenSource()); } for (int i = 0; i < MAX_STREAM_BUFFERS; i++) { Buffers.Enqueue(Al.GenBuffer()); } Instances = new InstanceInfo[MAX_INSTANCES]; for (int i = 0; i < MAX_INSTANCES; i++) { Instances[i].Source = uint.MaxValue; freeInstances.Enqueue((uint)i); } uint musicSource; for (int i = 0; i < 2; i++) { while (!freeSources.TryDequeue(out musicSource)) { } streamingSources.Enqueue(musicSource); } FLLog.Debug("Audio", "Audio initialised"); Ready = true; Al.alListenerf(Al.AL_GAIN, ALUtils.ClampVolume(ALUtils.LinearToAlGain(_masterVolume))); while (running) { //Run actions Action toRun; while (actions.TryDequeue(out toRun)) { toRun(); } //update SFX for (int i = sfxInstances.Count - 1; i >= 0; i--) { var src = Instances[sfxInstances[i]].Source; var instance = Instances[sfxInstances[i]].Instance; int state; Al.alGetSourcei(src, Al.AL_SOURCE_STATE, out state); Al.CheckErrors(); if (state == Al.AL_STOPPED) { Al.alSourcei(src, Al.AL_BUFFER, 0); freeSources.Enqueue(src); Instances[sfxInstances[i]].Source = uint.MaxValue; instance?.Stopped(); sfxInstances.RemoveAt(i); i--; } } //update Streaming foreach (var item in activeStreamers) { item.Update(); } foreach (var item in toRemove) { activeStreamers.Remove(item); item.OnStopped(); } toRemove.Clear(); Thread.Sleep((sfxInstances.Count > 0 || activeStreamers.Count > 0) ? 1 : 5); } //Delete context Alc.alcMakeContextCurrent(IntPtr.Zero); Alc.alcDestroyContext(ctx); Alc.alcCloseDevice(dev); }