#if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms. /******************************************************************************* The content of this file includes portions of the proprietary AUDIOKINETIC Wwise Technology released in source code form as part of the game integration package. The content of this file may not be used without valid licenses to the AUDIOKINETIC Wwise Technology. Note that the use of the game engine is subject to the Unity(R) Terms of Service at https://unity3d.com/legal/terms-of-service License Usage Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use this file in accordance with the end user license agreement provided with the software or, alternatively, in accordance with the terms contained in a written agreement between you and Audiokinetic Inc. Copyright (c) 2024 Audiokinetic Inc. *******************************************************************************/ /// @brief Maintains the list of loaded SoundBanks loaded. This is currently used only with AkAmbient objects. public static class AkBankManager { private static readonly System.Collections.Generic.Dictionary m_BankHandles = new System.Collections.Generic.Dictionary(); private static readonly System.Collections.Generic.List BanksToUnload = new System.Collections.Generic.List(); public static void DoUnloadBanks() { var count = BanksToUnload.Count; for (var i = 0; i < count; ++i) BanksToUnload[i].UnloadBank(); BanksToUnload.Clear(); } internal static void Reset() { lock (m_BankHandles) { m_BankHandles.Clear(); } BanksToUnload.Clear(); } public static void ReloadAllBanks() { if (!AkSoundEngine.IsInitialized()) { return; } lock (m_BankHandles) { foreach (var bankHandle in m_BankHandles.Values) { if (bankHandle != null) { bankHandle.UnloadBank(false); } } UnloadInitBank(); LoadInitBank(false); foreach (var bankHandle in m_BankHandles.Values) { if (bankHandle != null) { bankHandle.DoLoadBank(); } } } } public static void LoadInitBank(bool doReset = true) { if (doReset) { Reset(); } uint BankID; var result = AkSoundEngine.LoadBank("Init.bnk", out BankID); if (result != AKRESULT.AK_Success) { UnityEngine.Debug.LogError("WwiseUnity: Failed load Init.bnk with result: " + result); } } public static void UnloadInitBank() { AkSoundEngine.UnloadBank("Init.bnk", System.IntPtr.Zero); } /// Loads a SoundBank. This version blocks until the bank is loaded. See AK::SoundEngine::LoadBank for more information. public static void LoadBank(string name, bool decodeBank, bool saveDecodedBank) { BankHandle handle = null; lock (m_BankHandles) { if (m_BankHandles.TryGetValue(name, out handle)) { // Bank already loaded, increment its ref count. handle.IncRef(); return; } #if UNITY_SWITCH // No bank decoding on Nintendo switch handle = new BankHandle(name); #else handle = decodeBank ? new DecodableBankHandle(name, saveDecodedBank) : new BankHandle(name); #endif m_BankHandles.Add(name, handle); } handle.LoadBank(); } /// Loads a SoundBank. This version returns right away and loads in background. See AK::SoundEngine::LoadBank for more information. public static void LoadBankAsync(string name, AkCallbackManager.BankCallback callback = null) { BankHandle handle = null; lock (m_BankHandles) { if (m_BankHandles.TryGetValue(name, out handle)) { // Bank already loaded, increment its ref count. handle.IncRef(); return; } handle = new AsyncBankHandle(name, callback); m_BankHandles.Add(name, handle); } handle.LoadBank(); } /// Unloads a SoundBank. See AK::SoundEngine::UnloadBank for more information. public static void UnloadBank(string name) { lock (m_BankHandles) { BankHandle handle = null; if (m_BankHandles.TryGetValue(name, out handle)) handle.DecRef(); } } public static void UnloadAllBanks() { lock (m_BankHandles) { foreach(var bank in m_BankHandles) { bank.Value.UnloadBank(false); } Reset(); } } private class BankHandle { protected readonly string bankName; protected uint m_BankID; public BankHandle(string name) { bankName = name; } public int RefCount { get; private set; } /// Loads a bank. This version blocks until the bank is loaded. See AK::SoundEngine::LoadBank for more information. public virtual AKRESULT DoLoadBank() { return AkSoundEngine.LoadBank(bankName, out m_BankID); } public void LoadBank() { if (RefCount == 0 && !BanksToUnload.Remove(this)) { var res = DoLoadBank(); LogLoadResult(res); } IncRef(); } /// Unloads a bank. public virtual void UnloadBank(bool remove = true) { AkSoundEngine.UnloadBank(m_BankID, System.IntPtr.Zero, null, null); if (remove) { lock (m_BankHandles) m_BankHandles.Remove(bankName); } } public void IncRef() { if (RefCount == 0) BanksToUnload.Remove(this); RefCount++; } public void DecRef() { RefCount--; if (RefCount == 0) BanksToUnload.Add(this); } protected void LogLoadResult(AKRESULT result) { if (result != AKRESULT.AK_Success && AkSoundEngine.IsInitialized()) UnityEngine.Debug.LogWarning("WwiseUnity: Bank " + bankName + " failed to load (" + result + ")"); } } private class AsyncBankHandle : BankHandle { private readonly AkCallbackManager.BankCallback bankCallback; public AsyncBankHandle(string name, AkCallbackManager.BankCallback callback) : base(name) { bankCallback = callback; } private static void GlobalBankCallback(uint in_bankID, System.IntPtr in_pInMemoryBankPtr, AKRESULT in_eLoadResult, object in_Cookie) { var handle = (AsyncBankHandle)in_Cookie; var callback = handle.bankCallback; if (in_eLoadResult != AKRESULT.AK_Success) { handle.LogLoadResult(in_eLoadResult); if (in_eLoadResult != AKRESULT.AK_BankAlreadyLoaded) lock (m_BankHandles) m_BankHandles.Remove(handle.bankName); } if (callback != null) callback(in_bankID, in_pInMemoryBankPtr, in_eLoadResult, null); } /// Loads a bank. This version returns right away and loads in background. See AK::SoundEngine::LoadBank for more information public override AKRESULT DoLoadBank() { return AkSoundEngine.LoadBank(bankName, GlobalBankCallback, this, out m_BankID); } } private class DecodableBankHandle : BankHandle { private readonly bool decodeBank = true; private readonly string decodedBankPath; private readonly bool saveDecodedBank; public DecodableBankHandle(string name, bool save) : base(name) { saveDecodedBank = save; var bankFileName = bankName + ".bnk"; // test language-specific decoded file path var language = AkSoundEngine.GetCurrentLanguage(); var akBasePathGetterInstance = AkBasePathGetter.Get(); var decodedBankFullPath = akBasePathGetterInstance.DecodedBankFullPath; decodedBankPath = System.IO.Path.Combine(decodedBankFullPath, language); var decodedBankFilePath = System.IO.Path.Combine(decodedBankPath, bankFileName); var decodedFileExists = System.IO.File.Exists(decodedBankFilePath); if (!decodedFileExists) { // test non-language-specific decoded file path decodedBankPath = decodedBankFullPath; decodedBankFilePath = System.IO.Path.Combine(decodedBankPath, bankFileName); decodedFileExists = System.IO.File.Exists(decodedBankFilePath); } if (decodedFileExists) { try { var decodedFileTime = System.IO.File.GetLastWriteTime(decodedBankFilePath); var encodedBankFilePath = System.IO.Path.Combine(akBasePathGetterInstance.SoundBankBasePath, bankFileName); var encodedFileTime = System.IO.File.GetLastWriteTime(encodedBankFilePath); decodeBank = decodedFileTime <= encodedFileTime; } catch { // Assume the decoded bank exists, but is not accessible. Re-decode it anyway, so we do nothing. } } } /// Loads a bank. This version blocks until the bank is loaded. See AK::SoundEngine::LoadBank for more information. public override AKRESULT DoLoadBank() { if (decodeBank) return AkSoundEngine.LoadAndDecodeBank(bankName, saveDecodedBank, out m_BankID); if (string.IsNullOrEmpty(decodedBankPath)) return AkSoundEngine.LoadBank(bankName, out m_BankID); var res = AkSoundEngine.SetBasePath(decodedBankPath); if (res == AKRESULT.AK_Success) { res = AkSoundEngine.LoadBank(bankName, out m_BankID); AkSoundEngine.SetBasePath(AkBasePathGetter.Get().SoundBankBasePath); } return res; } /// Unloads a bank. public override void UnloadBank(bool remove = true) { if (decodeBank && !saveDecodedBank) AkSoundEngine.PrepareBank(AkPreparationType.Preparation_Unload, m_BankID); else base.UnloadBank(remove); } } } #endif // #if ! (UNITY_DASHBOARD_WIDGET || UNITY_WEBPLAYER || UNITY_WII || UNITY_WIIU || UNITY_NACL || UNITY_FLASH || UNITY_BLACKBERRY) // Disable under unsupported platforms.