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();
}
}