using Silk.NET.OpenAL; namespace DaggerFramework.Audio { public class OpenALAudioBackend : AudioBackend { public unsafe override void Initialize() { _alc = ALContext.GetApi(); _al = AL.GetApi(); _alDevice = _alc.OpenDevice(""); _context = _alc.CreateContext(_alDevice, null); _alc.MakeContextCurrent(_context); } public override void Update() { } public unsafe override void Shutdown() { _alc.CloseDevice(_alDevice); _al.Dispose(); _alc.Dispose(); } public override void AddBusEffect(T effect, string bus = "Master") { throw new NotImplementedException(); } public override void CreateBus(string busName) { throw new NotImplementedException(); } public override float GetBusVolume(string busName) { throw new NotImplementedException(); } public override void SetBusVolume(string busName, float volume) { throw new NotImplementedException(); } public override void PlaySound(Sound sound, string bus = "Master", float pitch = 1, float volume = 1) { ALSound alSound; if (_alSoundsForDaggerSounds.ContainsKey(sound)) { alSound = _alSoundsForDaggerSounds[sound]; PlayALSound(alSound, pitch); return; } alSound = CreateALSound(sound); _alSoundsForDaggerSounds.Add(sound, alSound); PlayALSound(alSound, pitch); } private void PlayALSound(ALSound sound, float pitch, float volume = 1.0f) { _al.SetSourceProperty(sound.SourceHandle, SourceFloat.Pitch, pitch); // TODO: Add gain. // _al.SetSourceProperty(sound.SourceHandle, SourceFloat.Gain, 0.0f); _al.SourcePlay(sound.SourceHandle); } private unsafe ALSound CreateALSound(Sound sound) { ALSound result; uint source = _al.GenSource(); uint buffer = _al.GenBuffer(); fixed (byte* pData = sound.Buffer) { BufferFormat bufferFormat = BufferFormat.Stereo16; if (sound.Format == SoundFormat.Mono) { bufferFormat = BufferFormat.Mono16; } else if (sound.Format == SoundFormat.Stereo) { bufferFormat = BufferFormat.Stereo16; } _al.BufferData(buffer, bufferFormat, pData, sound.BufferSize, sound.BufferSize); } result = new ALSound(buffer, source); _al.SetSourceProperty(source, SourceInteger.Buffer, buffer); return result; } private void DeleteALSound(ALSound sound) { _al.DeleteSource(sound.SourceHandle); _al.DeleteBuffer(sound.BufferHandle); } private Dictionary _alSoundsForDaggerSounds = new(); private ALContext _alc; private AL _al; private unsafe Device* _alDevice; private unsafe Context* _context; private struct ALSound { public uint BufferHandle { get; set; } public uint SourceHandle { get; set; } public ALSound(uint bufferHandle, uint sourceHandle) { BufferHandle = bufferHandle; SourceHandle = sourceHandle; } } } }