public OpenALAudioLayer(string name, OpenALAudioAdapter parent) : base(name) { if (_openALFormatId == 0) { _openALFormatId = _openALAudioFormat.BitsPerSample switch { 32 => Al.FORMAT_STEREO32F, 16 => _openALAudioFormat.Channels == 2 ? Al.FORMAT_STEREO16 : Al.FORMAT_MONO16, 8 => _openALAudioFormat.Channels == 2 ? Al.FORMAT_STEREO8 : Al.FORMAT_MONO8, _ => _openALFormatId } } ; if (_frameRequestSize == 0) { _frameRequestSize = _openALAudioFormat.GetFrameCount(BackendBufferExpectedAhead / 1000f); _frameRequestSize /= BUFFER_COUNT; } _parent = parent; Al.GenSource(out _source); _buffers = new uint[BUFFER_COUNT]; _bufferBusy = new bool[BUFFER_COUNT]; for (var i = 0; i < _buffers.Length; i++) { Al.GenBuffer(out _buffers[i]); } _uploadBuffer = new byte[_frameRequestSize * _openALAudioFormat.FrameSize]; }
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; } }
internal unsafe AudioClip(IResource resource) { Al.GenBuffer(out Buffer); using var reader = new VorbisReader(resource.OpenStream()); var channels = reader.Channels; var sampleRate = reader.SampleRate; var seconds = reader.TotalTime.TotalSeconds; var samples = (int)Math.Ceiling(seconds * sampleRate * channels); var floats = new Span <float>(new float[samples]); if (reader.ReadSamples(floats) <= 0) { throw new Exception("Failed to read OGG stream."); } var shorts = new Span <short>(new short[samples]); // 16 bit for (var i = 0; i < floats.Length; i++) shorts[i] = (short)(short.MaxValue * floats[i]); fixed(void *p = &shorts.GetPinnableReference()) { Al.BufferData(Buffer, channels == 2 ? Al.FormatStereo16 : Al.FormatMono16, p, shorts.Length * sizeof(short), sampleRate); } }
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 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; } }