WwiseResourceCookerImpl.cpp 88 KB

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