diff --git a/Nautilus/Handlers/CustomSoundHandler.cs b/Nautilus/Handlers/CustomSoundHandler.cs index e0590971..aca29f47 100644 --- a/Nautilus/Handlers/CustomSoundHandler.cs +++ b/Nautilus/Handlers/CustomSoundHandler.cs @@ -19,11 +19,13 @@ public static class CustomSoundHandler /// The Id of your custom sound which is used when checking which sounds to play. /// The file path on disk of the sound file to load. /// The bus path to play the sound on. + /// The audio MODE of the sound. + /// Standard values of this property can be found in the class (i.e. ). /// the loaded - public static Sound RegisterCustomSound(string id, string filePath, string busPath) + public static Sound RegisterCustomSound(string id, string filePath, string busPath, MODE mode = MODE.DEFAULT) { Bus bus = RuntimeManager.GetBus(busPath); - return RegisterCustomSound(id, filePath, bus); + return RegisterCustomSound(id, filePath, bus, mode); } /// @@ -32,10 +34,16 @@ public static Sound RegisterCustomSound(string id, string filePath, string busPa /// The Id of your custom sound which is used when checking which sounds to play. /// The file path on disk of the sound file to load. /// The bus to play the sound on. + /// The audio MODE of the sound. + /// Standard values of this property can be found in the class (i.e. ). /// the loaded - public static Sound RegisterCustomSound(string id, string filePath, Bus bus) + public static Sound RegisterCustomSound(string id, string filePath, Bus bus, MODE mode = MODE.DEFAULT) { - Sound sound = AudioUtils.CreateSound(filePath); + if (bus.getChannelGroup(out _) != RESULT.OK) + { + bus.lockChannelGroup().CheckResult(); + } + Sound sound = AudioUtils.CreateSound(filePath, mode); CustomSoundPatcher.CustomSounds[id] = sound; CustomSoundPatcher.CustomSoundBuses[id] = bus; return sound; @@ -47,11 +55,13 @@ public static Sound RegisterCustomSound(string id, string filePath, Bus bus) /// The Id of your custom sound which is used when checking which sounds to play. /// The AudioClip to register. /// The bus path to play the sound on. + /// The audio MODE of the sound. + /// Standard values of this property can be found in the class (i.e. ). /// the loaded - public static Sound RegisterCustomSound(string id, AudioClip audio, string busPath) + public static Sound RegisterCustomSound(string id, AudioClip audio, string busPath, MODE mode = MODE.DEFAULT) { Bus bus = RuntimeManager.GetBus(busPath); - return RegisterCustomSound(id, audio, bus); + return RegisterCustomSound(id, audio, bus, mode); } /// @@ -60,10 +70,16 @@ public static Sound RegisterCustomSound(string id, AudioClip audio, string busPa /// The Id of your custom sound which is used when checking which sounds to play. /// The AudioClip to register. /// The bus to play the sound on. + /// The audio MODE of the sound. + /// Standard values of this property can be found in the class (i.e. ). /// the loaded - public static Sound RegisterCustomSound(string id, AudioClip audio, Bus bus) + public static Sound RegisterCustomSound(string id, AudioClip audio, Bus bus, MODE mode = MODE.DEFAULT) { - Sound sound = AudioUtils.CreateSound(audio); + if (bus.getChannelGroup(out _) != RESULT.OK) + { + bus.lockChannelGroup().CheckResult(); + } + Sound sound = AudioUtils.CreateSound(audio, mode); CustomSoundPatcher.CustomSounds[id] = sound; CustomSoundPatcher.CustomSoundBuses[id] = bus; return sound; @@ -99,6 +115,10 @@ public static void RegisterCustomSound(string id, Sound sound, string busPath) /// The bus to play the sound on. public static void RegisterCustomSound(string id, Sound sound, Bus bus) { + if (bus.getChannelGroup(out _) != RESULT.OK) + { + bus.lockChannelGroup().CheckResult(); + } CustomSoundPatcher.CustomSounds[id] = sound; CustomSoundPatcher.CustomSoundBuses[id] = bus; } @@ -107,7 +127,7 @@ public static void RegisterCustomSound(string id, Sound sound, Bus bus) /// Try to find and play a custom that has been registered. /// /// The Id of the custom sound - /// the the sound is playing on. + /// the the sound is playing on. public static bool TryPlayCustomSound(string id, out Channel channel) { channel = default; diff --git a/Nautilus/Handlers/PDAHandler.cs b/Nautilus/Handlers/PDAHandler.cs index 43747512..97b191ed 100644 --- a/Nautilus/Handlers/PDAHandler.cs +++ b/Nautilus/Handlers/PDAHandler.cs @@ -180,7 +180,7 @@ public static void AddLogEntry(string key, string languageKey, Sound sound, Spri /// The icon that will be used in the Log tab for this entry. if unassigned, it will use the default log entry icon. public static void AddLogEntry(string key, string languageKey, AudioClip audioClip, Sprite icon = null) { - AddLogEntry(key, languageKey, CustomSoundHandler.RegisterCustomSound(key, audioClip, AudioUtils.BusPaths.PDAVoice), icon); + AddLogEntry(key, languageKey, CustomSoundHandler.RegisterCustomSound(key, audioClip, AudioUtils.BusPaths.PDAVoice, AudioUtils.StandardSoundModes_Stream), icon); } /// @@ -192,7 +192,7 @@ public static void AddLogEntry(string key, string languageKey, AudioClip audioCl /// The icon that will be used in the Log tab for this entry. if unassigned, it will use the default log entry icon. public static void AddLogEntry(string key, string languageKey, string soundFilePath, Sprite icon = null) { - AddLogEntry(key, languageKey, CustomSoundHandler.RegisterCustomSound(key, soundFilePath, AudioUtils.BusPaths.PDAVoice), icon); + AddLogEntry(key, languageKey, CustomSoundHandler.RegisterCustomSound(key, soundFilePath, AudioUtils.BusPaths.PDAVoice, AudioUtils.StandardSoundModes_Stream), icon); } /// diff --git a/Nautilus/Patchers/CustomSoundPatcher.cs b/Nautilus/Patchers/CustomSoundPatcher.cs index 2637b2d2..6ca5378b 100644 --- a/Nautilus/Patchers/CustomSoundPatcher.cs +++ b/Nautilus/Patchers/CustomSoundPatcher.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using FMOD; using FMOD.Studio; using FMODUnity; @@ -32,6 +32,43 @@ public static void PDASounds_Deinitialize_Postfix() PlayedChannels.Clear(); } + [HarmonyPrefix] + [HarmonyPatch(typeof(FMODExtensions), nameof(FMODExtensions.GetLength))] + public static bool FMODExtension_GetLength_Prefix(string path, ref int __result) + { + if(string.IsNullOrEmpty(path)) + { + __result = 0; + return false; + } + + InternalLogger.Debug($"FMODExtensions.GetLength(\"{path}\") executed. Checking if it's a custom sound..."); + + if (!CustomSounds.ContainsKey(path)) + return true; + + InternalLogger.Debug($"FMODExtensions.GetLength(\"{path}\") executed. It was a custom sound."); + + if(CustomSounds.TryGetValue(path, out Sound sound)) + { + RESULT res = sound.getLength(out uint length, TIMEUNIT.MS); + if(res == RESULT.OK) + { + __result = (int)length; + return false; + } + else + { + InternalLogger.Log($"An error occured while trying to get length of a sound.\n{res}"); + } + res.CheckResult(); + } + + InternalLogger.Debug($"FMODExtensions.GetLength(\"{path}\") executed. It was maybe not a CustomSounds but a CustomFModSounds ?"); + __result = 0; + return false; + } + #if SUBNAUTICA [HarmonyPatch(typeof(FMODUWE), nameof(FMODUWE.PlayOneShotImpl))] @@ -409,7 +446,7 @@ public static bool SoundQueue_Update_Prefix(SoundQueue __instance) return true; } #if BELOWZERO - if (SoundQueue.GetPlaybackState(__instance.eventInstance) is not PLAYBACK_STATE.STARTING or PLAYBACK_STATE.PLAYING) + if (SoundQueue.GetPlaybackState(__instance.eventInstance) is not (PLAYBACK_STATE.STARTING or PLAYBACK_STATE.PLAYING)) { return true; } @@ -417,7 +454,7 @@ public static bool SoundQueue_Update_Prefix(SoundQueue __instance) if (!SoundQueue.GetIsStartingOrPlaying(__instance.eventInstance)) return true; #endif - ATTRIBUTES_3D attributes = Player.main.transform.To3DAttributes(); + ATTRIBUTES_3D attributes = Player.main.transform.To3DAttributes(); channel.set3DAttributes(ref attributes.position, ref attributes.velocity); channel.getPosition(out uint position, TIMEUNIT.MS); instanceCurrent.position = (int)position; diff --git a/Nautilus/Utility/AudioUtils.cs b/Nautilus/Utility/AudioUtils.cs index 90aa0643..8ddccec8 100644 --- a/Nautilus/Utility/AudioUtils.cs +++ b/Nautilus/Utility/AudioUtils.cs @@ -14,6 +14,19 @@ namespace Nautilus.Utility; /// public static partial class AudioUtils { + /// + /// 3D sounds + /// + public const MODE StandardSoundModes_3D = MODE.DEFAULT | MODE._3D | MODE.ACCURATETIME | MODE._3D_LINEARSQUAREROLLOFF; + /// + /// 2D sounds + /// + public const MODE StandardSoundModes_2D = MODE.DEFAULT | MODE._2D | MODE.ACCURATETIME; + /// + /// For music, PDA voices and any 2D sounds that can have more than one instance at a time. + /// + public const MODE StandardSoundModes_Stream = StandardSoundModes_2D | MODE.CREATESTREAM; + private static FMOD.System FMOD_System => RuntimeManager.CoreSystem; /// @@ -72,6 +85,10 @@ public static bool TryPlaySound(Sound sound, string busPath, out Channel channel { channel = default; Bus bus = RuntimeManager.GetBus(busPath); + if (bus.getChannelGroup(out _) != RESULT.OK) + { + bus.lockChannelGroup().CheckResult(); + } return bus.getChannelGroup(out ChannelGroup channelGroup) == RESULT.OK && channelGroup.getPaused(out bool paused) == RESULT.OK && FMOD_System.playSound(sound, channelGroup, paused, out channel) == RESULT.OK; @@ -87,6 +104,10 @@ public static bool TryPlaySound(Sound sound, string busPath, out Channel channel public static bool TryPlaySound(Sound sound, Bus bus, out Channel channel) { channel = default; + if (bus.getChannelGroup(out _) != RESULT.OK) + { + bus.lockChannelGroup().CheckResult(); + } return bus.getChannelGroup(out ChannelGroup channelGroup) == RESULT.OK && channelGroup.getPaused(out bool paused) == RESULT.OK && FMOD_System.playSound(sound, channelGroup, paused, out channel) == RESULT.OK;