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)); } } }
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; } }
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; } }
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; }
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); }
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(); }
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; } }