Exemplo n.º 1
0
        public virtual void DeleteALBuffers()
        {
            Owner.KillChannels(this);
            if (alBuffer != 0)
            {
                if (!Al.IsBuffer(alBuffer))
                {
                    throw new Exception("Buffer to delete is invalid!");
                }

                Al.DeleteBuffer(alBuffer); alBuffer = 0;

                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }
            }
            if (alMuffledBuffer != 0)
            {
                if (!Al.IsBuffer(alMuffledBuffer))
                {
                    throw new Exception("Buffer to delete is invalid!");
                }

                Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;

                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }
            }
        }
Exemplo n.º 2
0
        public virtual void InitializeALBuffers()
        {
            if (!Stream)
            {
                Al.GenBuffer(out alBuffer);
                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }

                if (!Al.IsBuffer(alBuffer))
                {
                    throw new Exception("Generated OpenAL buffer is invalid!");
                }

                Al.GenBuffer(out alMuffledBuffer);
                alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }

                if (!Al.IsBuffer(alMuffledBuffer))
                {
                    throw new Exception("Generated OpenAL buffer is invalid!");
                }
            }
            else
            {
                alBuffer = 0;
            }
        }
Exemplo n.º 3
0
        public Sound(SoundManager owner, string filename, bool stream, bool streamsReliably, XElement xElement = null)
        {
            Owner           = owner;
            Filename        = Path.GetFullPath(filename.CleanUpPath()).CleanUpPath();
            Stream          = stream;
            StreamsReliably = streamsReliably;
            XElement        = xElement;

            BaseGain = 1.0f;
            BaseNear = 100.0f;
            BaseFar  = 200.0f;

            if (!stream)
            {
                Al.GenBuffer(out alBuffer);
                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }

                if (!Al.IsBuffer(alBuffer))
                {
                    throw new Exception("Generated OpenAL buffer is invalid!");
                }

                Al.GenBuffer(out alMuffledBuffer);
                alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }

                if (!Al.IsBuffer(alMuffledBuffer))
                {
                    throw new Exception("Generated OpenAL buffer is invalid!");
                }
            }
            else
            {
                alBuffer = 0;
            }
        }
Exemplo n.º 4
0
        public virtual void Dispose()
        {
            if (disposed)
            {
                return;
            }

            Owner.KillChannels(this);
            if (alBuffer != 0)
            {
                if (!Al.IsBuffer(alBuffer))
                {
                    throw new Exception("Buffer to delete is invalid!");
                }

                Al.DeleteBuffer(alBuffer); alBuffer = 0;

                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }
            }
            if (alMuffledBuffer != 0)
            {
                if (!Al.IsBuffer(alMuffledBuffer))
                {
                    throw new Exception("Buffer to delete is invalid!");
                }

                Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;

                int alError = Al.GetError();
                if (alError != Al.NoError)
                {
                    throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
                }
            }

            Owner.RemoveSound(this);
            disposed = true;
        }
Exemplo n.º 5
0
        public bool RequestAlBuffers()
        {
            if (AlBuffer != 0)
            {
                return(false);
            }
            int alError;

            lock (bufferPool)
            {
                while (bufferPool.Count < 2 && BuffersGenerated < MaxBuffers)
                {
                    Al.GenBuffer(out uint newBuffer);
                    alError = Al.GetError();
                    if (alError != Al.NoError)
                    {
                        DebugConsole.AddWarning($"Error when generating sound buffer: {Al.GetErrorString(alError)}. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
                        BuffersGenerated = MaxBuffers;
                    }
                    else if (!Al.IsBuffer(newBuffer))
                    {
                        DebugConsole.AddWarning($"Error when generating sound buffer: result is not a valid buffer. {BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
                        BuffersGenerated = MaxBuffers;
                    }
                    else
                    {
                        bufferPool.Add(newBuffer);
                        BuffersGenerated++;
                        if (BuffersGenerated >= MaxBuffers)
                        {
                            DebugConsole.AddWarning($"{BuffersGenerated} buffer(s) were generated. No more sound buffers will be generated.");
                        }
                    }
                }

                if (bufferPool.Count >= 2)
                {
                    AlBuffer = bufferPool.First();
                    bufferPool.Remove(AlBuffer);
                    AlMuffledBuffer = bufferPool.First();
                    bufferPool.Remove(AlMuffledBuffer);
                    return(true);
                }
            }

            //can't generate any more OpenAL buffers! we'll have to steal a buffer from someone...
            foreach (var otherSound in sound.Owner.LoadedSounds)
            {
                if (otherSound == sound)
                {
                    continue;
                }
                if (otherSound.IsPlaying())
                {
                    continue;
                }
                if (otherSound.Buffers == null)
                {
                    continue;
                }
                if (otherSound.Buffers.AlBuffer == 0)
                {
                    continue;
                }

                // Dispose all channels that are holding
                // a reference to these buffers, otherwise
                // an INVALID_OPERATION error will be thrown
                // when attempting to set the buffer data later.
                // Having the sources not play is not enough,
                // as OpenAL assumes that you may want to call
                // alSourcePlay without reassigning the buffer.
                otherSound.Owner.KillChannels(otherSound);

                AlBuffer                           = otherSound.Buffers.AlBuffer;
                AlMuffledBuffer                    = otherSound.Buffers.AlMuffledBuffer;
                otherSound.Buffers.AlBuffer        = 0;
                otherSound.Buffers.AlMuffledBuffer = 0;

                // For performance reasons, sift the current sound to
                // the end of the loadedSounds list, that way it'll
                // be less likely to have its buffers stolen, which
                // means less reuploads for frequently played sounds.
                sound.Owner.MoveSoundToPosition(sound, sound.Owner.LoadedSoundCount - 1);

                if (!Al.IsBuffer(AlBuffer))
                {
                    throw new Exception(sound.Filename + " has an invalid buffer!");
                }
                if (!Al.IsBuffer(AlMuffledBuffer))
                {
                    throw new Exception(sound.Filename + " has an invalid muffled buffer!");
                }

                return(true);
            }

            return(false);
        }
Exemplo n.º 6
0
        public SoundChannel(Sound sound, float gain, Vector3?position, float near, float far, string category, bool muffle = false)
        {
            Sound = sound;

            debugName = sound == null ?
                        "SoundChannel (null)" :
                        $"SoundChannel ({(string.IsNullOrEmpty(sound.Filename) ? "filename empty" : sound.Filename) })";

            IsStream         = sound.Stream;
            FilledByNetwork  = sound is VoipSound;
            decayTimer       = 0;
            streamSeekPos    = 0; reachedEndSample = false;
            buffersToRequeue = 4;
            muffled          = muffle;

            if (IsStream)
            {
                mutex = new object();
            }

            try
            {
                if (mutex != null)
                {
                    Monitor.Enter(mutex);
                }
                if (sound.Owner.CountPlayingInstances(sound) < sound.MaxSimultaneousInstances)
                {
                    ALSourceIndex = sound.Owner.AssignFreeSourceToChannel(this);
                }

                if (ALSourceIndex >= 0)
                {
                    if (!IsStream)
                    {
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
                        int alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
                        }

                        if (!Al.IsBuffer(sound.ALBuffer))
                        {
                            throw new Exception(sound.Filename + " has an invalid buffer!");
                        }

                        uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
                        }

                        Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to play source: " + debugName + ", " + Al.GetErrorString(alError));
                        }
                    }
                    else
                    {
                        uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
                        int alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
                        }

                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Looping, Al.False);
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to set stream looping state: " + debugName + ", " + Al.GetErrorString(alError));
                        }

                        streamShortBuffer = new short[STREAM_BUFFER_SIZE];

                        streamBuffers          = new uint[4];
                        unqueuedBuffers        = new uint[4];
                        streamBufferAmplitudes = new float[4];
                        for (int i = 0; i < 4; i++)
                        {
                            Al.GenBuffer(out streamBuffers[i]);

                            alError = Al.GetError();
                            if (alError != Al.NoError)
                            {
                                throw new Exception("Failed to generate stream buffers: " + debugName + ", " + Al.GetErrorString(alError));
                            }

                            if (!Al.IsBuffer(streamBuffers[i]))
                            {
                                throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid! " + debugName);
                            }
                        }
                        Sound.Owner.InitStreamThread();
                    }
                }

                this.Position = position;
                this.Gain     = gain;
                this.Looping  = false;
                this.Near     = near;
                this.Far      = far;
                this.Category = category;
            }
            catch
            {
                throw;
            }
            finally
            {
                if (mutex != null)
                {
                    Monitor.Exit(mutex);
                }
            }

            Sound.Owner.Update();
        }
Exemplo n.º 7
0
        public SoundChannel(Sound sound, float gain, Vector3?position, float near, float far, string category, bool muffle = false)
        {
            Sound = sound;

            IsStream        = sound.Stream;
            FilledByNetwork = sound is VoipSound;
            decayTimer      = 0;
            streamSeekPos   = 0; reachedEndSample = false;
            startedPlaying  = true;

            mutex = new object();

            lock (mutex)
            {
                if (sound.Owner.CountPlayingInstances(sound) < sound.MaxSimultaneousInstances)
                {
                    ALSourceIndex = sound.Owner.AssignFreeSourceToChannel(this);
                }

                if (ALSourceIndex >= 0)
                {
                    if (!IsStream)
                    {
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, 0);
                        int alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
                        }

                        if (!Al.IsBuffer(sound.ALBuffer))
                        {
                            throw new Exception(sound.Filename + " has an invalid buffer!");
                        }

                        uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + Al.GetErrorString(alError));
                        }

                        Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to play source: " + Al.GetErrorString(alError));
                        }
                    }
                    else
                    {
                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)sound.ALBuffer);
                        int alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to reset source buffer: " + Al.GetErrorString(alError));
                        }

                        Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Looping, Al.False);
                        alError = Al.GetError();
                        if (alError != Al.NoError)
                        {
                            throw new Exception("Failed to set stream looping state: " + Al.GetErrorString(alError));
                        }

                        streamShortBuffer = new short[STREAM_BUFFER_SIZE];

                        streamBuffers = new uint[4];
                        emptyBuffers  = new List <uint>();
                        for (int i = 0; i < 4; i++)
                        {
                            Al.GenBuffer(out streamBuffers[i]);

                            alError = Al.GetError();
                            if (alError != Al.NoError)
                            {
                                throw new Exception("Failed to generate stream buffers: " + Al.GetErrorString(alError));
                            }

                            if (!Al.IsBuffer(streamBuffers[i]))
                            {
                                throw new Exception("Generated streamBuffer[" + i.ToString() + "] is invalid!");
                            }
                        }

                        Sound.Owner.InitStreamThread();
                    }
                }

                this.Position = position;
                this.Gain     = gain;
                this.Looping  = false;
                this.Near     = near;
                this.Far      = far;
                this.Category = category;
            }
        }