OpenAL sound implementation.
This commit is contained in:
@@ -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>(T effect, string bus = "Master") where T : AudioEffect;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
private LehmerRandom _random = new LehmerRandom();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
125
Source/Audio/OpenALAudioBackend.cs
Normal file
125
Source/Audio/OpenALAudioBackend.cs
Normal file
@@ -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>(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<Sound, ALSound> _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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user