From 36eae40926ff3536b1219425a6f485120eee44a6 Mon Sep 17 00:00:00 2001 From: dnesov Date: Sat, 17 Jun 2023 00:56:17 +0200 Subject: [PATCH] OpenAL sound implementation. --- DaggerFramework.csproj | 1 + DaggerFramework.sln | 14 --- Source/Audio/AudioBackend.cs | 20 ++-- Source/Audio/DummyAudioBackend.cs | 7 +- Source/Audio/OpenALAudioBackend.cs | 125 +++++++++++++++++++++++ Source/Resources/Loaders/SoundLoader.cs | 42 +++++++- Source/Resources/Sound.cs | 11 +- TestGame/Resources/sounds/test_sound.ogg | Bin 0 -> 10774 bytes TestGame/TestGame.cs | 21 +++- 9 files changed, 211 insertions(+), 30 deletions(-) delete mode 100644 DaggerFramework.sln create mode 100644 Source/Audio/OpenALAudioBackend.cs create mode 100644 TestGame/Resources/sounds/test_sound.ogg diff --git a/DaggerFramework.csproj b/DaggerFramework.csproj index 4bd54b8..0cef74e 100644 --- a/DaggerFramework.csproj +++ b/DaggerFramework.csproj @@ -10,5 +10,6 @@ + \ No newline at end of file diff --git a/DaggerFramework.sln b/DaggerFramework.sln deleted file mode 100644 index bb32f59..0000000 --- a/DaggerFramework.sln +++ /dev/null @@ -1,14 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Source/Audio/AudioBackend.cs b/Source/Audio/AudioBackend.cs index 38714dd..9c520e0 100644 --- a/Source/Audio/AudioBackend.cs +++ b/Source/Audio/AudioBackend.cs @@ -1,29 +1,35 @@ namespace DaggerFramework.Audio { - public abstract class AudioBackend + public abstract class AudioBackend : IDisposable { public abstract void Initialize(); public abstract void Update(); + public abstract void Shutdown(); // BUS public abstract void CreateBus(string busName); public abstract void SetBusVolume(string busName, float volume); public abstract float GetBusVolume(string busName); // SOUND - protected abstract void PlaySound(Sound sound, string bus = "Master", float pitch = 1.0f, float volume = 1.0f); - public void PlaySound(Sound sound, string bus = "Master") => PlaySound(sound, bus, sound.PitchScale, sound.Volume); - public void PlaySoundVariation(Sound sound, string bus = "Master", float pitchVariation = 0.1f) + public abstract void PlaySound(Sound sound, string bus = "Master", float pitch = 1.0f, float volume = 1.0f); + public void PlaySound(Sound sound, string bus = "Master") => PlaySound(sound, bus, default, default); + public void PlaySoundVariation(Sound sound, string bus = "Master", float pitchVariation = 0.1f, float volume = 1.0f) { - var maxPitch = sound.PitchScale + pitchVariation; - var minPitch = sound.PitchScale - pitchVariation; + var maxPitch = 1.0f + pitchVariation; + var minPitch = 1.0f - pitchVariation; var pitch = (float)_random.NextDouble() * (maxPitch - minPitch) + minPitch; - PlaySound(sound, bus, pitch, sound.Volume); + PlaySound(sound, bus, pitch, volume); } // EFFECTS public abstract void AddBusEffect(T effect, string bus = "Master") where T : AudioEffect; + public void Dispose() + { + Shutdown(); + } + private LehmerRandom _random = new LehmerRandom(); } } \ No newline at end of file diff --git a/Source/Audio/DummyAudioBackend.cs b/Source/Audio/DummyAudioBackend.cs index 11c7410..fdff592 100644 --- a/Source/Audio/DummyAudioBackend.cs +++ b/Source/Audio/DummyAudioBackend.cs @@ -27,12 +27,17 @@ namespace DaggerFramework.Audio return; } + public override void Shutdown() + { + return; + } + public override void Update() { return; } - protected override void PlaySound(Sound sound, string bus = "Master", float pitch = 1, float volume = 1) + public override void PlaySound(Sound sound, string bus = "Master", float pitch = 1, float volume = 1) { return; } diff --git a/Source/Audio/OpenALAudioBackend.cs b/Source/Audio/OpenALAudioBackend.cs new file mode 100644 index 0000000..d7744e9 --- /dev/null +++ b/Source/Audio/OpenALAudioBackend.cs @@ -0,0 +1,125 @@ +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; + } + } + } +} \ No newline at end of file diff --git a/Source/Resources/Loaders/SoundLoader.cs b/Source/Resources/Loaders/SoundLoader.cs index f5d564b..109ab50 100644 --- a/Source/Resources/Loaders/SoundLoader.cs +++ b/Source/Resources/Loaders/SoundLoader.cs @@ -1,15 +1,47 @@ +using StbVorbisSharp; + namespace DaggerFramework { public class SoundLoader : ResourceLoader { public override Sound Load(string path) { - // TODO - // var data = File.ReadAllBytes(path); - var sound = new Sound(path, new byte[] { }); - sound.Path = path; + Vorbis vorbis; + Sound result; - return sound; + var fileBuffer = File.ReadAllBytes(path); + vorbis = Vorbis.FromMemory(fileBuffer); + + vorbis.SubmitBuffer(); + + if (vorbis.Decoded == 0) + { + vorbis.Restart(); + vorbis.SubmitBuffer(); + } + + var audioShort = vorbis.SongBuffer; + int length = vorbis.Decoded * vorbis.Channels; + byte[] audioData = new byte[length * 2]; + + for (int i = 0; i < length; i++) + { + if (i * 2 >= audioData.Length) break; + + var b1 = (byte)(audioShort[i] >> 8); + var b2 = (byte)(audioShort[i] & 256); + + audioData[i * 2] = b2; + audioData[i * 2 + 1] = b1; + } + + result = new Sound(path, audioData); + result.Format = (SoundFormat)vorbis.Channels - 1; + result.SampleRate = vorbis.SampleRate; + result.BufferSize = length; + + vorbis.Dispose(); + return result; } } } \ No newline at end of file diff --git a/Source/Resources/Sound.cs b/Source/Resources/Sound.cs index 725f3bf..766d369 100644 --- a/Source/Resources/Sound.cs +++ b/Source/Resources/Sound.cs @@ -2,11 +2,18 @@ namespace DaggerFramework { public class Sound : Resource { - public float PitchScale { get; set; } = 1.0f; - public float Volume { get; set; } = 1.0f; + public SoundFormat Format { get; set; } + public int SampleRate { get; set; } + public int BufferSize { get; set; } public Sound(string path, byte[] buffer) : base(path, buffer) { } } + + public enum SoundFormat + { + Mono, + Stereo + } } \ No newline at end of file diff --git a/TestGame/Resources/sounds/test_sound.ogg b/TestGame/Resources/sounds/test_sound.ogg new file mode 100644 index 0000000000000000000000000000000000000000..e2d17277997949e0f52d292f9a7831ac2153b791 GIT binary patch literal 10774 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 literal 0 HcmV?d00001 diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs index f98c7a7..9d46673 100644 --- a/TestGame/TestGame.cs +++ b/TestGame/TestGame.cs @@ -1,6 +1,7 @@ using DaggerFramework; using System.Numerics; using DaggerFramework.Rendering; +using DaggerFramework.Audio; public class TestGame : Game { @@ -8,18 +9,26 @@ public class TestGame : Game protected override void OnStart() { _renderer = new RaylibRenderer(); + _audioBackend = new OpenALAudioBackend(); + _inputHandler = new RaylibInputHandler(); _renderer.CreateAndInitialize(new WindowSettings() { Title = "Test Game", Size = new Vector2(1280, 720) }, RendererSettings.Default); + _renderer.SetTargetFps(60); + + _audioBackend.Initialize(); + + _inputHandler.AddInputMapping("play", new InputAction[] { new KeyInputAction(KeyboardKey.Spacebar) }); } protected override void LoadResources() { - + _soundLoader = new SoundLoader(); + _testSound = _soundLoader.Load($"{ResourceRoot}sounds/test_sound.ogg"); } protected override void MainLoop() @@ -28,6 +37,12 @@ public class TestGame : Game { _renderer.BeginFrame(); _renderer.ClearBackground(Color.Black); + + if (_inputHandler.IsActionJustPressed("play")) + { + _audioBackend.PlaySoundVariation(_testSound, default, 0.1f); + } + _renderer.SetTransform(new Vector2(640, 480)); _renderer.DrawCircle(16f, Color.Chocolate); _renderer.EndFrame(); @@ -39,4 +54,8 @@ public class TestGame : Game _renderer.Shutdown(); } private Renderer _renderer; + private SoundLoader _soundLoader; + private Sound _testSound; + private OpenALAudioBackend _audioBackend; + private InputHandler _inputHandler; } \ No newline at end of file