AkInitializationSettings.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #include "InitializationSettings/AkInitializationSettings.h"
  16. #include "Platforms/AkUEPlatform.h"
  17. #include "HAL/PlatformMemory.h"
  18. #include "Misc/App.h"
  19. #include "ProfilingDebugging/CpuProfilerTrace.h"
  20. #include "ProfilingDebugging/MiscTrace.h"
  21. #include "AkAudioDevice.h"
  22. #include "Wwise/WwiseIOHook.h"
  23. #include "Wwise/API/WwiseCommAPI.h"
  24. #include "Wwise/API/WwiseMemoryMgrAPI.h"
  25. #include "Wwise/API/WwiseMonitorAPI.h"
  26. #include "Wwise/API/WwiseMusicEngineAPI.h"
  27. #include "Wwise/API/WwiseSoundEngineAPI.h"
  28. #include "Wwise/API/WwiseSpatialAudioAPI.h"
  29. #include "Wwise/API/WwiseStreamMgrAPI.h"
  30. #include "Wwise/WwiseGlobalCallbacks.h"
  31. namespace AkInitializationSettings_Helpers
  32. {
  33. enum { IsLoggingInitialization = true };
  34. void AssertHook(const char* expression, const char* fileName, int lineNumber)
  35. {
  36. check(expression);
  37. check(fileName);
  38. const FString Expression(expression);
  39. const FString FileName(fileName);
  40. UE_LOG(LogAkAudio, Error, TEXT("AKASSERT: %s. File: %s, line: %d"), *Expression, *FileName, lineNumber);
  41. }
  42. FAkInitializationStructure::MemoryAllocFunction AllocFunction = nullptr;
  43. FAkInitializationStructure::MemoryFreeFunction FreeFunction = nullptr;
  44. void* AkMemAllocVM(size_t size, size_t* /*extra*/)
  45. {
  46. return AllocFunction(size);
  47. }
  48. void AkMemFreeVM(void* address, size_t /*size*/, size_t /*extra*/, size_t release)
  49. {
  50. if (release)
  51. {
  52. FreeFunction(address, release);
  53. }
  54. }
  55. void AkProfilerPushTimer(AkPluginID in_uPluginID, const char* in_pszZoneName)
  56. {
  57. if (!in_pszZoneName)
  58. {
  59. in_pszZoneName = "(Unknown)";
  60. }
  61. #if CPUPROFILERTRACE_ENABLED
  62. FCpuProfilerTrace::OutputBeginDynamicEvent(in_pszZoneName);
  63. #endif
  64. #if PLATFORM_IMPLEMENTS_BeginNamedEventStatic
  65. FPlatformMisc::BeginNamedEventStatic(WwiseNamedEvents::Color1, in_pszZoneName);
  66. #else
  67. FPlatformMisc::BeginNamedEvent(WwiseNamedEvents::Color1, in_pszZoneName);
  68. #endif
  69. }
  70. void AkProfilerPopTimer()
  71. {
  72. FPlatformMisc::EndNamedEvent();
  73. #if CPUPROFILERTRACE_ENABLED
  74. FCpuProfilerTrace::OutputEndEvent();
  75. #endif
  76. }
  77. void AkProfilerPostMarker(AkPluginID in_uPluginID, const char* in_pszMarkerName)
  78. {
  79. // Filter out audioFrameBoundary bookmarks, because those occur too frequently
  80. if (in_uPluginID != AKMAKECLASSID(AkPluginTypeNone, AKCOMPANYID_AUDIOKINETIC, AK::ProfilingID::AudioFrameBoundary))
  81. {
  82. TRACE_BOOKMARK(TEXT("AK Marker: %s"), in_pszMarkerName);
  83. }
  84. }
  85. }
  86. //////////////////////////////////////////////////////////////////////////
  87. // FAkInitializationStructure
  88. FAkInitializationStructure::FAkInitializationStructure()
  89. {
  90. auto* Comm = IWwiseCommAPI::Get();
  91. auto* MemoryMgr = IWwiseMemoryMgrAPI::Get();
  92. auto* MusicEngine = IWwiseMusicEngineAPI::Get();
  93. auto* SoundEngine = IWwiseSoundEngineAPI::Get();
  94. auto* StreamMgr = IWwiseStreamMgrAPI::Get();
  95. if (UNLIKELY(!Comm || !MemoryMgr || !MusicEngine || !SoundEngine || !StreamMgr)) return;
  96. MemoryMgr->GetDefaultSettings(MemSettings);
  97. StreamMgr->GetDefaultSettings(StreamManagerSettings);
  98. StreamMgr->GetDefaultDeviceSettings(DeviceSettings);
  99. DeviceSettings.uSchedulerTypeFlags = AK_SCHEDULER_DEFERRED_LINED_UP;
  100. DeviceSettings.uMaxConcurrentIO = AK_UNREAL_MAX_CONCURRENT_IO;
  101. SoundEngine->GetDefaultInitSettings(InitSettings);
  102. InitSettings.pfnAssertHook = AkInitializationSettings_Helpers::AssertHook;
  103. InitSettings.eFloorPlane = AkFloorPlane_XY;
  104. InitSettings.fGameUnitsToMeters = 100.f;
  105. InitSettings.fnProfilerPushTimer = AkInitializationSettings_Helpers::AkProfilerPushTimer;
  106. InitSettings.fnProfilerPopTimer = AkInitializationSettings_Helpers::AkProfilerPopTimer;
  107. InitSettings.fnProfilerPostMarker = AkInitializationSettings_Helpers::AkProfilerPostMarker;
  108. SoundEngine->GetDefaultPlatformInitSettings(PlatformInitSettings);
  109. MusicEngine->GetDefaultInitSettings(MusicSettings);
  110. #if AK_ENABLE_COMMUNICATION
  111. Comm->GetDefaultInitSettings(CommSettings);
  112. #endif
  113. }
  114. FAkInitializationStructure::~FAkInitializationStructure()
  115. {
  116. delete[] InitSettings.szPluginDLLPath;
  117. }
  118. void FAkInitializationStructure::SetPluginDllPath(const FString& PlatformArchitecture)
  119. {
  120. if (PlatformArchitecture.IsEmpty())
  121. {
  122. InitSettings.szPluginDLLPath = nullptr;
  123. return;
  124. }
  125. auto Path = FAkPlatform::GetDSPPluginsDirectory(PlatformArchitecture);
  126. auto Length = Path.Len() + 1;
  127. AkOSChar* PluginDllPath = new AkOSChar[Length];
  128. AKPLATFORM::SafeStrCpy(PluginDllPath, TCHAR_TO_AK(*Path), Length);
  129. InitSettings.szPluginDLLPath = PluginDllPath;
  130. }
  131. void FAkInitializationStructure::SetupLLMAllocFunctions(MemoryAllocFunction alloc, MemoryFreeFunction free, bool UseMemTracker)
  132. {
  133. ensure(alloc == nullptr && free == nullptr || alloc != nullptr && free != nullptr);
  134. AkInitializationSettings_Helpers::AllocFunction = alloc;
  135. AkInitializationSettings_Helpers::FreeFunction = free;
  136. #if ENABLE_LOW_LEVEL_MEM_TRACKER
  137. if (UseMemTracker)
  138. {
  139. int32 OutAlignment = 0;
  140. FPlatformMemory::GetLLMAllocFunctions(AkInitializationSettings_Helpers::AllocFunction, AkInitializationSettings_Helpers::FreeFunction, OutAlignment);
  141. }
  142. #endif
  143. if (!AkInitializationSettings_Helpers::AllocFunction || !AkInitializationSettings_Helpers::FreeFunction)
  144. return;
  145. MemSettings.pfAllocVM = AkInitializationSettings_Helpers::AkMemAllocVM;
  146. MemSettings.pfFreeVM = AkInitializationSettings_Helpers::AkMemFreeVM;
  147. }
  148. //////////////////////////////////////////////////////////////////////////
  149. // FAkMainOutputSettings
  150. void FAkMainOutputSettings::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  151. {
  152. auto* SoundEngine = IWwiseSoundEngineAPI::Get();
  153. if (UNLIKELY(!SoundEngine)) return;
  154. auto& OutputSettings = InitializationStructure.InitSettings.settingsMainOutput;
  155. auto ShareSetID = !AudioDeviceShareSet.IsEmpty() ? SoundEngine->GetIDFromString(TCHAR_TO_ANSI(*AudioDeviceShareSet)) : AK_INVALID_UNIQUE_ID;
  156. OutputSettings.audioDeviceShareset = ShareSetID;
  157. switch (ChannelConfigType)
  158. {
  159. case EAkChannelConfigType::Anonymous:
  160. OutputSettings.channelConfig.SetAnonymous(NumberOfChannels);
  161. break;
  162. case EAkChannelConfigType::Standard:
  163. OutputSettings.channelConfig.SetStandard(ChannelMask);
  164. break;
  165. case EAkChannelConfigType::Ambisonic:
  166. OutputSettings.channelConfig.SetAmbisonic(NumberOfChannels);
  167. break;
  168. }
  169. OutputSettings.ePanningRule = (AkPanningRule)PanningRule;
  170. OutputSettings.idDevice = DeviceID;
  171. }
  172. //////////////////////////////////////////////////////////////////////////
  173. // FAkSpatialAudioSettings
  174. void FAkSpatialAudioSettings::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  175. {
  176. auto& SpatialAudioInitSettings = InitializationStructure.SpatialAudioInitSettings;
  177. SpatialAudioInitSettings.uMaxSoundPropagationDepth = MaxSoundPropagationDepth;
  178. SpatialAudioInitSettings.fMovementThreshold = MovementThreshold;
  179. SpatialAudioInitSettings.uNumberOfPrimaryRays = NumberOfPrimaryRays;
  180. SpatialAudioInitSettings.uMaxReflectionOrder = ReflectionOrder;
  181. SpatialAudioInitSettings.uMaxDiffractionOrder = DiffractionOrder;
  182. SpatialAudioInitSettings.uDiffractionOnReflectionsOrder = DiffractionOnReflectionsOrder;
  183. SpatialAudioInitSettings.fMaxPathLength = MaximumPathLength;
  184. SpatialAudioInitSettings.fCPULimitPercentage = CPULimitPercentage;
  185. SpatialAudioInitSettings.uLoadBalancingSpread = LoadBalancingSpread;
  186. SpatialAudioInitSettings.bEnableGeometricDiffractionAndTransmission = EnableGeometricDiffractionAndTransmission;
  187. SpatialAudioInitSettings.bCalcEmitterVirtualPosition = CalcEmitterVirtualPosition;
  188. }
  189. //////////////////////////////////////////////////////////////////////////
  190. // FAkCommunicationSettings
  191. void FAkCommunicationSettings::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  192. {
  193. #ifndef AK_OPTIMIZED
  194. auto& CommSettings = InitializationStructure.CommSettings;
  195. CommSettings.ports.uDiscoveryBroadcast = DiscoveryBroadcastPort;
  196. CommSettings.ports.uCommand = CommandPort;
  197. const FString GameName = GetCommsNetworkName();
  198. FCStringAnsi::Strcpy(CommSettings.szAppNetworkName, AK_COMM_SETTINGS_MAX_STRING_SIZE, TCHAR_TO_ANSI(*GameName));
  199. #endif // AK_OPTIMIZED
  200. }
  201. FString FAkCommunicationSettings::GetCommsNetworkName() const
  202. {
  203. FString CommsNetworkName = NetworkName;
  204. if (CommsNetworkName.IsEmpty() && FApp::HasProjectName())
  205. {
  206. CommsNetworkName = FApp::GetProjectName();
  207. }
  208. #if WITH_EDITORONLY_DATA
  209. if (!CommsNetworkName.IsEmpty() && !IsRunningGame())
  210. {
  211. CommsNetworkName += TEXT(" (Editor)");
  212. }
  213. #endif
  214. return CommsNetworkName;
  215. }
  216. //////////////////////////////////////////////////////////////////////////
  217. // FAkCommunicationSettingsWithSystemInitialization
  218. void FAkCommunicationSettingsWithSystemInitialization::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  219. {
  220. Super::FillInitializationStructure(InitializationStructure);
  221. #if AK_ENABLE_COMMUNICATION
  222. InitializationStructure.CommSettings.bInitSystemLib = InitializeSystemComms;
  223. #endif
  224. }
  225. void FAkCommunicationSettingsWithCommSelection::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  226. {
  227. Super::FillInitializationStructure(InitializationStructure);
  228. #if AK_ENABLE_COMMUNICATION
  229. InitializationStructure.CommSettings.commSystem = (AkCommSettings::AkCommSystem)CommunicationSystem;
  230. #endif
  231. }
  232. //////////////////////////////////////////////////////////////////////////
  233. // FAkCommonInitializationSettings
  234. void FAkCommonInitializationSettings::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  235. {
  236. auto& InitSettings = InitializationStructure.InitSettings;
  237. InitSettings.uMaxNumPaths = MaximumNumberOfPositioningPaths;
  238. InitSettings.uCommandQueueSize = CommandQueueSize;
  239. InitSettings.uNumSamplesPerFrame = SamplesPerFrame;
  240. MainOutputSettings.FillInitializationStructure(InitializationStructure);
  241. auto& PlatformInitSettings = InitializationStructure.PlatformInitSettings;
  242. PlatformInitSettings.uNumRefillsInVoice = NumberOfRefillsInVoice;
  243. SpatialAudioSettings.FillInitializationStructure(InitializationStructure);
  244. InitializationStructure.MusicSettings.fStreamingLookAheadRatio = StreamingLookAheadRatio;
  245. }
  246. //////////////////////////////////////////////////////////////////////////
  247. // FAkAdvancedInitializationSettings
  248. void FAkAdvancedInitializationSettings::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  249. {
  250. auto& DeviceSettings = InitializationStructure.DeviceSettings;
  251. DeviceSettings.uIOMemorySize = IO_MemorySize;
  252. DeviceSettings.uGranularity = IO_Granularity == 0 ? (32 * 1024) : IO_Granularity;
  253. DeviceSettings.fTargetAutoStmBufferLength = TargetAutoStreamBufferLength;
  254. DeviceSettings.bUseStreamCache = UseStreamCache;
  255. DeviceSettings.uMaxCachePinnedBytes = MaximumPinnedBytesInCache;
  256. auto& InitSettings = InitializationStructure.InitSettings;
  257. InitSettings.bEnableGameSyncPreparation = EnableGameSyncPreparation;
  258. InitSettings.uContinuousPlaybackLookAhead = ContinuousPlaybackLookAhead;
  259. InitSettings.uMonitorQueuePoolSize = MonitorQueuePoolSize;
  260. InitSettings.uMaxHardwareTimeoutMs = MaximumHardwareTimeoutMs;
  261. InitSettings.bDebugOutOfRangeCheckEnabled = DebugOutOfRangeCheckEnabled;
  262. InitSettings.fDebugOutOfRangeLimit = DebugOutOfRangeLimit;
  263. }
  264. //////////////////////////////////////////////////////////////////////////
  265. // FAkAdvancedInitializationSettingsWithMultiCoreRendering
  266. void FAkAdvancedInitializationSettingsWithMultiCoreRendering::FillInitializationStructure(FAkInitializationStructure& InitializationStructure) const
  267. {
  268. Super::FillInitializationStructure(InitializationStructure);
  269. if (EnableMultiCoreRendering)
  270. {
  271. FAkAudioDevice* pDevice = FAkAudioDevice::Get();
  272. check(pDevice != nullptr);
  273. FAkJobWorkerScheduler* pScheduler = pDevice->GetAkJobWorkerScheduler();
  274. check(pScheduler != nullptr);
  275. auto& InitSettings = InitializationStructure.InitSettings;
  276. pScheduler->InstallJobWorkerScheduler(JobWorkerMaxExecutionTimeUSec, MaxNumJobWorkers, InitSettings.settingsJobManager);
  277. }
  278. }
  279. static void UELocalOutputFunc(
  280. AK::Monitor::ErrorCode in_eErrorCode,
  281. const AkOSChar* in_pszError,
  282. AK::Monitor::ErrorLevel in_eErrorLevel,
  283. AkPlayingID in_playingID,
  284. AkGameObjectID in_gameObjID)
  285. {
  286. if (!IsRunningCommandlet())
  287. {
  288. FString AkError(in_pszError);
  289. if (in_eErrorLevel == AK::Monitor::ErrorLevel_Message)
  290. {
  291. UE_LOG(LogWwiseMonitor, Log, TEXT("%s"), *AkError);
  292. }
  293. #if !UE_BUILD_SHIPPING
  294. else if (FPlatformMisc::IsDebuggerPresent() && AkError == TEXT("Voice Starvation"))
  295. {
  296. UE_LOG(LogWwiseMonitor, Log, TEXT("%s [Debugger])"), *AkError);
  297. }
  298. #endif
  299. else
  300. {
  301. #if UE_EDITOR
  302. UE_LOG(LogWwiseMonitor, Warning, TEXT("%s"), *AkError);
  303. #else
  304. UE_LOG(LogWwiseMonitor, Error, TEXT("%s"), *AkError);
  305. #endif
  306. }
  307. }
  308. }
  309. namespace FAkSoundEngineInitialization
  310. {
  311. bool Initialize(FWwiseIOHook* IOHook)
  312. {
  313. if (!IOHook)
  314. {
  315. UE_LOG(LogAkAudio, Error, TEXT("IOHook is null."));
  316. return false;
  317. }
  318. const UAkInitializationSettings* InitializationSettings = FAkPlatform::GetInitializationSettings();
  319. if (InitializationSettings == nullptr)
  320. {
  321. UE_LOG(LogAkAudio, Error, TEXT("InitializationSettings could not be found."));
  322. return false;
  323. }
  324. FAkInitializationStructure InitializationStructure;
  325. InitializationSettings->FillInitializationStructure(InitializationStructure);
  326. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Platform"));
  327. FAkPlatform::PreInitialize(InitializationStructure);
  328. auto* Comm = IWwiseCommAPI::Get();
  329. auto* MemoryMgr = IWwiseMemoryMgrAPI::Get();
  330. auto* Monitor = IWwiseMonitorAPI::Get();
  331. auto* MusicEngine = IWwiseMusicEngineAPI::Get();
  332. auto* SoundEngine = IWwiseSoundEngineAPI::Get();
  333. auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
  334. auto* StreamMgr = IWwiseStreamMgrAPI::Get();
  335. // Enable AK error redirection to UE log.
  336. if (LIKELY(Monitor))
  337. {
  338. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Monitor's Output"));
  339. Monitor->SetLocalOutput(AK::Monitor::ErrorLevel_All, UELocalOutputFunc);
  340. }
  341. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Memory Manager"));
  342. if (UNLIKELY(!MemoryMgr) || MemoryMgr->Init(&InitializationStructure.MemSettings) != AK_Success)
  343. {
  344. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize AK::MemoryMgr."));
  345. return false;
  346. }
  347. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Global Callbacks"));
  348. auto* GlobalCallbacks = FWwiseGlobalCallbacks::Get();
  349. if (UNLIKELY(!GlobalCallbacks) || !GlobalCallbacks->Initialize())
  350. {
  351. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize Global Callbacks."));
  352. return false;
  353. }
  354. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Stream Manager"));
  355. if (UNLIKELY(!StreamMgr) || !StreamMgr->Create(InitializationStructure.StreamManagerSettings))
  356. {
  357. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize AK::StreamMgr."));
  358. return false;
  359. }
  360. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing IOHook"));
  361. if (!IOHook->Init(InitializationStructure.DeviceSettings))
  362. {
  363. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize IOHook."));
  364. return false;
  365. }
  366. if (AkInitializationSettings_Helpers::IsLoggingInitialization && InitializationStructure.InitSettings.szPluginDLLPath)
  367. {
  368. FString DllPath(InitializationStructure.InitSettings.szPluginDLLPath);
  369. UE_LOG(LogAkAudio, Log, TEXT("Wwise plug-in DLL path: %s"), *DllPath);
  370. }
  371. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Sound Engine"));
  372. if (UNLIKELY(!SoundEngine) || SoundEngine->Init(&InitializationStructure.InitSettings, &InitializationStructure.PlatformInitSettings) != AK_Success)
  373. {
  374. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize AK::SoundEngine."));
  375. return false;
  376. }
  377. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Music Engine"));
  378. if (UNLIKELY(!MusicEngine) || MusicEngine->Init(&InitializationStructure.MusicSettings) != AK_Success)
  379. {
  380. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize AK::MusicEngine."));
  381. return false;
  382. }
  383. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Spatial Audio"));
  384. if (UNLIKELY(!SpatialAudio) || SpatialAudio->Init(InitializationStructure.SpatialAudioInitSettings) != AK_Success)
  385. {
  386. UE_LOG(LogAkAudio, Error, TEXT("Failed to initialize AK::SpatialAudio."));
  387. return false;
  388. }
  389. #if AK_ENABLE_COMMUNICATION
  390. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Initializing Communication"));
  391. if (UNLIKELY(!Comm) || Comm->Init(InitializationStructure.CommSettings) != AK_Success)
  392. {
  393. UE_LOG(LogAkAudio, Warning, TEXT("Could not initialize Wwise communication."));
  394. }
  395. else
  396. {
  397. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Log, TEXT("Wwise remote connection application name: %s"), ANSI_TO_TCHAR(InitializationStructure.CommSettings.szAppNetworkName));
  398. }
  399. #endif
  400. return true;
  401. }
  402. void Finalize(FWwiseIOHook* IOHook)
  403. {
  404. auto* Comm = IWwiseCommAPI::Get();
  405. auto* MemoryMgr = IWwiseMemoryMgrAPI::Get();
  406. auto* Monitor = IWwiseMonitorAPI::Get();
  407. auto* MusicEngine = IWwiseMusicEngineAPI::Get();
  408. auto* SoundEngine = IWwiseSoundEngineAPI::Get();
  409. auto* StreamMgr = IWwiseStreamMgrAPI::GetAkStreamMgr();
  410. #if AK_ENABLE_COMMUNICATION
  411. if (LIKELY(Comm))
  412. {
  413. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating Communication"));
  414. Comm->Term();
  415. }
  416. #endif
  417. // Note: No Spatial Audio Term
  418. if (LIKELY(MusicEngine))
  419. {
  420. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating Music Engine"));
  421. MusicEngine->Term();
  422. }
  423. if (LIKELY(SoundEngine && SoundEngine->IsInitialized()))
  424. {
  425. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating Sound Engine"));
  426. SoundEngine->Term();
  427. }
  428. if (LIKELY(IOHook))
  429. {
  430. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating IOHook"));
  431. IOHook->Term();
  432. }
  433. if (LIKELY(StreamMgr))
  434. {
  435. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating Stream Manager"));
  436. StreamMgr->Destroy();
  437. }
  438. if (LIKELY(MemoryMgr && MemoryMgr->IsInitialized()))
  439. {
  440. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Terminating Memory Manager"));
  441. MemoryMgr->Term();
  442. }
  443. if (LIKELY(Monitor))
  444. {
  445. UE_CLOG(AkInitializationSettings_Helpers::IsLoggingInitialization, LogAkAudio, Verbose, TEXT("Resetting Monitor's Output"));
  446. Monitor->SetLocalOutput(0, nullptr);
  447. }
  448. }
  449. }