Skip to content

Instantly share code, notes, and snippets.

@prunusnira
Last active April 1, 2023 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prunusnira/c95d52d8d270d29474c1511b5868d6c7 to your computer and use it in GitHub Desktop.
Save prunusnira/c95d52d8d270d29474c1511b5868d6c7 to your computer and use it in GitHub Desktop.
FMOD manager
public class SoundControllerFMOD : ISoundController
{
private FMOD.ChannelGroup channelGroup;
private List<FMOD.Channel> channels;
private FMOD.Channel bgmChannel;
private FMOD.Channel previewChannel;
private FMOD.Channel hitChannel;
private Dictionary<string, FMOD.Sound> soundLib;
private static SoundControllerFMOD instance;
public static SoundControllerFMOD Instance
{
get
{
if (instance == null)
{
instance = new SoundControllerFMOD();
}
return instance;
}
}
public SoundControllerFMOD()
{
channels = new List<FMOD.Channel>();
channelGroup = new FMOD.ChannelGroup();
soundLib = new Dictionary<string, FMOD.Sound>();
FMODUnity.RuntimeManager.CoreSystem.close();
FMOD.RESULT rst = FMODUnity.RuntimeManager.CoreSystem.init(2048, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
Debug.Log(rst);
}
public void UpdateBuffer(uint buffer, int num)
{
FMODUnity.RuntimeManager.CoreSystem.close();
FMODUnity.RuntimeManager.CoreSystem.setDSPBufferSize(buffer, num);
FMODUnity.RuntimeManager.CoreSystem.init(2048, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
}
// Execute after BMSAnalyzer.FullAnalyzer worked
public void PreloadSound(BMS bms)
{
foreach (string val in bms.WavList.Keys)
{
string filepath = bms.FolderPath + bms.WavList[val];
FMOD.Sound snd;
FMODUnity.RuntimeManager.CoreSystem.createSound(filepath, FMOD.MODE.CREATESAMPLE, out snd);
bms.WavFilesFM.Add(val, snd);
}
}
public void PreloadSound(string name, string file)
{
FMOD.Sound snd;
FMODUnity.RuntimeManager.CoreSystem.createSound(file, FMOD.MODE.CREATESAMPLE, out snd);
if (soundLib.ContainsKey(name))
{
soundLib.Remove(name);
}
soundLib.Add(name, snd);
}
public void PreloadSound(string name, AudioClip clip)
{
if (soundLib.ContainsKey(name))
{
soundLib.Remove(name);
}
soundLib.Add(name, ConvertAudioClipToFmod(clip));
}
public void PlayKeySound(string wavFile, BMS bms, int line, float volume)
{
if (bms.WavFilesFM.ContainsKey(wavFile))
{
FMOD.Channel channel;
FMODUnity.RuntimeManager.CoreSystem.playSound(
bms.WavFilesFM[wavFile],
channelGroup,
false,
out channel
);
channel.setVolume(Const.VolumeMaster * volume);
channel.setLoopCount(0);
channels.Add(channel);
}
}
public void PlaySfxSound(string name)
{
FMOD.Channel channel;
FMODUnity.RuntimeManager.CoreSystem.playSound(
soundLib[name],
channelGroup,
false,
out channel
);
channel.setVolume(Const.VolumeMaster * Const.VolumeSystemSFX);
channel.setLoopCount(0);
channels.Add(channel);
}
public void PlayHitSound()
{
FMODUnity.RuntimeManager.CoreSystem.playSound(
soundLib["clap"],
channelGroup,
false,
out hitChannel
);
hitChannel.setVolume(Const.VolumeMaster * Const.VolumeHitEffect);
hitChannel.setLoopCount(0);
channels.Add(hitChannel);
}
public void PlayBGMSound(string name)
{
FMODUnity.RuntimeManager.CoreSystem.playSound(
soundLib[name],
channelGroup,
false,
out bgmChannel
);
bgmChannel.setVolume(Const.VolumeMaster * Const.VolumeSystemBGM);
FMOD.RESULT rst = bgmChannel.setMode(FMOD.MODE.LOOP_NORMAL);
}
public void PlayPreviewSound(string name)
{
FMODUnity.RuntimeManager.CoreSystem.playSound(
soundLib[name],
channelGroup,
false,
out previewChannel
);
previewChannel.setVolume(Const.VolumeMaster * Const.VolumeSystemBGM);
FMOD.RESULT rst = previewChannel.setMode(FMOD.MODE.LOOP_NORMAL);
}
public bool CheckSoundPlaying(BMS bms = null)
{
bool isPlaying = false;
foreach (FMOD.Channel c in channels)
{
c.isPlaying(out isPlaying);
if (isPlaying)
{
break;
}
}
return isPlaying;
}
public void StopBGMSound()
{
bgmChannel.isPlaying(out bool playing);
if (playing)
{
bgmChannel.stop();
}
}
public void StopPreviewSound()
{
previewChannel.isPlaying(out bool playing);
if (playing)
{
previewChannel.stop();
soundLib["preview"].release();
}
}
public void SetVolumeBGMSound(float vol)
{
bgmChannel.isPlaying(out bool playing);
if (playing)
{
bgmChannel.setVolume(vol);
}
}
public void StopAll(BMS bms = null)
{
foreach (FMOD.Channel c in channels)
{
c.stop();
}
}
public void PauseAll(BMS bms = null)
{
foreach (FMOD.Channel c in channels)
{
c.setPaused(true);
}
}
public void ResumeAll(BMS bms = null)
{
foreach (FMOD.Channel c in channels)
{
c.setPaused(false);
}
}
public void FreeMemory(BMS bms)
{
foreach (FMOD.Sound snd in bms.WavFilesFM.Values)
{
snd.release();
}
}
public void FMODErrorCheck(FMOD.RESULT result)
{
if (result != FMOD.RESULT.OK)
{
Debug.LogError(FMOD.Error.String(result));
}
}
public FMOD.Sound ConvertAudioClipToFmod(AudioClip clip)
{
float[] samples = new float[clip.samples * clip.channels];
clip.GetData(samples, 0);
uint lenbytes = (uint)(clip.samples * clip.channels * sizeof(float));
FMOD.CREATESOUNDEXINFO soundinfo = new FMOD.CREATESOUNDEXINFO();
soundinfo.length = lenbytes;
soundinfo.format = FMOD.SOUND_FORMAT.PCMFLOAT;
soundinfo.defaultfrequency = clip.frequency;
soundinfo.numchannels = clip.channels;
soundinfo.cbsize = Marshal.SizeOf(typeof(FMOD.CREATESOUNDEXINFO));
FMOD.RESULT result;
FMOD.Sound sound;
result = FMODUnity.RuntimeManager.CoreSystem.createSound(clip.name, FMOD.MODE.OPENUSER, ref soundinfo, out sound);
result = sound.@lock(0, lenbytes, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2);
Marshal.Copy(samples, 0, ptr1, (int)(len1 / sizeof(float)));
if (len2 > 0)
{
Marshal.Copy(samples, (int)(len1 / sizeof(float)), ptr2, (int)(len2 / sizeof(float)));
}
result = sound.unlock(ptr1, ptr2, len1, len2);
result = sound.setMode(FMOD.MODE.LOOP_OFF);
return sound;
}
public void ClearAll()
{
foreach (FMOD.Sound item in soundLib.Values)
{
item.release();
}
foreach (FMOD.Channel ch in channels)
{
ch.stop();
ch.clearHandle();
}
channelGroup.clearHandle();
channelGroup = new FMOD.ChannelGroup();
soundLib.Clear();
channels.Clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment