WIP: SoLoud audio system, make Sound be in 16-bit PCM.
This commit is contained in:
BIN
TestGame/Resources/sounds/test_sound_mono.ogg
Normal file
BIN
TestGame/Resources/sounds/test_sound_mono.ogg
Normal file
Binary file not shown.
@@ -34,6 +34,7 @@ public class TestGame : Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager.TryLoad("icon.png", out _icon);
|
ResourceManager.TryLoad("icon.png", out _icon);
|
||||||
|
ResourceManager.TryLoad("sounds/test_sound_mono.ogg", out _sound);
|
||||||
|
|
||||||
if (!ResourceManager.TryLoad("fire_effect.toml", out _fireEffect))
|
if (!ResourceManager.TryLoad("fire_effect.toml", out _fireEffect))
|
||||||
{
|
{
|
||||||
@@ -52,8 +53,9 @@ public class TestGame : Game
|
|||||||
{
|
{
|
||||||
if (Input.IsActionPressed("reload"))
|
if (Input.IsActionPressed("reload"))
|
||||||
{
|
{
|
||||||
ResourceManager.Reload();
|
// ResourceManager.Reload();
|
||||||
_particleSystem!.RestartEmitter(_emitterId);
|
// _particleSystem!.RestartEmitter(_emitterId);
|
||||||
|
AudioSystem.PlaySound(_sound.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.KeyboardKeyJustPressed(KeyboardKey.One))
|
if (Input.KeyboardKeyJustPressed(KeyboardKey.One))
|
||||||
@@ -106,5 +108,6 @@ public class TestGame : Game
|
|||||||
private int _emitterId;
|
private int _emitterId;
|
||||||
private ResourceRef<ParticleEmitterSettingsResource> _fireEffect;
|
private ResourceRef<ParticleEmitterSettingsResource> _fireEffect;
|
||||||
private ResourceRef<Font> _font;
|
private ResourceRef<Font> _font;
|
||||||
|
private ResourceRef<Sound> _sound;
|
||||||
private ResourceRef<Texture2d> _icon;
|
private ResourceRef<Texture2d> _icon;
|
||||||
}
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
namespace Voile
|
|
||||||
{
|
|
||||||
public class AudioBus
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
namespace Voile
|
|
||||||
{
|
|
||||||
public class AudioEffect { }
|
|
||||||
|
|
||||||
public class AudioEffectReverb : AudioEffect
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,6 @@ public abstract class AudioSystem : IStartableSystem, IUpdatableSystem, IDisposa
|
|||||||
public abstract void SetBusVolume(string busName, float volume);
|
public abstract void SetBusVolume(string busName, float volume);
|
||||||
public abstract float GetBusVolume(string busName);
|
public abstract float GetBusVolume(string busName);
|
||||||
|
|
||||||
// SOUND
|
|
||||||
public abstract void PlaySound(Sound sound, float pitch, float volume, string bus = "Master");
|
public abstract void PlaySound(Sound sound, float pitch, float volume, string bus = "Master");
|
||||||
public void PlaySound(Sound sound, string bus = "Master") => PlaySound(sound, 1.0f, 1.0f, bus);
|
public void PlaySound(Sound sound, string bus = "Master") => PlaySound(sound, 1.0f, 1.0f, bus);
|
||||||
|
|
||||||
@@ -32,9 +31,6 @@ public abstract class AudioSystem : IStartableSystem, IUpdatableSystem, IDisposa
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EFFECTS
|
|
||||||
public abstract void AddBusEffect<T>(T effect, string bus = "Master") where T : AudioEffect;
|
|
||||||
|
|
||||||
|
|
||||||
private LehmerRandom _random = new LehmerRandom();
|
private LehmerRandom _random = new LehmerRandom();
|
||||||
}
|
}
|
||||||
@@ -5,11 +5,6 @@ namespace Voile.Audio
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DummyAudioSystem : AudioSystem
|
public class DummyAudioSystem : AudioSystem
|
||||||
{
|
{
|
||||||
public override void AddBusEffect<T>(T effect, string bus = "Master")
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void CreateBus(string busName)
|
public override void CreateBus(string busName)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
64
Voile/Source/Audio/StandardAudioSystem.cs
Normal file
64
Voile/Source/Audio/StandardAudioSystem.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using Raylib_cs;
|
||||||
|
using SoLoud;
|
||||||
|
|
||||||
|
namespace Voile.Audio;
|
||||||
|
|
||||||
|
public class StandardAudioSystem : AudioSystem
|
||||||
|
{
|
||||||
|
public StandardAudioSystem()
|
||||||
|
{
|
||||||
|
_engine = new Soloud();
|
||||||
|
}
|
||||||
|
protected override void Initialize()
|
||||||
|
{
|
||||||
|
_engine.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CreateBus(string busName)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float GetBusVolume(string busName)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PlaySound(Sound sound, float pitch, float volume, string bus = "Master")
|
||||||
|
{
|
||||||
|
PlayUnsafe(sound.Buffer, sound.BufferSize, sound.SampleRate, sound.Channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetBusVolume(string busName, float volume)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Shutdown()
|
||||||
|
{
|
||||||
|
_engine!.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayUnsafe(ReadOnlyMemory<short> soundBuffer, long length, int sampleRate, SoundChannel channels)
|
||||||
|
{
|
||||||
|
var wav = new Wav();
|
||||||
|
|
||||||
|
int channelCount = channels == SoundChannel.Stereo ? 2 : 1;
|
||||||
|
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
nint ptr = (nint)soundBuffer.Pin().Pointer;
|
||||||
|
wav.loadRawWave16(ptr, (uint)length, sampleRate, (uint)channelCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
_engine.play(wav);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Soloud _engine;
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using Voile.Audio;
|
||||||
using Voile.Input;
|
using Voile.Input;
|
||||||
using Voile.Rendering;
|
using Voile.Rendering;
|
||||||
using Voile.Resources;
|
using Voile.Resources;
|
||||||
@@ -42,6 +43,8 @@ namespace Voile
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected RenderSystem? Renderer { get; set; }
|
protected RenderSystem? Renderer { get; set; }
|
||||||
|
|
||||||
|
protected AudioSystem? AudioSystem { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of this game. Also used as a default window title.
|
/// Name of this game. Also used as a default window title.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -113,6 +116,13 @@ namespace Voile
|
|||||||
Input = new RaylibInputSystem();
|
Input = new RaylibInputSystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AudioSystem is null)
|
||||||
|
{
|
||||||
|
AudioSystem = new StandardAudioSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioSystem.Start();
|
||||||
|
|
||||||
Input.Start();
|
Input.Start();
|
||||||
InitializeRenderer();
|
InitializeRenderer();
|
||||||
}
|
}
|
||||||
@@ -121,6 +131,7 @@ namespace Voile
|
|||||||
{
|
{
|
||||||
Input?.Dispose();
|
Input?.Dispose();
|
||||||
Renderer?.Dispose();
|
Renderer?.Dispose();
|
||||||
|
AudioSystem?.Dispose();
|
||||||
ResourceManager.Dispose();
|
ResourceManager.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using StbVorbisSharp;
|
using StbVorbisSharp;
|
||||||
|
using Voile.VFS;
|
||||||
|
|
||||||
namespace Voile.Resources
|
namespace Voile.Resources
|
||||||
{
|
{
|
||||||
@@ -6,7 +7,7 @@ namespace Voile.Resources
|
|||||||
{
|
{
|
||||||
public override IEnumerable<string> SupportedExtensions => new string[]
|
public override IEnumerable<string> SupportedExtensions => new string[]
|
||||||
{
|
{
|
||||||
"ogg"
|
".ogg"
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override Sound LoadResource(string path)
|
protected override Sound LoadResource(string path)
|
||||||
@@ -14,9 +15,11 @@ namespace Voile.Resources
|
|||||||
Vorbis vorbis;
|
Vorbis vorbis;
|
||||||
Sound result;
|
Sound result;
|
||||||
|
|
||||||
var fileBuffer = File.ReadAllBytes(path);
|
using var stream = VirtualFileSystem.Read(path);
|
||||||
vorbis = Vorbis.FromMemory(fileBuffer);
|
byte[] fileBuffer = new byte[stream.Length];
|
||||||
|
int bytesRead = stream.Read(fileBuffer, 0, fileBuffer.Length);
|
||||||
|
|
||||||
|
vorbis = Vorbis.FromMemory(fileBuffer);
|
||||||
vorbis.SubmitBuffer();
|
vorbis.SubmitBuffer();
|
||||||
|
|
||||||
if (vorbis.Decoded == 0)
|
if (vorbis.Decoded == 0)
|
||||||
@@ -27,18 +30,9 @@ namespace Voile.Resources
|
|||||||
|
|
||||||
var audioShort = vorbis.SongBuffer;
|
var audioShort = vorbis.SongBuffer;
|
||||||
int length = vorbis.Decoded * vorbis.Channels;
|
int length = vorbis.Decoded * vorbis.Channels;
|
||||||
byte[] audioData = new byte[length * 2];
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++)
|
short[] audioData = new short[length];
|
||||||
{
|
Array.Copy(audioShort, audioData, length);
|
||||||
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 = new Sound(path, audioData)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
namespace Voile
|
namespace Voile
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents raw audio samples.
|
/// Represents raw audio samples in 16-bit PCM format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Sound : Resource
|
public class Sound : Resource
|
||||||
{
|
{
|
||||||
public SoundChannel Channel { get; set; }
|
public SoundChannel Channel { get; set; }
|
||||||
public int SampleRate { get; set; }
|
public int SampleRate { get; set; }
|
||||||
|
|
||||||
public byte[]? Buffer { get; private set; }
|
public short[]? Buffer { get; private set; }
|
||||||
public long BufferSize { get; set; }
|
public long BufferSize { get; set; }
|
||||||
|
|
||||||
public Sound(string path, byte[] buffer) : base(path)
|
public Sound(string path, short[] buffer) : base(path)
|
||||||
{
|
{
|
||||||
Buffer = buffer;
|
Buffer = buffer;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user