Bring back FMOD audio backend.
This commit is contained in:
@@ -32,4 +32,9 @@ namespace DaggerFramework.Audio
|
||||
|
||||
private LehmerRandom _random = new LehmerRandom();
|
||||
}
|
||||
|
||||
public struct SoundInstance
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,103 +1,136 @@
|
||||
// using FMOD;
|
||||
using FMOD;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// namespace RogueMine.Audio
|
||||
// {
|
||||
// public class FmodAudioBackend : AudioBackend
|
||||
// {
|
||||
// public override void Initialize()
|
||||
// {
|
||||
// CreateSystem();
|
||||
// _loadedSounds = new Dictionary<string, FMOD.Sound>();
|
||||
// _channelGroups = new Dictionary<string, ChannelGroup>();
|
||||
namespace DaggerFramework.Audio
|
||||
{
|
||||
public class FmodAudioBackend : AudioBackend
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
CreateSystem();
|
||||
_loadedSounds = new Dictionary<string, FMOD.Sound>();
|
||||
_channelGroups = new Dictionary<string, ChannelGroup>();
|
||||
|
||||
// CreateBus("Master");
|
||||
// }
|
||||
// public override void Update() => _system.update();
|
||||
CreateBus("Master");
|
||||
}
|
||||
public override void Update() => _system.update();
|
||||
|
||||
// protected override void PlaySound(Sound sound, string bus = "Master", float pitch = 1, float volume = 1)
|
||||
// {
|
||||
// var channel = PlaySoundFromPath(sound.Path, GetChannelGroup(bus));
|
||||
// channel.setVolume(volume);
|
||||
// channel.setPitch(pitch);
|
||||
// }
|
||||
public override void PlaySound(Sound sound, string bus = "Master", float pitch = 1, float volume = 1)
|
||||
{
|
||||
int channels = 0;
|
||||
|
||||
// public override void CreateBus(string busName)
|
||||
// {
|
||||
// ChannelGroup channelGroup;
|
||||
// _system.createChannelGroup(busName, out channelGroup);
|
||||
// _channelGroups.Add(busName, channelGroup);
|
||||
// }
|
||||
if (sound.Format == SoundFormat.Mono)
|
||||
{
|
||||
channels = 1;
|
||||
}
|
||||
else if (sound.Format == SoundFormat.Stereo)
|
||||
{
|
||||
channels = 2;
|
||||
}
|
||||
|
||||
// public override void SetBusVolume(string busName, float volume)
|
||||
// {
|
||||
// var channel = GetChannelGroup(busName);
|
||||
// channel.setVolume(volume);
|
||||
// }
|
||||
var channel = PlaySoundFromBuffer(sound.Path, sound.BufferSize, channels, sound.SampleRate, sound.Buffer, GetChannelGroup(bus));
|
||||
channel.setVolume(volume);
|
||||
channel.setPitch(pitch);
|
||||
}
|
||||
|
||||
// public override float GetBusVolume(string busName)
|
||||
// {
|
||||
// float volume;
|
||||
// GetChannelGroup(busName).getVolume(out volume);
|
||||
// return volume;
|
||||
// }
|
||||
public override void CreateBus(string busName)
|
||||
{
|
||||
ChannelGroup channelGroup;
|
||||
_system.createChannelGroup(busName, out channelGroup);
|
||||
_channelGroups.Add(busName, channelGroup);
|
||||
}
|
||||
|
||||
// public override void AddBusEffect<T>(T effect, string bus = "Master")
|
||||
// {
|
||||
// var channelGroup = GetChannelGroup(bus);
|
||||
// DSP dsp;
|
||||
public override void SetBusVolume(string busName, float volume)
|
||||
{
|
||||
var channel = GetChannelGroup(busName);
|
||||
channel.setVolume(volume);
|
||||
}
|
||||
|
||||
// switch (effect)
|
||||
// {
|
||||
// case AudioEffectReverb:
|
||||
// dsp = CreateReverbDsp(effect as AudioEffectReverb);
|
||||
// break;
|
||||
// default:
|
||||
// _system.createDSPByType(DSP_TYPE.UNKNOWN, out dsp);
|
||||
// break;
|
||||
// }
|
||||
public override float GetBusVolume(string busName)
|
||||
{
|
||||
float volume;
|
||||
GetChannelGroup(busName).getVolume(out volume);
|
||||
return volume;
|
||||
}
|
||||
|
||||
// channelGroup.addDSP(0, dsp);
|
||||
// }
|
||||
public override void AddBusEffect<T>(T effect, string bus = "Master")
|
||||
{
|
||||
var channelGroup = GetChannelGroup(bus);
|
||||
DSP dsp;
|
||||
|
||||
// private DSP CreateReverbDsp(AudioEffectReverb effectReverb)
|
||||
// {
|
||||
// DSP dsp;
|
||||
// _system.createDSPByType(DSP_TYPE.SFXREVERB, out dsp);
|
||||
// return dsp;
|
||||
// }
|
||||
switch (effect)
|
||||
{
|
||||
case AudioEffectReverb:
|
||||
dsp = CreateReverbDsp(effect as AudioEffectReverb);
|
||||
break;
|
||||
default:
|
||||
_system.createDSPByType(DSP_TYPE.UNKNOWN, out dsp);
|
||||
break;
|
||||
}
|
||||
|
||||
// private void CreateSystem()
|
||||
// {
|
||||
// var result = FMOD.Factory.System_Create(out _system);
|
||||
// _system.init(128, INITFLAGS.NORMAL, 0);
|
||||
// }
|
||||
channelGroup.addDSP(0, dsp);
|
||||
}
|
||||
|
||||
// private Channel PlaySoundFromPath(string path, ChannelGroup channelGroup)
|
||||
// {
|
||||
// FMOD.Channel fmodChannel;
|
||||
// FMOD.Sound fmodSound = IsLoaded(path) ? GetSoundFromLoaded(path) : CreateSound(path);
|
||||
// _system.playSound(fmodSound, channelGroup, false, out fmodChannel);
|
||||
private DSP CreateReverbDsp(AudioEffectReverb effectReverb)
|
||||
{
|
||||
DSP dsp;
|
||||
_system.createDSPByType(DSP_TYPE.SFXREVERB, out dsp);
|
||||
return dsp;
|
||||
}
|
||||
|
||||
// return fmodChannel;
|
||||
// }
|
||||
private void CreateSystem()
|
||||
{
|
||||
var result = FMOD.Factory.System_Create(out _system);
|
||||
_system.init(128, INITFLAGS.NORMAL, 0);
|
||||
}
|
||||
|
||||
// private FMOD.Sound GetSoundFromLoaded(string path) => _loadedSounds[path];
|
||||
// private bool IsLoaded(string path) => _loadedSounds.ContainsKey(path);
|
||||
private Channel PlaySoundFromBuffer(string path, int length, int channels, int sampleRate, byte[] buffer, ChannelGroup channelGroup)
|
||||
{
|
||||
Channel fmodChannel;
|
||||
FMOD.Sound fmodSound = IsLoaded(path) ? GetSoundFromLoaded(path) : CreateSound(length, channels, sampleRate, path, buffer);
|
||||
|
||||
// private FMOD.Sound CreateSound(string path)
|
||||
// {
|
||||
// FMOD.Sound sound;
|
||||
// _system.createSound(path, FMOD.MODE.DEFAULT, out sound);
|
||||
// AddToLoaded(path, sound);
|
||||
// return sound;
|
||||
// }
|
||||
_system.playSound(fmodSound, channelGroup, false, out fmodChannel);
|
||||
|
||||
// private void AddToLoaded(string path, FMOD.Sound sound) => _loadedSounds.Add(path, sound);
|
||||
return fmodChannel;
|
||||
}
|
||||
|
||||
// private ChannelGroup GetChannelGroup(string busName) => _channelGroups[busName];
|
||||
|
||||
// private FMOD.System _system;
|
||||
// private Dictionary<string, FMOD.Sound> _loadedSounds;
|
||||
// private Dictionary<string, ChannelGroup> _channelGroups;
|
||||
// }
|
||||
// }
|
||||
private FMOD.Sound GetSoundFromLoaded(string path) => _loadedSounds[path];
|
||||
private bool IsLoaded(string path) => _loadedSounds.ContainsKey(path);
|
||||
|
||||
private FMOD.Sound CreateSound(int length, int channels, int sampleRate, string path, byte[] buffer)
|
||||
{
|
||||
FMOD.Sound sound;
|
||||
CREATESOUNDEXINFO info = new CREATESOUNDEXINFO()
|
||||
{
|
||||
numchannels = channels,
|
||||
defaultfrequency = sampleRate,
|
||||
format = SOUND_FORMAT.PCM16,
|
||||
length = (uint)length,
|
||||
cbsize = Marshal.SizeOf(typeof(CREATESOUNDEXINFO))
|
||||
};
|
||||
|
||||
var result = _system.createSound(buffer, FMOD.MODE.OPENMEMORY | FMOD.MODE.OPENRAW | FMOD.MODE.CREATESAMPLE, ref info, out sound);
|
||||
AddToLoaded(path, sound);
|
||||
return sound;
|
||||
}
|
||||
|
||||
private void AddToLoaded(string path, FMOD.Sound sound) => _loadedSounds.Add(path, sound);
|
||||
|
||||
private ChannelGroup GetChannelGroup(string busName)
|
||||
{
|
||||
return _channelGroups[busName];
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private FMOD.System _system;
|
||||
|
||||
// TODO: use a different key for the dictionary, paths are not good :( (waste of memory lol)
|
||||
private Dictionary<string, FMOD.Sound> _loadedSounds;
|
||||
private Dictionary<string, ChannelGroup> _channelGroups;
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
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