diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs index f66be3e..0400abf 100644 --- a/TestGame/TestGame.cs +++ b/TestGame/TestGame.cs @@ -5,6 +5,7 @@ using Voile.Systems.Particles; using System.Numerics; using System.Diagnostics.CodeAnalysis; using Voile.Rendering; +using Voile.OpenAL; public class TestGame : Game { @@ -15,7 +16,10 @@ public class TestGame : Game { InitializeSystemsDefault(); + _audioSystem = new OpenALSystem(); _particleSystem = new ParticleSystem(); + + AddSystemToUpdate(_audioSystem); AddSystemToUpdate(_particleSystem); } @@ -55,6 +59,7 @@ public class TestGame : Game { // ResourceManager.Reload(); // _particleSystem!.RestartEmitter(_emitterId); + _audioSystem.PlaySound(_sound.Value, 1.0f); } if (Input.KeyboardKeyJustPressed(KeyboardKey.One)) @@ -104,6 +109,7 @@ public class TestGame : Game } [NotNull] private ParticleSystem _particleSystem; + private OpenALSystem _audioSystem; private int _emitterId; private ResourceRef _fireEffect; private ResourceRef _font; diff --git a/TestGame/TestGame.csproj b/TestGame/TestGame.csproj index 054790f..4d5227b 100644 --- a/TestGame/TestGame.csproj +++ b/TestGame/TestGame.csproj @@ -11,6 +11,7 @@ + diff --git a/Voile.OpenAL/OpenALSystem.cs b/Voile.OpenAL/OpenALSystem.cs new file mode 100644 index 0000000..013766e --- /dev/null +++ b/Voile.OpenAL/OpenALSystem.cs @@ -0,0 +1,59 @@ +using Voile.Audio; +using Silk.NET.OpenAL; + +namespace Voile.OpenAL; + +public class OpenALSystem : AudioSystem +{ + public OpenALSystem() + { + _al = AL.GetApi(); + _alc = ALContext.GetApi(); + + Init(); + } + + public override void PlaySound(Sound sound, float volume) + { + var buffer = CreateAlBuffer(sound.Buffer, sound.SampleRate, sound.Channel); + var source = CreateAlSource(buffer); + _al.SourcePlay(source); + } + + public override void Update(double deltaTime) + { + throw new NotImplementedException(); + } + + private unsafe void Init() + { + _device = _alc.OpenDevice(""); + _context = _alc.CreateContext(_device, null); + _alc.MakeContextCurrent(_context); + } + + private uint CreateAlBuffer(ReadOnlyMemory data, int sampleRate, SoundChannel channels) + { + var buffer = _al.GenBuffer(); + var format = channels == SoundChannel.Mono ? BufferFormat.Mono16 : BufferFormat.Stereo16; + + unsafe + { + _al.BufferData(buffer, format, data.Pin().Pointer, data.Length, sampleRate); + } + + return buffer; + } + + private uint CreateAlSource(uint buffer) + { + var source = _al.GenSource(); + _al.SetSourceProperty(source, SourceInteger.Buffer, buffer); + return source; + } + + private unsafe Device* _device; + private ALContext _alc; + private unsafe Context* _context; + private AL _al; +} diff --git a/Voile.OpenAL/Voile.OpenAL.csproj b/Voile.OpenAL/Voile.OpenAL.csproj new file mode 100644 index 0000000..355b36b --- /dev/null +++ b/Voile.OpenAL/Voile.OpenAL.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + true + + + + + + + + + + \ No newline at end of file diff --git a/Voile.sln b/Voile.sln index fbf3adc..17757cc 100644 --- a/Voile.sln +++ b/Voile.sln @@ -13,6 +13,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Folder", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestGame", "TestGame\TestGame.csproj", "{DBA85D7B-0A91-405B-9078-5463F49AE47E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Voile.OpenAL", "Voile.OpenAL\Voile.OpenAL.csproj", "{3ABB7D30-4B64-43AD-A14F-E532B12AFC60}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {DBA85D7B-0A91-405B-9078-5463F49AE47E}.Debug|Any CPU.Build.0 = Debug|Any CPU {DBA85D7B-0A91-405B-9078-5463F49AE47E}.Release|Any CPU.ActiveCfg = Release|Any CPU {DBA85D7B-0A91-405B-9078-5463F49AE47E}.Release|Any CPU.Build.0 = Release|Any CPU + {3ABB7D30-4B64-43AD-A14F-E532B12AFC60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3ABB7D30-4B64-43AD-A14F-E532B12AFC60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3ABB7D30-4B64-43AD-A14F-E532B12AFC60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3ABB7D30-4B64-43AD-A14F-E532B12AFC60}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Voile/Source/Audio/AudioSystem.cs b/Voile/Source/Audio/AudioSystem.cs new file mode 100644 index 0000000..4414f26 --- /dev/null +++ b/Voile/Source/Audio/AudioSystem.cs @@ -0,0 +1,7 @@ +namespace Voile.Audio; + +public abstract class AudioSystem : IUpdatableSystem +{ + public abstract void Update(double deltaTime); + public abstract void PlaySound(Sound sound, float volume); +} \ No newline at end of file diff --git a/Voile/Source/Game.cs b/Voile/Source/Game.cs index 4599f06..dc7e601 100644 --- a/Voile/Source/Game.cs +++ b/Voile/Source/Game.cs @@ -116,13 +116,6 @@ namespace Voile Input = new RaylibInputSystem(); } - if (AudioSystem is null) - { - AudioSystem = new StandardAudioSystem(); - } - - AudioSystem.Start(); - Input.Start(); InitializeRenderer(); } @@ -131,7 +124,6 @@ namespace Voile { Input?.Dispose(); Renderer?.Dispose(); - AudioSystem?.Dispose(); ResourceManager.Dispose(); }