using System; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System.IO; using System.Text; using System.Net.Sockets; using System.Linq; using System.Runtime.InteropServices; namespace FMODUnity { [InitializeOnLoad] public class Editor_FMODPreviewer : MonoBehaviour { public static void CheckResult(FMOD.RESULT result) { if (result != FMOD.RESULT.OK) { UnityEngine.Debug.LogError(string.Format("FMOD Studio: Encounterd Error: {0} {1}", result, FMOD.Error.String(result))); } } static Editor_FMODPreviewer() { EditorApplication.update += Update; AssemblyReloadEvents.beforeAssemblyReload += HandleBeforeAssemblyReload; EditorApplication.playModeStateChanged += HandleOnPlayModeChanged; EditorApplication.pauseStateChanged += HandleOnPausedModeChanged; } static void HandleBeforeAssemblyReload() { DestroySystem(); } static void HandleOnPausedModeChanged(PauseState state) { if (RuntimeManager.IsInitialized && RuntimeManager.HasBanksLoaded) { RuntimeManager.GetBus("bus:/").setPaused(EditorApplication.isPaused); RuntimeManager.StudioSystem.update(); } } static void HandleOnPlayModeChanged(PlayModeStateChange state) { // Entering Play Mode will cause scripts to reload, losing all state // This is the last chance to clean up FMOD and avoid a leak. if (state == PlayModeStateChange.ExitingEditMode) { DestroySystem(); } } static void Update() { // Update the editor system if (system.isValid()) { CheckResult(system.update()); } } public static FMOD.Studio.System system; static FMOD.SPEAKERMODE speakerMode; public static void DestroySystem() { if (system.isValid()) { UnityEngine.Debug.Log("FMOD Studio: Destroying editor system instance"); system.release(); system.clearHandle(); } UnloadAllBanks(); } static void CreateSystem() { UnityEngine.Debug.Log("FMOD Studio: Creating editor system instance"); RuntimeUtils.EnforceLibraryOrder(); FMOD.RESULT result = FMOD.Debug.Initialize(FMOD.DEBUG_FLAGS.LOG, FMOD.DEBUG_MODE.FILE, null, "fmod_editor.log"); if (result != FMOD.RESULT.OK) { UnityEngine.Debug.LogWarning("FMOD Studio: Cannot open fmod_editor.log. Logging will be disabled for importing and previewing"); } CheckResult(FMOD.Studio.System.create(out system)); FMOD.System lowlevel; CheckResult(system.getCoreSystem(out lowlevel)); // Use play-in-editor speaker mode for event browser preview and metering speakerMode = Settings.Instance.GetEditorSpeakerMode(); CheckResult(lowlevel.setSoftwareFormat(0, speakerMode, 0)); CheckResult(system.initialize(256, FMOD.Studio.INITFLAGS.ALLOW_MISSING_PLUGINS | FMOD.Studio.INITFLAGS.SYNCHRONOUS_UPDATE, FMOD.INITFLAGS.NORMAL, IntPtr.Zero)); FMOD.ChannelGroup master; CheckResult(lowlevel.getMasterChannelGroup(out master)); FMOD.DSP masterHead; CheckResult(master.getDSP(FMOD.CHANNELCONTROL_DSP_INDEX.HEAD, out masterHead)); CheckResult(masterHead.setMeteringEnabled(false, true)); LoadAllBanks(); editorDialogueCallback = new FMOD.Studio.EVENT_CALLBACK(ToolsAudio.DialogueEventCallback); } /// /// A ‘callback’ is a pointer to a function. /// All of the FMOD callbacks have to be global or static functions. /// So you define a function in your code which matches the function signature expected by FMOD and that allows FMOD to call your function. /// public static FMOD.Studio.EVENT_CALLBACK editorDialogueCallback; static void LoadAllBanks() { foreach (EditorBankRef masterBankRef in EventManager.MasterBanks) { FMOD.Studio.Bank masterBank; CheckResult(System.loadBankFile(masterBankRef.Path, FMOD.Studio.LOAD_BANK_FLAGS.NORMAL, out masterBank)); masterBanks.Add(masterBank); } } public static void UnloadAllBanks() { foreach (PreviewEventCapsule selectedPreviewInstance in previewEventInstanceList) { selectedPreviewInstance.PreviewStop(); } previewEventInstanceList.Clear(); masterBanks.ForEach(x => { x.unload(); x.clearHandle(); }); masterBanks.Clear(); } public static FMOD.Studio.System System { get { if (!system.isValid()) { CreateSystem(); } return system; } } static List masterBanks = new List(); } }