ccl4/blueberryPeak/Assets/Wwise/API/Runtime/Handwritten/Common/AkBankManager.cs
AgentSchmisch 9144907a10 ANGST
2025-06-12 18:45:34 +02:00

341 lines
9.8 KiB
C#

#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) 2025 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<string, BankHandle> m_BankHandles =
new System.Collections.Generic.Dictionary<string, BankHandle>();
private static readonly System.Collections.Generic.List<BankHandle> BanksToUnload =
new System.Collections.Generic.List<BankHandle>();
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 (!AkUnitySoundEngine.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 = AkUnitySoundEngine.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()
{
AkUnitySoundEngine.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 uint LoadBank(string name, bool decodeBank, bool saveDecodedBank, AkBankTypeEnum bankType = AkBankTypeEnum.AkBankType_User)
{
BankHandle handle = null;
lock (m_BankHandles)
{
if (m_BankHandles.TryGetValue(name, out handle))
{
// Bank already loaded, increment its ref count.
handle.IncRef();
return AkUnitySoundEngine.AK_INVALID_UNIQUE_ID;
}
if (decodeBank && bankType != AkBankTypeEnum.AkBankType_User)
{
UnityEngine.Debug.LogError("Decoding Auto-generated SoundBanks is not supported.");
decodeBank = false;
}
handle = decodeBank && AkUnitySoundEngine.PlatformSupportsDecodeBank() ?
new DecodableBankHandle(name, saveDecodedBank) : new BankHandle(name, bankType);
m_BankHandles.Add(name, handle);
}
return handle.LoadBank();
}
/// Loads a SoundBank. This version returns right away and loads in background. See AK::SoundEngine::LoadBank for more information.
public static uint LoadBankAsync(string name, AkCallbackManager.BankCallback callback = null, AkBankTypeEnum bankType = AkBankTypeEnum.AkBankType_User)
{
BankHandle handle = null;
lock (m_BankHandles)
{
if (m_BankHandles.TryGetValue(name, out handle))
{
// Bank already loaded, increment its ref count.
handle.IncRef();
return AkUnitySoundEngine.AK_INVALID_UNIQUE_ID;
}
handle = new AsyncBankHandle(name, callback, bankType);
m_BankHandles.Add(name, handle);
}
return 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;
protected AkBankTypeEnum m_BankType;
public BankHandle(string name, AkBankTypeEnum bankType)
{
bankName = name;
m_BankType = bankType;
}
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 AkUnitySoundEngine.LoadBank(bankName, out m_BankID, (uint)m_BankType);
}
public uint LoadBank()
{
if (RefCount == 0 && !BanksToUnload.Remove(this))
{
var res = DoLoadBank();
LogLoadResult(res);
}
IncRef();
return m_BankID;
}
/// Unloads a bank.
public virtual void UnloadBank(bool remove = true)
{
AkUnitySoundEngine.UnloadBank(m_BankID, System.IntPtr.Zero, null, null, (uint) m_BankType);
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 && AkUnitySoundEngine.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, AkBankTypeEnum bankType) : base(name, bankType)
{
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 AkUnitySoundEngine.LoadBank(bankName, GlobalBankCallback, this, out m_BankID, (uint)m_BankType);
}
}
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, AkBankTypeEnum.AkBankType_User)
{
saveDecodedBank = save;
var bankFileName = bankName + ".bnk";
// test language-specific decoded file path
var language = AkUnitySoundEngine.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 AkUnitySoundEngine.LoadAndDecodeBank(bankName, saveDecodedBank, out m_BankID);
}
if (string.IsNullOrEmpty(decodedBankPath))
{
return AkUnitySoundEngine.LoadBank(bankName, out m_BankID, (uint) m_BankType);
}
var res = AkUnitySoundEngine.SetBasePath(decodedBankPath);
if (res == AKRESULT.AK_Success)
{
res = AkUnitySoundEngine.LoadBank(bankName, out m_BankID, (uint)m_BankType);
AkUnitySoundEngine.SetBasePath(AkBasePathGetter.Get().SoundBankBasePath);
}
return res;
}
/// Unloads a bank.
public override void UnloadBank(bool remove = true)
{
if (decodeBank && !saveDecodedBank)
AkUnitySoundEngine.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.