示例#1
0
 public void SetAttenuation(float attenuation)
 {
     if (Active)
     {
         Al.alSourcef(ID, Al.AL_GAIN, ALUtils.DbToAlGain(attenuation) * man.GetVolume(SoundType.Sfx));
     }
     Al.CheckErrors();
 }
示例#2
0
        internal void UpdateAttenuation()
        {
            var gain = ALUtils.ClampVolume(ALUtils.DbToAlGain(attenuation) * man.GetVolume(SoundType.Sfx));

            gainSet         = true;
            dirtyFlags     |= FLAG_GAIN;
            properties.Gain = gain;
        }
示例#3
0
        public static StreamingSound GetSound(Stream stream)
        {
            var reader = new VorbisReader(stream, true);
            var snd    = new StreamingSound();

            snd.Data      = new VorbisStream(reader);
            snd.Frequency = reader.SampleRate;
            snd.Format    = ALUtils.GetFormat(reader.Channels, 16);
            return(snd);
        }
示例#4
0
        void _Begin()
        {
            if (playing)
            {
                Cleanup();
            }
            dataleft = true;
            playing  = true;
            var bytes = ArrayPool <byte> .Shared.Rent(POOL_BUFFER_SIZE);

            for (int i = 0; i < 3; i++)
            {
                var b    = manager.Buffers.Dequeue();
                int read = Read(bytes, sound.Data);
                if (read != 0)
                {
                    try
                    {
                        Al.BufferData(b, sound.Format, bytes, read, sound.Frequency);
                    }
                    catch (Exception)
                    {
                        FLLog.Error("AL", $"Error in source {info}");
                        throw;
                    }
                    Al.alSourceQueueBuffers(ID, 1, ref b);
                }
                else
                {
                    manager.Buffers.Enqueue(b);
                }
                if (read < POOL_BUFFER_SIZE)
                {
                    if (!looping)
                    {
                        dataleft = false;
                        break;
                    }
                    else
                    {
                        sound.Data.Seek(0, SeekOrigin.Begin);
                    }
                }
            }
            ArrayPool <byte> .Shared.Return(bytes);

            Al.alSourcef(ID, Al.AL_GAIN, ALUtils.ClampVolume(_gain));
            Al.alSourcePlay(ID);
            manager.activeStreamers.Add(this);
        }
        void _Begin()
        {
            if (playing)
            {
                Cleanup();
            }
            dataleft = true;
            playing  = true;
            var bytes = BufferAllocator.AllocateBytes();

            for (int i = 0; i < 3; i++)
            {
                var b    = manager.Buffers.Dequeue();
                int read = sound.Data.Read(bytes, 0, bytes.Length);
                if (read != 0)
                {
                    Al.BufferData(b, sound.Format, bytes, read, sound.Frequency);
                    Al.CheckErrors();
                    Al.alSourceQueueBuffers(ID, 1, ref b);
                    Al.CheckErrors();
                }
                else
                {
                    manager.Buffers.Enqueue(b);
                }
                if (read < bytes.Length)
                {
                    if (!looping)
                    {
                        dataleft = false;
                        break;
                    }
                    else
                    {
                        sound.Data.Seek(0, SeekOrigin.Begin);
                    }
                }
            }
            BufferAllocator.Free(bytes);
            Al.alSourcef(ID, Al.AL_GAIN, ALUtils.ClampVolume(_gain));
            Al.alSourcePlay(ID);
            Al.CheckErrors();
            manager.activeStreamers.Add(this);
        }
示例#6
0
        public AudioManager(IUIThread uithread)
        {
            UIThread      = uithread;
            audioThreadId = Thread.CurrentThread.ManagedThreadId;
            initTask      = Task.Run(() =>
            {
                Platform.RegisterDllMap(typeof(AudioManager).Assembly);
                Music = new MusicPlayer(this);
                //Init context
                dev = Alc.alcOpenDevice(null);
                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_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");
                Al.alListenerf(Al.AL_GAIN, ALUtils.ClampVolume(ALUtils.LinearToAlGain(_masterVolume)));
                Ready = true;
            });
        }
示例#7
0
        public static StreamingSound GetSound(Stream stream)
        {
            RiffLoader file = new RiffLoader(stream);

            if (file.Format == WaveFormat.PCM)
            {
                var snd = new StreamingSound();
                snd.Format    = ALUtils.GetFormat(file.m_Channels, file.Bits);
                snd.Frequency = file.Frequency;
                snd.Size      = file.dataLength;
                snd.Data      = file.GetDataStream();
                return(snd);
            }
            else if (file.Format == WaveFormat.MP3)
            {
                return(Mp3Utils.GetSound(file.GetDataStream(), file));
            }
            throw new NotSupportedException();
        }
示例#8
0
        void UpdateThread()
        {
            //Init context
            IntPtr dev = Alc.alcOpenDevice(null);
            IntPtr ctx = Alc.alcCreateContext(dev, IntPtr.Zero);

            Alc.alcMakeContextCurrent(ctx);
            Al.alListenerf(Al.AL_GAIN, ALUtils.LinearToAlGain(_masterVolume));
            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)
                {
                    SoundInstance 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);
                    Al.CheckErrors();
                    if (state != Al.AL_PLAYING)
                    {
                        sfxInstances[i].Active = false;
                        if (sfxInstances[i].Dispose != null)
                        {
                            sfxInstances[i].Dispose.Dispose();
                        }
                        if (sfxInstances[i].OnFinish != null)
                        {
                            UIThread.QueueUIThread(sfxInstances[i].OnFinish);
                        }
                        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();
                    }
                }
                toRemove.Clear();
                Thread.Sleep(5);
            }
            //Delete context
            Alc.alcMakeContextCurrent(IntPtr.Zero);
            Alc.alcDestroyContext(ctx);
            Alc.alcCloseDevice(ctx);
        }
示例#9
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);
        }
示例#10
0
 void UpdateGain()
 {
     sound.Gain = ALUtils.LinearToAlGain(_volume) * ALUtils.DbToAlGain(attenuation);
 }