예제 #1
0
        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);
        }
예제 #2
0
        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);
        }