WwiseResourceCookerImpl.cpp 88 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285
  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 "Wwise/WwiseResourceCookerImpl.h"
  16. #include "Wwise/WwiseExternalSourceManager.h"
  17. #include "Wwise/WwiseResourceLoader.h"
  18. #include "Wwise/WwiseCookingCache.h"
  19. #include "Wwise/Metadata/WwiseMetadataPlatformInfo.h"
  20. #include "Wwise/Metadata/WwiseMetadataPlugin.h"
  21. #include "Wwise/Stats/ResourceCooker.h"
  22. #include "Async/Async.h"
  23. #include "Async/MappedFileHandle.h"
  24. #include "Misc/FileHelper.h"
  25. #if UE_5_0_OR_LATER
  26. #include "HAL/PlatformFileManager.h"
  27. #else
  28. #include "HAL/PlatformFilemanager.h"
  29. #endif
  30. #include "Wwise/CookedData/WwiseSoundBankCookedData.h"
  31. #include "Wwise/Stats/ResourceCooker.h"
  32. FWwiseResourceCookerImpl::FWwiseResourceCookerImpl() :
  33. ExportDebugNameRule(EWwiseExportDebugNameRule::ObjectPath),
  34. CookingCache(nullptr),
  35. ProjectDatabaseOverride(nullptr)
  36. {
  37. }
  38. FWwiseResourceCookerImpl::~FWwiseResourceCookerImpl()
  39. {
  40. }
  41. FWwiseProjectDatabase* FWwiseResourceCookerImpl::GetProjectDatabase()
  42. {
  43. if (ProjectDatabaseOverride.IsValid())
  44. {
  45. return ProjectDatabaseOverride.Get();
  46. }
  47. else
  48. {
  49. return FWwiseProjectDatabase::Get();
  50. }
  51. }
  52. const FWwiseProjectDatabase* FWwiseResourceCookerImpl::GetProjectDatabase() const
  53. {
  54. if (ProjectDatabaseOverride.IsValid())
  55. {
  56. return ProjectDatabaseOverride.Get();
  57. }
  58. else
  59. {
  60. return FWwiseProjectDatabase::Get();
  61. }
  62. }
  63. void FWwiseResourceCookerImpl::PrepareResourceCookerForPlatform(FWwiseProjectDatabase*&& InProjectDatabaseOverride, EWwiseExportDebugNameRule InExportDebugNameRule)
  64. {
  65. ProjectDatabaseOverride.Reset(InProjectDatabaseOverride);
  66. ExportDebugNameRule = InExportDebugNameRule;
  67. CookingCache.Reset(new FWwiseCookingCache);
  68. CookingCache->ExternalSourceManager = IWwiseExternalSourceManager::Get();
  69. }
  70. void FWwiseResourceCookerImpl::CookAuxBusToSandbox(const FWwiseAuxBusCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  71. {
  72. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking AuxBus %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.AuxBusId);
  73. for (const auto& SoundBank : InCookedData.SoundBanks)
  74. {
  75. CookSoundBankToSandbox(SoundBank, WriteAdditionalFile);
  76. }
  77. for (const auto& Media : InCookedData.Media)
  78. {
  79. CookMediaToSandbox(Media, WriteAdditionalFile);
  80. }
  81. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("Done cooking AuxBus %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.AuxBusId);
  82. }
  83. void FWwiseResourceCookerImpl::CookEventToSandbox(const FWwiseEventCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  84. {
  85. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking Event %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.EventId);
  86. for (const auto& SoundBank : InCookedData.SoundBanks)
  87. {
  88. CookSoundBankToSandbox(SoundBank, WriteAdditionalFile);
  89. }
  90. for (const auto& Media : InCookedData.Media)
  91. {
  92. CookMediaToSandbox(Media, WriteAdditionalFile);
  93. }
  94. for (const auto& ExternalSource : InCookedData.ExternalSources)
  95. {
  96. CookExternalSourceToSandbox(ExternalSource, WriteAdditionalFile);
  97. }
  98. for (const auto& SwitchContainerLeaf : InCookedData.SwitchContainerLeaves)
  99. {
  100. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking Event %s %" PRIu32 " Switched Media"), *InCookedData.DebugName.ToString(), (uint32)InCookedData.EventId);
  101. for (const auto& SoundBank : SwitchContainerLeaf.SoundBanks)
  102. {
  103. CookSoundBankToSandbox(SoundBank, WriteAdditionalFile);
  104. }
  105. for (const auto& Media : SwitchContainerLeaf.Media)
  106. {
  107. CookMediaToSandbox(Media, WriteAdditionalFile);
  108. }
  109. for (const auto& ExternalSource : SwitchContainerLeaf.ExternalSources)
  110. {
  111. CookExternalSourceToSandbox(ExternalSource, WriteAdditionalFile);
  112. }
  113. }
  114. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("Done cooking Event %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.EventId);
  115. }
  116. void FWwiseResourceCookerImpl::CookExternalSourceToSandbox(const FWwiseExternalSourceCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  117. {
  118. if (LIKELY(CookingCache && CookingCache->ExternalSourceManager))
  119. {
  120. CookingCache->ExternalSourceManager->Cook(*this, InCookedData, WriteAdditionalFile, GetCurrentPlatform(), GetCurrentLanguage());
  121. }
  122. else
  123. {
  124. UE_LOG(LogWwiseResourceCooker, Error, TEXT("No External Source Manager while cooking External Source %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.Cookie);
  125. }
  126. }
  127. void FWwiseResourceCookerImpl::CookInitBankToSandbox(const FWwiseInitBankCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  128. {
  129. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking Init SoundBank %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.SoundBankId);
  130. CookSoundBankToSandbox(InCookedData, WriteAdditionalFile);
  131. for (const auto& Media : InCookedData.Media)
  132. {
  133. CookMediaToSandbox(Media, WriteAdditionalFile);
  134. }
  135. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("Done cooking Init SoundBank %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.SoundBankId);
  136. }
  137. void FWwiseResourceCookerImpl::CookMediaToSandbox(const FWwiseMediaCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  138. {
  139. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking Media %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.MediaId);
  140. if (UNLIKELY(InCookedData.MediaPathName.IsNone()))
  141. {
  142. UE_LOG(LogWwiseResourceCooker, Fatal, TEXT("Empty pathname for Media %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.MediaId);
  143. return;
  144. }
  145. auto* ResourceLoader = GetResourceLoader();
  146. if (UNLIKELY(!ResourceLoader))
  147. {
  148. return;
  149. }
  150. const FString GeneratedSoundBanksPath = ResourceLoader->GetUnrealGeneratedSoundBanksPath(InCookedData.MediaPathName);
  151. CookFileToSandbox(GeneratedSoundBanksPath, InCookedData.MediaPathName, WriteAdditionalFile);
  152. }
  153. void FWwiseResourceCookerImpl::CookShareSetToSandbox(const FWwiseShareSetCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  154. {
  155. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking ShareSet %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.ShareSetId);
  156. for (const auto& SoundBank : InCookedData.SoundBanks)
  157. {
  158. CookSoundBankToSandbox(SoundBank, WriteAdditionalFile);
  159. }
  160. for (const auto& Media : InCookedData.Media)
  161. {
  162. CookMediaToSandbox(Media, WriteAdditionalFile);
  163. }
  164. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("Done cooking ShareSet %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.ShareSetId);
  165. }
  166. void FWwiseResourceCookerImpl::CookSoundBankToSandbox(const FWwiseSoundBankCookedData& InCookedData, WriteAdditionalFileFunction WriteAdditionalFile)
  167. {
  168. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("Cooking SoundBank %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.SoundBankId);
  169. if (UNLIKELY(InCookedData.SoundBankPathName.IsNone()))
  170. {
  171. UE_LOG(LogWwiseResourceCooker, Fatal, TEXT("Empty pathname for SoundBank %s %" PRIu32), *InCookedData.DebugName.ToString(), (uint32)InCookedData.SoundBankId);
  172. return;
  173. }
  174. auto* ResourceLoader = GetResourceLoader();
  175. if (UNLIKELY(!ResourceLoader))
  176. {
  177. return;
  178. }
  179. const FString GeneratedSoundBanksPath = ResourceLoader->GetUnrealGeneratedSoundBanksPath(InCookedData.SoundBankPathName);
  180. CookFileToSandbox(GeneratedSoundBanksPath, InCookedData.SoundBankPathName, WriteAdditionalFile);
  181. }
  182. void FWwiseResourceCookerImpl::CookFileToSandbox(const FString& InInputPathName, const FName& InOutputPathName, WriteAdditionalFileFunction WriteAdditionalFile, bool bInStageRelativeToContent)
  183. {
  184. auto* ResourceLoader = GetResourceLoader();
  185. if (UNLIKELY(!ResourceLoader))
  186. {
  187. return;
  188. }
  189. FString StagePath = bInStageRelativeToContent
  190. ? SandboxRootPath / InOutputPathName.ToString()
  191. : SandboxRootPath / ResourceLoader->GetUnrealStagePath(InOutputPathName);
  192. auto& StageFiles = CookingCache->StagedFiles;
  193. if (const auto* AlreadyStaged = StageFiles.Find(StagePath))
  194. {
  195. if (*AlreadyStaged == InInputPathName)
  196. {
  197. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("Cook: Skipping already present file %s -> %s"), *InInputPathName, *StagePath);
  198. }
  199. else
  200. {
  201. UE_LOG(LogWwiseResourceCooker, Error, TEXT("Cook: Trying to stage two different files to the same path: [%s and %s] -> %s"), *InInputPathName, **AlreadyStaged, *StagePath);
  202. }
  203. return;
  204. }
  205. StageFiles.Add(StagePath, InInputPathName);
  206. if (auto* MappedHandle = FPlatformFileManager::Get().GetPlatformFile().OpenMapped(*InInputPathName))
  207. {
  208. auto* MappedRegion = MappedHandle->MapRegion();
  209. if (MappedRegion)
  210. {
  211. UE_LOG(LogWwiseResourceCooker, Display, TEXT("Adding file %s [%" PRIi64 " bytes]"), *StagePath, MappedRegion->GetMappedSize());
  212. WriteAdditionalFile(*StagePath, (void*)MappedRegion->GetMappedPtr(), MappedRegion->GetMappedSize());
  213. delete MappedRegion;
  214. delete MappedHandle;
  215. return;
  216. }
  217. else
  218. {
  219. delete MappedHandle;
  220. }
  221. }
  222. TArray<uint8> Data;
  223. if (!FFileHelper::LoadFileToArray(Data, *InInputPathName))
  224. {
  225. UE_LOG(LogWwiseResourceCooker, Error, TEXT("Cook: Could not read file %s"), *InInputPathName);
  226. return;
  227. }
  228. UE_LOG(LogWwiseResourceCooker, Display, TEXT("Adding file %s [%" PRIi64 " bytes]"), *StagePath, (int64)Data.Num());
  229. WriteAdditionalFile(*StagePath, (void*)Data.GetData(), Data.Num());
  230. }
  231. bool FWwiseResourceCookerImpl::GetAcousticTextureCookedData(FWwiseAcousticTextureCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  232. {
  233. const auto* ProjectDatabase = GetProjectDatabase();
  234. if (UNLIKELY(!ProjectDatabase))
  235. {
  236. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetAcousticTextureCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  237. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  238. return false;
  239. }
  240. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  241. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  242. if (UNLIKELY(!PlatformData))
  243. {
  244. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetAcousticTextureCookedData (%s %" PRIu32 " %s): No data for platform"),
  245. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  246. return false;
  247. }
  248. FWwiseRefAcousticTexture AcousticTextureRef;
  249. if (UNLIKELY(!PlatformData->GetRef(AcousticTextureRef, FWwiseSharedLanguageId(), InInfo)))
  250. {
  251. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAcousticTextureCookedData (%s %" PRIu32 " %s): No acoustic texture data found"),
  252. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  253. return false;
  254. }
  255. const auto* AcousticTexture = AcousticTextureRef.GetAcousticTexture();
  256. OutCookedData.AbsorptionLow = AcousticTexture->AbsorptionLow;
  257. OutCookedData.AbsorptionMidLow = AcousticTexture->AbsorptionMidLow;
  258. OutCookedData.AbsorptionMidHigh = AcousticTexture->AbsorptionMidHigh;
  259. OutCookedData.AbsorptionHigh = AcousticTexture->AbsorptionHigh;
  260. OutCookedData.ShortId = AcousticTexture->Id;
  261. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  262. {
  263. OutCookedData.DebugName = FName();
  264. }
  265. else
  266. {
  267. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? AcousticTexture->Name : AcousticTexture->ObjectPath);
  268. }
  269. return true;
  270. }
  271. bool FWwiseResourceCookerImpl::GetAuxBusCookedData(FWwiseLocalizedAuxBusCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  272. {
  273. const auto* ProjectDatabase = GetProjectDatabase();
  274. if (UNLIKELY(!ProjectDatabase))
  275. {
  276. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  277. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  278. return false;
  279. }
  280. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  281. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  282. if (UNLIKELY(!PlatformData))
  283. {
  284. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): No data for platform"),
  285. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  286. return false;
  287. }
  288. const auto* PlatformInfo = PlatformData->PlatformRef.GetPlatformInfo();
  289. if (UNLIKELY(!PlatformInfo)) return false;
  290. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  291. TMap<FWwiseSharedLanguageId, TSet<FWwiseRefAuxBus>> RefLanguageMap;
  292. PlatformData->GetRefMap(RefLanguageMap, Languages, InInfo);
  293. if (UNLIKELY(RefLanguageMap.Num() == 0))
  294. {
  295. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): No ref found"),
  296. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  297. return false;
  298. }
  299. OutCookedData.AuxBusLanguageMap.Empty(RefLanguageMap.Num());
  300. for (auto& Ref : RefLanguageMap)
  301. {
  302. FWwiseAuxBusCookedData CookedData;
  303. TSet<FWwiseSoundBankCookedData> SoundBankSet;
  304. TSet<FWwiseMediaCookedData> MediaSet;
  305. TSet<FWwiseRefAuxBus>& AuxBusses = Ref.Value;
  306. if (UNLIKELY(AuxBusses.Num() == 0))
  307. {
  308. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): Empty ref for language"),
  309. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  310. return false;
  311. }
  312. // Set up basic global Aux Bus information
  313. {
  314. TSet<FWwiseRefAuxBus>::TConstIterator FirstAuxBus(AuxBusses);
  315. CookedData.AuxBusId = FirstAuxBus->AuxBusId();
  316. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  317. {
  318. OutCookedData.DebugName = FName();
  319. }
  320. else
  321. {
  322. CookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? FirstAuxBus->AuxBusName() : FirstAuxBus->AuxBusObjectPath());
  323. OutCookedData.DebugName = CookedData.DebugName;
  324. }
  325. OutCookedData.AuxBusId = CookedData.AuxBusId;
  326. }
  327. for (auto& AuxBusRef : AuxBusses)
  328. {
  329. const auto* AuxBus = AuxBusRef.GetAuxBus();
  330. if (UNLIKELY(!AuxBus))
  331. {
  332. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): Could not get AuxBus from Ref"),
  333. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  334. continue;
  335. }
  336. TSet<const FWwiseRefAuxBus*> SubAuxBusRefs;
  337. AuxBusRef.GetAllAuxBusRefs(SubAuxBusRefs, PlatformData->AuxBusses);
  338. for (const auto* SubAuxBusRef : SubAuxBusRefs)
  339. {
  340. const auto* SoundBank = SubAuxBusRef->GetSoundBank();
  341. if (UNLIKELY(!SoundBank))
  342. {
  343. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  344. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  345. continue;
  346. }
  347. if (!SoundBank->IsInitBank())
  348. {
  349. FWwiseSoundBankCookedData SoundBankCookedData;
  350. if (UNLIKELY(!FillSoundBankBaseInfo(SoundBankCookedData, *PlatformInfo, *SoundBank)))
  351. {
  352. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  353. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  354. continue;
  355. }
  356. SoundBankSet.Add(SoundBankCookedData);
  357. }
  358. {
  359. WwiseCustomPluginIdsMap CustomPluginsRefs = SubAuxBusRef->GetAuxBusCustomPlugins(PlatformData->CustomPlugins);
  360. for (const auto& Plugin : CustomPluginsRefs)
  361. {
  362. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  363. for (const auto& MediaRef : MediaRefs)
  364. {
  365. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  366. {
  367. return false;
  368. }
  369. }
  370. }
  371. }
  372. {
  373. WwisePluginShareSetIdsMap ShareSetRefs = SubAuxBusRef->GetAuxBusPluginShareSets(PlatformData->PluginShareSets);
  374. for (const auto& ShareSet : ShareSetRefs)
  375. {
  376. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  377. for (const auto& MediaRef : MediaRefs)
  378. {
  379. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  380. {
  381. return false;
  382. }
  383. }
  384. }
  385. }
  386. {
  387. WwiseAudioDeviceIdsMap AudioDevicesRefs = SubAuxBusRef->GetAuxBusAudioDevices(PlatformData->AudioDevices);
  388. for (const auto& AudioDevice : AudioDevicesRefs)
  389. {
  390. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  391. for (const auto& MediaRef : MediaRefs)
  392. {
  393. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  394. {
  395. return false;
  396. }
  397. }
  398. }
  399. }
  400. }
  401. }
  402. CookedData.SoundBanks = SoundBankSet.Array();
  403. CookedData.Media = MediaSet.Array();
  404. OutCookedData.AuxBusLanguageMap.Add(FWwiseLanguageCookedData(Ref.Key.GetLanguageId(), Ref.Key.GetLanguageName(), Ref.Key.LanguageRequirement), MoveTemp(CookedData));
  405. }
  406. if (UNLIKELY(OutCookedData.AuxBusLanguageMap.Num() == 0))
  407. {
  408. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): No AuxBus"),
  409. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  410. return false;
  411. }
  412. // Make this a SFX if all CookedData are identical
  413. {
  414. auto& Map = OutCookedData.AuxBusLanguageMap;
  415. TArray<FWwiseLanguageCookedData> Keys;
  416. Map.GetKeys(Keys);
  417. auto LhsKey = Keys.Pop(false);
  418. const auto* Lhs = Map.Find(LhsKey);
  419. while (Keys.Num() > 0)
  420. {
  421. auto RhsKey = Keys.Pop(false);
  422. const auto* Rhs = Map.Find(RhsKey);
  423. if (Lhs->AuxBusId != Rhs->AuxBusId
  424. || Lhs->DebugName != Rhs->DebugName
  425. || Lhs->SoundBanks.Num() != Rhs->SoundBanks.Num()
  426. || Lhs->Media.Num() != Rhs->Media.Num())
  427. {
  428. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): AuxBus has languages"),
  429. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  430. return true;
  431. }
  432. for (const auto& Elem : Lhs->SoundBanks)
  433. {
  434. if (!Rhs->SoundBanks.Contains(Elem))
  435. {
  436. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): AuxBus has languages due to banks"),
  437. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  438. return true;
  439. }
  440. }
  441. for (const auto& Elem : Lhs->Media)
  442. {
  443. if (!Rhs->Media.Contains(Elem))
  444. {
  445. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): AuxBus has languages due to media"),
  446. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  447. return true;
  448. }
  449. }
  450. }
  451. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): AuxBus is a SFX"),
  452. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  453. std::remove_reference_t<decltype(Map)> SfxMap;
  454. SfxMap.Add(FWwiseLanguageCookedData::Sfx, *Lhs);
  455. Map = SfxMap;
  456. }
  457. return true;
  458. }
  459. bool FWwiseResourceCookerImpl::GetEventCookedData(FWwiseLocalizedEventCookedData& OutCookedData, const FWwiseEventInfo& InInfo) const
  460. {
  461. const auto* ProjectDatabase = GetProjectDatabase();
  462. if (UNLIKELY(!ProjectDatabase))
  463. {
  464. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetEventCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  465. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  466. return false;
  467. }
  468. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  469. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  470. if (UNLIKELY(!PlatformData))
  471. {
  472. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetEventCookedData (%s %" PRIu32 " %s): No data for platform"),
  473. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  474. return false;
  475. }
  476. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  477. const auto* PlatformInfo = PlatformData->PlatformRef.GetPlatformInfo();
  478. if (UNLIKELY(!PlatformInfo))
  479. {
  480. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): No Platform Info"),
  481. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  482. return false;
  483. }
  484. TMap<FWwiseSharedLanguageId, TSet<FWwiseRefEvent>> RefLanguageMap;
  485. PlatformData->GetRefMap(RefLanguageMap, Languages, InInfo);
  486. if (UNLIKELY(RefLanguageMap.Num() == 0))
  487. {
  488. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): No ref found"),
  489. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  490. return false;
  491. }
  492. OutCookedData.EventLanguageMap.Empty(RefLanguageMap.Num());
  493. UE_LOG(LogWwiseResourceCooker, Verbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Adding %d languages to map"),
  494. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString(), RefLanguageMap.Num());
  495. for (auto& Ref : RefLanguageMap)
  496. {
  497. FWwiseEventCookedData CookedData;
  498. TSet<FWwiseSoundBankCookedData> SoundBankSet;
  499. TSet<FWwiseMediaCookedData> MediaSet;
  500. const FWwiseSharedLanguageId& LanguageId = Ref.Key;
  501. TSet<FWwiseRefEvent>& Events = Ref.Value;
  502. WwiseSwitchContainerArray SwitchContainerRefs;
  503. if (UNLIKELY(Events.Num() == 0))
  504. {
  505. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Empty ref for language"),
  506. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  507. return false;
  508. }
  509. // Set up basic global Event information
  510. {
  511. TSet<FWwiseRefEvent>::TConstIterator FirstEvent(Events);
  512. CookedData.EventId = FirstEvent->EventId();
  513. if (ExportDebugNameRule != EWwiseExportDebugNameRule::Release)
  514. {
  515. CookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? FirstEvent->EventName() : FirstEvent->EventObjectPath());
  516. OutCookedData.DebugName = CookedData.DebugName;
  517. }
  518. OutCookedData.EventId = CookedData.EventId;
  519. SwitchContainerRefs = FirstEvent->GetSwitchContainers(PlatformData->SwitchContainersByEvent);
  520. }
  521. // Add extra events recursively
  522. {
  523. TSet<FWwiseRefEvent> DiffEvents = Events;
  524. while (true)
  525. {
  526. bool bHaveMore = false;
  527. TSet<FWwiseRefEvent> OldEvents(Events);
  528. for (auto& EventRef : OldEvents)
  529. {
  530. const FWwiseMetadataEvent* Event = EventRef.GetEvent();
  531. if (UNLIKELY(!Event))
  532. {
  533. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get Event from Ref"),
  534. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  535. return false;
  536. }
  537. for (const auto& ActionPostEvent : Event->ActionPostEvent)
  538. {
  539. bool bHaveMoreInThisEvent = PlatformData->GetRef(Events, LanguageId, FWwiseEventInfo(ActionPostEvent.Id, ActionPostEvent.Name));
  540. bHaveMore = bHaveMore || bHaveMoreInThisEvent;
  541. }
  542. }
  543. if (bHaveMore)
  544. {
  545. DiffEvents = Events.Difference(OldEvents);
  546. if (DiffEvents.Num() == 0)
  547. {
  548. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): GetRef should return false when no more additional Refs"),
  549. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  550. break;
  551. }
  552. for (auto& EventRef : DiffEvents)
  553. {
  554. SwitchContainerRefs.Append(EventRef.GetSwitchContainers(PlatformData->SwitchContainersByEvent));
  555. }
  556. }
  557. else
  558. {
  559. break;
  560. }
  561. }
  562. }
  563. // Add mandatory SoundBank information
  564. TSet<FWwiseExternalSourceCookedData> ExternalSourceSet;
  565. TSet<FWwiseAnyRef> RequiredGroupValueSet;
  566. for (auto& EventRef : Events)
  567. {
  568. const FWwiseMetadataEvent* Event = EventRef.GetEvent();
  569. if (UNLIKELY(!Event))
  570. {
  571. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get Event from Ref"),
  572. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  573. return false;
  574. }
  575. if (LIKELY(Event->IsMandatory()) || LIKELY(Events.Num() == 1))
  576. {
  577. // Add main SoundBank
  578. {
  579. const auto* SoundBank = EventRef.GetSoundBank();
  580. if (UNLIKELY(!SoundBank))
  581. {
  582. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  583. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  584. return false;
  585. }
  586. if (!SoundBank->IsInitBank())
  587. {
  588. FWwiseSoundBankCookedData MainSoundBank;
  589. if (UNLIKELY(!FillSoundBankBaseInfo(MainSoundBank, *PlatformInfo, *SoundBank)))
  590. {
  591. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  592. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  593. return false;
  594. }
  595. SoundBankSet.Add(MainSoundBank);
  596. }
  597. }
  598. // Get Aux Bus banks & media
  599. {
  600. WwiseAuxBusIdsMap AuxBusRefs = EventRef.GetEventAuxBusses(PlatformData->AuxBusses);
  601. TSet<const FWwiseRefAuxBus*> SubAuxBusRefs;
  602. for (const auto& AuxBusRef : AuxBusRefs)
  603. {
  604. AuxBusRef.Value.GetAllAuxBusRefs(SubAuxBusRefs, PlatformData->AuxBusses);
  605. }
  606. for (const auto* SubAuxBusRef : SubAuxBusRefs)
  607. {
  608. const auto* SoundBank = SubAuxBusRef->GetSoundBank();
  609. if (UNLIKELY(!SoundBank))
  610. {
  611. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  612. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  613. return false;
  614. }
  615. if (!SoundBank->IsInitBank())
  616. {
  617. FWwiseSoundBankCookedData SoundBankCookedData;
  618. if (UNLIKELY(!FillSoundBankBaseInfo(SoundBankCookedData, *PlatformInfo, *SoundBank)))
  619. {
  620. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  621. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  622. return false;
  623. }
  624. SoundBankSet.Add(SoundBankCookedData);
  625. }
  626. {
  627. WwiseCustomPluginIdsMap CustomPluginsRefs = SubAuxBusRef->GetAuxBusCustomPlugins(PlatformData->CustomPlugins);
  628. for (const auto& Plugin : CustomPluginsRefs)
  629. {
  630. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  631. for (const auto& MediaRef : MediaRefs)
  632. {
  633. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  634. {
  635. return false;
  636. }
  637. }
  638. }
  639. }
  640. {
  641. WwisePluginShareSetIdsMap ShareSetRefs = SubAuxBusRef->GetAuxBusPluginShareSets(PlatformData->PluginShareSets);
  642. for (const auto& ShareSet : ShareSetRefs)
  643. {
  644. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  645. for (const auto& MediaRef : MediaRefs)
  646. {
  647. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  648. {
  649. return false;
  650. }
  651. }
  652. }
  653. }
  654. {
  655. WwiseAudioDeviceIdsMap AudioDevicesRefs = SubAuxBusRef->GetAuxBusAudioDevices(PlatformData->AudioDevices);
  656. for (const auto& AudioDevice : AudioDevicesRefs)
  657. {
  658. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  659. for (const auto& MediaRef : MediaRefs)
  660. {
  661. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  662. {
  663. return false;
  664. }
  665. }
  666. }
  667. }
  668. }
  669. }
  670. // Get media
  671. {
  672. WwiseMediaIdsMap MediaRefs = EventRef.GetEventMedia(PlatformData->MediaFiles);
  673. for (const auto& MediaRef : MediaRefs)
  674. {
  675. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  676. {
  677. return false;
  678. }
  679. }
  680. }
  681. // Get Media from custom plugins
  682. {
  683. WwiseCustomPluginIdsMap CustomPluginsRefs = EventRef.GetEventCustomPlugins(PlatformData->CustomPlugins);
  684. for (const auto& Plugin : CustomPluginsRefs)
  685. {
  686. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  687. for (const auto& MediaRef : MediaRefs)
  688. {
  689. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  690. {
  691. return false;
  692. }
  693. }
  694. }
  695. }
  696. // Get Media from plugin ShareSets
  697. {
  698. WwisePluginShareSetIdsMap ShareSetRefs = EventRef.GetEventPluginShareSets(PlatformData->PluginShareSets);
  699. for (const auto& ShareSet : ShareSetRefs)
  700. {
  701. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  702. for (const auto& MediaRef : MediaRefs)
  703. {
  704. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  705. {
  706. return false;
  707. }
  708. }
  709. }
  710. }
  711. // Get Media from audio devices
  712. {
  713. WwiseAudioDeviceIdsMap AudioDevicesRefs = EventRef.GetEventAudioDevices(PlatformData->AudioDevices);
  714. for (const auto& AudioDevice : AudioDevicesRefs)
  715. {
  716. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  717. for (const auto& MediaRef : MediaRefs)
  718. {
  719. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  720. {
  721. return false;
  722. }
  723. }
  724. }
  725. }
  726. // Get External Sources
  727. {
  728. WwiseExternalSourceIdsMap ExternalSourceRefs = EventRef.GetEventExternalSources(PlatformData->ExternalSources);
  729. for (const auto& ExternalSourceRef : ExternalSourceRefs)
  730. {
  731. if (UNLIKELY(!AddRequirementsForExternalSource(ExternalSourceSet, ExternalSourceRef.Value)))
  732. {
  733. return false;
  734. }
  735. }
  736. }
  737. // Get required GroupValues
  738. {
  739. for (const auto& Switch : EventRef.GetActionSetSwitch(PlatformData->Switches))
  740. {
  741. if (LIKELY(Switch.Value.IsValid()))
  742. {
  743. RequiredGroupValueSet.Add(FWwiseAnyRef::Create(Switch.Value));
  744. }
  745. }
  746. for (const auto& State : EventRef.GetActionSetState(PlatformData->States))
  747. {
  748. if (LIKELY(State.Value.IsValid()))
  749. {
  750. RequiredGroupValueSet.Add(FWwiseAnyRef::Create(State.Value));
  751. }
  752. }
  753. }
  754. }
  755. }
  756. // Get Switched Media, negating required switches.
  757. {
  758. TMap<FWwiseRefSwitchContainer, TSet<FWwiseAnyRef>> SwitchValuesMap;
  759. for (const auto& SwitchContainerRef : SwitchContainerRefs)
  760. {
  761. const auto* SwitchContainer = SwitchContainerRef.GetSwitchContainer();
  762. if (UNLIKELY(!SwitchContainer))
  763. {
  764. return false;
  765. }
  766. auto SwitchValues = TSet<FWwiseAnyRef>(SwitchContainerRef.GetSwitchValues(PlatformData->Switches, PlatformData->States));
  767. TSet<FWwiseAnyRef> SwitchesToRemove;
  768. for (const auto& SwitchValue : SwitchValues)
  769. {
  770. // Remove all SwitchValues if we load them all by default
  771. if (InInfo.SwitchContainerLoading == EWwiseEventSwitchContainerLoading::AlwaysLoad)
  772. {
  773. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Skip value %s (%" PRIu32 ":%" PRIu32 "): Event Switch Container set to AlwaysLoad"),
  774. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString(), *SwitchValue.GetName().ToString(), SwitchValue.GetGroupId(), SwitchValue.GetId());
  775. SwitchesToRemove.Add(SwitchValue);
  776. continue;
  777. }
  778. // Remove SwitchValues that are already present in RequiredGroupValueSet
  779. if (RequiredGroupValueSet.Contains(SwitchValue))
  780. {
  781. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Skip value %s (%" PRIu32 ":%" PRIu32 "): Already in the required set"),
  782. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString(), *SwitchValue.GetName().ToString(), SwitchValue.GetGroupId(), SwitchValue.GetId());
  783. SwitchesToRemove.Add(SwitchValue);
  784. continue;
  785. }
  786. // Remove SwitchValues that have an ID of "0" (wildcard in music)
  787. if (SwitchValue.GetId() == 0)
  788. {
  789. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Skip value %s (%" PRIu32 ":%" PRIu32 "): Wildcard ID"),
  790. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString(), *SwitchValue.GetName().ToString(), SwitchValue.GetGroupId(), SwitchValue.GetId());
  791. SwitchesToRemove.Add(SwitchValue);
  792. continue;
  793. }
  794. // Remove Switch groups that are controlled by a Game Parameter (RTPC)
  795. if (SwitchValue.GetType() == EWwiseRefType::Switch)
  796. {
  797. const auto* SwitchRef = SwitchValue.GetSwitchRef();
  798. check(SwitchRef);
  799. if (SwitchRef->IsControlledByGameParameter())
  800. {
  801. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Skip value %s (%" PRIu32 ":%" PRIu32 "): Controlled by Game Parameter"),
  802. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString(), *SwitchValue.GetName().ToString(), SwitchValue.GetGroupId(), SwitchValue.GetId());
  803. SwitchesToRemove.Add(SwitchValue);
  804. continue;
  805. }
  806. }
  807. }
  808. SwitchValues = SwitchValues.Difference(SwitchesToRemove);
  809. if (SwitchValues.Num() == 0)
  810. {
  811. // Media and SoundBank are compulsory. Add them so they are always loaded.
  812. const auto* SoundBank = SwitchContainerRef.GetSoundBank();
  813. if (UNLIKELY(!SoundBank))
  814. {
  815. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Switch Container Ref"),
  816. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  817. return false;
  818. }
  819. if (!SoundBank->IsInitBank())
  820. {
  821. FWwiseSoundBankCookedData SwitchContainerSoundBank;
  822. if (UNLIKELY(!FillSoundBankBaseInfo(SwitchContainerSoundBank, *PlatformInfo, *SoundBank)))
  823. {
  824. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Switch Container Data"),
  825. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  826. return false;
  827. }
  828. SoundBankSet.Add(SwitchContainerSoundBank);
  829. }
  830. {
  831. TArray<FWwiseRefMedia> MediaToAdd;
  832. SwitchContainerRef.GetSwitchContainerMedia(PlatformData->MediaFiles).GenerateValueArray(MediaToAdd);
  833. for (const auto& MediaRef : MediaToAdd)
  834. {
  835. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef, Ref.Key, *PlatformData)))
  836. {
  837. return false;
  838. }
  839. }
  840. }
  841. {
  842. WwiseCustomPluginIdsMap CustomPluginsRefs = SwitchContainerRef.GetSwitchContainerCustomPlugins(PlatformData->CustomPlugins);
  843. for (const auto& Plugin : CustomPluginsRefs)
  844. {
  845. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  846. for (const auto& MediaRef : MediaRefs)
  847. {
  848. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  849. {
  850. return false;
  851. }
  852. }
  853. }
  854. }
  855. {
  856. WwisePluginShareSetIdsMap ShareSetRefs = SwitchContainerRef.GetSwitchContainerPluginShareSets(PlatformData->PluginShareSets);
  857. for (const auto& ShareSet : ShareSetRefs)
  858. {
  859. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  860. for (const auto& MediaRef : MediaRefs)
  861. {
  862. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  863. {
  864. return false;
  865. }
  866. }
  867. }
  868. }
  869. {
  870. WwiseAudioDeviceIdsMap AudioDevicesRefs = SwitchContainerRef.GetSwitchContainerAudioDevices(PlatformData->AudioDevices);
  871. for (const auto& AudioDevice : AudioDevicesRefs)
  872. {
  873. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  874. for (const auto& MediaRef : MediaRefs)
  875. {
  876. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, LanguageId, *PlatformData)))
  877. {
  878. return false;
  879. }
  880. }
  881. }
  882. }
  883. TArray<FWwiseRefExternalSource> ExternalSourcesToAdd;
  884. SwitchContainerRef.GetSwitchContainerExternalSources(PlatformData->ExternalSources).GenerateValueArray(ExternalSourcesToAdd);
  885. for (const auto& ExternalSourceRef : ExternalSourcesToAdd)
  886. {
  887. if (UNLIKELY(!AddRequirementsForExternalSource(ExternalSourceSet, ExternalSourceRef)))
  888. {
  889. return false;
  890. }
  891. }
  892. }
  893. else
  894. {
  895. // Media is optional. Will process later
  896. SwitchValuesMap.Add(SwitchContainerRef, SwitchValues);
  897. }
  898. }
  899. // Process Switch Containers that seemingly contain additional media and conditions
  900. for (const auto& SwitchContainerRef : SwitchContainerRefs)
  901. {
  902. const auto* SwitchValues = SwitchValuesMap.Find(SwitchContainerRef);
  903. if (!SwitchValues)
  904. {
  905. continue;
  906. }
  907. // Prepare media and main SoundBank to add
  908. TSet<FWwiseSoundBankCookedData> SoundBankSetToAdd;
  909. TSet<FWwiseMediaCookedData> MediaSetToAdd;
  910. TSet<FWwiseExternalSourceCookedData> ExternalSourceSetToAdd;
  911. const auto* SoundBank = SwitchContainerRef.GetSoundBank();
  912. if (UNLIKELY(!SoundBank))
  913. {
  914. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Switch Container Ref"),
  915. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  916. return false;
  917. }
  918. if (!SoundBank->IsInitBank())
  919. {
  920. FWwiseSoundBankCookedData SwitchContainerSoundBank;
  921. if (UNLIKELY(!FillSoundBankBaseInfo(SwitchContainerSoundBank, *PlatformInfo, *SoundBank)))
  922. {
  923. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Switch Container Data"),
  924. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  925. return false;
  926. }
  927. SoundBankSetToAdd.Add(SwitchContainerSoundBank);
  928. }
  929. {
  930. TArray<FWwiseRefMedia> MediaToAdd;
  931. SwitchContainerRef.GetSwitchContainerMedia(PlatformData->MediaFiles).GenerateValueArray(MediaToAdd);
  932. FWwiseMediaCookedData MediaCookedData;
  933. for (const auto& MediaRef : MediaToAdd)
  934. {
  935. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSetToAdd, MediaSetToAdd, MediaRef, Ref.Key, *PlatformData)))
  936. {
  937. return false;
  938. }
  939. }
  940. }
  941. {
  942. WwiseCustomPluginIdsMap CustomPluginsRefs = SwitchContainerRef.GetSwitchContainerCustomPlugins(PlatformData->CustomPlugins);
  943. for (const auto& Plugin : CustomPluginsRefs)
  944. {
  945. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  946. for (const auto& MediaRef : MediaRefs)
  947. {
  948. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSetToAdd, MediaSetToAdd, MediaRef.Value, LanguageId, *PlatformData)))
  949. {
  950. return false;
  951. }
  952. }
  953. }
  954. }
  955. {
  956. WwisePluginShareSetIdsMap ShareSetRefs = SwitchContainerRef.GetSwitchContainerPluginShareSets(PlatformData->PluginShareSets);
  957. for (const auto& ShareSet : ShareSetRefs)
  958. {
  959. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  960. for (const auto& MediaRef : MediaRefs)
  961. {
  962. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSetToAdd, MediaSetToAdd, MediaRef.Value, LanguageId, *PlatformData)))
  963. {
  964. return false;
  965. }
  966. }
  967. }
  968. }
  969. {
  970. WwiseAudioDeviceIdsMap AudioDevicesRefs = SwitchContainerRef.GetSwitchContainerAudioDevices(PlatformData->AudioDevices);
  971. for (const auto& AudioDevice : AudioDevicesRefs)
  972. {
  973. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  974. for (const auto& MediaRef : MediaRefs)
  975. {
  976. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSetToAdd, MediaSetToAdd, MediaRef.Value, LanguageId, *PlatformData)))
  977. {
  978. return false;
  979. }
  980. }
  981. }
  982. }
  983. TArray<FWwiseRefExternalSource> ExternalSourcesToAdd;
  984. SwitchContainerRef.GetSwitchContainerExternalSources(PlatformData->ExternalSources).GenerateValueArray(ExternalSourcesToAdd);
  985. for (const auto& ExternalSourceRef : ExternalSourcesToAdd)
  986. {
  987. if (UNLIKELY(!AddRequirementsForExternalSource(ExternalSourceSetToAdd, ExternalSourceRef)))
  988. {
  989. return false;
  990. }
  991. }
  992. SoundBankSetToAdd = SoundBankSetToAdd.Difference(SoundBankSet);
  993. MediaSetToAdd = MediaSetToAdd.Difference(MediaSet);
  994. ExternalSourceSetToAdd = ExternalSourceSetToAdd.Difference(ExternalSourceSet);
  995. // Have we already included all the external banks and media
  996. if (SoundBankSetToAdd.Num() == 0 && MediaSetToAdd.Num() == 0 && ExternalSourceSetToAdd.Num() == 0)
  997. {
  998. continue;
  999. }
  1000. // Fill up SwitchContainerCookedData and add it to SwitchContainerLeaves
  1001. FWwiseSwitchContainerLeafCookedData SwitchContainerCookedData;
  1002. for (const auto& SwitchValue : *SwitchValues)
  1003. {
  1004. FWwiseGroupValueCookedData SwitchCookedData;
  1005. switch (SwitchValue.GetType())
  1006. {
  1007. case EWwiseRefType::Switch: SwitchCookedData.Type = EWwiseGroupType::Switch; break;
  1008. case EWwiseRefType::State: SwitchCookedData.Type = EWwiseGroupType::State; break;
  1009. default: SwitchCookedData.Type = EWwiseGroupType::Unknown;
  1010. }
  1011. SwitchCookedData.GroupId = SwitchValue.GetGroupId();
  1012. SwitchCookedData.Id = SwitchValue.GetId();
  1013. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1014. {
  1015. SwitchCookedData.DebugName = FName();
  1016. }
  1017. else
  1018. {
  1019. SwitchCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? SwitchValue.GetName() : SwitchValue.GetObjectPath());
  1020. }
  1021. SwitchContainerCookedData.GroupValueSet.Add(MoveTemp(SwitchCookedData));
  1022. }
  1023. if (auto* ExistingSwitchedMedia = CookedData.SwitchContainerLeaves.FindByPredicate([&SwitchContainerCookedData](const FWwiseSwitchContainerLeafCookedData& RhsValue)
  1024. {
  1025. return RhsValue.GroupValueSet.Difference(SwitchContainerCookedData.GroupValueSet).Num() == 0
  1026. && SwitchContainerCookedData.GroupValueSet.Difference(RhsValue.GroupValueSet).Num() == 0;
  1027. }))
  1028. {
  1029. SoundBankSetToAdd.Append(ExistingSwitchedMedia->SoundBanks);
  1030. MediaSetToAdd.Append(ExistingSwitchedMedia->Media);
  1031. ExternalSourceSetToAdd.Append(ExistingSwitchedMedia->ExternalSources);
  1032. ExistingSwitchedMedia->SoundBanks = SoundBankSetToAdd.Array();
  1033. ExistingSwitchedMedia->Media = MediaSetToAdd.Array();
  1034. ExistingSwitchedMedia->ExternalSources = ExternalSourceSetToAdd.Array();
  1035. }
  1036. else
  1037. {
  1038. SwitchContainerCookedData.SoundBanks = SoundBankSetToAdd.Array();
  1039. SwitchContainerCookedData.Media = MediaSetToAdd.Array();
  1040. SwitchContainerCookedData.ExternalSources = ExternalSourceSetToAdd.Array();
  1041. CookedData.SwitchContainerLeaves.Add(MoveTemp(SwitchContainerCookedData));
  1042. }
  1043. }
  1044. }
  1045. // Finalize banks and media
  1046. CookedData.SoundBanks.Append(SoundBankSet.Array());
  1047. if (CookedData.SoundBanks.Num() == 0)
  1048. {
  1049. UE_LOG(LogWwiseResourceCooker, Log, TEXT("GetEventCookedData (%s %" PRIu32 " %s): No SoundBank set for Event. Unless Switch values are properly set, no SoundBank will be loaded."),
  1050. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1051. }
  1052. CookedData.Media.Append(MediaSet.Array());
  1053. CookedData.ExternalSources.Append(ExternalSourceSet.Array());
  1054. for (const auto& SwitchRef : RequiredGroupValueSet)
  1055. {
  1056. FWwiseGroupValueCookedData SwitchCookedData;
  1057. switch (SwitchRef.GetType())
  1058. {
  1059. case EWwiseRefType::Switch: SwitchCookedData.Type = EWwiseGroupType::Switch; break;
  1060. case EWwiseRefType::State: SwitchCookedData.Type = EWwiseGroupType::State; break;
  1061. default: SwitchCookedData.Type = EWwiseGroupType::Unknown;
  1062. }
  1063. SwitchCookedData.GroupId = SwitchRef.GetGroupId();
  1064. SwitchCookedData.Id = SwitchRef.GetId();
  1065. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1066. {
  1067. SwitchCookedData.DebugName = FName();
  1068. }
  1069. else
  1070. {
  1071. SwitchCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? SwitchRef.GetName() : SwitchRef.GetObjectPath());
  1072. }
  1073. CookedData.RequiredGroupValueSet.Add(MoveTemp(SwitchCookedData));
  1074. }
  1075. CookedData.DestroyOptions = InInfo.DestroyOptions;
  1076. OutCookedData.EventLanguageMap.Add(FWwiseLanguageCookedData(LanguageId.GetLanguageId(), LanguageId.GetLanguageName(), LanguageId.LanguageRequirement), MoveTemp(CookedData));
  1077. }
  1078. if (UNLIKELY(OutCookedData.EventLanguageMap.Num() == 0))
  1079. {
  1080. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetEventCookedData (%s %" PRIu32 " %s): No Event"),
  1081. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1082. return false;
  1083. }
  1084. // Make this a SFX if all CookedData are identical
  1085. {
  1086. auto& Map = OutCookedData.EventLanguageMap;
  1087. TArray<FWwiseLanguageCookedData> Keys;
  1088. Map.GetKeys(Keys);
  1089. auto LhsKey = Keys.Pop(false);
  1090. const auto* Lhs = Map.Find(LhsKey);
  1091. while (Keys.Num() > 0)
  1092. {
  1093. auto RhsKey = Keys.Pop(false);
  1094. const auto* Rhs = Map.Find(RhsKey);
  1095. if (Lhs->EventId != Rhs->EventId
  1096. || Lhs->DebugName != Rhs->DebugName
  1097. || Lhs->SoundBanks.Num() != Rhs->SoundBanks.Num()
  1098. || Lhs->ExternalSources.Num() != Rhs->ExternalSources.Num()
  1099. || Lhs->Media.Num() != Rhs->Media.Num()
  1100. || Lhs->RequiredGroupValueSet.Num() != Rhs->RequiredGroupValueSet.Num()
  1101. || Lhs->SwitchContainerLeaves.Num() != Rhs->SwitchContainerLeaves.Num())
  1102. {
  1103. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages"),
  1104. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1105. return true;
  1106. }
  1107. for (const auto& Elem : Lhs->SoundBanks)
  1108. {
  1109. if (!Rhs->SoundBanks.Contains(Elem))
  1110. {
  1111. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to banks"),
  1112. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1113. return true;
  1114. }
  1115. }
  1116. for (const auto& Elem : Lhs->ExternalSources)
  1117. {
  1118. if (!Rhs->ExternalSources.Contains(Elem))
  1119. {
  1120. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to external sources"),
  1121. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1122. return true;
  1123. }
  1124. }
  1125. for (const auto& Elem : Lhs->Media)
  1126. {
  1127. if (!Rhs->Media.Contains(Elem))
  1128. {
  1129. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to media"),
  1130. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1131. return true;
  1132. }
  1133. }
  1134. for (const auto& Elem : Lhs->RequiredGroupValueSet)
  1135. {
  1136. if (!Rhs->RequiredGroupValueSet.Contains(Elem))
  1137. {
  1138. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to required group values"),
  1139. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1140. return true;
  1141. }
  1142. }
  1143. for (const auto& LhsLeaf : Lhs->SwitchContainerLeaves)
  1144. {
  1145. const auto RhsLeafIndex = Rhs->SwitchContainerLeaves.Find(LhsLeaf);
  1146. if (RhsLeafIndex == INDEX_NONE)
  1147. {
  1148. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to switch container"),
  1149. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1150. return true;
  1151. }
  1152. const auto& RhsLeaf = Rhs->SwitchContainerLeaves[RhsLeafIndex];
  1153. for (const auto& Elem : LhsLeaf.SoundBanks)
  1154. {
  1155. if (!RhsLeaf.SoundBanks.Contains(Elem))
  1156. {
  1157. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to banks in switch container"),
  1158. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1159. return true;
  1160. }
  1161. }
  1162. for (const auto& Elem : LhsLeaf.ExternalSources)
  1163. {
  1164. if (!RhsLeaf.ExternalSources.Contains(Elem))
  1165. {
  1166. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to external sources in switch container"),
  1167. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1168. return true;
  1169. }
  1170. }
  1171. for (const auto& Elem : LhsLeaf.Media)
  1172. {
  1173. if (!RhsLeaf.Media.Contains(Elem))
  1174. {
  1175. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event has languages due to media in switch container"),
  1176. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1177. return true;
  1178. }
  1179. }
  1180. }
  1181. }
  1182. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetEventCookedData (%s %" PRIu32 " %s): Event is a SFX"),
  1183. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1184. std::remove_reference_t<decltype(Map)> SfxMap;
  1185. SfxMap.Add(FWwiseLanguageCookedData::Sfx, *Lhs);
  1186. Map = SfxMap;
  1187. }
  1188. return true;
  1189. }
  1190. bool FWwiseResourceCookerImpl::GetExternalSourceCookedData(FWwiseExternalSourceCookedData& OutCookedData, uint32 InCookie) const
  1191. {
  1192. const auto* ProjectDatabase = GetProjectDatabase();
  1193. if (UNLIKELY(!ProjectDatabase))
  1194. {
  1195. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetExternalSourceCookedData (%" PRIu32 "): ProjectDatabase not initialized"),
  1196. InCookie);
  1197. return false;
  1198. }
  1199. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1200. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1201. if (UNLIKELY(!PlatformData))
  1202. {
  1203. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetExternalSourceCookedData (%" PRIu32 "): No data for platform"),
  1204. InCookie);
  1205. return false;
  1206. }
  1207. const auto LocalizableId = FWwiseDatabaseLocalizableIdKey(InCookie, FWwiseDatabaseLocalizableIdKey::GENERIC_LANGUAGE);
  1208. const auto* ExternalSourceRef = PlatformData->ExternalSources.Find(LocalizableId);
  1209. if (UNLIKELY(!ExternalSourceRef))
  1210. {
  1211. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetExternalSourceCookedData (%" PRIu32 "): Could not find External Source"),
  1212. InCookie);
  1213. return false;
  1214. }
  1215. const auto* ExternalSource = ExternalSourceRef->GetExternalSource();
  1216. if (UNLIKELY(!ExternalSource))
  1217. {
  1218. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetExternalSourceCookedData (%" PRIu32 "): Could not get External Source"),
  1219. InCookie);
  1220. return false;
  1221. }
  1222. if (UNLIKELY(!FillExternalSourceBaseInfo(OutCookedData, *ExternalSource)))
  1223. {
  1224. return false;
  1225. }
  1226. return true;
  1227. }
  1228. bool FWwiseResourceCookerImpl::GetGameParameterCookedData(FWwiseGameParameterCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1229. {
  1230. const auto* ProjectDatabase = GetProjectDatabase();
  1231. if (UNLIKELY(!ProjectDatabase))
  1232. {
  1233. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetGameParameterCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  1234. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1235. return false;
  1236. }
  1237. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1238. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1239. if (UNLIKELY(!PlatformData))
  1240. {
  1241. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetGameParameterCookedData (%s %" PRIu32 " %s): No data for platform"),
  1242. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1243. return false;
  1244. }
  1245. FWwiseRefGameParameter GameParameterRef;
  1246. if (UNLIKELY(!PlatformData->GetRef(GameParameterRef, FWwiseSharedLanguageId(), InInfo)))
  1247. {
  1248. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetGameParameterCookedData (%s %" PRIu32 " %s): No game parameter found"),
  1249. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1250. return false;
  1251. }
  1252. const auto* GameParameter = GameParameterRef.GetGameParameter();
  1253. OutCookedData.ShortId = GameParameter->Id;
  1254. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1255. {
  1256. OutCookedData.DebugName = FName();
  1257. }
  1258. else
  1259. {
  1260. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? GameParameter->Name : GameParameter->ObjectPath);
  1261. }
  1262. return true;
  1263. }
  1264. bool FWwiseResourceCookerImpl::GetInitBankCookedData(FWwiseInitBankCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1265. {
  1266. const auto* ProjectDatabase = GetProjectDatabase();
  1267. if (UNLIKELY(!ProjectDatabase))
  1268. {
  1269. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  1270. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1271. return false;
  1272. }
  1273. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1274. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1275. if (UNLIKELY(!PlatformData))
  1276. {
  1277. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): No data for platform"),
  1278. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1279. return false;
  1280. }
  1281. const auto* PlatformInfo = PlatformData->PlatformRef.GetPlatformInfo();
  1282. if (UNLIKELY(!PlatformInfo))
  1283. {
  1284. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): No Platform Info"),
  1285. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1286. return false;
  1287. }
  1288. FWwiseRefSoundBank SoundBankRef;
  1289. if (UNLIKELY(!PlatformData->GetRef(SoundBankRef, FWwiseSharedLanguageId(), InInfo)))
  1290. {
  1291. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): No ref found"),
  1292. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1293. return false;
  1294. }
  1295. if (UNLIKELY(!SoundBankRef.IsInitBank()))
  1296. {
  1297. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): Not an init SoundBank"),
  1298. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1299. return false;
  1300. }
  1301. TSet<FWwiseSoundBankCookedData> AdditionalSoundBanks;
  1302. {
  1303. const auto* SoundBank = SoundBankRef.GetSoundBank();
  1304. if (UNLIKELY(!SoundBank))
  1305. {
  1306. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  1307. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1308. return false;
  1309. }
  1310. if (UNLIKELY(!FillSoundBankBaseInfo(OutCookedData, *PlatformInfo, *SoundBank)))
  1311. {
  1312. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetInitBankCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  1313. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1314. return false;
  1315. }
  1316. // Add all Init SoundBank media
  1317. TSet<FWwiseMediaCookedData> MediaSet;
  1318. {
  1319. for (const auto& MediaRef : SoundBankRef.GetSoundBankMedia(PlatformData->MediaFiles))
  1320. {
  1321. if (UNLIKELY(!AddRequirementsForMedia(AdditionalSoundBanks, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1322. {
  1323. return false;
  1324. }
  1325. }
  1326. }
  1327. {
  1328. WwiseCustomPluginIdsMap CustomPluginsRefs = SoundBankRef.GetSoundBankCustomPlugins(PlatformData->CustomPlugins);
  1329. for (const auto& Plugin : CustomPluginsRefs)
  1330. {
  1331. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  1332. for (const auto& MediaRef : MediaRefs)
  1333. {
  1334. if (UNLIKELY(!AddRequirementsForMedia(AdditionalSoundBanks, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1335. {
  1336. return false;
  1337. }
  1338. }
  1339. }
  1340. }
  1341. {
  1342. WwisePluginShareSetIdsMap ShareSetRefs = SoundBankRef.GetSoundBankPluginShareSets(PlatformData->PluginShareSets);
  1343. for (const auto& ShareSet : ShareSetRefs)
  1344. {
  1345. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  1346. for (const auto& MediaRef : MediaRefs)
  1347. {
  1348. if (UNLIKELY(!AddRequirementsForMedia(AdditionalSoundBanks, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1349. {
  1350. return false;
  1351. }
  1352. }
  1353. }
  1354. }
  1355. {
  1356. WwiseAudioDeviceIdsMap AudioDevicesRefs = SoundBankRef.GetSoundBankAudioDevices(PlatformData->AudioDevices);
  1357. for (const auto& AudioDevice : AudioDevicesRefs)
  1358. {
  1359. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  1360. for (const auto& MediaRef : MediaRefs)
  1361. {
  1362. if (UNLIKELY(!AddRequirementsForMedia(AdditionalSoundBanks, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1363. {
  1364. return false;
  1365. }
  1366. }
  1367. }
  1368. }
  1369. OutCookedData.Media = MediaSet.Array();
  1370. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  1371. OutCookedData.Language.Empty(Languages.Num());
  1372. for (const FWwiseSharedLanguageId& Language : Languages)
  1373. {
  1374. OutCookedData.Language.Add({ Language.GetLanguageId(), Language.GetLanguageName(), Language.LanguageRequirement });
  1375. }
  1376. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1377. {
  1378. OutCookedData.DebugName = FName();
  1379. }
  1380. else
  1381. {
  1382. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? SoundBank->ShortName : SoundBank->ObjectPath);
  1383. }
  1384. }
  1385. return true;
  1386. }
  1387. bool FWwiseResourceCookerImpl::GetMediaCookedData(FWwiseMediaCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1388. {
  1389. const auto* ProjectDatabase = GetProjectDatabase();
  1390. if (UNLIKELY(!ProjectDatabase))
  1391. {
  1392. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetMediaCookedData (%" PRIu32 "): ProjectDatabase not initialized"),
  1393. InInfo.WwiseShortId);
  1394. return false;
  1395. }
  1396. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1397. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1398. if (UNLIKELY(!PlatformData))
  1399. {
  1400. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetMediaCookedData (%" PRIu32 "): No data for platform"),
  1401. InInfo.WwiseShortId);
  1402. return false;
  1403. }
  1404. auto MediaId = FWwiseDatabaseMediaIdKey(InInfo.WwiseShortId, InInfo.HardCodedSoundBankShortId);
  1405. const auto* MediaRef = PlatformData->MediaFiles.Find(MediaId);
  1406. if (UNLIKELY(!MediaRef))
  1407. {
  1408. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetMediaCookedData (%" PRIu32 "): Could not find Media in SoundBank %" PRIu32),
  1409. InInfo.WwiseShortId, InInfo.HardCodedSoundBankShortId);
  1410. return false;
  1411. }
  1412. const FWwiseSharedLanguageId* LanguageRefPtr = nullptr;
  1413. if (MediaRef->LanguageId)
  1414. {
  1415. const auto& Languages = DataStructure.GetLanguages();
  1416. LanguageRefPtr = Languages.Find(FWwiseSharedLanguageId(MediaRef->LanguageId, TEXT(""), EWwiseLanguageRequirement::IsOptional));
  1417. if (UNLIKELY(!LanguageRefPtr))
  1418. {
  1419. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetMediaCookedData (%" PRIu32 "): Could not find language %" PRIu32),
  1420. InInfo.WwiseShortId, MediaRef->LanguageId);
  1421. return false;
  1422. }
  1423. }
  1424. const auto& LanguageRef = LanguageRefPtr ? *LanguageRefPtr : FWwiseSharedLanguageId();
  1425. TSet<FWwiseSoundBankCookedData> SoundBankSet;
  1426. TSet<FWwiseMediaCookedData> MediaSet;
  1427. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, *MediaRef, LanguageRef, *PlatformData)))
  1428. {
  1429. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetMediaCookedData (%" PRIu32 "): Could not get requirements for media."),
  1430. InInfo.WwiseShortId);
  1431. return false;
  1432. }
  1433. if (UNLIKELY(SoundBankSet.Num() > 0))
  1434. {
  1435. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetMediaCookedData (%" PRIu32 "): Asking for a media in a particular SoundBank (%" PRIu32 ") must have it fully defined in this SoundBank."),
  1436. InInfo.WwiseShortId, InInfo.HardCodedSoundBankShortId);
  1437. return false;
  1438. }
  1439. if (MediaSet.Num() == 0)
  1440. {
  1441. // Not directly an error: Media is in this SoundBank, without streaming. Can be a logical error, but it's not our error.
  1442. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetMediaCookedData (%" PRIu32 "): Media is fully in SoundBank. Returning no media."),
  1443. InInfo.WwiseShortId);
  1444. return false;
  1445. }
  1446. auto Media = MediaSet.Array()[0];
  1447. OutCookedData = MoveTemp(Media);
  1448. return true;
  1449. }
  1450. bool FWwiseResourceCookerImpl::GetShareSetCookedData(FWwiseLocalizedShareSetCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1451. {
  1452. const auto* ProjectDatabase = GetProjectDatabase();
  1453. if (UNLIKELY(!ProjectDatabase))
  1454. {
  1455. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  1456. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1457. return false;
  1458. }
  1459. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1460. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1461. if (UNLIKELY(!PlatformData))
  1462. {
  1463. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): No data for platform"),
  1464. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1465. return false;
  1466. }
  1467. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  1468. const auto* PlatformInfo = PlatformData->PlatformRef.GetPlatformInfo();
  1469. if (UNLIKELY(!PlatformInfo))
  1470. {
  1471. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): No Platform Info"),
  1472. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1473. return false;
  1474. }
  1475. TMap<FWwiseSharedLanguageId, TSet<FWwiseRefPluginShareSet>> RefLanguageMap;
  1476. PlatformData->GetRefMap(RefLanguageMap, Languages, InInfo);
  1477. if (UNLIKELY(RefLanguageMap.Num() == 0))
  1478. {
  1479. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): No ref found"),
  1480. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1481. return false;
  1482. }
  1483. OutCookedData.ShareSetLanguageMap.Empty(RefLanguageMap.Num());
  1484. for (auto& Ref : RefLanguageMap)
  1485. {
  1486. FWwiseShareSetCookedData CookedData;
  1487. TSet<FWwiseSoundBankCookedData> SoundBankSet;
  1488. TSet<FWwiseMediaCookedData> MediaSet;
  1489. TSet<FWwiseRefPluginShareSet>& ShareSets = Ref.Value;
  1490. if (UNLIKELY(ShareSets.Num() == 0))
  1491. {
  1492. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetAuxBusCookedData (%s %" PRIu32 " %s): Empty ref for language"),
  1493. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1494. return false;
  1495. }
  1496. // Set up basic global Aux bus information
  1497. {
  1498. TSet<FWwiseRefPluginShareSet>::TConstIterator FirstShareSet(ShareSets);
  1499. CookedData.ShareSetId = FirstShareSet->PluginShareSetId();
  1500. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1501. {
  1502. OutCookedData.DebugName = FName();
  1503. }
  1504. else
  1505. {
  1506. CookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? FirstShareSet->PluginShareSetName() : FirstShareSet->PluginShareSetObjectPath());
  1507. OutCookedData.DebugName = CookedData.DebugName;
  1508. }
  1509. OutCookedData.ShareSetId = CookedData.ShareSetId;
  1510. }
  1511. for (auto& ShareSetRef : ShareSets)
  1512. {
  1513. const auto* PluginShareSet = ShareSetRef.GetPlugin();
  1514. if (UNLIKELY(!PluginShareSet))
  1515. {
  1516. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): Could not get ShareSet from Ref"),
  1517. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1518. return false;
  1519. }
  1520. CookedData.ShareSetId = PluginShareSet->Id;
  1521. const auto* SoundBank = ShareSetRef.GetSoundBank();
  1522. if (UNLIKELY(!SoundBank))
  1523. {
  1524. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  1525. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1526. return false;
  1527. }
  1528. if (!SoundBank->IsInitBank())
  1529. {
  1530. FWwiseSoundBankCookedData MainSoundBank;
  1531. if (UNLIKELY(!FillSoundBankBaseInfo(MainSoundBank, *PlatformInfo, *SoundBank)))
  1532. {
  1533. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  1534. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1535. return false;
  1536. }
  1537. SoundBankSet.Add(MainSoundBank);
  1538. }
  1539. {
  1540. WwiseCustomPluginIdsMap CustomPluginsRefs = ShareSetRef.GetPluginCustomPlugins(PlatformData->CustomPlugins);
  1541. for (const auto& Plugin : CustomPluginsRefs)
  1542. {
  1543. const WwiseMediaIdsMap MediaRefs = Plugin.Value.GetPluginMedia(PlatformData->MediaFiles);
  1544. for (const auto& MediaRef : MediaRefs)
  1545. {
  1546. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1547. {
  1548. return false;
  1549. }
  1550. }
  1551. }
  1552. }
  1553. {
  1554. WwisePluginShareSetIdsMap ShareSetRefs = ShareSetRef.GetPluginPluginShareSets(PlatformData->PluginShareSets);
  1555. for (const auto& ShareSet : ShareSetRefs)
  1556. {
  1557. const WwiseMediaIdsMap MediaRefs = ShareSet.Value.GetPluginMedia(PlatformData->MediaFiles);
  1558. for (const auto& MediaRef : MediaRefs)
  1559. {
  1560. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1561. {
  1562. return false;
  1563. }
  1564. }
  1565. }
  1566. }
  1567. {
  1568. WwiseAudioDeviceIdsMap AudioDevicesRefs = ShareSetRef.GetPluginAudioDevices(PlatformData->AudioDevices);
  1569. for (const auto& AudioDevice : AudioDevicesRefs)
  1570. {
  1571. const WwiseMediaIdsMap MediaRefs = AudioDevice.Value.GetPluginMedia(PlatformData->MediaFiles);
  1572. for (const auto& MediaRef : MediaRefs)
  1573. {
  1574. if (UNLIKELY(!AddRequirementsForMedia(SoundBankSet, MediaSet, MediaRef.Value, FWwiseSharedLanguageId(), *PlatformData)))
  1575. {
  1576. return false;
  1577. }
  1578. }
  1579. }
  1580. }
  1581. }
  1582. CookedData.SoundBanks = SoundBankSet.Array();
  1583. CookedData.Media = MediaSet.Array();
  1584. OutCookedData.ShareSetLanguageMap.Add(FWwiseLanguageCookedData(Ref.Key.GetLanguageId(), Ref.Key.GetLanguageName(), Ref.Key.LanguageRequirement), MoveTemp(CookedData));
  1585. }
  1586. if (UNLIKELY(OutCookedData.ShareSetLanguageMap.Num() == 0))
  1587. {
  1588. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): No ShareSet"),
  1589. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1590. return false;
  1591. }
  1592. // Make this a SFX if all CookedData are identical
  1593. {
  1594. auto& Map = OutCookedData.ShareSetLanguageMap;
  1595. TArray<FWwiseLanguageCookedData> Keys;
  1596. Map.GetKeys(Keys);
  1597. auto LhsKey = Keys.Pop(false);
  1598. const auto* Lhs = Map.Find(LhsKey);
  1599. while (Keys.Num() > 0)
  1600. {
  1601. auto RhsKey = Keys.Pop(false);
  1602. const auto* Rhs = Map.Find(RhsKey);
  1603. if (Lhs->ShareSetId != Rhs->ShareSetId
  1604. || Lhs->DebugName != Rhs->DebugName
  1605. || Lhs->SoundBanks.Num() != Rhs->SoundBanks.Num()
  1606. || Lhs->Media.Num() != Rhs->Media.Num())
  1607. {
  1608. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): ShareSet has languages"),
  1609. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1610. return true;
  1611. }
  1612. for (const auto& Elem : Lhs->SoundBanks)
  1613. {
  1614. if (!Rhs->SoundBanks.Contains(Elem))
  1615. {
  1616. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): ShareSet has languages due to banks"),
  1617. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1618. return true;
  1619. }
  1620. }
  1621. for (const auto& Elem : Lhs->Media)
  1622. {
  1623. if (!Rhs->Media.Contains(Elem))
  1624. {
  1625. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): ShareSet has languages due to media"),
  1626. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1627. return true;
  1628. }
  1629. }
  1630. }
  1631. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetShareSetCookedData (%s %" PRIu32 " %s): ShareSet is a SFX"),
  1632. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1633. std::remove_reference_t<decltype(Map)> SfxMap;
  1634. SfxMap.Add(FWwiseLanguageCookedData::Sfx, *Lhs);
  1635. Map = SfxMap;
  1636. }
  1637. return true;
  1638. }
  1639. bool FWwiseResourceCookerImpl::GetSoundBankCookedData(FWwiseLocalizedSoundBankCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1640. {
  1641. const auto* ProjectDatabase = GetProjectDatabase();
  1642. if (UNLIKELY(!ProjectDatabase))
  1643. {
  1644. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  1645. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1646. return false;
  1647. }
  1648. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1649. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1650. if (UNLIKELY(!PlatformData))
  1651. {
  1652. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): No data for platform"),
  1653. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1654. return false;
  1655. }
  1656. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  1657. const auto* PlatformInfo = PlatformData->PlatformRef.GetPlatformInfo();
  1658. if (UNLIKELY(!PlatformInfo))
  1659. {
  1660. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): No Platform Info"),
  1661. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1662. return false;
  1663. }
  1664. TMap<FWwiseSharedLanguageId, FWwiseRefSoundBank> RefLanguageMap;
  1665. PlatformData->GetRefMap(RefLanguageMap, Languages, InInfo);
  1666. if (UNLIKELY(RefLanguageMap.Num() == 0))
  1667. {
  1668. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): No ref found"),
  1669. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1670. return false;
  1671. }
  1672. OutCookedData.SoundBankLanguageMap.Empty(RefLanguageMap.Num());
  1673. for (const auto& Ref : RefLanguageMap)
  1674. {
  1675. FWwiseSoundBankCookedData CookedData;
  1676. const auto* SoundBank = Ref.Value.GetSoundBank();
  1677. if (UNLIKELY(!SoundBank))
  1678. {
  1679. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): Could not get SoundBank from Ref"),
  1680. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1681. return false;
  1682. }
  1683. if (UNLIKELY(!FillSoundBankBaseInfo(CookedData, *PlatformInfo, *SoundBank)))
  1684. {
  1685. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): Could not fill SoundBank from Data"),
  1686. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1687. return false;
  1688. }
  1689. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1690. {
  1691. OutCookedData.DebugName = FName();
  1692. }
  1693. else
  1694. {
  1695. CookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? SoundBank->ShortName : SoundBank->ObjectPath);
  1696. OutCookedData.DebugName = CookedData.DebugName;
  1697. }
  1698. OutCookedData.SoundBankId = CookedData.SoundBankId;
  1699. OutCookedData.SoundBankLanguageMap.Add(FWwiseLanguageCookedData(Ref.Key.GetLanguageId(), Ref.Key.GetLanguageName(), Ref.Key.LanguageRequirement), MoveTemp(CookedData));
  1700. }
  1701. if (UNLIKELY(OutCookedData.SoundBankLanguageMap.Num() == 0))
  1702. {
  1703. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): No SoundBank"),
  1704. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1705. return false;
  1706. }
  1707. // Make this a SFX if all CookedData are identical
  1708. {
  1709. auto& Map = OutCookedData.SoundBankLanguageMap;
  1710. TArray<FWwiseLanguageCookedData> Keys;
  1711. Map.GetKeys(Keys);
  1712. auto LhsKey = Keys.Pop(false);
  1713. const auto* Lhs = Map.Find(LhsKey);
  1714. while (Keys.Num() > 0)
  1715. {
  1716. auto RhsKey = Keys.Pop(false);
  1717. const auto* Rhs = Map.Find(RhsKey);
  1718. if (GetTypeHash(*Lhs) != GetTypeHash(*Rhs))
  1719. {
  1720. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): SoundBank has languages"),
  1721. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1722. return true;
  1723. }
  1724. }
  1725. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("GetSoundBankCookedData (%s %" PRIu32 " %s): SoundBank is a SFX"),
  1726. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1727. std::remove_reference_t<decltype(Map)> SfxMap;
  1728. SfxMap.Add(FWwiseLanguageCookedData::Sfx, *Lhs);
  1729. Map = SfxMap;
  1730. }
  1731. return true;
  1732. }
  1733. bool FWwiseResourceCookerImpl::GetStateCookedData(FWwiseGroupValueCookedData& OutCookedData, const FWwiseGroupValueInfo& InInfo) const
  1734. {
  1735. const auto* ProjectDatabase = GetProjectDatabase();
  1736. if (UNLIKELY(!ProjectDatabase))
  1737. {
  1738. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetStateCookedData (%s %" PRIu32 " %" PRIu32 " %s): ProjectDatabase not initialized"),
  1739. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1740. return false;
  1741. }
  1742. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1743. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1744. if (UNLIKELY(!PlatformData))
  1745. {
  1746. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetStateCookedData (%s %" PRIu32 " %" PRIu32 " %s): No data for platform"),
  1747. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1748. return false;
  1749. }
  1750. FWwiseRefState StateRef;
  1751. if (UNLIKELY(!PlatformData->GetRef(StateRef, FWwiseSharedLanguageId(), InInfo)))
  1752. {
  1753. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetStateCookedData (%s %" PRIu32 " %" PRIu32 " %s): No state found"),
  1754. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1755. return false;
  1756. }
  1757. const auto* State = StateRef.GetState();
  1758. const auto* StateGroup = StateRef.GetStateGroup();
  1759. if (UNLIKELY(!State || !StateGroup))
  1760. {
  1761. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetStateCookedData (%s %" PRIu32 " %" PRIu32 " %s): No state in ref"),
  1762. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1763. return false;
  1764. }
  1765. OutCookedData.Type = EWwiseGroupType::State;
  1766. OutCookedData.GroupId = StateGroup->Id;
  1767. OutCookedData.Id = State->Id;
  1768. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1769. {
  1770. OutCookedData.DebugName = FName();
  1771. }
  1772. else
  1773. {
  1774. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? State->Name : State->ObjectPath);
  1775. }
  1776. return true;
  1777. }
  1778. bool FWwiseResourceCookerImpl::GetSwitchCookedData(FWwiseGroupValueCookedData& OutCookedData, const FWwiseGroupValueInfo& InInfo) const
  1779. {
  1780. const auto* ProjectDatabase = GetProjectDatabase();
  1781. if (UNLIKELY(!ProjectDatabase))
  1782. {
  1783. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetSwitchCookedData (%s %" PRIu32 " %" PRIu32 " %s): ProjectDatabase not initialized"),
  1784. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1785. return false;
  1786. }
  1787. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1788. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1789. if (UNLIKELY(!PlatformData))
  1790. {
  1791. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetSwitchCookedData (%s %" PRIu32 " %" PRIu32 " %s): No data for platform"),
  1792. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1793. return false;
  1794. }
  1795. FWwiseRefSwitch SwitchRef;
  1796. if (UNLIKELY(!PlatformData->GetRef(SwitchRef, FWwiseSharedLanguageId(), InInfo)))
  1797. {
  1798. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSwitchCookedData (%s %" PRIu32 " %" PRIu32 " %s): No switch found"),
  1799. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1800. return false;
  1801. }
  1802. const auto* Switch = SwitchRef.GetSwitch();
  1803. const auto* SwitchGroup = SwitchRef.GetSwitchGroup();
  1804. if (UNLIKELY(!Switch || !SwitchGroup))
  1805. {
  1806. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetSwitchCookedData (%s %" PRIu32 " %" PRIu32 " %s): No switch in ref"),
  1807. *InInfo.WwiseGuid.ToString(), InInfo.GroupShortId, InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1808. return false;
  1809. }
  1810. OutCookedData.Type = EWwiseGroupType::Switch;
  1811. OutCookedData.GroupId = SwitchGroup->Id;
  1812. OutCookedData.Id = Switch->Id;
  1813. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1814. {
  1815. OutCookedData.DebugName = FName();
  1816. }
  1817. else
  1818. {
  1819. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? Switch->Name : Switch->ObjectPath);
  1820. }
  1821. return true;
  1822. }
  1823. bool FWwiseResourceCookerImpl::GetTriggerCookedData(FWwiseTriggerCookedData& OutCookedData, const FWwiseObjectInfo& InInfo) const
  1824. {
  1825. const auto* ProjectDatabase = GetProjectDatabase();
  1826. if (UNLIKELY(!ProjectDatabase))
  1827. {
  1828. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetTriggerCookedData (%s %" PRIu32 " %s): ProjectDatabase not initialized"),
  1829. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1830. return false;
  1831. }
  1832. const FWwiseDataStructureScopeLock DataStructure(*ProjectDatabase);
  1833. const auto* PlatformData = DataStructure.GetCurrentPlatformData();
  1834. if (UNLIKELY(!PlatformData))
  1835. {
  1836. UE_LOG(LogWwiseResourceCooker, Error, TEXT("GetTriggerCookedData (%s %" PRIu32 " %s): No data for platform"),
  1837. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1838. return false;
  1839. }
  1840. const TSet<FWwiseSharedLanguageId>& Languages = DataStructure.GetLanguages();
  1841. FWwiseRefTrigger TriggerRef;
  1842. if (UNLIKELY(!PlatformData->GetRef(TriggerRef, FWwiseSharedLanguageId(), InInfo)))
  1843. {
  1844. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("GetTriggerCookedData (%s %" PRIu32 " %s): No trigger data found"),
  1845. *InInfo.WwiseGuid.ToString(), InInfo.WwiseShortId, *InInfo.WwiseName.ToString());
  1846. return false;
  1847. }
  1848. const auto* Trigger = TriggerRef.GetTrigger();
  1849. OutCookedData.TriggerId = Trigger->Id;
  1850. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1851. {
  1852. OutCookedData.DebugName = FName();
  1853. }
  1854. else
  1855. {
  1856. OutCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? Trigger->Name : Trigger->ObjectPath);
  1857. }
  1858. return true;
  1859. }
  1860. bool FWwiseResourceCookerImpl::FillSoundBankBaseInfo(FWwiseSoundBankCookedData& OutSoundBankCookedData, const FWwiseMetadataPlatformInfo& InPlatformInfo, const FWwiseMetadataSoundBank& InSoundBank) const
  1861. {
  1862. OutSoundBankCookedData.SoundBankId = InSoundBank.Id;
  1863. OutSoundBankCookedData.SoundBankPathName = InSoundBank.Path;
  1864. OutSoundBankCookedData.MemoryAlignment = InSoundBank.Align == 0 ? InPlatformInfo.DefaultAlign : InSoundBank.Align;
  1865. OutSoundBankCookedData.bDeviceMemory = InSoundBank.bDeviceMemory;
  1866. OutSoundBankCookedData.bContainsMedia = InSoundBank.ContainsMedia();
  1867. switch (InSoundBank.Type)
  1868. {
  1869. case EMetadataSoundBankType::Bus:
  1870. OutSoundBankCookedData.SoundBankType = EWwiseSoundBankType::Bus;
  1871. break;
  1872. case EMetadataSoundBankType::Event:
  1873. OutSoundBankCookedData.SoundBankType = EWwiseSoundBankType::Event;
  1874. break;
  1875. case EMetadataSoundBankType::User:
  1876. default:
  1877. OutSoundBankCookedData.SoundBankType = EWwiseSoundBankType::User;
  1878. }
  1879. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1880. {
  1881. OutSoundBankCookedData.DebugName = FName();
  1882. }
  1883. else
  1884. {
  1885. OutSoundBankCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? InSoundBank.ShortName : InSoundBank.ObjectPath);
  1886. }
  1887. return true;
  1888. }
  1889. bool FWwiseResourceCookerImpl::FillMediaBaseInfo(FWwiseMediaCookedData& OutMediaCookedData, const FWwiseMetadataPlatformInfo& InPlatformInfo, const FWwiseMetadataSoundBank& InSoundBank, const FWwiseMetadataMediaReference& InMediaReference) const
  1890. {
  1891. for (const auto& Media : InSoundBank.Media)
  1892. {
  1893. if (Media.Id == InMediaReference.Id)
  1894. {
  1895. return FillMediaBaseInfo(OutMediaCookedData, InPlatformInfo, InSoundBank, Media);
  1896. }
  1897. }
  1898. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("FillMediaBaseInfo: Could not get Media Reference %" PRIu32 " in SoundBank %s %" PRIu32),
  1899. InMediaReference.Id, *InSoundBank.ShortName.ToString(), InSoundBank.Id);
  1900. return false;
  1901. }
  1902. bool FWwiseResourceCookerImpl::FillMediaBaseInfo(FWwiseMediaCookedData& OutMediaCookedData, const FWwiseMetadataPlatformInfo& InPlatformInfo, const FWwiseMetadataSoundBank& InSoundBank, const FWwiseMetadataMedia& InMedia) const
  1903. {
  1904. OutMediaCookedData.MediaId = InMedia.Id;
  1905. if (InMedia.Path.IsNone())
  1906. {
  1907. if (UNLIKELY(InMedia.CachePath.IsNone()))
  1908. {
  1909. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("FillMediaBaseInfo: Empty path for Media %" PRIu32 " in SoundBank %s %" PRIu32),
  1910. InMedia.Id, *InSoundBank.ShortName.ToString(), InSoundBank.Id);
  1911. return false;
  1912. }
  1913. OutMediaCookedData.MediaPathName = InMedia.CachePath;
  1914. }
  1915. else
  1916. {
  1917. OutMediaCookedData.MediaPathName = InMedia.Path;
  1918. }
  1919. OutMediaCookedData.PrefetchSize = InMedia.PrefetchSize;
  1920. OutMediaCookedData.MemoryAlignment = InMedia.Align == 0 ? InPlatformInfo.DefaultAlign : InMedia.Align;
  1921. OutMediaCookedData.bDeviceMemory = InMedia.bDeviceMemory;
  1922. OutMediaCookedData.bStreaming = InMedia.bStreaming;
  1923. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1924. {
  1925. OutMediaCookedData.DebugName = FName();
  1926. }
  1927. else
  1928. {
  1929. OutMediaCookedData.DebugName = FName(InMedia.ShortName);
  1930. }
  1931. return true;
  1932. }
  1933. bool FWwiseResourceCookerImpl::FillExternalSourceBaseInfo(FWwiseExternalSourceCookedData& OutExternalSourceCookedData, const FWwiseMetadataExternalSource& InExternalSource) const
  1934. {
  1935. OutExternalSourceCookedData.Cookie = InExternalSource.Cookie;
  1936. if (ExportDebugNameRule == EWwiseExportDebugNameRule::Release)
  1937. {
  1938. OutExternalSourceCookedData.DebugName = FName();
  1939. }
  1940. else
  1941. {
  1942. OutExternalSourceCookedData.DebugName = FName((ExportDebugNameRule == EWwiseExportDebugNameRule::Name) ? InExternalSource.Name : InExternalSource.ObjectPath);
  1943. }
  1944. return true;
  1945. }
  1946. bool FWwiseResourceCookerImpl::AddRequirementsForMedia(TSet<FWwiseSoundBankCookedData>& OutSoundBankSet, TSet<FWwiseMediaCookedData>& OutMediaSet,
  1947. const FWwiseRefMedia& InMediaRef, const FWwiseSharedLanguageId& InLanguage,
  1948. const FWwisePlatformDataStructure& InPlatformData) const
  1949. {
  1950. const auto* Media = InMediaRef.GetMedia();
  1951. if (UNLIKELY(!Media))
  1952. {
  1953. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia: Could not get Media from Media Ref"));
  1954. return false;
  1955. }
  1956. const auto* PlatformInfo = InPlatformData.PlatformRef.GetPlatformInfo();
  1957. if (UNLIKELY(!PlatformInfo)) return false;
  1958. if (Media->Location == EWwiseMetadataMediaLocation::Memory && !Media->bStreaming)
  1959. {
  1960. // In-Memory media is already loaded with current SoundBank
  1961. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Media is in memory and not streaming. Skipping."),
  1962. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  1963. }
  1964. else if (Media->Location == EWwiseMetadataMediaLocation::OtherBank)
  1965. {
  1966. // Media resides in another SoundBank. Find that other SoundBank and add it as a requirement.
  1967. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Media is in another SoundBank. Locate SoundBank and add requirement."),
  1968. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  1969. FWwiseObjectInfo MediaInfo;
  1970. MediaInfo.WwiseShortId = Media->Id;
  1971. MediaInfo.WwiseName = Media->ShortName;
  1972. FWwiseRefMedia OtherSoundBankMediaRef;
  1973. if (UNLIKELY(!InPlatformData.GetRef(OtherSoundBankMediaRef, InLanguage, MediaInfo)))
  1974. {
  1975. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Could not get Ref for other SoundBank media %s %" PRIu32 " %s"),
  1976. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId(),
  1977. *MediaInfo.WwiseGuid.ToString(), MediaInfo.WwiseShortId, *MediaInfo.WwiseName.ToString());
  1978. return false;
  1979. }
  1980. const auto* SoundBank = OtherSoundBankMediaRef.GetSoundBank();
  1981. if (UNLIKELY(!SoundBank))
  1982. {
  1983. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Could not get SoundBank from Media in another SoundBank Ref"),
  1984. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  1985. return false;
  1986. }
  1987. if (SoundBank->IsInitBank())
  1988. {
  1989. // We assume Init SoundBanks are fully loaded
  1990. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Media is in Init SoundBank. Skipping."),
  1991. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  1992. }
  1993. FWwiseSoundBankCookedData MediaSoundBank;
  1994. if (UNLIKELY(!FillSoundBankBaseInfo(MediaSoundBank, *PlatformInfo, *SoundBank)))
  1995. {
  1996. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Could not fill SoundBank from Media in another SoundBank Data"),
  1997. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  1998. return false;
  1999. }
  2000. OutSoundBankSet.Add(MoveTemp(MediaSoundBank));
  2001. }
  2002. else
  2003. {
  2004. // Media has a required loose file.
  2005. UE_LOG(LogWwiseResourceCooker, VeryVerbose, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Adding loose media requirement."),
  2006. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  2007. const auto* SoundBank = InMediaRef.GetSoundBank();
  2008. if (UNLIKELY(!SoundBank))
  2009. {
  2010. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Could not get SoundBank from Media"),
  2011. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  2012. return false;
  2013. }
  2014. FWwiseMediaCookedData MediaCookedData;
  2015. if (UNLIKELY(!FillMediaBaseInfo(MediaCookedData, *PlatformInfo, *SoundBank, *Media)))
  2016. {
  2017. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForMedia (%s %" PRIu32 " in %s %" PRIu32 "): Could not fill Media from Media Ref"),
  2018. *Media->ShortName.ToString(), Media->Id, *InLanguage.GetLanguageName().ToString(), InLanguage.GetLanguageId());
  2019. return false;
  2020. }
  2021. OutMediaSet.Add(MoveTemp(MediaCookedData));
  2022. }
  2023. return true;
  2024. }
  2025. bool FWwiseResourceCookerImpl::AddRequirementsForExternalSource(TSet<FWwiseExternalSourceCookedData>& OutExternalSourceSet, const FWwiseRefExternalSource& InExternalSourceRef) const
  2026. {
  2027. const auto* ExternalSource = InExternalSourceRef.GetExternalSource();
  2028. if (UNLIKELY(!ExternalSource))
  2029. {
  2030. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForExternalSource: Could not get External Source from External Source Ref"));
  2031. return false;
  2032. }
  2033. FWwiseExternalSourceCookedData ExternalSourceCookedData;
  2034. if (UNLIKELY(!FillExternalSourceBaseInfo(ExternalSourceCookedData, *ExternalSource)))
  2035. {
  2036. UE_LOG(LogWwiseResourceCooker, Warning, TEXT("AddRequirementsForExternalSource (%s %" PRIu32 "): Could not fill External Source from External Source Ref"),
  2037. *ExternalSource->Name.ToString(), ExternalSource->Cookie);
  2038. return false;
  2039. }
  2040. OutExternalSourceSet.Add(MoveTemp(ExternalSourceCookedData));
  2041. return true;
  2042. }