1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318 |
- /*******************************************************************************
- The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
- Technology released in source code form as part of the game integration package.
- The content of this file may not be used without valid licenses to the
- AUDIOKINETIC Wwise Technology.
- Note that the use of the game engine is subject to the Unreal(R) Engine End User
- License Agreement at https://www.unrealengine.com/en-US/eula/unreal
-
- License Usage
-
- Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
- this file in accordance with the end user license agreement provided with the
- software or, alternatively, in accordance with the terms contained
- in a written agreement between you and Audiokinetic Inc.
- Copyright (c) 2023 Audiokinetic Inc.
- *******************************************************************************/
- /*=============================================================================
- AkAudioDevice.cpp: Audiokinetic Audio interface object.
- =============================================================================*/
- #define AK_ENABLE_ROOMS
- #define AK_ENABLE_PORTALS
- #include "AkAudioDevice.h"
- #include "AkAcousticPortal.h"
- #include "AkAudioEvent.h"
- #include "AkAudioModule.h"
- #include "Wwise/WwiseFileHandlerModule.h"
- #include "Wwise/WwiseIOHook.h"
- #include "Wwise/WwiseResourceLoader.h"
- #include "Wwise/WwiseResourceLoaderImpl.h"
- #include "Wwise/API/WAAPI.h"
- #include "Wwise/API/WwiseMonitorAPI.h"
- #include "Wwise/API/WwiseSoundEngineAPI.h"
- #include "Wwise/API/WwiseSpatialAudioAPI.h"
- #include "Wwise/API/WwiseStreamMgrAPI.h"
- #include "Wwise/Stats/Global.h"
- #include "WwiseInitBankLoader/WwiseInitBankLoader.h"
- #include "AkCallbackInfoPool.h"
- #include "AkComponent.h"
- #include "AkComponentCallbackManager.h"
- #include "AkComponentHelpers.h"
- #include "AkGameObject.h"
- #include "AkLateReverbComponent.h"
- #include "AkRoomComponent.h"
- #include "AkRtpc.h"
- #include "AkSettings.h"
- #include "AkSpotReflector.h"
- #include "AkStateValue.h"
- #include "AkSwitchValue.h"
- #include "AkTrigger.h"
- #include "WwiseUnrealDefines.h"
- #include "AkWaapiClient.h"
- #include "AkWaapiUtils.h"
- #include "EngineUtils.h"
- #include "Async/Async.h"
- #include "Async/TaskGraphInterfaces.h"
- #include "Camera/PlayerCameraManager.h"
- #include "Components/BrushComponent.h"
- #include "Engine/GameEngine.h"
- #include "GameFramework/PlayerController.h"
- #include "GameFramework/WorldSettings.h"
- #include "InitializationSettings/AkInitializationSettings.h"
- #include "Internationalization/Culture.h"
- #include "Internationalization/Internationalization.h"
- #include "Misc/App.h"
- #include "Misc/ScopeLock.h"
- #include "Runtime/Launch/Resources/Version.h"
- #include "UObject/Object.h"
- #include "UObject/UObjectGlobals.h"
- #include "UObject/UObjectIterator.h"
- #include "Wwise/WwiseExternalSourceManager.h"
- #if WITH_EDITOR
- #include "Editor.h"
- #include "EditorSupportDelegates.h"
- #include "LevelEditor.h"
- #include "SEditorViewport.h"
- #include "UnrealEdMisc.h"
- #ifndef AK_OPTIMIZED
- #include "AkSettingsPerUser.h"
- #endif
- #endif
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- #include "Wwise/WwiseProjectDatabase.h"
- #endif
- #include <inttypes.h>
- /*------------------------------------------------------------------------------------
- Statics and Globals
- ------------------------------------------------------------------------------------*/
- bool FAkAudioDevice::m_bSoundEngineInitialized = false;
- bool FAkAudioDevice::m_EngineExiting = false;
- TMap<uint32, TArray<uint32>> FAkAudioDevice::EventToPlayingIDMap;
- TMap<uint32, EAkAudioContext> FAkAudioDevice::PlayingIDToAudioContextMap;
- TMap<uint32, FOnSwitchValueLoaded> FAkAudioDevice::OnSwitchValueLoadedMap;
- TArray<TWeakObjectPtr<UAkAudioType>> FAkAudioDevice::AudioObjectsToLoadAfterInitialization;
- FCriticalSection FAkAudioDevice::EventToPlayingIDMapCriticalSection;
- /*------------------------------------------------------------------------------------
- Defines
- ------------------------------------------------------------------------------------*/
- static constexpr auto InvariantLCID = 0x7F;
- /*------------------------------------------------------------------------------------
- Helpers
- ------------------------------------------------------------------------------------*/
- namespace FAkAudioDevice_Helpers
- {
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- static TMap<AkGameObjectID, FName> ComponentNameMap;
- #endif
- AKRESULT RegisterGameObject(AkGameObjectID in_gameObjId, const FString& Name)
- {
- AKRESULT Result;
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- #ifdef AK_OPTIMIZED
- Result = SoundEngine->RegisterGameObj(in_gameObjId);
- #else
- if (Name.Len() > 0)
- {
- Result = SoundEngine->RegisterGameObj(in_gameObjId, TCHAR_TO_ANSI(*Name));
- }
- else
- {
- Result = SoundEngine->RegisterGameObj(in_gameObjId);
- }
- #endif
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- if (Result == AK_Success)
- {
- ComponentNameMap.Add(in_gameObjId, FName(Name));
- }
- #endif
- UE_CLOG(LIKELY(Result == AK_Success), LogAkAudio, VeryVerbose, TEXT("Registered Object ID %" PRIu64 " (%s)"), in_gameObjId, *Name);
- UE_CLOG(UNLIKELY(Result != AK_Success), LogAkAudio, Warning, TEXT("Error registering Object ID %" PRIu64 " (%s): (%" PRIu32 ") %s"), in_gameObjId, *Name, Result, WwiseUnrealHelper::GetResultString(Result));
- return Result;
- }
- typedef TMap<AkGlobalCallbackLocation, FAkAudioDeviceDelegates::FOnAkGlobalCallback> FDelegateLocationMap;
- FDelegateLocationMap DelegateLocationMap;
- void GlobalCallback(AK::IAkGlobalPluginContext* Context, AkGlobalCallbackLocation Location, void* Cookie)
- {
- const FAkAudioDeviceDelegates::FOnAkGlobalCallback* Delegate = DelegateLocationMap.Find(Location);
- if (Delegate && Delegate->IsBound())
- {
- Delegate->Broadcast(Context, Location);
- }
- }
- void UnregisterGlobalCallbackDelegate(FAkAudioDeviceDelegates::FOnAkGlobalCallback* Delegate, FDelegateHandle Handle, AkGlobalCallbackLocation Location)
- {
- if (!Delegate)
- return;
- Delegate->Remove(Handle);
- if (Delegate->IsBound())
- return;
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->UnregisterGlobalCallback(GlobalCallback, Location);
- }
- void UnregisterAllGlobalCallbacks()
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- for (auto DelegateLocationPair : FAkAudioDevice_Helpers::DelegateLocationMap)
- {
- auto Location = DelegateLocationPair.Key;
- SoundEngine->UnregisterGlobalCallback(GlobalCallback, Location);
- }
- }
- FAkAudioDevice_Helpers::DelegateLocationMap.Empty();
- }
- }
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- static bool GetInfoErrorMessageTranslatorFunction(IWwiseSoundEngineAPI::TagInformationBridge::Type* in_pTagList, AkUInt32 in_uCount, AkUInt32& out_uTranslated)
- {
- FString Name;
- FWwiseDataStructureScopeLock DB(*FWwiseProjectDatabase::Get());
- for (AkUInt32 i = 0; i < in_uCount && out_uTranslated != in_uCount; i++)
- {
- auto& Tag = in_pTagList[i];
- if (Tag.m_infoIsParsed)
- continue;
- const AkUInt32 ID = FPlatformMemory::ReadUnaligned<AkUInt32>((AkUInt8*)Tag.m_args);
- const auto AssetInfo = FWwiseObjectInfo(ID);
- switch (*Tag.m_pTag)
- {
- case 'b': //Bank ID
- {
- const auto RefBank = DB.GetSoundBank(AssetInfo);
- if (LIKELY(RefBank.IsValid()))
- {
- Name = RefBank.SoundBankShortName().ToString();
- }
- break;
- }
- case 'g': //The only tag in 64 bits
- {
- const AkUInt64 GoId = FPlatformMemory::ReadUnaligned<AkUInt64>((AkUInt8*)Tag.m_args);
- const auto* NamePtr = FAkAudioDevice_Helpers::ComponentNameMap.Find(GoId);
- if (LIKELY(NamePtr))
- {
- Name = NamePtr->ToString();
- }
- break;
- }
- case 'm': //Media ID
- {
- const auto RefMedia = DB.GetMediaFile(AssetInfo);
- if (LIKELY(RefMedia.IsValid()))
- {
- Name = RefMedia.MediaShortName().ToString();
- }
- break;
- }
- case 'p': //Plugin
- {
- const auto RefPlugin = DB.GetCustomPlugin(AssetInfo);
- if (LIKELY(RefPlugin.IsValid()))
- {
- Name = RefPlugin.CustomPluginName().ToString();
- }
- break;
- }
- case 's': //SwitchStates ID
- {
- const auto RefSwitchGroup = DB.GetSwitchGroup(AssetInfo);
- if (RefSwitchGroup.IsValid())
- {
- Name = RefSwitchGroup.SwitchGroupName().ToString();
- break;
- }
- const auto RefStateGroup = DB.GetStateGroup(AssetInfo);
- if (RefStateGroup.IsValid())
- {
- Name = RefStateGroup.StateGroupName().ToString();
- }
- break;
- }
- case 'w': //WwiseObject ID
- {
- //$w is generic, it can mean a lot of unrelated types.
- const TCHAR* FoundType = TEXT("");
- FString FoundName;
- const auto EventInfo = FWwiseEventInfo(ID);
- const auto RefEvents = DB.GetEvent(EventInfo);
- if (RefEvents.Num() > 0)
- {
- FoundType = TEXT("Event");
- FoundName = RefEvents.Array()[0].EventName().ToString();
- }
- const auto RefGameParameter = DB.GetGameParameter(AssetInfo);
- if (RefGameParameter.IsValid())
- {
- const auto NewName = RefGameParameter.GameParameterName().ToString();
- if (UNLIKELY(!FoundName.IsEmpty() && NewName != FoundName))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Found two different names for the same object ID %" PRIu32 ": %s %s and GameParameter %s. Ignoring."), FoundType, *FoundName, *NewName);
- continue;
- }
- FoundType = TEXT("GameParameter");
- FoundName = NewName;
- }
-
- const auto RefShareSet = DB.GetPluginShareSet(AssetInfo);
- if (RefShareSet.IsValid())
- {
- const auto NewName = RefShareSet.PluginShareSetName().ToString();
- if (UNLIKELY(!FoundName.IsEmpty() && NewName != FoundName))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Found two different names for the same object ID %" PRIu32 ": %s %s and ShareSet %s. Ignoring."), FoundType, *FoundName, *NewName);
- continue;
- }
- FoundType = TEXT("ShareSet");
- FoundName = NewName;
- }
-
- const auto RefBus = DB.GetBus(AssetInfo);
- if (RefBus.IsValid())
- {
- const auto NewName = RefBus.BusName().ToString();
- if (UNLIKELY(!FoundName.IsEmpty() && NewName != FoundName))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Found two different names for the same object ID %" PRIu32 ": %s %s and Bus %s. Ignoring."), FoundType, *FoundName, *NewName);
- continue;
- }
- FoundType = TEXT("Bus");
- FoundName = NewName;
- }
- const auto RefAuxBus = DB.GetAuxBus(AssetInfo);
- if (RefAuxBus.IsValid())
- {
- const auto NewName = RefAuxBus.AuxBusName().ToString();
- if (UNLIKELY(!FoundName.IsEmpty() && NewName != FoundName))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Found two different names for the same object ID %" PRIu32 ": %s %s and AuxBus %s. Ignoring."), FoundType, *FoundName, *NewName);
- continue;
- }
- FoundType = TEXT("AuxBus");
- FoundName = NewName;
- }
- // Can be other things, such as Sound.
- if (!FoundName.IsEmpty())
- {
- Name = FoundName;
- break;
- }
- else
- {
- continue;
- }
- }
- default:
- continue; //Not supported, ignore.
- }
- if (!Name.IsEmpty())
- {
- AKPLATFORM::SafeStrCpy(Tag.m_parsedInfo, TCHAR_TO_AK(*Name), AK_TRANSLATOR_MAX_NAME_SIZE);
- Tag.m_len = Name.Len();
- Tag.m_infoIsParsed = true;
- out_uTranslated++;
- }
- }
- return out_uTranslated == in_uCount;
- }
- #endif
- /*------------------------------------------------------------------------------------
- Implementation
- ------------------------------------------------------------------------------------*/
- FDelegateHandle FAkAudioDevice::RegisterGlobalCallback(FAkAudioDeviceDelegates::FOnAkGlobalCallback::FDelegate Callback, AkGlobalCallbackLocation Location)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return {};
- auto& Delegate = FAkAudioDevice_Helpers::DelegateLocationMap.FindOrAdd(Location);
- FDelegateHandle Handle = Delegate.Add(Callback);
- auto result = SoundEngine->RegisterGlobalCallback(FAkAudioDevice_Helpers::GlobalCallback, Location);
- if (result != AK_Success)
- {
- FAkAudioDevice_Helpers::UnregisterGlobalCallbackDelegate(&Delegate, Handle, Location);
- Handle.Reset();
- }
- return Handle;
- }
- void FAkAudioDevice::UnregisterGlobalCallback(FDelegateHandle Handle, AkGlobalCallbackLocation Location)
- {
- const auto& Delegate = FAkAudioDevice_Helpers::DelegateLocationMap.Find(Location);
- FAkAudioDevice_Helpers::UnregisterGlobalCallbackDelegate(Delegate, Handle, Location);
- }
- AKRESULT FAkAudioDevice::RegisterOutputDeviceMeteringCallback(AkOutputDeviceID OutputID,
- AkOutputDeviceMeteringCallbackFunc Callback,
- AkMeteringFlags MeteringFlags,
- void* Cookie)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->RegisterOutputDeviceMeteringCallback(OutputID, Callback, MeteringFlags, Cookie);
- }
- AKRESULT FAkAudioDevice::UnregisterOutputDeviceMeteringCallback(AkOutputDeviceID OutputID)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->RegisterOutputDeviceMeteringCallback(OutputID, nullptr, AK_NoMetering, nullptr);
- }
- #if WITH_EDITORONLY_DATA
- UAkComponent* FAkAudioDevice::CreateListener(UWorld* World, FEditorViewportClient* ViewportClient)
- {
- if (!IsRunningGame())
- {
- FString ComponentName = TEXT("AkListener_") + World->GetName();
- if (ViewportClient)
- {
- ComponentName = TEXT("AkListener_") + FString::FromInt(ViewportClient->ViewIndex) + World->GetName();
- }
- UAkComponent* Listener = NewObject<UAkComponent>(World->GetWorldSettings(), FName(*ComponentName), RF_Transient);
- if (Listener != nullptr)
- {
- Listener->MarkAsEditorOnlySubobject();
- Listener->RegisterComponentWithWorld(World);
- AddDefaultListener(Listener);
- }
- return Listener;
- }
- else
- {
- return nullptr;
- }
- }
- FTransform FAkAudioDevice::GetEditorListenerPosition(int32 ViewIndex) const
- {
- if (ViewIndex < ListenerTransforms.Num())
- {
- return ListenerTransforms[ViewIndex];
- }
- return FTransform();
- }
- #endif
- bool FAkAudioDevice::ShouldNotifySoundEngine(EWorldType::Type WorldType) { return WorldType == EWorldType::PIE || WorldType == EWorldType::Game; }
- void FAkAudioDevice::LoadAudioObjectsAfterInitialization(TWeakObjectPtr<UAkAudioType>&& InAudioType)
- {
- AudioObjectsToLoadAfterInitialization.Add(InAudioType);
- }
- void FAkAudioDevice::LoadDelayedObjects()
- {
- if (AudioObjectsToLoadAfterInitialization.Num() > 0)
- {
- SCOPED_AKAUDIO_EVENT_F_3(TEXT("LoadDelayedObjects: Loading %d Object%s"), (int)AudioObjectsToLoadAfterInitialization.Num(), AudioObjectsToLoadAfterInitialization.Num() > 1 ? TEXT("s") : TEXT(""));
- UE_LOG(LogAkAudio, Log, TEXT("FAkAudioDevice::LoadDelayedObjects: Loading %d delayed Wwise Object%s after initialization."), AudioObjectsToLoadAfterInitialization.Num(), AudioObjectsToLoadAfterInitialization.Num() > 1 ? TEXT("s") : TEXT(""));
- for (auto& WeakAudioType : AudioObjectsToLoadAfterInitialization)
- {
- auto* AudioType = WeakAudioType.Get();
- if (LIKELY(AudioType))
- {
- AudioType->LoadData();
- }
- }
- AudioObjectsToLoadAfterInitialization.Empty();
- }
- }
- namespace FAkAudioDevice_WaapiHelper
- {
- void Subscribe(FAkWaapiClient* waapiClient, uint64& subscriptionId, const char* uri, const TSharedRef<FJsonObject>& options, WampEventCallback callback)
- {
- if (subscriptionId == 0)
- {
- TSharedPtr<FJsonObject> result;
- waapiClient->Subscribe(uri, options, callback, subscriptionId, result);
- }
- }
- void RemoveCallback(FAkWaapiClient* waapiClient, uint64& subscriptionId)
- {
- if (subscriptionId > 0)
- {
- waapiClient->RemoveWampEventCallback(subscriptionId);
- subscriptionId = 0;
- }
- }
- void Unsubscribe(FAkWaapiClient* waapiClient, uint64& subscriptionId)
- {
- if (subscriptionId > 0)
- {
- TSharedPtr<FJsonObject> result;
- waapiClient->Unsubscribe(subscriptionId, result);
- RemoveCallback(waapiClient, subscriptionId);
- }
- }
- }
- /**
- * Initializes the audio device and creates sources.
- *
- * @return true if initialization was successful, false otherwise
- */
- bool FAkAudioDevice::Init()
- {
- SCOPED_AKAUDIO_EVENT_2(TEXT("FAkAudioDevice::Init"));
- #if UE_SERVER
- return false;
- #endif
- if (!EnsureInitialized()) // ensure audiolib is initialized
- {
- UE_LOG(LogAkAudio, Log, TEXT("Audiokinetic Audio Device initialization failed."));
- return false;
- }
- #if !WITH_EDITOR
- if (auto* akSettings = GetDefault<UAkSettings>())
- {
- for (auto& entry : akSettings->UnrealCultureToWwiseCulture)
- {
- auto culturePtr = FInternationalization::Get().GetCulture(entry.Key);
- if (culturePtr && culturePtr->GetLCID() != InvariantLCID)
- {
- CachedUnrealToWwiseCulture.Add(culturePtr, entry.Value);
- }
- }
- }
- #endif
- #if AK_SUPPORT_WAAPI
- if (auto waapiClient = FAkWaapiClient::Get())
- {
- ProjectLoadedHandle = waapiClient->OnProjectLoaded.AddLambda([this, waapiClient]
- {
- if (!waapiClient->IsConnected())
- return;
- TSharedRef<FJsonObject> options = MakeShareable(new FJsonObject());
- options->SetArrayField(WwiseWaapiHelper::RETURN, TArray<TSharedPtr<FJsonValue>> { MakeShareable(new FJsonValueString(WwiseWaapiHelper::PARENT)) });
- auto wampEventCallback = WampEventCallback::CreateLambda([this](uint64_t id, TSharedPtr<FJsonObject> in_UEJsonObject)
- {
- AsyncTask(ENamedThreads::GameThread, [this]
- {
- #if WITH_EDITOR
- FEditorSupportDelegates::RedrawAllViewports.Broadcast();
- #endif
- OnWwiseProjectModification.Broadcast();
- });
- });
- FAkAudioDevice_WaapiHelper::Subscribe(waapiClient, WaapiSubscriptionIds.Renamed, ak::wwise::core::object::nameChanged, options, wampEventCallback);
- FAkAudioDevice_WaapiHelper::Subscribe(waapiClient, WaapiSubscriptionIds.PreDeleted, ak::wwise::core::object::preDeleted, options, wampEventCallback);
- FAkAudioDevice_WaapiHelper::Subscribe(waapiClient, WaapiSubscriptionIds.ChildRemoved, ak::wwise::core::object::childRemoved, options, wampEventCallback);
- FAkAudioDevice_WaapiHelper::Subscribe(waapiClient, WaapiSubscriptionIds.ChildAdded, ak::wwise::core::object::childAdded, options, wampEventCallback);
- FAkAudioDevice_WaapiHelper::Subscribe(waapiClient, WaapiSubscriptionIds.Created, ak::wwise::core::object::created, options, wampEventCallback);
- });
- ConnectionLostHandle = waapiClient->OnConnectionLost.AddLambda([this, waapiClient]
- {
- if (!waapiClient->IsConnected())
- return;
- FAkAudioDevice_WaapiHelper::RemoveCallback(waapiClient, WaapiSubscriptionIds.Renamed);
- FAkAudioDevice_WaapiHelper::RemoveCallback(waapiClient, WaapiSubscriptionIds.PreDeleted);
- FAkAudioDevice_WaapiHelper::RemoveCallback(waapiClient, WaapiSubscriptionIds.ChildRemoved);
- FAkAudioDevice_WaapiHelper::RemoveCallback(waapiClient, WaapiSubscriptionIds.ChildAdded);
- FAkAudioDevice_WaapiHelper::RemoveCallback(waapiClient, WaapiSubscriptionIds.Created);
- });
- ClientBeginDestroyHandle = waapiClient->OnClientBeginDestroy.AddLambda([this, waapiClient]
- {
- if (ProjectLoadedHandle.IsValid())
- {
- waapiClient->OnProjectLoaded.Remove(ProjectLoadedHandle);
- ProjectLoadedHandle.Reset();
- }
- if (ConnectionLostHandle.IsValid())
- {
- waapiClient->OnConnectionLost.Remove(ConnectionLostHandle);
- ConnectionLostHandle.Reset();
- }
- });
- }
- #endif // AK_SUPPORT_WAAPI
- FWorldDelegates::OnPreWorldInitialization.AddLambda(
- [&](UWorld* World, const UWorld::InitializationValues IVS)
- {
- WorldVolumesUpdatedMap.Add(World, false);
- }
- );
- FWorldDelegates::OnPostWorldInitialization.AddLambda(
- [&](UWorld* World, const UWorld::InitializationValues IVS)
- {
- World->AddOnActorSpawnedHandler(FOnActorSpawned::FDelegate::CreateRaw(this, &FAkAudioDevice::OnActorSpawned));
- }
- );
-
- FWorldDelegates::OnWorldCleanup.AddLambda(
- [this](UWorld* World, bool bSessionEnded, bool bCleanupResources)
- {
- CleanupComponentMapsForWorld(World);
- if (WorldVolumesUpdatedMap.Contains(World))
- WorldVolumesUpdatedMap.Remove(World);
- }
- );
- FWorldDelegates::OnWorldPostActorTick.AddLambda(
- [&](UWorld* World, ELevelTick TickType, float DeltaSeconds)
- {
- if (WorldVolumesUpdatedMap.Contains(World))
- WorldVolumesUpdatedMap[World] = false;
- else
- WorldVolumesUpdatedMap.Add(World, false);
- }
- );
- m_SpatialAudioListener = nullptr;
- #if WITH_EDITORONLY_DATA
- if (!IsRunningGame())
- {
- static const FName kLevelEditorModuleName = TEXT("LevelEditor");
- auto MapChangedHandler = [this](UWorld* World, EMapChangeType MapChangeType)
- {
- if (World && World->AllowAudioPlayback() && World->WorldType == EWorldType::Editor)
- {
- if (MapChangeType == EMapChangeType::TearDownWorld)
- {
- if (EditorListener && World == EditorListener->GetWorld())
- {
- EditorListener->DestroyComponent();
- EditorListener = nullptr;
- }
- }
- else if (EditorListener == nullptr && MapChangeType != EMapChangeType::SaveMap)
- {
- EditorListener = CreateListener(World);
- // The Editor Listener should NEVER be the spatial audio listener
- if (m_SpatialAudioListener == EditorListener)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (LIKELY(SpatialAudio))
- {
- SpatialAudio->UnregisterListener(m_SpatialAudioListener->GetAkGameObjectID());
- }
- m_SpatialAudioListener = nullptr;
- }
- }
- }
- };
- auto LevelEditorModulePtr = FModuleManager::Get().GetModulePtr<FLevelEditorModule>(kLevelEditorModuleName);
- if (LevelEditorModulePtr)
- {
- LevelEditorModulePtr->OnMapChanged().AddLambda(MapChangedHandler);
- }
- else
- {
- FModuleManager::Get().OnModulesChanged().AddLambda([this, MapChangedHandler](FName InModuleName, EModuleChangeReason Reason)
- {
- if (InModuleName == kLevelEditorModuleName && Reason == EModuleChangeReason::ModuleLoaded)
- {
- auto& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>(kLevelEditorModuleName);
- LevelEditorModule.OnMapChanged().AddLambda(MapChangedHandler);
- }
- });
- }
- FWorldDelegates::OnPostWorldInitialization.AddLambda(
- [this](UWorld* World, const UWorld::InitializationValues IVS)
- {
- if (World && World->AllowAudioPlayback() && World->WorldType == EWorldType::Editor && EditorListener == nullptr)
- {
- EditorListener = CreateListener(World);
- // The Editor Listener should NEVER be the spatial audio listener
- if (m_SpatialAudioListener == EditorListener)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (LIKELY(SpatialAudio))
- {
- SpatialAudio->UnregisterListener(m_SpatialAudioListener->GetAkGameObjectID());
- }
- m_SpatialAudioListener = nullptr;
- }
- }
- }
- );
- FWorldDelegates::OnWorldTickStart.AddLambda(
- [&](UWorld* World, ELevelTick LevelTick, float Tick)
- {
- if(World->WorldType != EWorldType::EditorPreview)
- {
- return;
- }
- auto& ViewportClients = GEditor->GetAllViewportClients();
- for(auto ViewportClient : ViewportClients)
- {
- if(ViewportClient->GetWorld() == World && ViewportClient->IsFocused(ViewportClient->Viewport))
- {
- auto Quat = ViewportClient->GetViewRotation().Quaternion();
- AkSoundPosition SoundPos;
- FVectorsToAKWorldTransform(
- ViewportClient->GetViewLocation(),
- Quat.GetForwardVector(),
- Quat.GetUpVector(),
- SoundPos
- );
- SetPosition(EditorListener, SoundPos);
- }
- }
- }
- );
- FEditorDelegates::OnEditorCameraMoved.AddLambda(
- [&](const FVector& Location, const FRotator& Rotation, ELevelViewportType ViewportType, int32 ViewIndex)
- {
- auto& allViewportClient = GEditor->GetAllViewportClients();
- if (allViewportClient[ViewIndex]->Viewport && allViewportClient[ViewIndex]->Viewport->HasFocus())
- {
- if (ListenerTransforms.Num() <= ViewIndex)
- {
- ListenerTransforms.AddDefaulted(ViewIndex - ListenerTransforms.Num() + 1);
- }
- ListenerTransforms[ViewIndex].SetLocation(Location);
- ListenerTransforms[ViewIndex].SetRotation(Rotation.Quaternion());
- UWorld * ViewportWorld = allViewportClient[ViewIndex]->GetWorld();
- if (ViewportWorld && ViewportWorld->WorldType != EWorldType::PIE)
- {
- auto Quat = Rotation.Quaternion();
- AkSoundPosition SoundPos;
- FVectorsToAKWorldTransform(
- Location,
- Quat.GetForwardVector(),
- Quat.GetUpVector(),
- SoundPos
- );
- SetPosition(EditorListener, SoundPos);
- }
- }
- }
- );
- FEditorDelegates::BeginPIE.AddRaw(this, &FAkAudioDevice::BeginPIE);
- FEditorDelegates::EndPIE.AddRaw(this, &FAkAudioDevice::EndPIE);
- FEditorDelegates::PausePIE.AddRaw(this, &FAkAudioDevice::PausePIE);
- FEditorDelegates::ResumePIE.AddRaw(this, &FAkAudioDevice::ResumePie);
- FEditorDelegates::OnSwitchBeginPIEAndSIE.AddRaw(this, &FAkAudioDevice::OnSwitchBeginPIEAndSIE);
- }
- #endif
- UE_LOG(LogAkAudio, Log, TEXT("Audiokinetic Audio Device initialized."));
- return 1;
- }
- #if WITH_EDITORONLY_DATA
- void FAkAudioDevice::BeginPIE(const bool bIsSimulating)
- {
- if (!bIsSimulating && EditorListener != nullptr)
- {
- RemoveDefaultListener(EditorListener);
- }
- else if (EditorListener == nullptr)
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Undefined Behavior: EditorListener was set to null on BeginPIE."));
- }
- }
- void FAkAudioDevice::PausePIE(const bool bIsSimulating)
- {
- for (auto& Event: EventToPlayingIDMap)
- {
- for (auto PlayingID: Event.Value)
- {
- EAkAudioContext* Context = PlayingIDToAudioContextMap.Find(PlayingID);
- if (Context)
- {
- if (*Context == EAkAudioContext::GameplayAudio)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- SoundEngine->ExecuteActionOnPlayingID(AK::SoundEngine::AkActionOnEventType_Pause, PlayingID);
- }
- }
- }
- }
- }
- }
- void FAkAudioDevice::ResumePie(const bool bIsSimulating)
- {
- for (auto& Event: EventToPlayingIDMap)
- {
- for (auto PlayingID: Event.Value)
- {
- EAkAudioContext* Context = PlayingIDToAudioContextMap.Find(PlayingID);
- if (Context)
- {
- if (*Context == EAkAudioContext::GameplayAudio)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- SoundEngine->ExecuteActionOnPlayingID(AK::SoundEngine::AkActionOnEventType_Resume, PlayingID);
- }
- }
- }
- }
- }
- }
- void FAkAudioDevice::OnSwitchBeginPIEAndSIE(const bool bIsSimulating)
- {
- if(EditorListener != nullptr)
- {
- if (bIsSimulating)
- {
- AddDefaultListener(EditorListener);
- // The Editor Listener should NEVER be the spatial audio listener
- if (m_SpatialAudioListener == EditorListener)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (LIKELY(SpatialAudio))
- {
- SpatialAudio->UnregisterListener(m_SpatialAudioListener->GetAkGameObjectID());
- }
- m_SpatialAudioListener = nullptr;
- }
- }
- else
- {
- RemoveDefaultListener(EditorListener);
- }
- }
- else
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Undefined Behavior: EditorListener was set to null on SwitchBeginPIEAndSIE."));
- }
- }
- void FAkAudioDevice::EndPIE(const bool bIsSimulating)
- {
- //Reset Unreal Global gameobject to avoid complications from removing Spatial Audio listener
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- AkGameObjectID tempID = DUMMY_GAMEOBJ;
- SoundEngine->SetListeners(DUMMY_GAMEOBJ, &tempID, 1);
- }
- if (!bIsSimulating && EditorListener != nullptr)
- {
- AddDefaultListener(EditorListener);
- // The Editor Listener should NEVER be the spatial audio listener
- if (m_SpatialAudioListener == EditorListener)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (LIKELY(SpatialAudio))
- {
- SpatialAudio->UnregisterListener(m_SpatialAudioListener->GetAkGameObjectID());
- }
- m_SpatialAudioListener = nullptr;
- }
- }
- else if(EditorListener == nullptr)
- {
- UE_LOG(LogAkAudio, Warning, TEXT("Undefined Behavior: EditorListener was set to null on EndPIE."));
- }
- StopAllSounds();
- }
- #endif
- void FAkAudioDevice::UpdateRoomsForPortals()
- {
- #ifdef AK_ENABLE_ROOMS
- if (WorldsInNeedOfPortalRoomsUpdate.Num() == 0)
- {
- return;
- }
- for (auto& World : WorldsInNeedOfPortalRoomsUpdate)
- {
- auto Portals = WorldPortalsMap.Find(World);
- if (Portals != nullptr)
- {
- for (auto Portal : *Portals)
- {
- if (Portal.IsValid())
- {
- const bool RoomsChanged = Portal->UpdateConnectedRooms();
- if (RoomsChanged)
- SetSpatialAudioPortal(Portal.Get());
- }
- }
- }
- }
- WorldsInNeedOfPortalRoomsUpdate.Empty();
- #endif
- }
- void FAkAudioDevice::CleanupComponentMapsForWorld(UWorld* World)
- {
- LateReverbIndex.Clear(World);
- RoomIndex.Clear(World);
- WorldPortalsMap.Remove(World);
- OutdoorsConnectedPortals.Remove(World);
- }
- /**
- * Update the audio device and calculates the cached inverse transform later
- * on used for spatialization.
- */
- bool FAkAudioDevice::Update( float DeltaTime )
- {
- SCOPED_AKAUDIO_EVENT_2(TEXT("FAkAudioDevice::Update"));
- if (m_bSoundEngineInitialized)
- {
- UpdateRoomsForPortals();
- // Suspend audio when not in VR focus
- if (FApp::UseVRFocus())
- {
- if (FApp::HasVRFocus())
- {
- WakeupFromSuspend();
- }
- else
- {
- Suspend(true);
- }
- }
- UpdateSetCurrentAudioCultureAsyncTasks();
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return false;
- SoundEngine->RenderAudio();
- }
- return true;
- }
- /**
- * Tears down audio device by stopping all sounds, removing all buffers,
- * destroying all sources, ... Called by both Destroy and ShutdownAfterError
- * to perform the actual tear down.
- */
- void FAkAudioDevice::Teardown()
- {
- SCOPED_AKAUDIO_EVENT_2(TEXT("FAkAudioDevice::Teardown"));
- #if AK_SUPPORT_WAAPI
- if (auto waapiClient = FAkWaapiClient::Get())
- {
- FAkAudioDevice_WaapiHelper::Unsubscribe(waapiClient, WaapiSubscriptionIds.Renamed);
- FAkAudioDevice_WaapiHelper::Unsubscribe(waapiClient, WaapiSubscriptionIds.PreDeleted);
- FAkAudioDevice_WaapiHelper::Unsubscribe(waapiClient, WaapiSubscriptionIds.ChildRemoved);
- FAkAudioDevice_WaapiHelper::Unsubscribe(waapiClient, WaapiSubscriptionIds.ChildAdded);
- FAkAudioDevice_WaapiHelper::Unsubscribe(waapiClient, WaapiSubscriptionIds.Created);
- if (ProjectLoadedHandle.IsValid())
- {
- waapiClient->OnProjectLoaded.Remove(ProjectLoadedHandle);
- ProjectLoadedHandle.Reset();
- }
- if (ConnectionLostHandle.IsValid())
- {
- waapiClient->OnConnectionLost.Remove(ConnectionLostHandle);
- ConnectionLostHandle.Reset();
- }
- if (ClientBeginDestroyHandle.IsValid())
- {
- waapiClient->OnClientBeginDestroy.Remove(ClientBeginDestroyHandle);
- ClientBeginDestroyHandle.Reset();
- }
- OnWwiseProjectModification.Clear();
- }
- #endif // AK_SUPPORT_WAAPI
- if (m_bSoundEngineInitialized)
- {
- m_EngineExiting = true;
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- SoundEngine->UnregisterGameObj(DUMMY_GAMEOBJ);
- if (SoundEngine->IsInitialized())
- {
- FAkAudioDevice_Helpers::UnregisterAllGlobalCallbacks();
- SoundEngine->StopAll();
- SoundEngine->RenderAudio();
- }
- }
- FAkSoundEngineInitialization::Finalize(IOHook);
- if (LIKELY(CallbackManager))
- {
- delete CallbackManager;
- CallbackManager = nullptr;
- }
- if (LIKELY(CallbackInfoPool))
- {
- delete CallbackInfoPool;
- CallbackInfoPool = nullptr;
- }
- if (LIKELY(IOHook))
- {
- delete IOHook;
- IOHook = nullptr;
- }
- auto* Monitor = IWwiseMonitorAPI::Get();
- if (LIKELY(Monitor))
- {
- Monitor->TerminateDefaultWAAPIErrorTranslator();
- Monitor->ResetTranslator();
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- delete m_UnrealErrorTranslator;
- m_UnrealErrorTranslator = nullptr;
- #endif
- }
- m_bSoundEngineInitialized = false;
- }
- FWorldDelegates::LevelRemovedFromWorld.RemoveAll(this);
- #if !WITH_EDITOR
- CachedUnrealToWwiseCulture.Empty();
- #endif
- UE_LOG(LogAkAudio, Log, TEXT("Audiokinetic Audio Device terminated."));
- }
- /**
- * Stops all game sounds (and possibly UI) sounds
- *
- * @param bShouldStopUISounds If true, this function will stop UI sounds as well
- */
- void FAkAudioDevice::StopAllSounds(bool bShouldStopUISounds)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- for (const auto& Event: EventToPlayingIDMap)
- {
- for (const auto& PlayingID: Event.Value)
- {
- if (EAkAudioContext* Context = PlayingIDToAudioContextMap.Find(PlayingID))
- {
- if (*Context == EAkAudioContext::GameplayAudio)
- {
- SoundEngine->StopPlayingID(PlayingID);
- }
- if (bShouldStopUISounds && *Context == EAkAudioContext::EditorAudio)
- {
- SoundEngine->StopPlayingID(PlayingID);
- }
- }
- }
- }
- }
- void FAkAudioDevice::StopAllSounds(EAkAudioContext AudioContext)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- for (const auto& Event: EventToPlayingIDMap)
- {
- for (const auto& PlayingID: Event.Value)
- {
- if (EAkAudioContext* Context = PlayingIDToAudioContextMap.Find(PlayingID))
- {
- if (*Context == AudioContext)
- {
- SoundEngine->StopPlayingID(PlayingID);
- }
- }
- }
- }
- }
- /**
- * Stop all audio associated with a scene
- *
- * @param SceneToFlush Interface of the scene to flush
- */
- void FAkAudioDevice::Flush(UWorld* WorldToFlush)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- StopAllSounds();
- }
- /**
- * Determine if any rooms or reverb volumes have been added to World during the current frame
- */
- bool FAkAudioDevice::WorldSpatialAudioVolumesUpdated(UWorld* World)
- {
- if (World == nullptr)
- return false;
- if (WorldVolumesUpdatedMap.Contains(World))
- return WorldVolumesUpdatedMap[World];
- return false;
- }
- /**
- * Clears all loaded SoundBanks and associated media
- *
- * @return Result from ak sound engine
- */
- void FAkAudioDevice::ClearSoundBanksAndMedia()
- {
- if (m_bSoundEngineInitialized)
- {
- StopAllSounds();
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- SoundEngine->RenderAudio();
- FPlatformProcess::Sleep(0.1f);
- }
- }
- for (TObjectIterator<UAkAudioType> AudioAssetIt; AudioAssetIt; ++AudioAssetIt)
- {
- AudioAssetIt->UnloadData();
- }
- }
- AKRESULT FAkAudioDevice::LoadBank(
- const FString& in_BankName,
- AkBankID& out_bankID
- )
- {
- AKRESULT eResult = AK_Fail;
- if (EnsureInitialized()) // ensure audiolib is initialized
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->LoadBank(TCHAR_TO_AK(*in_BankName), out_bankID);
- }
- if (eResult != AK_Success)
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::LoadBank: Failed to load bank %s. %s"), *in_BankName, WwiseUnrealHelper::GetResultString(eResult));
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::LoadBank(
- const FString& in_BankName,
- AkBankCallbackFunc in_pfnBankCallback,
- void * in_pCookie,
- AkBankID & out_bankID
- )
- {
- if (EnsureInitialized()) // ensure audiolib is initialized
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->LoadBank(TCHAR_TO_AK(*in_BankName), in_pfnBankCallback, in_pCookie, out_bankID);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::LoadBank(
- const FString& in_BankName,
- FWaitEndBankAction* LoadBankLatentAction
- )
- {
- if (EnsureInitialized()) // ensure audiolib is initialized
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkBankID BankId;
- return SoundEngine->LoadBank(TCHAR_TO_AK(*in_BankName), nullptr, LoadBankLatentAction, BankId);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::LoadBankAsync(
- const FString& in_BankName,
- const FOnAkBankCallback& BankLoadedCallback,
- AkBankID & out_bankID
- )
- {
- if (EnsureInitialized()) // ensure audiolib is initialized
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->LoadBank(TCHAR_TO_AK(*in_BankName), out_bankID);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::LoadBankFromMemory(
- const void* MemoryPtr,
- uint32 MemorySize,
- AkBankType BankType,
- AkBankID& OutBankID
- )
- {
- if (EnsureInitialized() && MemoryPtr && MemorySize > 0)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->LoadBankMemoryView(MemoryPtr, MemorySize, OutBankID, BankType);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::UnloadBank(
- const FString& in_BankName
- )
- {
- AKRESULT eResult = AK_Fail;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->UnloadBank(TCHAR_TO_AK(*in_BankName), nullptr );
- }
- if (eResult != AK_Success)
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::UnloadBank: Failed to unload bank %s. %s"), *in_BankName, WwiseUnrealHelper::GetResultString(eResult));
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::UnloadBank(
- const FString& in_BankName,
- AkBankCallbackFunc in_pfnBankCallback,
- void * in_pCookie
- )
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnloadBank(TCHAR_TO_AK(*in_BankName), NULL, in_pfnBankCallback, in_pCookie);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::UnloadBank(
- const FString& in_BankName,
- FWaitEndBankAction* UnloadBankLatentAction
- )
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnloadBank(TCHAR_TO_AK(*in_BankName), nullptr);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::UnloadBankFromMemory(
- AkBankID in_bankID,
- const void* in_memoryPtr
- )
- {
- if (EnsureInitialized() && in_memoryPtr)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnloadBank(in_bankID, in_memoryPtr);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::UnloadBankFromMemoryAsync(
- AkBankID in_bankID,
- const void* in_memoryPtr,
- AkBankCallbackFunc in_pfnBankCallback,
- void* in_pCookie,
- uint32 BankType
- )
- {
- if (EnsureInitialized() && in_memoryPtr)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnloadBank(in_bankID, in_memoryPtr, in_pfnBankCallback, in_pCookie, BankType);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::UnloadBankAsync(
- const FString& in_BankName,
- const FOnAkBankCallback& BankUnloadedCallback
- )
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnloadBank(TCHAR_TO_AK(*in_BankName), nullptr);
- }
- return AK_Fail;
- }
- AkUInt32 FAkAudioDevice::GetShortIDFromString(const FString& InString)
- {
- if (InString.IsEmpty())
- {
- return AK_INVALID_UNIQUE_ID;
- }
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_INVALID_UNIQUE_ID;
- return SoundEngine->GetIDFromString(TCHAR_TO_ANSI(*InString));
- }
- AkUInt32 FAkAudioDevice::GetShortID(UAkAudioType* AudioAsset, const FString& BackupName)
- {
- AkUInt32 ShortId;
- if (AudioAsset)
- {
- ShortId = AudioAsset->GetShortID();
- }
- else
- {
- ShortId = GetShortIDFromString(BackupName);
- }
- if (ShortId == AK_INVALID_UNIQUE_ID)
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetShortID : Returning invalid ShortId for Wwise Object named %s."), AudioAsset? *AudioAsset->GetName() : *BackupName);
- }
- return ShortId;
- }
- AKRESULT FAkAudioDevice::SetMedia(AkSourceSettings* in_pSourceSettings, uint32 in_uNumSourceSettings)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->SetMedia(in_pSourceSettings, in_uNumSourceSettings);
- }
- AKRESULT FAkAudioDevice::TryUnsetMedia(AkSourceSettings* in_pSourceSettings, uint32 in_uNumSourceSettings, AKRESULT* out_pUnsetResults)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->TryUnsetMedia(in_pSourceSettings, in_uNumSourceSettings, out_pUnsetResults);
- }
- AKRESULT FAkAudioDevice::UnsetMedia(AkSourceSettings* in_pSourceSettings, uint32 in_uNumSourceSettings)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->UnsetMedia(in_pSourceSettings, in_uNumSourceSettings);
- }
- FString FAkAudioDevice::GetCurrentAudioCulture() const
- {
- auto* StreamMgr = IWwiseStreamMgrAPI::Get();
- if (UNLIKELY(!StreamMgr))
- {
- return {};
- }
- return FString(StreamMgr->GetCurrentLanguage());
- }
- FString FAkAudioDevice::GetDefaultLanguage()
- {
- auto* WwiseInitBankLoader = FWwiseInitBankLoader::Get();
- if (LIKELY(WwiseInitBankLoader))
- {
- auto* InitBankAsset = WwiseInitBankLoader->GetInitBankAsset();
- if (LIKELY(InitBankAsset))
- {
- TArray<FWwiseLanguageCookedData> Languages = InitBankAsset->GetLanguages();
- for (auto& Language : Languages)
- {
- if (Language.LanguageRequirement == EWwiseLanguageRequirement::IsDefault)
- {
- return Language.LanguageName.ToString();
- }
- }
- }
- else
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetDefaultLanguage: Could not get AkInitBank asset, returning empty language."));
- }
- }
- else
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetDefaultLanguage: Could not get WwiseInitBankLoader, returning empty language."));
- }
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetDefaultLanguage: Could not find default language in available languages list."));
- return {};
- }
- TArray<FString> FAkAudioDevice::GetAvailableAudioCultures() const
- {
- auto* WwiseInitBankLoader = FWwiseInitBankLoader::Get();
- if (UNLIKELY(!WwiseInitBankLoader))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetAvailableAudioCultures: Could not get WwiseInitBankLoader, returning empty list."));
- return {};
- }
- auto* InitBankAsset = WwiseInitBankLoader->GetInitBankAsset();
- if (UNLIKELY(!InitBankAsset))
- {
- UE_LOG(LogAkAudio, Warning, TEXT("FAkAudioDevice::GetAvailableAudioCultures: Could not get AkInitBank asset, returning empty list."));
- return {};
- }
- TSet<FString> LanguageNames;
- for(const auto& Language : InitBankAsset->InitBankCookedData.Language)
- {
- LanguageNames.Add(Language.LanguageName.ToString());
- }
- return LanguageNames.Array();
- }
- FWwiseLanguageCookedData FAkAudioDevice::GetLanguageCookedDataFromString(const FString& WwiseLanguage)
- {
- auto* WwiseInitBankLoader = FWwiseInitBankLoader::Get();
- if (LIKELY(WwiseInitBankLoader))
- {
- auto* InitBankAsset = WwiseInitBankLoader->GetInitBankAsset();
- if (LIKELY(InitBankAsset))
- {
- for (auto& Language : InitBankAsset->InitBankCookedData.Language)
- {
- if (Language.LanguageName.ToString() == WwiseLanguage)
- {
- return FWwiseLanguageCookedData(Language.LanguageId, Language.LanguageName, Language.LanguageRequirement);
- }
- }
- }
- }
- return FWwiseLanguageCookedData(GetShortIDFromString(WwiseLanguage), FName(WwiseLanguage), EWwiseLanguageRequirement::IsOptional);
- }
- void FAkAudioDevice::SetCurrentAudioCulture(const FString& NewAudioCulture)
- {
- FString NewWwiseLanguage;
- if (FindWwiseLanguage(NewAudioCulture, NewWwiseLanguage))
- {
- auto* ResourceLoader = FWwiseResourceLoader::Get();
- if (UNLIKELY(!ResourceLoader))
- {
- return;
- }
- ResourceLoader->SetLanguage(GetLanguageCookedDataFromString(NewWwiseLanguage), EWwiseReloadLanguage::Immediate);
- auto* StreamMgr = IWwiseStreamMgrAPI::Get();
- if (UNLIKELY(!StreamMgr))
- {
- return;
- }
- StreamMgr->SetCurrentLanguage(TCHAR_TO_AK(*NewWwiseLanguage));
- }
- }
- void FAkAudioDevice::SetCurrentAudioCultureAsync(const FString& NewAudioCulture, FSetCurrentAudioCultureAction* LatentAction)
- {
- FString NewWwiseLanguage;
- if (FindWwiseLanguage(NewAudioCulture, NewWwiseLanguage))
- {
- SetCurrentAudioCultureAsyncTask* newTask = new SetCurrentAudioCultureAsyncTask(GetLanguageCookedDataFromString(NewWwiseLanguage), LatentAction);
- if (newTask->Start())
- {
- AudioCultureAsyncTasks.Add(newTask);
- }
- else
- {
- LatentAction->ActionDone = true;
- delete newTask;
- }
- }
- else
- {
- LatentAction->ActionDone = true;
- }
- }
- void FAkAudioDevice::SetCurrentAudioCultureAsync(const FString& NewAudioCulture, const FOnSetCurrentAudioCultureCompleted& CompletedCallback)
- {
- FString NewWwiseLanguage;
- if (FindWwiseLanguage(NewAudioCulture, NewWwiseLanguage))
- {
- SetCurrentAudioCultureAsyncTask* newTask = new SetCurrentAudioCultureAsyncTask(GetLanguageCookedDataFromString(NewWwiseLanguage), CompletedCallback);
- if (newTask->Start())
- {
- AudioCultureAsyncTasks.Add(newTask);
- }
- else
- {
- CompletedCallback.ExecuteIfBound(false);
- delete newTask;
- }
- }
- else
- {
- CompletedCallback.ExecuteIfBound(true);
- }
- }
- bool FAkAudioDevice::FindWwiseLanguage(const FString& NewAudioCulture, FString& FoundWwiseLanguage)
- {
- auto oldAudioCulture = GetCurrentAudioCulture();
- FoundWwiseLanguage = NewAudioCulture;
- auto newCulturePtr = FInternationalization::Get().GetCulture(FoundWwiseLanguage);
- if (newCulturePtr && newCulturePtr->GetLCID() != InvariantLCID)
- {
- auto& newLanguage = newCulturePtr->GetTwoLetterISOLanguageName();
- auto& newRegion = newCulturePtr->GetRegion();
- auto& newScript = newCulturePtr->GetScript();
- int maxMatch = 0;
- auto findMostCompatibleCulture = [&maxMatch, &newLanguage, &newRegion, &newScript, &FoundWwiseLanguage](const FCulturePtr& currentCulture, const FString& currentValue) {
- auto& currentLanguageName = currentCulture->GetTwoLetterISOLanguageName();
- auto& currentRegionName = currentCulture->GetRegion();
- auto& currentScript = currentCulture->GetScript();
- int currentMatch = 0;
- if (currentLanguageName == newLanguage)
- {
- currentMatch = 1;
- // This is inspired by how UE processes culture from most to least specific. For example:
- // zh - Hans - CN is processed as "zh-Hans-CN", then "zh-CN", then "zh-Hans", then "zh".
- // This is how I selected the weight for each match.
- if (!currentScript.IsEmpty() && !newScript.IsEmpty()
- && !currentRegionName.IsEmpty() && !newRegion.IsEmpty())
- {
- if (currentScript == newScript && currentRegionName == newRegion)
- {
- currentMatch += 4;
- }
- else
- {
- --currentMatch;
- }
- }
- if (!currentRegionName.IsEmpty() && !newRegion.IsEmpty())
- {
- if (currentRegionName == newRegion)
- {
- currentMatch += 3;
- }
- else
- {
- --currentMatch;
- }
- }
- if (!currentScript.IsEmpty() && !newScript.IsEmpty())
- {
- if (currentScript == newScript)
- {
- currentMatch += 2;
- }
- else
- {
- --currentMatch;
- }
- }
- }
- if (currentMatch > 0)
- {
- // When the current culture is missing script or region but the new culture
- // has it, give a weight boost of 1
- if (!newScript.IsEmpty() && currentScript.IsEmpty())
- {
- ++currentMatch;
- }
- if (!newRegion.IsEmpty() && currentRegionName.IsEmpty())
- {
- ++currentMatch;
- }
- }
- if (maxMatch < currentMatch)
- {
- FoundWwiseLanguage = currentValue;
- maxMatch = currentMatch;
- }
- };
- #if WITH_EDITOR
- if (auto* akSettings = GetDefault<UAkSettings>())
- {
- for (auto& entry : akSettings->UnrealCultureToWwiseCulture)
- {
- auto currentCulture = FInternationalization::Get().GetCulture(entry.Key);
- if (currentCulture && currentCulture->GetLCID() != InvariantLCID)
- {
- findMostCompatibleCulture(currentCulture, entry.Value);
- }
- }
- }
- #else
- for (auto& entry : CachedUnrealToWwiseCulture)
- {
- findMostCompatibleCulture(entry.Key, entry.Value);
- }
- #endif
- }
- return oldAudioCulture != FoundWwiseLanguage;
- }
- void FAkAudioDevice::UpdateSetCurrentAudioCultureAsyncTasks()
- {
- if(AudioCultureAsyncTasks.Num() == 0)
- {
- return;
- }
- for (auto task : AudioCultureAsyncTasks)
- {
- task->Update();
- }
- for (int32 i = AudioCultureAsyncTasks.Num() - 1; i >= 0; --i)
- {
- if (AudioCultureAsyncTasks[i]->IsDone)
- {
- delete AudioCultureAsyncTasks[i];
- AudioCultureAsyncTasks[i] = nullptr;
- }
- }
- AudioCultureAsyncTasks.RemoveAll([](SetCurrentAudioCultureAsyncTask* Task) { return Task == nullptr; });
- }
- template<typename FCreateCallbackPackage>
- AkPlayingID FAkAudioDevice::PostEventWithCallbackPackageOnAkGameObject(
- const AkUInt32 EventShortID,
- UAkGameObject* GameObject,
- const TArray<AkExternalSourceInfo>& ExternalSources,
- FCreateCallbackPackage CreateCallbackPackage,
- EAkAudioContext AudioContext
- )
- {
- AkPlayingID PlayingID = AK_INVALID_PLAYING_ID;
- if (m_bSoundEngineInitialized && GameObject && CallbackManager)
- {
- if (EventShortID != AK_INVALID_UNIQUE_ID && GameObject->AllowAudioPlayback())
- {
- GameObject->UpdateObstructionAndOcclusion();
- auto gameObjID = GameObject->GetAkGameObjectID();
- PlayingID = PostEventWithCallbackPackageOnGameObjectId(EventShortID, gameObjID, ExternalSources, CreateCallbackPackage, AudioContext);
- if (PlayingID != AK_INVALID_PLAYING_ID)
- {
- GameObject->EventPosted();
- }
- }
- }
- return PlayingID;
- }
- void FAkAudioDevice::SAComponentAddedRemoved(UWorld* World)
- {
- if (World != nullptr)
- {
- if (WorldVolumesUpdatedMap.Contains(World))
- WorldVolumesUpdatedMap[World] = true;
- else
- WorldVolumesUpdatedMap.Add(World, true);
- }
- }
- /** Find UAkLateReverbComponents at a given location. */
- TArray<class UAkLateReverbComponent*> FAkAudioDevice::FindLateReverbComponentsAtLocation(const FVector& Loc, const UWorld* World)
- {
- return LateReverbIndex.Query<UAkLateReverbComponent>(Loc, World);
- }
- /** Add a UAkLateReverbComponent to the linked list. */
- void FAkAudioDevice::IndexLateReverb(class UAkLateReverbComponent* ComponentToAdd)
- {
- check(!ComponentToAdd->IsIndexed);
- LateReverbIndex.Add(ComponentToAdd);
- SAComponentAddedRemoved(ComponentToAdd->GetWorld());
- ComponentToAdd->IsIndexed = true;
- }
- /** Remove a UAkLateReverbComponent from the linked list. */
- void FAkAudioDevice::UnindexLateReverb(class UAkLateReverbComponent* ComponentToRemove)
- {
- check(ComponentToRemove->IsIndexed);
- if (LateReverbIndex.Remove(ComponentToRemove))
- {
- SAComponentAddedRemoved(ComponentToRemove->GetWorld());
- }
- ComponentToRemove->IsIndexed = false;
- }
- void FAkAudioDevice::ReindexLateReverb(class UAkLateReverbComponent* ComponentToUpdate)
- {
- check(ComponentToUpdate->IsIndexed);
- LateReverbIndex.Update(ComponentToUpdate);
- SAComponentAddedRemoved(ComponentToUpdate->GetWorld());
- }
- bool FAkAudioDevice::WorldHasActiveRooms(UWorld* World)
- {
- return !RoomIndex.IsEmpty(World);
- }
- /** Find UAkRoomComponents at a given location. */
- TArray<class UAkRoomComponent*> FAkAudioDevice::FindRoomComponentsAtLocation(const FVector& Loc, const UWorld* World)
- {
- return RoomIndex.Query<UAkRoomComponent>(Loc, World);
- }
- /** Add a UAkRoomComponent to the linked list. */
- void FAkAudioDevice::IndexRoom(class UAkRoomComponent* ComponentToAdd)
- {
- RoomIndex.Add(ComponentToAdd);
- SAComponentAddedRemoved(ComponentToAdd->GetWorld());
- }
- /** Remove a UAkRoomComponent from the linked list. */
- void FAkAudioDevice::UnindexRoom(class UAkRoomComponent* ComponentToRemove)
- {
- if (RoomIndex.Remove(ComponentToRemove))
- {
- SAComponentAddedRemoved(ComponentToRemove->GetWorld());
- }
- }
- void FAkAudioDevice::ReindexRoom(class UAkRoomComponent* ComponentToAdd)
- {
- RoomIndex.Update(ComponentToAdd);
- SAComponentAddedRemoved(ComponentToAdd->GetWorld());
- }
- /** Return true if any UAkRoomComponents have been added to the prioritized list of rooms **/
- bool FAkAudioDevice::UsingSpatialAudioRooms(const UWorld* World)
- {
- return !RoomIndex.IsEmpty(World);
- }
- /** Seek on an event in the ak soundengine.
- * @param EventShortID Name of the event on which to seek.
- * @param Actor The associated Actor. If this is nullptr, defaul object will be used.
- * @param in_fPercent Desired percent where playback should restart.
- * @param in_bSeekToNearestMarker If true, the final seeking position will be made equal to the nearest marker.
- *
- * @return Success or failure.
- */
- AKRESULT FAkAudioDevice::SeekOnEvent(
- const AkUInt32 EventShortID,
- AActor* Actor,
- AkReal32 Percent,
- bool bSeekToNearestMarker /*= false*/,
- AkPlayingID PlayingID /*= AK_INVALID_PLAYING_ID*/
- )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- if (!Actor)
- {
- // SeekOnEvent must be bound to a game object. Passing DUMMY_GAMEOBJ as default game object.
- return SoundEngine->SeekOnEvent(EventShortID, DUMMY_GAMEOBJ, Percent, bSeekToNearestMarker, PlayingID);
- }
- else if (!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- {
- UAkComponent* pComponent = GetAkComponent(Actor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset);
- if (pComponent)
- {
- return SeekOnEvent(EventShortID, pComponent, Percent, bSeekToNearestMarker, PlayingID);
- }
- }
- return AKRESULT::AK_Fail;
- }
- /** Seek on an event in the ak soundengine.
- * @param EventShortID Name of the event on which to seek.
- * @param Component The associated AkComponent.
- * @param in_fPercent Desired percent where playback should restart.
- * @param in_bSeekToNearestMarker If true, the final seeking position will be made equal to the nearest marker.
- *
- * @return Success or failure.
- */
- AKRESULT FAkAudioDevice::SeekOnEvent(
- const AkUInt32 EventShortID,
- UAkComponent* Component,
- AkReal32 Percent,
- bool bSeekToNearestMarker /*= false*/,
- AkPlayingID PlayingID /*= AK_INVALID_PLAYING_ID*/
- )
- {
- if (m_bSoundEngineInitialized && Component)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- if (Component->AllowAudioPlayback())
- {
- return SoundEngine->SeekOnEvent(EventShortID, Component->GetAkGameObjectID(), Percent, bSeekToNearestMarker, PlayingID);
- }
- }
- return AKRESULT::AK_Fail;
- }
- void FAkAudioDevice::UpdateAllSpatialAudioPortals(UWorld* InWorld)
- {
- #ifdef AK_ENABLE_PORTALS
- auto Portals = WorldPortalsMap.Find(InWorld);
- if (Portals != nullptr)
- {
- for (auto Portal : *Portals)
- {
- if (Portal.IsValid())
- {
- SetSpatialAudioPortal(Portal.Get());
- }
- }
- }
- #endif
- }
- void FAkAudioDevice::SetSpatialAudioPortal(UAkPortalComponent* in_Portal)
- {
- if(!IsValid(in_Portal) || IsRunningCommandlet())
- return;
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return;
- #ifdef AK_ENABLE_PORTALS
- UWorld* World = in_Portal->GetWorld();
- auto Portals = WorldPortalsMap.Find(World);
- if (Portals == nullptr)
- Portals = &WorldPortalsMap.Add(World, TArray<TWeakObjectPtr<UAkPortalComponent>>());
- if (Portals != nullptr)
- {
- if (!Portals->Contains(in_Portal))
- {
- Portals->Add(in_Portal);
- }
- }
- /* Only update the sound engine for game worlds. */
- if (ShouldNotifySoundEngine(World->WorldType))
- {
- AkPortalID portalID = in_Portal->GetPortalID();
- if (!in_Portal->PortalPlacementValid())
- {
- SpatialAudio->RemovePortal(portalID);
- UE_LOG(LogAkAudio, Log, TEXT("UAkPortalComponent %s must have a front room which is distinct from its back room."), *(in_Portal->GetOwner() != nullptr ? in_Portal->GetOwner()->GetName() : in_Portal->GetName()));
- }
- else
- {
- FString nameStr = in_Portal->GetName();
- AActor* portalOwner = in_Portal->GetOwner();
- UPrimitiveComponent* primitiveParent = in_Portal->GetPrimitiveParent();
- if (portalOwner != nullptr)
- {
- #if WITH_EDITOR
- nameStr = portalOwner->GetActorLabel();
- #else
- nameStr = portalOwner->GetName();
- #endif
- if (primitiveParent != nullptr)
- {
- // ensures unique and meaningful names when we have multiple portals in the same actor.
- TInlineComponentArray<UAkPortalComponent*> PortalComponents;
- portalOwner->GetComponents(PortalComponents);
- if (PortalComponents.Num() > 1)
- nameStr.Append(FString("_").Append(primitiveParent->GetName()));
- }
- }
- AkPortalParams Params;
- UPrimitiveComponent* Parent = in_Portal->GetPrimitiveParent();
- if (IsValid(Parent))
- {
- AkComponentHelpers::GetPrimitiveTransformAndExtent(*Parent, Params.Transform, Params.Extent);
- }
- Params.bEnabled = in_Portal->GetCurrentState() == AkAcousticPortalState::Open;
- Params.FrontRoom = in_Portal->GetFrontRoomID();
- Params.BackRoom = in_Portal->GetBackRoomID();
- SpatialAudio->SetPortal(portalID, Params, TCHAR_TO_ANSI(*nameStr));
- }
- }
- #endif
- }
- void FAkAudioDevice::RemoveSpatialAudioPortal(UAkPortalComponent* in_Portal)
- {
- if (IsRunningCommandlet())
- return;
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return;
- #ifdef AK_ENABLE_PORTALS
- auto Portals = WorldPortalsMap.Find(in_Portal->GetWorld());
- if (Portals != nullptr && Portals->Contains(in_Portal))
- {
- Portals->Remove(in_Portal);
- }
- if (ShouldNotifySoundEngine(in_Portal->GetWorld()->WorldType))
- {
- AkPortalID portalID = in_Portal->GetPortalID();
- SpatialAudio->RemovePortal(portalID);
- }
- #endif
- }
- /** Get a sorted list of AkAuxSendValue at a location
- *
- * @param Loc Location at which to find Reverb Volumes
- * @param AkReverbVolumes Array of AkAuxSendValue at this location
- */
- void FAkAudioDevice::GetAuxSendValuesAtLocation(FVector Loc, TArray<AkAuxSendValue>& AkAuxSendValues, const UWorld* in_World)
- {
- // Check if there are AkReverbVolumes at this location
- TArray<UAkLateReverbComponent*> FoundComponents = LateReverbIndex.Query<UAkLateReverbComponent>(Loc, in_World);
- // Sort the found Volumes
- if (FoundComponents.Num() > 1)
- {
- FoundComponents.Sort([](const UAkLateReverbComponent& A, const UAkLateReverbComponent& B)
- {
- return A.Priority > B.Priority;
- });
- }
- // Apply the found Aux Sends
- AkAuxSendValue TmpSendValue;
- // Build a list to set as AuxBusses
- for( uint8 Idx = 0; Idx < FoundComponents.Num() && Idx < MaxAuxBus; Idx++ )
- {
- TmpSendValue.listenerID = AK_INVALID_GAME_OBJECT;
- TmpSendValue.auxBusID = FoundComponents[Idx]->GetAuxBusId();
- TmpSendValue.fControlValue = FoundComponents[Idx]->SendLevel;
- AkAuxSendValues.Add(TmpSendValue);
- }
- }
- void FAkAudioDevice::PostEventAtLocationEndOfEventCallback(AkCallbackType in_eType, AkCallbackInfo* in_pCallbackInfo)
- {
- if (auto* Device = FAkAudioDevice::Get())
- {
- Device->RemovePlayingID(((AkEventCallbackInfo*)in_pCallbackInfo)->eventID, ((AkEventCallbackInfo*)in_pCallbackInfo)->playingID);
- auto pPackage = (IAkUserEventCallbackPackage*)in_pCallbackInfo->pCookie;
- if (pPackage && pPackage->HasExternalSources)
- {
- if (auto* ExternalSourceManager = IWwiseExternalSourceManager::Get())
- {
- ExternalSourceManager->OnEndOfEvent(((AkEventCallbackInfo*)in_pCallbackInfo)->playingID);
- }
- }
- }
- }
- UAkComponent* FAkAudioDevice::SpawnAkComponentAtLocation( class UAkAudioEvent* in_pAkEvent, FVector Location, FRotator Orientation, bool AutoPost, const FString& EventName, bool AutoDestroy, UWorld* in_World)
- {
- UAkComponent * AkComponent = NULL;
- if (in_World)
- {
- AkComponent = NewObject<UAkComponent>(in_World->GetWorldSettings());
- }
- else
- {
- AkComponent = NewObject<UAkComponent>();
- }
- if( AkComponent )
- {
- AkComponent->AkAudioEvent = in_pAkEvent;
- AkComponent->SetWorldLocationAndRotation(Location, Orientation.Quaternion());
- if(in_World)
- {
- AkComponent->RegisterComponentWithWorld(in_World);
- }
- AkComponent->SetAutoDestroy(AutoDestroy);
- if(AutoPost)
- {
- if (AkComponent->PostAssociatedAkEvent(0, FOnAkPostEventCallback()) == AK_INVALID_PLAYING_ID && AutoDestroy)
- {
- AkComponent->ConditionalBeginDestroy();
- AkComponent = NULL;
- }
- }
- }
- return AkComponent;
- }
- /**
- * Post a trigger to ak soundengine
- *
- * @param in_pszTrigger Name of the trigger
- * @param in_pAkComponent AkComponent on which to post the trigger
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::PostTrigger(
- const TCHAR * in_pszTrigger,
- AActor * in_pActor
- )
- {
- AkGameObjectID GameObjID = AK_INVALID_GAME_OBJECT;
- AKRESULT eResult = GetGameObjectID( in_pActor, GameObjID );
- if ( m_bSoundEngineInitialized && eResult == AK_Success)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->PostTrigger(TCHAR_TO_AK(in_pszTrigger), GameObjID );
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::PostTrigger(
- const UAkTrigger* in_TriggerValue,
- AActor* in_pActor
- )
- {
- AkGameObjectID GameObjID = AK_INVALID_GAME_OBJECT;
- AKRESULT eResult = GetGameObjectID(in_pActor, GameObjID);
- if (m_bSoundEngineInitialized && in_TriggerValue && eResult == AK_Success)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->PostTrigger(in_TriggerValue->GetShortID(), GameObjID);
- }
- return eResult;
- }
- /**
- * Set a RTPC in ak soundengine
- *
- * @param in_pszRtpcName Name of the RTPC
- * @param in_value Value to set
- * @param in_pActor Actor on which to set the RTPC
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetRTPCValue(
- const TCHAR * in_pszRtpcName,
- AkRtpcValue in_value,
- int32 in_interpolationTimeMs = 0,
- AActor * in_pActor = NULL
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- auto RtpcID = SoundEngine->GetIDFromString(TCHAR_TO_AK(in_pszRtpcName));
- eResult = SetRTPCValue(RtpcID, in_value, in_interpolationTimeMs, in_pActor);
- }
- return eResult;
- }
- /**
- * Set a RTPC in ak soundengine
- *
- * @param in_Rtpc RTPC Short ID
- * @param in_value Value to set
- * @param in_interpolationTimeMs - Duration during which the RTPC is interpolated towards in_value (in ms)
- * @param in_pActor AActor on which to set the RTPC
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetRTPCValue(
- AkRtpcID in_Rtpc,
- AkRtpcValue in_value,
- int32 in_interpolationTimeMs = 0,
- AActor * in_pActor = NULL
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkGameObjectID GameObjID = AK_INVALID_GAME_OBJECT; // RTPC at global scope is supported
- if (in_pActor)
- {
- eResult = GetGameObjectID(in_pActor, GameObjID);
- if (eResult != AK_Success)
- return eResult;
- }
- eResult = SoundEngine->SetRTPCValue(in_Rtpc, in_value, GameObjID, in_interpolationTimeMs);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetRTPCValue(
- const UAkRtpc* in_RtpcValue,
- AkRtpcValue in_value,
- int32 in_interpolationTimeMs = 0,
- AActor * in_pActor = NULL
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized && in_RtpcValue)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkGameObjectID GameObjID = AK_INVALID_GAME_OBJECT; // RTPC at global scope is supported
- if (in_pActor)
- {
- eResult = GetGameObjectID(in_pActor, GameObjID);
- if (eResult != AK_Success)
- return eResult;
- }
- eResult = SoundEngine->SetRTPCValue(in_RtpcValue->GetShortID(), in_value, GameObjID, in_interpolationTimeMs);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetRTPCValueByPlayingID(
- AkRtpcID in_Rtpc,
- AkRtpcValue in_value,
- AkPlayingID in_playingID,
- int32 in_interpolationTimeMs
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetRTPCValueByPlayingID(in_Rtpc, in_value, in_playingID, in_interpolationTimeMs);
- }
- return eResult;
- }
- /**
- * Get the value of a real-time parameter control (by ID)
- * An RTPC can have a any combination of a global value, a unique value for each game object, or a unique value for each playing ID.
- * The value requested is determined by RTPCValue_type, in_gameObjectID and in_playingID.
- * If a value at the requested scope (determined by RTPCValue_type) is not found, the value that is available at the the next broadest scope will be returned, and io_rValueType will be changed to indicate this.
- * @note
- * When looking up RTPC values via playing ID (ie. io_rValueType is RTPC_PlayingID), in_gameObjectID can be set to a specific game object (if it is available to the caller) to use as a fall back value.
- * If the game object is unknown or unavailable, AK_INVALID_GAME_OBJECT can be passed in in_gameObjectID, and the game object will be looked up via in_playingID.
- * However in this case, it is not possible to retrieve a game object value as a fall back value if the playing id does not exist. It is best to pass in the game object if possible.
- *
- * @return AK_Success if succeeded, AK_IDNotFound if the game object was not registered, or AK_Fail if the RTPC value could not be obtained
- */
- AKRESULT FAkAudioDevice::GetRTPCValue(
- const TCHAR * in_pszRtpcName,
- AkGameObjectID in_gameObjectID, ///< Associated game object ID, ignored if io_rValueType is RTPCValue_Global.
- AkPlayingID in_playingID, ///< Associated playing ID, ignored if io_rValueType is not RTPC_PlayingID.
- AkRtpcValue& out_rValue, ///< Value returned
- AK::SoundEngine::Query::RTPCValue_type& io_rValueType ///< In/Out value, the user must specify the requested type. The function will return in this variable the type of the returned value. );
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->Query->GetRTPCValue(TCHAR_TO_AK(in_pszRtpcName), in_gameObjectID, in_playingID, out_rValue, io_rValueType);
- }
- return eResult;
- }
- /**
- * Get the value of a real-time parameter control (by ID)
- * An RTPC can have a any combination of a global value, a unique value for each game object, or a unique value for each playing ID.
- * The value requested is determined by RTPCValue_type, in_gameObjectID and in_playingID.
- * If a value at the requested scope (determined by RTPCValue_type) is not found, the value that is available at the the next broadest scope will be returned, and io_rValueType will be changed to indicate this.
- * @note
- * When looking up RTPC values via playing ID (ie. io_rValueType is RTPC_PlayingID), in_gameObjectID can be set to a specific game object (if it is available to the caller) to use as a fall back value.
- * If the game object is unknown or unavailable, AK_INVALID_GAME_OBJECT can be passed in in_gameObjectID, and the game object will be looked up via in_playingID.
- * However in this case, it is not possible to retrieve a game object value as a fall back value if the playing id does not exist. It is best to pass in the game object if possible.
- *
- * @return AK_Success if succeeded, AK_IDNotFound if the game object was not registered, or AK_Fail if the RTPC value could not be obtained
- */
- AKRESULT FAkAudioDevice::GetRTPCValue(
- AkRtpcID in_Rtpc,
- AkGameObjectID in_gameObjectID, ///< Associated game object ID, ignored if io_rValueType is RTPCValue_Global.
- AkPlayingID in_playingID, ///< Associated playing ID, ignored if io_rValueType is not RTPC_PlayingID.
- AkRtpcValue& out_rValue, ///< Value returned
- AK::SoundEngine::Query::RTPCValue_type& io_rValueType ///< In/Out value, the user must specify the requested type. The function will return in this variable the type of the returned value. );
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->Query->GetRTPCValue(in_Rtpc, in_gameObjectID, in_playingID, out_rValue, io_rValueType);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::GetRTPCValue(
- const UAkRtpc* in_RtpcValue,
- AkGameObjectID in_gameObjectID, ///< Associated game object ID, ignored if io_rValueType is RTPCValue_Global.
- AkPlayingID in_playingID, ///< Associated playing ID, ignored if io_rValueType is not RTPC_PlayingID.
- AkRtpcValue& out_rValue, ///< Value returned
- AK::SoundEngine::Query::RTPCValue_type& io_rValueType ///< In/Out value, the user must specify the requested type. The function will return in this variable the type of the returned value. );
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized && in_RtpcValue)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->Query->GetRTPCValue(in_RtpcValue->GetShortID(), in_gameObjectID, in_playingID, out_rValue, io_rValueType);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::ResetRTPCValue(const UAkRtpc* in_RtpcValue, AkGameObjectID in_gameObjectID, int32 in_interpolationTimeMs)
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized && in_RtpcValue)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->ResetRTPCValue(in_RtpcValue->GetShortID(), in_gameObjectID, in_interpolationTimeMs);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::ResetRTPCValue(AkRtpcID in_rtpcID, AkGameObjectID in_gameObjectID, int32 in_interpolationTimeMs)
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized && in_rtpcID)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->ResetRTPCValue(in_rtpcID, in_gameObjectID, in_interpolationTimeMs);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::ResetRTPCValue(const TCHAR* in_pszRtpcName, AkGameObjectID in_gameObjectID, int32 in_interpolationTimeMs)
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->ResetRTPCValue(TCHAR_TO_AK(in_pszRtpcName), in_gameObjectID, in_interpolationTimeMs);
- }
- return eResult;
- }
- /**
- * Set a state in ak soundengine
- *
- * @param in_pszStateGroup Name of the state group
- * @param in_pszState Name of the state
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetState(
- const TCHAR * in_pszStateGroup,
- const TCHAR * in_pszState
- )
- {
- AKRESULT eResult = AK_Success;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- auto StateGroupID = SoundEngine->GetIDFromString(TCHAR_TO_AK(in_pszStateGroup));
- auto StateID = SoundEngine->GetIDFromString(TCHAR_TO_AK(in_pszState));
- eResult = SoundEngine->SetState(StateGroupID, StateID);
- }
- return eResult;
- }
- /**
- * Set a state in ak soundengine
- *
- * @param in_StateGroup State group short ID
- * @param in_State State short ID
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetState(
- AkStateGroupID in_StateGroup,
- AkStateID in_State
- )
- {
- AKRESULT eResult = AK_Success;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetState(in_StateGroup, in_State);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetState(
- const UAkStateValue* in_stateValue
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized && in_stateValue)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetState(in_stateValue->GetGroupID(), in_stateValue->GetShortID());
- }
- return eResult;
- }
- /**
- * Set a switch in ak soundengine
- *
- * @param in_pszSwitchGroup Name of the switch group
- * @param in_pszSwitchState Name of the switch
- * @param in_pComponent AkComponent on which to set the switch
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetSwitch(
- const TCHAR * in_pszSwitchGroup,
- const TCHAR * in_pszSwitchState,
- AActor * in_pActor
- )
- {
- AKRESULT eResult = AK_Success;
- if ( m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- auto SwitchGroupID = SoundEngine->GetIDFromString(TCHAR_TO_AK(in_pszSwitchGroup));
- auto SwitchStateID = SoundEngine->GetIDFromString(TCHAR_TO_AK(in_pszSwitchState));
- eResult = SetSwitch(SwitchGroupID, SwitchStateID, in_pActor);
- }
- return eResult;
- }
- /**
- * Set a switch in ak soundengine
- *
- * @param in_SwitchGroup Short ID of the switch group
- * @param in_SwitchState Short ID of the switch
- * @param in_pComponent AkComponent on which to set the switch
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetSwitch(
- AkSwitchGroupID in_SwitchGroup,
- AkSwitchStateID in_SwitchState,
- AActor * in_pActor
- )
- {
- AkGameObjectID GameObjID = DUMMY_GAMEOBJ;
- // Switches must be bound to a game object. passing DUMMY_GAMEOBJ as default game object.
- AKRESULT eResult = GetGameObjectID( in_pActor, GameObjID );
- if ( m_bSoundEngineInitialized && eResult == AK_Success)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetSwitch(in_SwitchGroup, in_SwitchState, GameObjID);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetSwitch(
- const UAkSwitchValue* in_switchValue,
- AActor * in_pActor
- )
- {
- AkGameObjectID GameObjID = DUMMY_GAMEOBJ;
- // Switches must be bound to a game object. passing DUMMY_GAMEOBJ as default game object.
- AKRESULT eResult = GetGameObjectID(in_pActor, GameObjID);
- if (m_bSoundEngineInitialized && in_switchValue && eResult == AK_Success)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetSwitch(in_switchValue->GetGroupID(), in_switchValue->GetShortID(), GameObjID);
- }
- return eResult;
- }
- static AK::SoundEngine::MultiPositionType GetSoundEngineMultiPositionType(AkMultiPositionType in_eType)
- {
- switch (in_eType)
- {
- case AkMultiPositionType::SingleSource: return AK::SoundEngine::MultiPositionType_SingleSource;
- case AkMultiPositionType::MultiSources: return AK::SoundEngine::MultiPositionType_MultiSources;
- case AkMultiPositionType::MultiDirections: return AK::SoundEngine::MultiPositionType_MultiDirections;
- // Unknown multi position type!
- default: check(false); return AK::SoundEngine::MultiPositionType_SingleSource;
- }
- }
- /** Sets multiple positions to a single game object.
- * Setting multiple positions on a single game object is a way to simulate multiple emission sources while using the resources of only one voice.
- * This can be used to simulate wall openings, area sounds, or multiple objects emitting the same sound in the same area.
- * Note: Calling AK::SoundEngine::SetMultiplePositions() with only one position is the same as calling AK::SoundEngine::SetPosition()
- * @param in_pGameObjectAkComponent Game Object AkComponent.
- * @param in_pPositions Array of positions to apply.
- * @param in_eMultiPositionType Position type
- * @return AK_Success when successful, AK_InvalidParameter if parameters are not valid.
- *
- */
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- UAkComponent* in_pGameObjectAkComponent,
- TArray<FTransform> in_aPositions,
- AkMultiPositionType in_eMultiPositionType /*= AkMultiPositionType::MultiDirections*/
- )
- {
- if (!in_pGameObjectAkComponent)
- {
- return AK_Fail;
- }
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- const int numPositions = in_aPositions.Num();
- TArray<AkSoundPosition> aPositions;
- aPositions.Empty();
- for (int i = 0; i < numPositions; ++i)
- {
- AkSoundPosition soundpos;
- FAkAudioDevice::FVectorsToAKWorldTransform(in_aPositions[i].GetLocation(), in_aPositions[i].GetRotation().GetForwardVector(), in_aPositions[i].GetRotation().GetUpVector(), soundpos);
- aPositions.Add(soundpos);
- }
- return SoundEngine->SetMultiplePositions(in_pGameObjectAkComponent->GetAkGameObjectID(), aPositions.GetData(),
- aPositions.Num(), GetSoundEngineMultiPositionType(in_eMultiPositionType));
- }
- template<typename ChannelConfig>
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- UAkComponent* in_pGameObjectAkComponent,
- const TArray<ChannelConfig>& in_aChannelConfigurations,
- const TArray<FTransform>& in_aPositions,
- AkMultiPositionType in_eMultiPositionType /*= AkMultiPositionType::MultiDirections*/
- )
- {
- if (!in_pGameObjectAkComponent)
- {
- return AK_Fail;
- }
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- const int32 numPositions = FMath::Min(in_aPositions.Num(), in_aChannelConfigurations.Num());
- TArray<AkChannelEmitter> emitters;
- emitters.Reserve(numPositions);
- for (int i = 0; i < numPositions; ++i)
- {
- AkSoundPosition soundpos;
- FAkAudioDevice::FVectorsToAKWorldTransform(in_aPositions[i].GetLocation(), in_aPositions[i].GetRotation().GetForwardVector(), in_aPositions[i].GetRotation().GetUpVector(), soundpos);
- AkChannelConfig config;
- GetChannelConfig(in_aChannelConfigurations[i], config);
- emitters.Add(AkChannelEmitter());
- emitters[i].uInputChannels = config.uChannelMask;
- emitters[i].position = soundpos;
- }
- return SoundEngine->SetMultiplePositions(in_pGameObjectAkComponent->GetAkGameObjectID(), emitters.GetData(),
- emitters.Num(), GetSoundEngineMultiPositionType(in_eMultiPositionType));
- }
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- UAkComponent* in_pGameObjectAkComponent,
- const TArray<AkChannelConfiguration>& in_aChannelConfigurations,
- const TArray<FTransform>& in_aPositions,
- AkMultiPositionType in_eMultiPositionType
- )
- {
- return SetMultiplePositions<AkChannelConfiguration>(in_pGameObjectAkComponent, in_aChannelConfigurations, in_aPositions, in_eMultiPositionType);
- }
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- UAkComponent* in_pGameObjectAkComponent,
- const TArray<FAkChannelMask>& in_channelMasks,
- const TArray<FTransform>& in_aPositions,
- AkMultiPositionType in_eMultiPositionType
- )
- {
- return SetMultiplePositions<FAkChannelMask>(in_pGameObjectAkComponent, in_channelMasks, in_aPositions, in_eMultiPositionType);
- }
- /** Sets multiple positions to a single game object.
- * Setting multiple positions on a single game object is a way to simulate multiple emission sources while using the resources of only one voice.
- * This can be used to simulate wall openings, area sounds, or multiple objects emitting the same sound in the same area.
- * Note: Calling AK::SoundEngine::SetMultiplePositions() with only one position is the same as calling AK::SoundEngine::SetPosition()
- * @param in_GameObjectID Game Object identifier.
- * @param in_pPositions Array of positions to apply.
- * @param in_NumPositions Number of positions specified in the provided array.
- * @param in_eMultiPositionType Position type
- * @return AK_Success when successful, AK_InvalidParameter if parameters are not valid.
- */
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- AkGameObjectID in_GameObjectID,
- const AkSoundPosition * in_pPositions,
- AkUInt16 in_NumPositions,
- AK::SoundEngine::MultiPositionType in_eMultiPositionType /*= AK::SoundEngine::MultiDirections*/
- )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->SetMultiplePositions(in_GameObjectID, in_pPositions, in_NumPositions, in_eMultiPositionType);
- }
- /** Sets multiple positions to a single game object, with flexible assignment of input channels.
- * Setting multiple positions on a single game object is a way to simulate multiple emission sources while using the resources of only one voice.
- * This can be used to simulate wall openings, area sounds, or multiple objects emitting the same sound in the same area.
- * Note: Calling AK::SoundEngine::SetMultiplePositions() with only one position is the same as calling AK::SoundEngine::SetPosition()
- * @param in_GameObjectID Game Object identifier.
- * @param in_pPositions Array of positions to apply.
- * @param in_NumPositions Number of positions specified in the provided array.
- * @param in_eMultiPositionType Position type
- * @return AK_Success when successful, AK_InvalidParameter if parameters are not valid.
- */
- AKRESULT FAkAudioDevice::SetMultiplePositions(
- AkGameObjectID in_GameObjectID,
- const AkChannelEmitter * in_pPositions,
- AkUInt16 in_NumPositions,
- AK::SoundEngine::MultiPositionType in_eMultiPositionType /*= AK::SoundEngine::MultiDirections*/
- )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->SetMultiplePositions(in_GameObjectID, in_pPositions, in_NumPositions, in_eMultiPositionType);
- }
- /**
- * Set auxiliary sends
- *
- * @param in_GameObjId Wwise Game Object ID
- * @param in_AuxSendValues Array of AkAuxSendValue, containins all Aux Sends to set on the game objectt
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetAuxSends(
- const UAkComponent* in_akComponent,
- TArray<AkAuxSendValue>& in_AuxSendValues
- )
- {
- AKRESULT eResult = AK_Success;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetGameObjectAuxSendValues(in_akComponent->GetAkGameObjectID(), in_AuxSendValues.GetData(), in_AuxSendValues.Num());
- }
-
- return eResult;
- }
- void FAkAudioDevice::GetChannelConfig(AkChannelConfiguration ChannelConfiguration, AkChannelConfig& config)
- {
- switch (ChannelConfiguration)
- {
- case AkChannelConfiguration::Ak_MainMix:
- config.eConfigType = AK_ChannelConfigType_UseDeviceMain;
- break;
- case AkChannelConfiguration::Ak_Passthrough:
- config.eConfigType = AK_ChannelConfigType_UseDevicePassthrough;
- break;
- case AkChannelConfiguration::Ak_LFE:
- config.SetStandard(AK_SPEAKER_SETUP_0POINT1);
- break;
- case AkChannelConfiguration::AK_Audio_Objects:
- config.SetObject();
- break;
- case AkChannelConfiguration::Ak_1_0:
- config.SetStandard(AK_SPEAKER_SETUP_MONO);
- break;
- case AkChannelConfiguration::Ak_2_0:
- config.SetStandard(AK_SPEAKER_SETUP_STEREO);
- break;
- case AkChannelConfiguration::Ak_2_1:
- config.SetStandard(AK_SPEAKER_SETUP_2POINT1);
- break;
- case AkChannelConfiguration::Ak_3_0:
- config.SetStandard(AK_SPEAKER_SETUP_3STEREO);
- break;
- case AkChannelConfiguration::Ak_3_1:
- config.SetStandard(AK_SPEAKER_SETUP_3POINT1);
- break;
- case AkChannelConfiguration::Ak_4_0:
- config.SetStandard(AK_SPEAKER_SETUP_4);
- break;
- case AkChannelConfiguration::Ak_4_1:
- config.SetStandard(AK_SPEAKER_SETUP_4POINT1);
- break;
- case AkChannelConfiguration::Ak_5_0:
- config.SetStandard(AK_SPEAKER_SETUP_5);
- break;
- case AkChannelConfiguration::Ak_5_1:
- config.SetStandard(AK_SPEAKER_SETUP_5POINT1);
- break;
- case AkChannelConfiguration::Ak_7_1:
- config.SetStandard(AK_SPEAKER_SETUP_7POINT1);
- break;
- case AkChannelConfiguration::Ak_5_1_2:
- config.SetStandard(AK_SPEAKER_SETUP_DOLBY_5_1_2);
- break;
- case AkChannelConfiguration::Ak_7_1_2:
- config.SetStandard(AK_SPEAKER_SETUP_DOLBY_7_1_2);
- break;
- case AkChannelConfiguration::Ak_7_1_4:
- config.SetStandard(AK_SPEAKER_SETUP_DOLBY_7_1_4);
- break;
- case AkChannelConfiguration::Ak_Auro_9_1:
- config.SetStandard(AK_SPEAKER_SETUP_AURO_9POINT1);
- break;
- case AkChannelConfiguration::Ak_Auro_10_1:
- config.SetStandard(AK_SPEAKER_SETUP_AURO_10POINT1);
- break;
- case AkChannelConfiguration::Ak_Auro_11_1:
- config.SetStandard(AK_SPEAKER_SETUP_AURO_11POINT1);
- break;
- case AkChannelConfiguration::Ak_Auro_13_1:
- config.SetStandard(AK_SPEAKER_SETUP_AURO_13POINT1_751);
- break;
- case AkChannelConfiguration::Ak_Ambisonics_1st_order:
- config.SetAmbisonic(4);
- break;
- case AkChannelConfiguration::Ak_Ambisonics_2nd_order:
- config.SetAmbisonic(9);
- break;
- case AkChannelConfiguration::Ak_Ambisonics_3rd_order:
- config.SetAmbisonic(16);
- break;
- case AkChannelConfiguration::Ak_Ambisonics_4th_order:
- config.SetAmbisonic(25);
- break;
- case AkChannelConfiguration::Ak_Ambisonics_5th_order:
- config.SetAmbisonic(36);
- break;
- case AkChannelConfiguration::Ak_Parent:
- default:
- config.Clear();
- break;
- }
- }
- void FAkAudioDevice::GetChannelConfig(FAkChannelMask SpeakerConfig, AkChannelConfig& config)
- {
- config.SetStandard(SpeakerConfig.ChannelMask);
- }
- /**
- * Set spatial audio room
- *
- * @param in_GameObjId Wwise Game Object ID
- * @param in_RoomID ID of the room that the game object is inside.
- * @return Result from ak sound engine
- */
- AKRESULT FAkAudioDevice::SetInSpatialAudioRoom(
- const AkGameObjectID in_GameObjId,
- AkRoomID in_RoomID
- )
- {
- AKRESULT eResult = AK_Success;
- #ifdef AK_ENABLE_ROOMS
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->SetGameObjectInRoom(in_GameObjId, in_RoomID);
- }
- #endif
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetBusConfig(
- const FString& in_BusName,
- AkChannelConfig in_Config
- )
- {
- AKRESULT eResult = AK_Fail;
- if (in_BusName.IsEmpty())
- {
- return eResult;
- }
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkUniqueID BusId = GetShortIDFromString(in_BusName);
- eResult = SoundEngine->SetBusConfig(BusId, in_Config);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetPanningRule(
- AkPanningRule in_ePanningRule
- )
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetPanningRule(in_ePanningRule);
- }
- return eResult;
- }
- AkOutputDeviceID FAkAudioDevice::GetOutputID(
- const FString& in_szShareSet,
- AkUInt32 in_idDevice
- )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_INVALID_OUTPUT_DEVICE_ID;
- return SoundEngine->GetOutputID(TCHAR_TO_AK(*in_szShareSet), in_idDevice);
- }
- AKRESULT FAkAudioDevice::ReplaceMainOutput(const AkOutputSettings& MainOutputSettings)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AKRESULT Result = SoundEngine->ReplaceOutput(MainOutputSettings, 0);
- SoundEngine->RenderAudio();
- return Result;
- }
- AKRESULT FAkAudioDevice::GetSpeakerAngles(
- TArray<AkReal32>& out_pfSpeakerAngles,
- AkReal32& out_fHeightAngle,
- AkOutputDeviceID in_idOutput
- )
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkUInt32 numSpeakers;
- // Retrieve the number of speaker and height angle
- eResult = SoundEngine->GetSpeakerAngles(NULL, numSpeakers, out_fHeightAngle);
- if (eResult != AK_Success)
- return eResult;
- // Retrieve the speaker angles
- out_pfSpeakerAngles.SetNum(numSpeakers);
- eResult = SoundEngine->GetSpeakerAngles(out_pfSpeakerAngles.GetData(), numSpeakers, out_fHeightAngle, in_idOutput);
- }
-
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetSpeakerAngles(
- const TArray<AkReal32>& in_pfSpeakerAngles,
- AkReal32 in_fHeightAngle,
- AkOutputDeviceID in_idOutput
- )
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetSpeakerAngles(in_pfSpeakerAngles.GetData(), in_pfSpeakerAngles.Num(), in_fHeightAngle, in_idOutput);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetGameObjectOutputBusVolume(
- const UAkComponent* in_pEmitter,
- const UAkComponent* in_pListener,
- float in_fControlValue
- )
- {
- AKRESULT eResult = AK_Success;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- const AkGameObjectID emitterId = in_pEmitter ? in_pEmitter->GetAkGameObjectID() : DUMMY_GAMEOBJ;
- const AkGameObjectID listenerId = in_pListener ? in_pListener->GetAkGameObjectID() : DUMMY_GAMEOBJ;
- eResult = SoundEngine->SetGameObjectOutputBusVolume(emitterId, listenerId, in_fControlValue);
- }
- return eResult;
- }
- /**
- * Obtain a pointer to the singleton instance of FAkAudioDevice
- *
- * @return Pointer to the singleton instance of FAkAudioDevice
- */
- FAkAudioDevice * FAkAudioDevice::Get()
- {
- if (UNLIKELY(m_EngineExiting))
- {
- return nullptr;
- }
- if (LIKELY(FAkAudioModule::AkAudioModuleInstance))
- {
- return FAkAudioModule::AkAudioModuleInstance->GetAkAudioDevice();
- }
- else
- {
- FAkAudioModule* ModulePtr = FModuleManager::LoadModulePtr<FAkAudioModule>(TEXT("AkAudio"));
- UE_CLOG(!ModulePtr, LogAkAudio, Warning, TEXT("No AkAudio module"));
- UE_CLOG(FAkAudioModule::AkAudioModuleInstance != ModulePtr, LogAkAudio, Warning, TEXT("AkAudio instance (%p) differs from loaded module (%p)."), FAkAudioModule::AkAudioModuleInstance, ModulePtr);
- return ModulePtr ? ModulePtr->GetAkAudioDevice() : nullptr;
- }
- }
- /**
- * Gets the system sample rate
- *
- * @return Sample rate
- */
- AkUInt32 FAkAudioDevice::GetSampleRate()
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return 0;
- return m_bSoundEngineInitialized ? SoundEngine->GetSampleRate() : 0;
- }
- /**
- * Enables/disables offline rendering
- *
- * @param bEnable Set to true to enable offline rendering
- */
- AKRESULT FAkAudioDevice::SetOfflineRendering(bool bEnable)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return m_bSoundEngineInitialized ? SoundEngine->SetOfflineRendering(bEnable) : AK_Fail;
- }
- /**
- * Sets the offline rendering frame time in seconds.
- *
- * @param FrameTimeInSeconds Frame time in seconds used during offline rendering
- */
- AKRESULT FAkAudioDevice::SetOfflineRenderingFrameTime(AkReal32 FrameTimeInSeconds)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return m_bSoundEngineInitialized ? SoundEngine->SetOfflineRenderingFrameTime(FrameTimeInSeconds) : AK_Fail;
- }
- /**
- * Registers a callback used for retrieving audio samples.
- *
- * @param Callback Capture callback function to register
- * @param OutputId The audio device specific id, return by AK::SoundEngine::AddOutput or AK::SoundEngine::GetOutputID
- * @param Cookie Callback cookie that will be sent to the callback function along with additional information
- */
- AKRESULT FAkAudioDevice::RegisterCaptureCallback(AkCaptureCallbackFunc Callback, AkOutputDeviceID OutputId /*= AK_INVALID_OUTPUT_DEVICE_ID*/, void* Cookie /*= nullptr*/)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return m_bSoundEngineInitialized ? SoundEngine->RegisterCaptureCallback(Callback, OutputId, Cookie) : AK_Fail;
- }
- /**
- * Unregisters a callback used for retrieving audio samples.
- *
- * @param Callback Capture callback function to register
- * @param OutputId The audio device specific id, return by AK::SoundEngine::AddOutput or AK::SoundEngine::GetOutputID
- * @param Cookie Callback cookie that will be sent to the callback function along with additional information
- */
- AKRESULT FAkAudioDevice::UnregisterCaptureCallback(AkCaptureCallbackFunc Callback, AkOutputDeviceID OutputId /*= AK_INVALID_OUTPUT_DEVICE_ID*/, void* Cookie /*= nullptr*/)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return m_bSoundEngineInitialized ? SoundEngine->UnregisterCaptureCallback(Callback, OutputId, Cookie) : AK_Fail;
- }
- /**
- * Stop all audio associated with a game object
- *
- * @param in_GameObjID ID of the game object
- */
- void FAkAudioDevice::StopGameObject( UAkComponent * in_pComponent )
- {
- AkGameObjectID gameObjId = DUMMY_GAMEOBJ;
- if ( in_pComponent )
- {
- gameObjId = in_pComponent->GetAkGameObjectID();
- }
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->StopAll( gameObjId );
- }
- }
- /**
- * Stop all audio associated with a playing ID
- *
- * @param in_playingID Playing ID to stop
- * @param in_uTransitionDuration Fade duration
- * @param in_eFadeCurve Curve type to be used for the transition
- */
- void FAkAudioDevice::StopPlayingID( AkPlayingID in_playingID,
- AkTimeMs in_uTransitionDuration /*= 0*/,
- AkCurveInterpolation in_eFadeCurve /*= AkCurveInterpolation_Linear*/)
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->ExecuteActionOnPlayingID(AK::SoundEngine::AkActionOnEventType_Stop, in_playingID, in_uTransitionDuration, in_eFadeCurve );
- }
- }
- /**
- * Register an ak audio component with ak sound engine
- *
- * @param in_pComponent Pointer to the component to register
- */
- void FAkAudioDevice::RegisterComponent( UAkComponent * in_pComponent )
- {
- if (m_bSoundEngineInitialized && in_pComponent)
- {
- FString WwiseGameObjectName = TEXT("");
- in_pComponent->GetAkGameObjectName(WwiseGameObjectName);
-
- const AkGameObjectID gameObjId = in_pComponent->GetAkGameObjectID();
- FAkAudioDevice_Helpers::RegisterGameObject(gameObjId, WwiseGameObjectName);
- if (CallbackManager != nullptr)
- CallbackManager->RegisterGameObject(gameObjId);
- }
- }
- /**
- * Register a game object with ak sound engine
- *
- * @param GameObjectID ID of the game object to register
- */
- void FAkAudioDevice::RegisterComponent(AkGameObjectID GameObjectID)
- {
- if (m_bSoundEngineInitialized && GameObjectID)
- {
- FAkAudioDevice_Helpers::RegisterGameObject(GameObjectID, "");
- if (CallbackManager != nullptr)
- CallbackManager->RegisterGameObject(GameObjectID);
- }
- }
- /**
- * Unregister an ak audio component with ak sound engine
- *
- * @param in_pComponent Pointer to the component to unregister
- */
- void FAkAudioDevice::UnregisterComponent( UAkComponent * in_pComponent )
- {
- if (m_bSoundEngineInitialized && in_pComponent)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- const AkGameObjectID gameObjId = in_pComponent->GetAkGameObjectID();
- SoundEngine->UnregisterGameObj(gameObjId);
- if (CallbackManager != nullptr)
- {
- CallbackManager->UnregisterGameObject(gameObjId);
- }
- }
- }
- if (m_defaultListeners.Contains(in_pComponent))
- {
- RemoveDefaultListener(in_pComponent);
- }
- check(!m_defaultListeners.Contains(in_pComponent));
- if (m_SpatialAudioListener == in_pComponent)
- m_SpatialAudioListener = nullptr;
- }
- void FAkAudioDevice::UnregisterComponent( AkGameObjectID GameObjectId )
- {
- if (m_bSoundEngineInitialized && GameObjectId)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (LIKELY(SoundEngine))
- {
- SoundEngine->UnregisterGameObj(GameObjectId);
- }
- if (CallbackManager != nullptr)
- {
- CallbackManager->UnregisterGameObject(GameObjectId);
- }
- }
- }
- AKRESULT FAkAudioDevice::SetGeometry(AkGeometrySetID GeometrySetID, const AkGeometryParams& Params)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->SetGeometry(GeometrySetID, Params);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetGeometryInstance(AkGeometryInstanceID GeometryInstanceID, const AkGeometryInstanceParams& Params)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->SetGeometryInstance(GeometryInstanceID, Params);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::RemoveGeometrySet(AkGeometrySetID GeometrySetID)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->RemoveGeometry(GeometrySetID);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::RemoveGeometryInstance(AkGeometryInstanceID GeometryInstanceID)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->RemoveGeometryInstance(GeometryInstanceID);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetEarlyReflectionsAuxBus(UAkComponent* in_pComponent, const AkUInt32 AuxBusID)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pComponent)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- const AkGameObjectID gameObjId = in_pComponent->GetAkGameObjectID();
- eResult = SpatialAudio->SetEarlyReflectionsAuxSend(gameObjId, AuxBusID);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetEarlyReflectionsVolume(UAkComponent* in_pComponent, float in_fSendVolume)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pComponent)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- const AkGameObjectID gameObjId = in_pComponent->GetAkGameObjectID();
- eResult = SpatialAudio->SetEarlyReflectionsVolume(gameObjId, in_fSendVolume);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetReflectionsOrder(int Order, bool RefreshPaths)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- eResult = SpatialAudio->SetReflectionsOrder(Order, RefreshPaths);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetMultipleObstructionAndOcclusion(AkGameObjectID in_Object, AkGameObjectID in_listener, AkObstructionOcclusionValues* ObstructionAndOcclusionValues, AkUInt32 in_uNumObstructionAndOcclusion)
- {
- AKRESULT eResult = AK_Fail;
- if(m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetMultipleObstructionAndOcclusion(in_Object, in_listener, ObstructionAndOcclusionValues, in_uNumObstructionAndOcclusion);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetObjectObstructionAndOcclusion(AkGameObjectID in_Object, AkGameObjectID in_listener, AkReal32 Obstruction, AkReal32 Occlusion)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetObjectObstructionAndOcclusion(in_Object, in_listener, Obstruction, Occlusion);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetPortalObstructionAndOcclusion(const UAkPortalComponent* in_pPortal, float in_fObstructionValue, float in_fOcclusionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pPortal)
- {
- auto World = in_pPortal->GetWorld();
- if (World && ShouldNotifySoundEngine(World->WorldType))
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- const AkPortalID portalID = in_pPortal->GetPortalID();
- eResult = SpatialAudio->SetPortalObstructionAndOcclusion(portalID, in_fObstructionValue, in_fOcclusionValue);
- }
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetGameObjectToPortalObstruction(const UAkComponent* in_pComponent, const UAkPortalComponent* in_pPortal, float in_fObstructionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pComponent && in_pPortal)
- {
- auto World = in_pComponent->GetWorld();
- if (World && ShouldNotifySoundEngine(World->WorldType))
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- const AkGameObjectID gameObjId = in_pComponent->GetAkGameObjectID();
- const AkPortalID portalID = in_pPortal->GetPortalID();
- eResult = SpatialAudio->SetGameObjectToPortalObstruction(gameObjId, portalID, in_fObstructionValue);
- }
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetPortalToPortalObstruction(const UAkPortalComponent* in_pPortal0, const UAkPortalComponent* in_pPortal1, float in_fObstructionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pPortal0 && in_pPortal1)
- {
- auto World = in_pPortal0->GetWorld();
- if (World && ShouldNotifySoundEngine(World->WorldType))
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- const AkPortalID portalID0 = in_pPortal0->GetPortalID();
- const AkPortalID portalID1 = in_pPortal1->GetPortalID();
- eResult = SpatialAudio->SetPortalToPortalObstruction(portalID0, portalID1, in_fObstructionValue);
- }
- }
- return eResult;
- }
- void FAkAudioDevice::UpdateDefaultActiveListeners()
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- auto NumDefaultListeners = m_defaultListeners.Num();
- auto pListenerIds = (AkGameObjectID*)alloca(NumDefaultListeners * sizeof(AkGameObjectID));
- int index = 0;
- for (auto DefaultListenerIter = m_defaultListeners.CreateConstIterator(); DefaultListenerIter; ++DefaultListenerIter)
- pListenerIds[index++] = (*DefaultListenerIter)->GetAkGameObjectID();
- if (NumDefaultListeners > 0)
- {
- SoundEngine->SetDefaultListeners(pListenerIds, NumDefaultListeners);
- }
- }
- }
- AKRESULT FAkAudioDevice::SetPosition(UAkComponent* in_akComponent, const AkSoundPosition& in_SoundPosition)
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- return SoundEngine->SetPosition(in_akComponent->GetAkGameObjectID(), in_SoundPosition);
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::AddRoom(UAkRoomComponent* in_pRoom, const AkRoomParams& in_RoomParams)
- {
- if (ShouldNotifySoundEngine(in_pRoom->GetWorld()->WorldType))
- {
- AKRESULT result = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- UAkLateReverbComponent* ReverbComp = in_pRoom->GetReverbComponent();
- UE_CLOG(UNLIKELY(ReverbComp && ReverbComp->bEnable && in_RoomParams.ReverbAuxBus == AK_INVALID_AUX_ID), LogAkAudio, Warning, TEXT("Enabled Late Reverb component for room %s without an assigned Late Reverb Aux Bus"), *in_pRoom->GetRoomName());
- result = SpatialAudio->SetRoom(in_pRoom->GetRoomID(), in_RoomParams, TCHAR_TO_ANSI(*in_pRoom->GetRoomName()));
- if (result == AK_Success)
- {
- IndexRoom(in_pRoom);
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- }
- }
- return result;
- }
- IndexRoom(in_pRoom);
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- return AK_Success;
- }
- AKRESULT FAkAudioDevice::UpdateRoom(UAkRoomComponent* in_pRoom, const AkRoomParams& in_RoomParams)
- {
- if (ShouldNotifySoundEngine(in_pRoom->GetWorld()->WorldType))
- {
- AKRESULT result = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- check(in_pRoom->HasBeenRegisteredWithWwise());
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- check(in_pRoom->HasBeenRegisteredWithWwise());
- result = SpatialAudio->SetRoom(in_pRoom->GetRoomID(), in_RoomParams, TCHAR_TO_ANSI(*in_pRoom->GetRoomName()));
- if (result == AK_Success)
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- }
- return result;
- }
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- return AK_Success;
- }
- AKRESULT FAkAudioDevice::RemoveRoom(UAkRoomComponent* in_pRoom)
- {
- if (ShouldNotifySoundEngine(in_pRoom->GetWorld()->WorldType))
- {
- AKRESULT result = AK_Fail;
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- result = SpatialAudio->RemoveRoom(in_pRoom->GetRoomID());
- if (result == AK_Success)
- {
- UnindexRoom(in_pRoom);
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- }
- }
- return result;
- }
- UnindexRoom(in_pRoom);
- PortalsNeedRoomUpdate(in_pRoom->GetWorld());
- return AK_Success;
- }
- AKRESULT FAkAudioDevice::SetGameObjectRadius(UAkComponent* in_akComponent, float in_outerRadius, float in_innerRadius)
- {
- if (!m_bSoundEngineInitialized)
- return AK_Fail;
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- return SpatialAudio->SetGameObjectRadius(AkGameObjectID(in_akComponent), in_outerRadius, in_innerRadius);
- }
- AKRESULT FAkAudioDevice::SetImageSource(AAkSpotReflector* in_pSpotReflector, const AkImageSourceSettings& in_ImageSourceInfo, AkUniqueID in_AuxBusID, UAkComponent* in_AkComponent)
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- return SpatialAudio->SetImageSource(in_pSpotReflector->GetImageSourceID(), in_ImageSourceInfo, TCHAR_TO_ANSI(*in_pSpotReflector->GetSpotReflectorName()), in_AuxBusID, in_AkComponent->GetAkGameObjectID());
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::RemoveImageSource(AAkSpotReflector* in_pSpotReflector, AkUniqueID in_AuxBusID, UAkComponent* in_AkComponent)
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- return SpatialAudio->RemoveImageSource(in_pSpotReflector->GetImageSourceID(), in_AuxBusID, in_AkComponent->GetAkGameObjectID());
- }
- return AK_Fail;
- }
- AKRESULT FAkAudioDevice::ClearImageSources(AkUniqueID in_AuxBusID, UAkComponent* in_AkComponent)
- {
- if (m_bSoundEngineInitialized)
- {
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return AK_NotInitialized;
- return SpatialAudio->ClearImageSources(in_AuxBusID, in_AkComponent == NULL ? AK_INVALID_GAME_OBJECT : in_AkComponent->GetAkGameObjectID());
- }
- return AK_Fail;
- }
- void FAkAudioDevice::SetListeners(UAkComponent* in_pEmitter, const TArray<UAkComponent*>& in_listenerSet)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- check(!in_pEmitter->UseDefaultListeners());
- auto NumListeners = in_listenerSet.Num();
- auto pListenerIds = (AkGameObjectID*)alloca(NumListeners * sizeof(AkGameObjectID));
- int index = 0;
- for (const auto& Listener : in_listenerSet)
- pListenerIds[index++] = Listener->GetAkGameObjectID();
- SoundEngine->SetListeners(in_pEmitter->GetAkGameObjectID(), pListenerIds, NumListeners);
- }
- bool FAkAudioDevice::SetSpatialAudioListener(UAkComponent* in_pListener)
- {
- #if WITH_EDITOR
- if (in_pListener == EditorListener)
- {
- return false;
- }
- #endif
- m_SpatialAudioListener = in_pListener;
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (UNLIKELY(!SpatialAudio)) return false;
- SpatialAudio->RegisterListener((AkGameObjectID)m_SpatialAudioListener);
- return true;
- }
- UAkComponent* FAkAudioDevice::GetSpatialAudioListener() const
- {
- return m_SpatialAudioListener;
- }
- UAkComponent* FAkAudioDevice::GetAkComponent(class USceneComponent* AttachToComponent, FName AttachPointName, const FVector * Location, EAttachLocation::Type LocationType)
- {
- bool ComponentCreated;
- return GetAkComponent(AttachToComponent, AttachPointName, Location, LocationType, ComponentCreated);
- }
- UAkComponent* FAkAudioDevice::GetAkComponent( class USceneComponent* AttachToComponent, FName AttachPointName, const FVector * Location, EAttachLocation::Type LocationType, bool& ComponentCreated )
- {
- if (!AttachToComponent)
- {
- return NULL;
- }
- UAkComponent* AkComponent = NULL;
- FAttachmentTransformRules AttachRules = FAttachmentTransformRules::KeepRelativeTransform;
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return nullptr;
- if( GEngine && SoundEngine->IsInitialized())
- {
- AActor * Actor = AttachToComponent->GetOwner();
- if( Actor )
- {
- if( !IsValid(Actor) )
- {
- // Avoid creating component if we're trying to play a sound on an already destroyed actor.
- return NULL;
- }
- TArray<UAkComponent*> AkComponents;
- Actor->GetComponents(AkComponents);
- for ( int32 CompIdx = 0; CompIdx < AkComponents.Num(); CompIdx++ )
- {
- UAkComponent* pCompI = AkComponents[CompIdx];
- if ( pCompI && pCompI->IsRegistered() )
- {
- if ( AttachToComponent == pCompI )
- {
- return pCompI;
- }
- if ( AttachToComponent != pCompI->GetAttachParent()
- || AttachPointName != pCompI->GetAttachSocketName() )
- {
- continue;
- }
- // If a location is requested, try to match location.
- if ( Location )
- {
- if (LocationType == EAttachLocation::KeepWorldPosition)
- {
- AttachRules = FAttachmentTransformRules::KeepWorldTransform;
- if ( !FVector::PointsAreSame(*Location, pCompI->GetComponentLocation()) )
- continue;
- }
- else
- {
- AttachRules = FAttachmentTransformRules::KeepRelativeTransform;
- auto RelLoc = pCompI->GetRelativeLocation();
- if ( !FVector::PointsAreSame(*Location, RelLoc) )
- continue;
- }
- }
- // AkComponent found which exactly matches the attachment: reuse it.
- ComponentCreated = false;
- return pCompI;
- }
- }
- }
- else
- {
- // Try to find if there is an AkComponent attached to AttachToComponent (will be the case if AttachToComponent has no owner)
- const TArray<USceneComponent*> AttachChildren = AttachToComponent->GetAttachChildren();
- for(int32 CompIdx = 0; CompIdx < AttachChildren.Num(); CompIdx++)
- {
- UAkComponent* pCompI = Cast<UAkComponent>(AttachChildren[CompIdx]);
- if ( pCompI && pCompI->IsRegistered() )
- {
- // There is an associated AkComponent to AttachToComponent, no need to add another one.
- ComponentCreated = false;
- return pCompI;
- }
- }
- }
- if ( AkComponent == NULL )
- {
- if( Actor )
- {
- AkComponent = NewObject<UAkComponent>(Actor);
- }
- else
- {
- AkComponent = NewObject<UAkComponent>();
- }
- }
- ComponentCreated = true;
- check( AkComponent );
- if (Location)
- {
- if (LocationType == EAttachLocation::KeepWorldPosition)
- {
- AttachRules = FAttachmentTransformRules::KeepWorldTransform;
- AkComponent->SetWorldLocation(*Location);
- }
- else
- {
- AttachRules = FAttachmentTransformRules::KeepRelativeTransform;
- AkComponent->SetRelativeLocation(*Location);
- }
- }
- AkComponent->RegisterComponentWithWorld(AttachToComponent->GetWorld());
- AkComponent->AttachToComponent(AttachToComponent, AttachRules, AttachPointName);
- }
- return( AkComponent );
- }
- /**
- * Cancel the callback cookie for a dispatched event
- *
- * @param in_cookie The cookie to cancel
- */
- void FAkAudioDevice::CancelEventCallbackCookie(void* in_cookie)
- {
- if (m_bSoundEngineInitialized)
- {
- CallbackManager->CancelEventCallback(in_cookie);
- }
- }
- /**
- * Cancel the callback cookie for a dispatched event
- *
- * @param in_cookie The cookie to cancel
- */
- void FAkAudioDevice::CancelEventCallbackDelegate(const FOnAkPostEventCallback& in_Delegate)
- {
- if (m_bSoundEngineInitialized)
- {
- CallbackManager->CancelEventCallback(in_Delegate);
- }
- }
- AKRESULT FAkAudioDevice::SetAttenuationScalingFactor(AActor* Actor, float ScalingFactor)
- {
- AKRESULT eResult = AK_Fail;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkGameObjectID GameObjID = DUMMY_GAMEOBJ;
- eResult = GetGameObjectID( Actor, GameObjID );
- if( eResult == AK_Success )
- {
- eResult = SoundEngine->SetScalingFactor(GameObjID, ScalingFactor);
- }
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetAttenuationScalingFactor(UAkComponent* AkComponent, float ScalingFactor)
- {
- AKRESULT eResult = AK_Fail;
- if ( m_bSoundEngineInitialized && AkComponent)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetScalingFactor(AkComponent->GetAkGameObjectID(), ScalingFactor);
- }
- return eResult;
- }
- AKRESULT FAkAudioDevice::SetDistanceProbe(UAkComponent* Listener, UAkComponent* DistanceProbe)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && Listener)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- eResult = SoundEngine->SetDistanceProbe(Listener->GetAkGameObjectID(), DistanceProbe != nullptr ? DistanceProbe->GetAkGameObjectID() : AK_INVALID_GAME_OBJECT );
- }
- return eResult;
- }
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- AkErrorMessageTranslator* FAkAudioDevice::m_UnrealErrorTranslator;
- #endif
- AKRESULT FAkAudioDevice::RegisterGameObject(AkGameObjectID GameObjectID, const FString& Name)
- {
- return FAkAudioDevice_Helpers::RegisterGameObject(GameObjectID, Name);
- }
- bool FAkAudioDevice::EnsureInitialized()
- {
- static bool bPermanentInitializationFailure = false;
- static bool bLogWwiseVersionOnce = true;
- if (LIKELY(m_bSoundEngineInitialized))
- {
- return true;
- }
- if (UNLIKELY(bPermanentInitializationFailure))
- {
- return false;
- }
- SCOPED_AKAUDIO_EVENT_2(TEXT("FAkAudioDevice::EnsureInitialized"));
- UE_CLOG(bLogWwiseVersionOnce, LogAkAudio, Log,
- TEXT("Wwise(R) SDK Version %d.%d.%d Build %d [%s]. Copyright (c) 2006-%d Audiokinetic Inc."),
- AK_WWISESDK_VERSION_MAJOR,
- AK_WWISESDK_VERSION_MINOR,
- AK_WWISESDK_VERSION_SUBMINOR,
- AK_WWISESDK_VERSION_BUILD,
- TEXT(WWISE_CONFIGURATION_DIR),
- AK_WWISESDK_VERSION_MAJOR);
- bLogWwiseVersionOnce = false;
- auto* ResourceLoader = FWwiseResourceLoader::Get();
- if (UNLIKELY(!ResourceLoader))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Wwise Initialization Error: No ResourceLoader module"));
- bPermanentInitializationFailure = true;
- return false;
- }
- // We don't want sound in those cases.
- if (AK_USE_NULL_SOUNDENGINE)
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: Using the null SoundEngine."));
- UE_LOG(LogWwiseHints, Log, TEXT("Usage of the null SoundEngine is determined during UBT. Check UBT logs for more information."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- if (FParse::Param(FCommandLine::Get(), TEXT("nosound")))
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: \"nosound\" command line parameter."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- if (FApp::IsBenchmarking())
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: App is benchmarking."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- if (IsRunningDedicatedServer())
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: Running a dedicated server."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- if (IsRunningCommandlet())
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: Running a commandlet."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- const UAkSettings* AkSettings = GetDefault<UAkSettings>();
- if (UNLIKELY(!AkSettings))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Wwise Initialization Error: No default settings."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- if (!AkSettings->bWwiseSoundEngineEnabled)
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise SoundEngine is disabled: Audio Routing is set to Enable Unreal Audio only."));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- auto* FileHandlerModule = IWwiseFileHandlerModule::GetModule();
- if (UNLIKELY(!FileHandlerModule))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Wwise Initialization Error: No file handling module"));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Wwise Initialization Error: No Sound Engine"));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- IOHook = FileHandlerModule->InstantiateIOHook();
- if (UNLIKELY(!IOHook))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Wwise Initialization Error: No IO Hook"));
- bPermanentInitializationFailure = true;
- ResourceLoader->Disable();
- return false;
- }
- // From this point on, if we get an error, we can try initializing later
- if (UNLIKELY(!FAkSoundEngineInitialization::Initialize(IOHook)))
- {
- UE_LOG(LogAkAudio, Display, TEXT("Wwise Initialization Error."));
- FAkSoundEngineInitialization::Finalize(IOHook);
- delete IOHook;
- IOHook = nullptr;
- ResourceLoader->Disable();
- return false;
- }
- UE_LOG(LogAkAudio, Log, TEXT("Wwise SoundEngine successfully initialized."));
- SetLocalOutput();
- // Init dummy game object
- SoundEngine->RegisterGameObj(DUMMY_GAMEOBJ, "Unreal Global");
- #if WITH_EDITOR
- if (!IsRunningGame())
- {
- AkGameObjectID tempID = DUMMY_GAMEOBJ;
- SoundEngine->SetListeners(DUMMY_GAMEOBJ, &tempID, 1);
- }
- #endif
- m_bSoundEngineInitialized = true;
- CallbackInfoPool = new AkCallbackInfoPool;
- // Go get the max number of Aux busses
- MaxAuxBus = AkSettings->MaxSimultaneousReverbVolumes;
- //TUniquePtr
- CallbackManager = new FAkComponentCallbackManager();
- SetCurrentAudioCulture(GetDefaultLanguage());
- UE_LOG(LogAkAudio, Log, TEXT("Initialization complete."));
- return CallbackManager != nullptr;
- }
- void FAkAudioDevice::SetLocalOutput()
- {
- auto* Monitor = IWwiseMonitorAPI::Get();
- if (UNLIKELY(!Monitor))
- {
- return;
- }
- Monitor->ResetTranslator();
- #if WITH_EDITORONLY_DATA && !defined(AK_OPTIMIZED)
- const UAkSettingsPerUser* AkSettingsPerUser = GetDefault<UAkSettingsPerUser>();
- if (AkSettingsPerUser->WaapiTranslatorTimeout > 0)
- {
- #if AK_SUPPORT_WAAPI
- Monitor->SetupDefaultWAAPIErrorTranslator(AkSettingsPerUser->WaapiIPAddress, AkSettingsPerUser->WaapiPort, AkSettingsPerUser->WaapiTranslatorTimeout);
- #endif //AK_SUPPORT_WAAPI
- }
- if (!m_UnrealErrorTranslator)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine))
- {
- return;
- }
- m_UnrealErrorTranslator = SoundEngine->NewErrorMessageTranslator(&GetInfoErrorMessageTranslatorFunction);
- }
- if (m_UnrealErrorTranslator)
- {
- Monitor->AddTranslator(m_UnrealErrorTranslator);
- }
- #endif
- }
- void FAkAudioDevice::AddDefaultListener(UAkComponent* in_pListener)
- {
- bool bAlreadyInSet;
- m_defaultListeners.Add(in_pListener, &bAlreadyInSet);
- if (!bAlreadyInSet)
- {
- for (TObjectIterator<UAkComponent> Emitter; Emitter; ++Emitter)
- {
- Emitter->OnDefaultListenerAdded(in_pListener);
- }
-
- in_pListener->IsListener = true;
- in_pListener->IsDefaultListener = true;
- UpdateDefaultActiveListeners();
- if (m_SpatialAudioListener == nullptr)
- SetSpatialAudioListener(in_pListener);
- }
- }
- void FAkAudioDevice::RemoveDefaultListener(UAkComponent* in_pListener)
- {
- for (TObjectIterator<UAkComponent> Emitter; Emitter; ++Emitter)
- {
- Emitter->OnListenerUnregistered(in_pListener);
- }
- m_defaultListeners.Remove(in_pListener);
- in_pListener->IsListener = false;
- in_pListener->IsDefaultListener = false;
- UpdateDefaultActiveListeners();
- // We are setting Aux Sends with the SpatialAudio API, and that requires a Spatial Audio listener.
- // When running dedicated server, Unreal creates a camera manager (default listener 1 gets set as spatial audio listener), then another one (default listener 2), and then destroys the first. This leaves us with a default listener, but no spatial audio listener. This fix targets that issue.
- if (m_SpatialAudioListener == in_pListener )
- {
- // Unregister the Spatial Audio Listener if its game object is unregistered
- auto* SpatialAudio = IWwiseSpatialAudioAPI::Get();
- if (LIKELY(SpatialAudio))
- {
- SpatialAudio->UnregisterListener(m_SpatialAudioListener->GetAkGameObjectID());
- }
- m_SpatialAudioListener = nullptr;
- if (m_defaultListeners.Num() > 0)
- {
- for (auto listener : m_defaultListeners)
- {
- if (SetSpatialAudioListener(m_defaultListeners.Array()[0]))
- {
- break;
- }
- }
- }
- }
- }
- void FAkAudioDevice::OnActorSpawned(AActor* SpawnedActor)
- {
- APlayerCameraManager* AsPlayerCameraManager = Cast<APlayerCameraManager>(SpawnedActor);
- if (AsPlayerCameraManager && AsPlayerCameraManager->GetWorld()->AllowAudioPlayback())
- {
- APlayerController* CameraOwner = Cast<APlayerController>(AsPlayerCameraManager->GetOwner());
- if (CameraOwner && CameraOwner->IsLocalPlayerController())
- {
- UAkComponent* pAkComponent = NewObject<UAkComponent>(SpawnedActor);
- if (pAkComponent != nullptr)
- {
- pAkComponent->RegisterComponentWithWorld(SpawnedActor->GetWorld());
- pAkComponent->AttachToComponent(SpawnedActor->GetRootComponent(), FAttachmentTransformRules::KeepWorldTransform, FName());
- AddDefaultListener(pAkComponent);
- }
- }
- }
- }
- FString FAkAudioDevice::GetBasePath()
- {
- return WwiseUnrealHelper::GetSoundBankDirectory();
- }
- /**
- * Allocates memory from permanent pool. This memory will NEVER be freed.
- *
- * @param Size Size of allocation.
- *
- * @return pointer to a chunk of memory with size Size
- */
- void* FAkAudioDevice::AllocatePermanentMemory( int32 Size, bool& AllocatedInPool )
- {
- return 0;
- }
- AKRESULT FAkAudioDevice::GetGameObjectID( AActor * in_pActor, AkGameObjectID& io_GameObject )
- {
- if ( IsValid(in_pActor) )
- {
- UAkComponent * pComponent = GetAkComponent( in_pActor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset );
- if ( pComponent )
- {
- io_GameObject = pComponent->GetAkGameObjectID();
- return AK_Success;
- }
- else
- return AK_Fail;
- }
- // we do not modify io_GameObject, letting it to the specified default value.
- return AK_Success;
- }
- AKRESULT FAkAudioDevice::GetGameObjectID( AActor * in_pActor, AkGameObjectID& io_GameObject, bool in_bStopWhenOwnerDestroyed )
- {
- if ( IsValid(in_pActor) )
- {
- UAkComponent * pComponent = GetAkComponent( in_pActor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset );
- if ( pComponent )
- {
- pComponent->StopWhenOwnerDestroyed = in_bStopWhenOwnerDestroyed;
- io_GameObject = pComponent->GetAkGameObjectID();
- return AK_Success;
- }
- else
- return AK_Fail;
- }
- // we do not modify io_GameObject, letting it to the specified default value.
- return AK_Success;
- }
- void FAkAudioDevice::Suspend(bool in_bRenderAnyway /* = false */)
- {
- if (!m_isSuspended)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->Suspend(in_bRenderAnyway);
- m_isSuspended = true;
- }
- }
- void FAkAudioDevice::WakeupFromSuspend()
- {
- if (m_isSuspended)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->WakeupFromSuspend();
- m_isSuspended = false;
- }
- }
- void FAkAudioDevice::StartOutputCapture(const FString& Filename)
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->StartOutputCapture(TCHAR_TO_AK(*Filename));
- }
- }
- void FAkAudioDevice::StopOutputCapture()
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->StopOutputCapture();
- }
- }
- void FAkAudioDevice::StartProfilerCapture(const FString& Filename)
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->StartProfilerCapture(TCHAR_TO_AK(*Filename));
- }
- }
- void FAkAudioDevice::AddOutputCaptureMarker(const FString& MarkerText)
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->AddOutputCaptureMarker(TCHAR_TO_ANSI(*MarkerText));
- }
- }
- void FAkAudioDevice::StopProfilerCapture()
- {
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->StopProfilerCapture();
- }
- }
- AKRESULT FAkAudioDevice::RegisterPluginDLL(const FString& in_DllName, const FString& in_DllPath)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- AkOSChar* szPath = nullptr;
- if (!in_DllPath.IsEmpty())
- {
- auto Length = in_DllPath.Len() + 1;
- szPath = new AkOSChar[Length];
- AKPLATFORM::SafeStrCpy(szPath, TCHAR_TO_AK(*in_DllPath), Length);
- }
- AKRESULT eResult = SoundEngine->RegisterPluginDLL(TCHAR_TO_AK(*in_DllName), szPath);
- delete[] szPath;
- return eResult;
- }
- // end
- FAkAudioDevice::SetCurrentAudioCultureAsyncTask::SetCurrentAudioCultureAsyncTask(FWwiseLanguageCookedData NewLanguage, FSetCurrentAudioCultureAction* LatentAction)
- : Language(NewLanguage)
- , SetAudioCultureLatentAction(LatentAction)
- {
- CompletionActionType = CompletionType::LatentAction;
- LatentActionValidityToken = MakeShared<FPendingLatentActionValidityToken, ESPMode::ThreadSafe>();
- SetAudioCultureLatentAction->ValidityToken = LatentActionValidityToken;
- }
- FAkAudioDevice::SetCurrentAudioCultureAsyncTask::SetCurrentAudioCultureAsyncTask(FWwiseLanguageCookedData NewLanguage, const FOnSetCurrentAudioCultureCompleted& CompletedCallback)
- : Language(NewLanguage)
- , SetAudioCultureCompletedCallback(CompletedCallback)
- {
- CompletionActionType = CompletionType::Callback;
- }
- bool FAkAudioDevice::SetCurrentAudioCultureAsyncTask::Start()
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Switching Wwise language to '%s'"), *Language.GetLanguageName().ToString());
- auto* StreamMgr = IWwiseStreamMgrAPI::Get();
- if (UNLIKELY(!StreamMgr))
- {
- return false;
- }
- StreamMgr->SetCurrentLanguage(TCHAR_TO_AK(*Language.GetLanguageName().ToString()));
- AsyncTask(ENamedThreads::AnyNormalThreadNormalTask, [this]()
- {
- auto* ResourceLoader = FWwiseResourceLoader::Get();
- if (UNLIKELY(!ResourceLoader))
- {
- UE_LOG(LogAkAudio, Error, TEXT("SetCurrentAudioCultureAsync: Could not get resource loader, cannot change language."));
- Succeeded = false;
- IsDone = true;
- return;
- }
- ResourceLoader->SetLanguage(Language, EWwiseReloadLanguage::Immediate);
- IsDone = true;
- Succeeded = true;
- });
- return true;
- }
- void FAkAudioDevice::SetCurrentAudioCultureAsyncTask::Update()
- {
- if (IsDone)
- {
- switch (CompletionActionType)
- {
- case CompletionType::Callback:
- SetAudioCultureCompletedCallback.ExecuteIfBound(Succeeded);
- break;
- case CompletionType::LatentAction:
- if (LatentActionValidityToken->bValid && SetAudioCultureLatentAction)
- {
- SetAudioCultureLatentAction->ActionDone = true;
- }
- break;
- }
- }
- }
- void FAkAudioDevice::AddPlayingID(uint32 EventID, uint32 PlayingID, EAkAudioContext AudioContext)
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto& PlayingIDArray = EventToPlayingIDMap.FindOrAdd(EventID);
- PlayingIDArray.Add(PlayingID);
- PlayingIDToAudioContextMap.Add(PlayingID, AudioContext);
- }
- bool FAkAudioDevice::IsPlayingIDActive(uint32 EventID, uint32 PlayingID)
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto* PlayingIDArray = EventToPlayingIDMap.Find(EventID);
- if (PlayingIDArray && PlayingIDArray->Contains(PlayingID))
- {
- return true;
- }
- return false;
- }
- bool FAkAudioDevice::IsEventIDActive(uint32 EventID)
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- return EventToPlayingIDMap.Contains(EventID);
- }
- void FAkAudioDevice::RemovePlayingID(uint32 EventID, uint32 PlayingID)
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto* PlayingIDArray = EventToPlayingIDMap.Find(EventID);
- if (PlayingIDArray)
- {
- PlayingIDArray->Remove(PlayingID);
- if (PlayingIDArray->Num() == 0)
- {
- EventToPlayingIDMap.Remove(EventID);
- PlayingIDToAudioContextMap.Remove(PlayingID);
- }
- }
- }
- void FAkAudioDevice::StopEventID(uint32 EventID)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto* PlayingIDs = EventToPlayingIDMap.Find(EventID);
- if (PlayingIDs)
- {
- for (auto pID : *PlayingIDs)
- {
- StopPlayingID(pID);
- }
- SoundEngine->RenderAudio();
- }
- }
- FOnSwitchValueLoaded& FAkAudioDevice::GetOnSwitchValueLoaded(uint32 SwitchID)
- {
- return OnSwitchValueLoadedMap.FindOrAdd(SwitchID);
- }
- void FAkAudioDevice::BroadcastOnSwitchValueLoaded(UAkGroupValue* GroupValue)
- {
- FOnSwitchValueLoaded* EventToBroadcast = OnSwitchValueLoadedMap.Find(GroupValue->GetShortID());
- if (EventToBroadcast)
- {
- EventToBroadcast->Broadcast(GroupValue);
- }
- }
- void FAkAudioDevice::AddPortalConnectionToOutdoors(const UWorld* in_world, UAkPortalComponent* in_pPortal)
- {
- if (in_world == nullptr)
- {
- return;
- }
- OutdoorsConnectedPortals.FindOrAdd(in_world).Add(in_pPortal->GetPortalID(), in_pPortal);
- }
- void FAkAudioDevice::RemovePortalConnectionToOutdoors(const UWorld* in_world, AkPortalID in_portalID)
- {
- if (in_world == nullptr)
- {
- return;
- }
- auto pPortals = OutdoorsConnectedPortals.Find(in_world);
- if (pPortals == nullptr)
- {
- return;
- }
- pPortals->Remove(in_portalID);
- }
- void FAkAudioDevice::GetObsOccServicePortalMap(const UAkRoomComponent* InRoom, const UWorld* InWorld, AkObstructionAndOcclusionService::PortalMap& OutPortalMap) const
- {
- PortalComponentMap ConnectedPortals;
- if (InRoom != nullptr)
- {
- ConnectedPortals = InRoom->GetConnectedPortals();
- }
- else
- {
- auto Portals = OutdoorsConnectedPortals.Find(InWorld);
- if (Portals != nullptr)
- {
- ConnectedPortals = *Portals;
- }
- }
- for (auto& Portal : ConnectedPortals)
- {
- AkObstructionAndOcclusionService::FPortalInfo PortalInfo(Portal.Value->Bounds.GetBox().GetCenter(), Portal.Value->ObstructionRefreshInterval != 0.f);
- OutPortalMap.Add(Portal.Key, PortalInfo);
- }
- }
|