123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791 |
- /*******************************************************************************
- 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 "AkUnrealHelper.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 "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, AkUnrealHelper::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;
- }
- }
- }
- );
- 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)
- {
- RemoveDefaultListener(EditorListener);
- }
- }
- 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)
- {
- ExecuteActionOnPlayingID(AkActionOnEventType::Pause, PlayingID, 0.0f, EAkCurveInterpolation::Linear);
- }
- }
- }
- }
- }
- 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)
- {
- ExecuteActionOnPlayingID(AkActionOnEventType::Resume, PlayingID, 0.0f, EAkCurveInterpolation::Linear);
- }
- }
- }
- }
- }
- void FAkAudioDevice::OnSwitchBeginPIEAndSIE(const bool bIsSimulating)
- {
- 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);
- }
- }
- 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)
- {
- 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;
- }
- }
- 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)
- {
- const bool RoomsChanged = Portal->UpdateConnectedRooms();
- if (RoomsChanged)
- SetSpatialAudioPortal(Portal);
- }
- }
- }
- WorldsInNeedOfPortalRoomsUpdate.Empty();
- #endif
- }
- void FAkAudioDevice::CleanupComponentMapsForWorld(UWorld* World)
- {
- LateReverbIndex.Clear(World);
- RoomIndex.Clear(World);
- WorldPortalsMap.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
- */
- AKRESULT 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();
- }
- return AK_Success;
- }
- return AK_NotInitialized;
- }
- AKRESULT FAkAudioDevice::ClearBanks()
- {
- return ClearSoundBanksAndMedia();
- }
- 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, AkUnrealHelper::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, AkUnrealHelper::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::PostEventWithCallbackPackageOnGameObjectId(
- const AkUInt32 EventShortID,
- const AkGameObjectID GameObjectID,
- const TArray<AkExternalSourceInfo>& ExternalSources,
- FCreateCallbackPackage CreateCallbackPackage,
- EAkAudioContext AudioContext
- )
- {
- UE_LOG(LogWwiseHints, Warning, TEXT("[Deprecated 22.1] Posting Event(%" PRIu32 ") GameObject(%" PRIu64 "). Should use Event posting through an AkAudioEvent class instead."), EventShortID, GameObjectID);
- AkPlayingID PlayingID = AK_INVALID_PLAYING_ID;
- if (m_bSoundEngineInitialized && CallbackManager)
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_INVALID_PLAYING_ID;
- auto pPackage = CreateCallbackPackage(GameObjectID);
- if (pPackage)
- {
- PlayingID = SoundEngine->PostEvent(
- EventShortID
- , GameObjectID
- , pPackage->uUserFlags | AK_EndOfEvent
- , &FAkComponentCallbackManager::AkComponentCallback
- , pPackage
- , ExternalSources.Num()
- , const_cast<AkExternalSourceInfo*>(ExternalSources.GetData())
- );
- if (PlayingID == AK_INVALID_PLAYING_ID)
- {
- CallbackManager->RemoveCallbackPackage(pPackage, GameObjectID);
- }
- else
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto& PlayingIDArray = EventToPlayingIDMap.FindOrAdd(EventShortID);
- PlayingIDArray.Add(PlayingID);
- PlayingIDToAudioContextMap.Add(PlayingID, AudioContext);
- }
- }
- }
- return PlayingID;
- }
- 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;
- }
- AkPlayingID FAkAudioDevice::PostAkAudioEventOnActor(
- UAkAudioEvent* AkEvent,
- AActor* Actor,
- AkUInt32 Flags /*= 0*/,
- AkCallbackFunc Callback /*= NULL*/,
- void* Cookie /*= NULL*/,
- bool bStopWhenOwnerDestroyed, /*= false*/
- EAkAudioContext AudioContext /* = GameplayAudio*/
- )
- {
- if (UNLIKELY(!AkEvent))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post AkAudioEvent without an AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- if (UNLIKELY(!IsValid(AkEvent)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post with invalid AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- return AkEvent->PostOnActor(Actor, nullptr, Callback, Cookie, (AkCallbackType)Flags, nullptr, bStopWhenOwnerDestroyed, AudioContext);
- }
- AkPlayingID FAkAudioDevice::PostAkAudioEventOnComponent(
- UAkAudioEvent* AkEvent,
- UAkComponent* Component,
- AkUInt32 Flags,
- AkCallbackFunc Callback,
- void* Cookie,
- bool bStopWhenOwnerDestroyed,
- EAkAudioContext AudioContext)
- {
- if (UNLIKELY(!AkEvent))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post AkAudioEvent without an AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- if (UNLIKELY(!IsValid(AkEvent)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post with invalid AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- return AkEvent->PostOnComponent(Component, nullptr, Callback, Cookie, (AkCallbackType)Flags, nullptr, bStopWhenOwnerDestroyed, AudioContext);
- }
- AkPlayingID FAkAudioDevice::PostEventOnActor(
- const AkUInt32 EventShortID,
- AActor * Actor,
- AkUInt32 Flags /*= 0*/,
- AkCallbackFunc Callback /*= NULL*/,
- void * Cookie /*= NULL*/,
- bool bStopWhenOwnerDestroyed /*= false*/,
- const TArray<AkExternalSourceInfo> ExternalSources, /* = TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- if (m_bSoundEngineInitialized)
- {
- if (!Actor)
- {
- return PostEventWithCallbackPackageOnGameObjectId(EventShortID, DUMMY_GAMEOBJ, ExternalSources, [Callback, Cookie, Flags, this, HasExtSrc=ExternalSources.Num()>0](AkGameObjectID gameObjID) {
- return CallbackManager->CreateCallbackPackage(Callback, Cookie, Flags, gameObjID, HasExtSrc);
- }, AudioContext);
- }
- else if (!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- {
- UAkComponent* pComponent = GetAkComponent(Actor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset);
- if (pComponent)
- {
- pComponent->StopWhenOwnerDestroyed = bStopWhenOwnerDestroyed;
- return PostEventOnAkComponent(EventShortID, pComponent, Flags, Callback, Cookie, ExternalSources, AudioContext);
- }
- }
- }
- return AK_INVALID_PLAYING_ID;
- }
- AkPlayingID FAkAudioDevice::PostEventOnActor(
- const AkUInt32 EventShortID,
- AActor* Actor,
- const FOnAkPostEventCallback& PostEventCallback,
- AkUInt32 Flags /*= 0*/,
- bool bStopWhenOwnerDestroyed,
- /*= false*/
- const TArray<AkExternalSourceInfo>& ExternalSources, /* = TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- if (m_bSoundEngineInitialized)
- {
- if (!Actor)
- {
- UE_LOG(LogAkAudio, Error, TEXT("PostEvent accepting a FOnAkPostEventCallback delegate requires a valid actor"));
- }
- else if (!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- {
- UAkComponent* pComponent = GetAkComponent(Actor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset);
- if (pComponent)
- {
- pComponent->StopWhenOwnerDestroyed = bStopWhenOwnerDestroyed;
- return PostEventOnAkGameObject(EventShortID, pComponent, PostEventCallback, Flags, ExternalSources, AudioContext);
- }
- }
- }
- return AK_INVALID_PLAYING_ID;
- }
- AkPlayingID FAkAudioDevice::PostEventOnActorWithLatentAction(
- const AkUInt32 EventShortID,
- AActor* Actor,
- bool bStopWhenOwnerDestroyed,
- FWaitEndOfEventAction* LatentAction,
- const TArray<AkExternalSourceInfo>& ExternalSources, /* = TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- if (m_bSoundEngineInitialized)
- {
- if (!Actor)
- {
- UE_LOG(LogAkAudio, Error, TEXT("PostEvent accepting a FWaitEndOfEventAction requires a valid actor"));
- }
- else if (!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- {
- UAkComponent* pComponent = GetAkComponent(Actor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset);
- if (pComponent)
- {
- pComponent->StopWhenOwnerDestroyed = bStopWhenOwnerDestroyed;
- return PostEventOnComponentWithLatentAction(EventShortID, pComponent, LatentAction, ExternalSources, AudioContext);
- }
- }
- }
- return AK_INVALID_PLAYING_ID;
- }
- /**
- * Post an event to ak soundengine by name
- *
- * @param EventShortID Name of the event to post
- * @param in_pGameObject UAkGameObject on which to play the event
- * @param in_uFlags Bitmask: see \ref AkCallbackType
- * @param in_pfnCallback Callback function
- * @param in_pCookie Callback cookie that will be sent to the callback function along with additional information.
- * @return ID assigned by ak soundengine
- */
- AkPlayingID FAkAudioDevice::PostEventOnAkComponent(
- const AkUInt32 EventShortID,
- UAkComponent* Component,
- AkUInt32 Flags /*= 0*/,
- AkCallbackFunc Callback /*= NULL*/,
- void * Cookie,
- /*= NULL*/
- const TArray<AkExternalSourceInfo>& ExternalSources, /*= TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- return PostEventWithCallbackPackageOnAkGameObject(EventShortID, Component, ExternalSources, [Callback, Cookie, Flags, this, HasExtSrc = ExternalSources.Num() > 0](AkGameObjectID gameObjID) {
- return CallbackManager->CreateCallbackPackage(Callback, Cookie, Flags, gameObjID, HasExtSrc);
- }, AudioContext);
- }
- AkPlayingID FAkAudioDevice::PostEventOnGameObjectID(
- const AkUInt32 EventShortID,
- AkGameObjectID GameObject,
- AkUInt32 Flags /*= 0*/,
- AkCallbackFunc Callback /*= NULL*/,
- void* Cookie,
- /*= NULL*/
- const TArray<AkExternalSourceInfo>& ExternalSources, /*= TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- return PostEventWithCallbackPackageOnGameObjectId(EventShortID, GameObject, ExternalSources, [Callback, Cookie, Flags, this, HasExtSrc = ExternalSources.Num() > 0](AkGameObjectID gameObjID) {
- return CallbackManager->CreateCallbackPackage(Callback, Cookie, Flags, gameObjID, HasExtSrc);
- }, AudioContext);
- }
- AkPlayingID FAkAudioDevice::PostEventOnAkGameObject(
- const AkUInt32 EventShortID,
- UAkGameObject* AkGameObject,
- const FOnAkPostEventCallback& PostEventCallback,
- AkUInt32 Flags,
- /*= 0*/
- const TArray<AkExternalSourceInfo>& ExternalSources, /*= TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- return PostEventWithCallbackPackageOnAkGameObject(EventShortID, AkGameObject, ExternalSources, [PostEventCallback, Flags, this, HasExtSrc = ExternalSources.Num() > 0](AkGameObjectID gameObjID) {
- return CallbackManager->CreateCallbackPackage(PostEventCallback, Flags, gameObjID, HasExtSrc);
- }, AudioContext);
- }
- AkPlayingID FAkAudioDevice::PostEventOnComponentWithLatentAction(
- const AkUInt32 EventShortID,
- UAkComponent* AkComponent,
- FWaitEndOfEventAction* LatentAction,
- const TArray<AkExternalSourceInfo>& ExternalSources, /*= TArray<AkExternalSourceInfo>()*/
- EAkAudioContext AudioContext
- )
- {
- return PostEventWithCallbackPackageOnAkGameObject(EventShortID, AkComponent, ExternalSources, [LatentAction, this, HasExtSrc = ExternalSources.Num() > 0](AkGameObjectID gameObjID) {
- return CallbackManager->CreateCallbackPackage(LatentAction, gameObjID, HasExtSrc);
- }, AudioContext);
- }
- void FAkAudioDevice::SAComponentAddedRemoved(UWorld* World)
- {
- if (World != nullptr)
- {
- if (WorldVolumesUpdatedMap.Contains(World))
- WorldVolumesUpdatedMap[World] = true;
- else
- WorldVolumesUpdatedMap.Add(World, true);
- }
- }
- TFuture<AkPlayingID> FAkAudioDevice::PostAkAudioEventOnActorAsync(
- UAkAudioEvent* AkEvent,
- AActor* Actor,
- const FOnAkPostEventCallback& PostEventCallback,
- AkUInt32 CallbackFlags,
- bool bStopWhenOwnerDestroyed,
- EAkAudioContext AudioContext
- )
- {
- UE_CLOG(AkEvent && Actor, LogWwiseHints, Log, TEXT("[Deprecated 22.1] PostAsync on Event(%s; %" PRIu32 ") Actor(%s). Async operations on Events are deprecated."), *AkEvent->GetName(), AkEvent->GetShortID(), *Actor->GetName());
- TPromise<AkPlayingID> PlayingIDPromise;
- auto PlayingIDFuture = PlayingIDPromise.GetFuture();
- if (UNLIKELY(!AkEvent))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post AkAudioEvent without an AkAudioEvent."))
- PlayingIDPromise.SetValue(AK_INVALID_PLAYING_ID);
- return PlayingIDFuture;
- }
- if (!Actor)
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post AkAudioEvent '%s': accepting a FOnAkPostEventCallback delegate requires a valid actor"), *AkEvent->GetName());
- PlayingIDPromise.SetValue(AK_INVALID_PLAYING_ID);
- return PlayingIDFuture;
- }
- const auto PollMediaReadyTask = FFunctionGraphTask::CreateAndDispatchWhenReady([Actor, AkEvent]()
- {
- while (LIKELY(!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- && LIKELY(IsValid(AkEvent))
- && !AkEvent->IsDataFullyLoaded())
- {
- FPlatformProcess::Sleep(1.f / 60.f);
- }
- }, GET_STATID(STAT_PostEventAsync), nullptr, ENamedThreads::AnyThread);
- FFunctionGraphTask::CreateAndDispatchWhenReady([this, AkEvent, Actor, PostEventCallback, CallbackFlags, bStopWhenOwnerDestroyed, PlayingIDPromise = MoveTemp(PlayingIDPromise), AudioContext]() mutable
- {
- if (UNLIKELY(!IsValid(AkEvent)))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post invalid AkAudioEvent."))
- PlayingIDPromise.SetValue(AK_INVALID_PLAYING_ID);
- return;
- }
- PlayingIDPromise.SetValue(AkEvent->PostOnActor(Actor, &PostEventCallback, nullptr, nullptr, (AkCallbackType)CallbackFlags, nullptr, bStopWhenOwnerDestroyed, AudioContext));
- }, GET_STATID(STAT_PostEventAsync), PollMediaReadyTask, ENamedThreads::GameThread);
- return PlayingIDFuture;
- }
- TFuture<AkPlayingID> FAkAudioDevice::PostAkAudioEventOnAkGameObjectAsync(
- UAkAudioEvent* AudioEvent,
- UAkGameObject* GameObject,
- const FOnAkPostEventCallback& PostEventCallback,
- AkUInt32 CallbackFlags,
- EAkAudioContext AudioContext)
- {
- UE_CLOG(AudioEvent && GameObject, LogWwiseHints, Log, TEXT("[Deprecated 22.1] PostAsync on Event(%s; %" PRIu32 ") GameObject(%s). Async operations on Events are deprecated."), *AudioEvent->GetName(), AudioEvent->GetShortID(), *GameObject->GetName());
- auto PlayingIDFuture = Async(EAsyncExecution::TaskGraph, [AudioEvent] {
- while (IsValid(AudioEvent) && !AudioEvent->IsDataFullyLoaded())
- {
- FPlatformProcess::Sleep(1.f / 60.f);
- }
- }).Then([this, AudioEvent, GameObject, PostEventCallback, CallbackFlags, AudioContext](auto PreviousFuture) {
- if (UNLIKELY(!IsValid(AudioEvent)))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post invalid AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- return AudioEvent->PostOnGameObject(GameObject, &PostEventCallback, nullptr, nullptr, (AkCallbackType)CallbackFlags, nullptr, AudioContext);
- });
- return PlayingIDFuture;
- }
- TFuture<AkPlayingID> FAkAudioDevice::PostAkAudioEventAtLocationAsync(
- UAkAudioEvent* Event,
- FVector Location,
- FRotator Orientation,
- class UWorld* World,
- EAkAudioContext AudioContext
- )
- {
- UE_CLOG(Event, LogWwiseHints, Log, TEXT("[Deprecated 22.1] PostAsync on Event(%s; %" PRIu32 ") AtLocation. Async operations on Events are deprecated."), *Event->GetName(), Event->GetShortID());
- TPromise<AkPlayingID> playingIDPromise;
- auto playingIDFuture = playingIDPromise.GetFuture();
- auto pollMediaReadyTask = FFunctionGraphTask::CreateAndDispatchWhenReady([Event]()
- {
- while (IsValid(Event) && !Event->IsDataFullyLoaded())
- {
- FPlatformProcess::Sleep(1.f / 60.f);
- }
- }, GET_STATID(STAT_PostEventAsync), nullptr, ENamedThreads::AnyThread);
- FFunctionGraphTask::CreateAndDispatchWhenReady([this, Event, Location, Orientation, World, playingIDPromiseCopy(MoveTemp(playingIDPromise)), AudioContext]() mutable {
- if (UNLIKELY(!IsValid(Event)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post invalid AkAudioEvent."))
- playingIDPromiseCopy.SetValue(AK_INVALID_PLAYING_ID);
- return;
- }
- playingIDPromiseCopy.SetValue(Event->PostAtLocation(Location, Orientation, World, nullptr, nullptr, nullptr, (AkCallbackType)0, nullptr, AudioContext));
- }, GET_STATID(STAT_PostEventAsync), pollMediaReadyTask, ENamedThreads::GameThread);
- return playingIDFuture;
- }
- TFuture<AkPlayingID> FAkAudioDevice::PostAkAudioEventWithLatentActionOnActorAsync(
- UAkAudioEvent* AudioEvent,
- AActor* Actor,
- bool bStopWhenOwnerDestroyed,
- FWaitEndOfEventAction* LatentAction,
- EAkAudioContext AudioContext)
- {
- UE_CLOG(AudioEvent && Actor, LogWwiseHints, Log, TEXT("[Deprecated 22.1] PostAsync on Event(%s; %" PRIu32 ") Actor(%s). Async operations on Events are deprecated."), *AudioEvent->GetName(), AudioEvent->GetShortID(), *Actor->GetName());
- TPromise<AkPlayingID> PlayingIDPromise;
- auto PlayingIDFuture = PlayingIDPromise.GetFuture();
- auto PollMediaReadyTask = FFunctionGraphTask::CreateAndDispatchWhenReady([AudioEvent]()
- {
- while (IsValid(AudioEvent) && !AudioEvent->IsDataFullyLoaded())
- {
- FPlatformProcess::Sleep(1.f / 60.f);
- }
- }, GET_STATID(STAT_PostEventAsync), nullptr, ENamedThreads::AnyThread);
- FFunctionGraphTask::CreateAndDispatchWhenReady([this, AudioEvent, Actor, bStopWhenOwnerDestroyed, LatentAction, PlayingIDPromiseCopy(MoveTemp(PlayingIDPromise)), AudioContext]() mutable {
- if (UNLIKELY(!IsValid(AudioEvent)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post invalid AkAudioEvent."))
- PlayingIDPromiseCopy.SetValue(AK_INVALID_PLAYING_ID);
- return;
- }
- PlayingIDPromiseCopy.SetValue(AudioEvent->PostOnActor(Actor, nullptr, nullptr, nullptr, (AkCallbackType)0, LatentAction, bStopWhenOwnerDestroyed, AudioContext));
- }, GET_STATID(STAT_PostEventAsync), PollMediaReadyTask, ENamedThreads::GameThread);
- return PlayingIDFuture;
- }
- TFuture<AkPlayingID> FAkAudioDevice::PostAkAudioEventWithLatentActionOnAkComponentAsync(
- UAkAudioEvent* AudioEvent,
- UAkComponent* AkComponent,
- bool bStopWhenOwnerDestroyed,
- FWaitEndOfEventAction* LatentAction,
- EAkAudioContext AudioContext)
- {
- UE_CLOG(AudioEvent && AkComponent, LogWwiseHints, Log, TEXT("[Deprecated 22.1] PostAsync on Event(%s; %" PRIu32 ") AkComponent(%s). Async operations on Events are deprecated."), *AudioEvent->GetName(), AudioEvent->GetShortID(), *AkComponent->GetName());
- auto PlayingIDFuture = Async(EAsyncExecution::TaskGraph, [AudioEvent]
- {
- while (AudioEvent && !AudioEvent->IsDataFullyLoaded())
- {
- FPlatformProcess::Sleep(1.f / 60.f);
- }
- }).Then([this, AudioEvent, AkComponent, bStopWhenOwnerDestroyed, LatentAction, AudioContext](auto PreviousFuture)
- {
- if (UNLIKELY(!IsValid(AudioEvent)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post invalid AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- return AudioEvent->PostOnComponent(AkComponent, nullptr, nullptr, nullptr, (AkCallbackType)0, LatentAction, bStopWhenOwnerDestroyed, AudioContext);
- });
- return PlayingIDFuture;
- }
- /** 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);
- }
- AKRESULT FAkAudioDevice::ExecuteActionOnEvent(
- const AkUInt32 EventShortID,
- AkActionOnEventType ActionType,
- AActor* Actor,
- AkTimeMs TransitionDuration,
- EAkCurveInterpolation FadeCurve,
- AkPlayingID PlayingID
- )
- {
- UE_CLOG(Actor, LogWwiseHints, Warning, TEXT("[Deprecated 22.1] Executing action on Event(%" PRIu32 ") PlayingID(%" PRIu32 ") for Actor(%s). Should use Event posting through an AkAudioEvent class instead."), EventShortID, PlayingID, *Actor->GetName());
- UE_CLOG(!Actor, LogWwiseHints, Warning, TEXT("[Deprecated 22.1] Executing action on Event(%" PRIu32 ") PlayingID(%" PRIu32 ") on Ambient sound. Should use Event posting through an AkAudioEvent class instead."), EventShortID, PlayingID);
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_NotInitialized;
- if (!Actor)
- {
- return SoundEngine->ExecuteActionOnEvent(EventShortID,
- static_cast<AK::SoundEngine::AkActionOnEventType>(ActionType),
- DUMMY_GAMEOBJ,
- TransitionDuration,
- static_cast<AkCurveInterpolation>(FadeCurve),
- PlayingID
- );
- }
- else if (!Actor->IsActorBeingDestroyed() && IsValid(Actor))
- {
- UAkComponent* pComponent = GetAkComponent(Actor->GetRootComponent(), FName(), NULL, EAttachLocation::KeepRelativeOffset);
- if (pComponent)
- {
- return SoundEngine->ExecuteActionOnEvent(EventShortID,
- static_cast<AK::SoundEngine::AkActionOnEventType>(ActionType),
- pComponent->GetAkGameObjectID(),
- TransitionDuration,
- static_cast<AkCurveInterpolation>(FadeCurve),
- PlayingID
- );
- }
- }
- return AKRESULT::AK_Fail;
- }
- void FAkAudioDevice::ExecuteActionOnPlayingID(
- AkActionOnEventType in_ActionType,
- AkPlayingID in_PlayingID,
- AkTimeMs in_uTransitionDuration,
- EAkCurveInterpolation in_eFadeCuve
- )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return;
- SoundEngine->ExecuteActionOnPlayingID(
- static_cast<AK::SoundEngine::AkActionOnEventType>(in_ActionType),
- in_PlayingID,
- in_uTransitionDuration,
- static_cast<AkCurveInterpolation>(in_eFadeCuve)
- );
- }
- /** 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)
- {
- SetSpatialAudioPortal(Portal);
- }
- }
- #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<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->GetFrontRoom();
- Params.BackRoom = in_Portal->GetBackRoom();
- 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);
- }
- }
- /**
- * Post an event and location to ak soundengine
- *
- * @param Event Name of the event to post
- * @param in_Location Location at which to play the event
- * @return ID assigned by ak soundengine
- */
- AkPlayingID FAkAudioDevice::PostAkAudioEventAtLocation(
- UAkAudioEvent * Event,
- FVector Location,
- FRotator Orientation,
- UWorld* World,
- EAkAudioContext AudioContext
- )
- {
- if (UNLIKELY(!Event))
- {
- UE_LOG(LogAkAudio, Verbose, TEXT("Failed to post AkAudioEvent without an AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- if (UNLIKELY(!IsValid(Event)))
- {
- UE_LOG(LogAkAudio, Error, TEXT("Failed to post invalid AkAudioEvent."))
- return AK_INVALID_PLAYING_ID;
- }
- return Event->PostAtLocation(Location, Orientation, World, nullptr, nullptr, nullptr, (AkCallbackType)0, nullptr, AudioContext);
- }
- 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);
- }
- }
- }
- }
- /**
- * Post an event by name at location to ak soundengine
- *
- * @param in_pEvent Name of the event to post
- * @param Location Location at which to play the event
- * @return ID assigned by ak soundengine
- */
- AkPlayingID FAkAudioDevice::PostEventAtLocation(
- const FString& EventName,
- const AkUInt32 EventShortID,
- FVector Location,
- FRotator Orientation,
- UWorld* World,
- const TArray<AkExternalSourceInfo>& ExternalSources,
- EAkAudioContext AudioContext
- )
- {
- UE_LOG(LogWwiseHints, Warning, TEXT("[Deprecated 22.1] Posting Event(%s; %" PRIu32 ") At Location. Should use Event posting through an AkAudioEvent class instead."), *EventName, EventShortID);
- AkPlayingID PlayingID = AK_INVALID_PLAYING_ID;
- if ( m_bSoundEngineInitialized )
- {
- auto* SoundEngine = IWwiseSoundEngineAPI::Get();
- if (UNLIKELY(!SoundEngine)) return AK_INVALID_PLAYING_ID;
- const AkGameObjectID objId = (AkGameObjectID)&EventName;
- FAkAudioDevice_Helpers::RegisterGameObject(objId, EventName);
- TArray<AkAuxSendValue> AkReverbVolumes;
- GetAuxSendValuesAtLocation(Location, AkReverbVolumes, World);
- SoundEngine->SetGameObjectAuxSendValues(objId, AkReverbVolumes.GetData(), AkReverbVolumes.Num());
- AkRoomID RoomID;
- TArray<UAkRoomComponent*> AkRooms = RoomIndex.Query<UAkRoomComponent>(Location, World);
- if (AkRooms.Num() > 0)
- RoomID = AkRooms[0]->GetRoomID();
- SetInSpatialAudioRoom(objId, RoomID);
- AkSoundPosition soundpos;
- FQuat tempQuat(Orientation);
- FVectorsToAKWorldTransform(Location, tempQuat.GetForwardVector(), tempQuat.GetUpVector(), soundpos);
- SoundEngine->SetPosition(objId, soundpos);
- PlayingID = SoundEngine->PostEvent(EventShortID, objId, AK_EndOfEvent, &FAkAudioDevice::PostEventAtLocationEndOfEventCallback, nullptr,
- ExternalSources.Num(), const_cast<AkExternalSourceInfo*>(ExternalSources.GetData()));
- if (PlayingID != AK_INVALID_PLAYING_ID)
- {
- FScopeLock Lock(&EventToPlayingIDMapCriticalSection);
- auto& PlayingIDs = EventToPlayingIDMap.FindOrAdd(EventShortID);
- PlayingIDs.Add(PlayingID);
- PlayingIDToAudioContextMap.Add(PlayingID, AudioContext);
- }
- SoundEngine->UnregisterGameObj( objId );
- }
- return 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->EventName = EventName;
- 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: AKASSERT(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)
- {
- if (in_pComponent->UseDefaultListeners())
- m_defaultEmitters.Add(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);
- }
- if (in_pComponent->UseDefaultListeners())
- {
- m_defaultEmitters.Remove(in_pComponent);
- }
- check(!m_defaultListeners.Contains(in_pComponent) && !m_defaultEmitters.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(UAkPortalComponent* in_pPortal, float in_fObstructionValue, float in_fOcclusionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pPortal)
- {
- 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(UAkComponent* in_pComponent, UAkPortalComponent* in_pPortal, float in_fObstructionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pComponent && in_pPortal)
- {
- 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(UAkPortalComponent* in_pPortal0, UAkPortalComponent* in_pPortal1, float in_fObstructionValue)
- {
- AKRESULT eResult = AK_Fail;
- if (m_bSoundEngineInitialized && in_pPortal0 && in_pPortal1)
- {
- 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());
- m_defaultEmitters.Remove(in_pEmitter); //This emitter is no longer using the default listener set.
- 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. Copyright (c) 2006-%d Audiokinetic Inc."),
- AK_WWISESDK_VERSION_MAJOR,
- AK_WWISESDK_VERSION_MINOR,
- AK_WWISESDK_VERSION_SUBMINOR,
- AK_WWISESDK_VERSION_BUILD,
- 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."));
- 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 (auto& Emitter : m_defaultEmitters)
- Emitter->OnDefaultListenerAdded(in_pListener);
- in_pListener->IsDefaultListener = true;
- UpdateDefaultActiveListeners();
- if (m_SpatialAudioListener == nullptr)
- SetSpatialAudioListener(in_pListener);
- }
- }
- void FAkAudioDevice::RemoveDefaultListener(UAkComponent* in_pListener)
- {
- for (auto& Emitter : m_defaultEmitters)
- {
- Emitter->OnListenerUnregistered(in_pListener);
- }
- m_defaultListeners.Remove(in_pListener);
- 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 AkUnrealHelper::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);
- }
- }
|