예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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;
        }
예제 #4
0
        public void Resume()
        {
            if (AL.GetSourceState(alSourceId) != ALSourceState.Paused)
            {
                return;
            }

            OggStreamer.Instance.AddStream(this);
            AL.SourcePlay(alSourceId);
            ALHelper.Check();
        }
예제 #5
0
        public void Pause()
        {
            if (AL.GetSourceState(alSourceId) != ALSourceState.Playing)
            {
                return;
            }

            OggStreamer.Instance.RemoveStream(this);
            AL.SourcePause(alSourceId);
            ALHelper.Check();
        }
예제 #6
0
        //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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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();
        }
예제 #9
0
        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);
        }
예제 #10
0
        public static void Resume(int sourceIndex)
        {
            if (Disabled)
            {
                return;
            }

            if (AL.GetSourceState(alSources[sourceIndex]) != ALSourceState.Paused)
            {
                return;
            }

            AL.SourcePlay(alSources[sourceIndex]);
            ALHelper.Check();
        }
예제 #11
0
        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);
        }
예제 #12
0
        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;
        }
예제 #13
0
        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);
        }
예제 #14
0
        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;
            }
        }
예제 #15
0
        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();
                }
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
        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();
        }
예제 #18
0
        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;
            }
        }
예제 #19
0
 void StopPlayback()
 {
     AL.SourceStop(alSourceId);
     ALHelper.Check();
 }
예제 #20
0
        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();
                        }
                    }
                }
            }
        }