// // audio/northaudioengine.cpp // // Copyright (C) 1999-2015 Rockstar Games. All Rights Reserved. // #include "northaudioengine.h" //#include "audiogeometry.h" #include "pedaudioentity.h" #include "pedscenariomanager.h" #include "glassaudioentity.h" #include "ambience/ambientaudioentity.h" #include "ambience/audambientzone.h" #include "ambience/water/audshorelinePool.h" #include "ambience/water/audshorelineRiver.h" #include "ambience/water/audshorelineOcean.h" #include "ambience/water/audshorelineLake.h" #include "environment/audwarpmanager.h" #include "vehiclereflectionsaudioentity.h" #include "explosionaudioentity.h" #include "emitteraudioentity.h" #include "fireaudioentity.h" #include "frontendaudioentity.h" #include "collisionaudioentity.h" #include "cutsceneaudioentity.h" #include "dynamicmixer.h" #include "radioaudioentity.h" #include "scriptaudioentity.h" #include "speechaudioentity.h" #include "speechmanager.h" #include "weaponaudioentity.h" #include "vehicleaudioentity.h" #include "heliaudioentity.h" #include "trainaudioentity.h" #include "caraudioentity.h" #include "planeaudioentity.h" #include "bicycleaudioentity.h" #include "traileraudioentity.h" #include "boataudioentity.h" #include "vehiclefireaudio.h" #include "frontend/NewHud.h" #include "vehicleengine/vehicleengine.h" #include "vehicleengine/electricengine.h" #include "vehicleengine/turbo.h" #include "vehicleengine/transmission.h" #include "weatheraudioentity.h" #include "audio/environment/environment.h" #include "policescanner.h" #include "music/musicplayer.h" #include "replayaudioentity.h" #include "camera/CamInterface.h" #include "camera/cinematic/CinematicDirector.h" #include "camera/gameplay/aim/ThirdPersonPedAssistedAimCamera.h" #include "camera/viewports/ViewportManager.h" #include "control/gamelogic.h" #include "control/stuntjump.h" #include "core/game.h" #include "cutscene/CutSceneManagerNew.h" #include "debug/debug.h" #include "debug/debugscene.h" #include "grcore/debugdraw.h" #include "game/clock.h" #include "vehicles/Metadata/VehicleSeatInfo.h" #include "input/mouse.h" #include "scene/DataFileMgr.h" #include "scene/FileLoader.h" #include "scene/RefMacros.h" #include "system/system.h" #include "audiodata/simpletypes.h" #include "audioeffecttypes/delayeffect.h" #include "audioeffecttypes/filterdefs.h" #include "audioengine/categorymanager.h" #include "audioengine/categorycontrollermgr.h" #include "audioengine/curverepository.h" #include "audioengine/engine.h" #include "audioengine/engineutil.h" #include "audioengine/environment.h" #include "audioengine/soundfactory.h" #include "audioengine/soundmanager.h" #include "audiohardware/channel.h" #include "audiohardware/config.h" #include "audiohardware/grainplayer.h" #include "audiohardware/device_360.h" #include "audioengine/dynamicmixmgr.h" #include "audiohardware/device.h" #include "audiohardware/device_ps3.h" #include "audiohardware/driver.h" #include "audiohardware/driverutil.h" #include "audiohardware/device_xaudio_pc.h" #include "audiosoundtypes/speechsound.h" #include "audiosoundtypes/environmentsound.h" #include "audiosynth/synthesizer.h" #include "frontend/PauseMenu.h" #include "frontend/ProfileSettings.h" #include "modelinfo/MloModelInfo.h" #include "parser/manager.h" #include "profile/profiler.h" #include "renderer/PostProcessFX.h" #include "renderer/water.h" #include "scene/playerswitch/PlayerSwitchInterface.h" #include "scene/scene.h" #include "system/ControlMgr.h" #include "system/memory.h" #include "system/param.h" #include "system/performancetimer.h" #include "system/simpleallocator.h" #include "peds/ped.h" #include "vfx/VisualEffects.h" #include "net/nethardware.h" #include "frontend/MobilePhone.h" #include "system/ThreadPriorities.h" #include "system/memvisualize.h" #include "streaming/streamingvisualize.h" #include "video/VideoPlayback.h" #include "debugaudio.h" #include "grprofile/pix.h" #include "Network/Commerce/CommerceManager.h" #include "Network/Live/livemanager.h" #include "Network/Network.h" #include "Network/Voice/NetworkVoice.h" #if RSG_ORBIS #include "audiohardware/device_orbis.h" #include "rline/rlnp.h" #endif #if GTA_REPLAY #include "replaycoordinator/ReplayCoordinator.h" #include "camera/replay/ReplayFreeCamera.h" #include "replayaudioentity.h" #endif #if RSG_PC #include "audiohardware/device_xaudio_pc.h" #if __BANK && RSG_PC bool g_ShowAudioFrameDebugInfo; u32 g_NumberOfMixBuffers = rage::kXAudioNumberOfBuffers; bool g_OverrideCPULimitedAudioSetting = false; bool g_ForceMinSpecMode = false; #endif #endif AUDIO_OPTIMISATIONS() extern bool g_UseInteriorCarFilter; bool g_HasInitialisedStaticClasses = false; static bool s_HasScanStarted; static const char *g_AudioConfigPath = "audio:/config/"; // PURPOSE // Specifies the distance relative to camera that RegisterLoundSound() responds to static const f32 g_audLoudSoundDistanceMag = 40.f; char * audNorthAudioEngine::sm_ExtraContentPath = NULL; naAnimHandler audNorthAudioEngine::sm_AudAnimHandler; #if __BANK static bool g_ShouldMuteWind = false; static audCategoryController * g_WindMuteController = NULL; bool g_ForceDefaultCutsceneSettings = false; bool g_ForceAllowRadioOverScreenFade = false; extern bool g_DebugPlayingScriptSounds; extern bool g_GameTimerCutscenes; bool g_WarpToStaticEmitter = false; bool g_WarpToAmbientZone = false; bool g_WarpToInterior = false; const StaticEmitter *g_RequestedWarpEmitter = NULL; const AmbientZone *g_RequestedWarpAmbZone = NULL; const CInteriorProxy *g_RequestedWarpInterior = NULL; bool g_IgnoreFrontendVolumeSliders = false; bool g_DisplaySlowMo = false; #endif namespace rage { extern float g_SFXHPFCutoff; extern bool g_SFXHPFBypass; } #if !__FINAL bool audNorthAudioEngine::sm_ShouldAddStrVisMarkers = false; class naStreamingDebugInterface : public audStreamingDebugInterface { public: void SetMarker(const char *text) const { if(audNorthAudioEngine::ShouldAddStrVisMarkers()) { STRVIS_SET_MARKER_TEXT(text); } } }; #endif volatile bool audNorthAudioEngine::sm_IsAudioUpdateCurrentlyRunning = false; audMetadataDataFileMounter *audNorthAudioEngine::sm_SoundDlcMounter; audMetadataDataFileMounter *audNorthAudioEngine::sm_DynamicMixDlcMounter; audMetadataDataFileMounter *audNorthAudioEngine::sm_GameObjectDlcMounter; audMetadataDataFileMounter *audNorthAudioEngine::sm_CurveDlcMounter; audMetadataDataFileMounter *audNorthAudioEngine::sm_SynthDlcMounter; #if NA_RADIO_ENABLED static f32 g_RadioDuckingVolume = -7.0f; static f32 g_RadioDuckingVolumeStereo = -7.0f; static f32 g_RadioDuckingVolumeVoiceChat = -18.0f; static f32 g_TalkRadioDuckingVolume = -12.0f; static f32 g_RadioNonMusicAdditionalDucking = -3.f; BANK_ONLY(static f32 g_RadioGPSDuckingVolume = -3.0f); static bool sm_ShouldDuckRadio = false; #endif static f32 g_RadioDuckingSmoothRate = 0.001f; static f32 g_RadioDuckingSmoothRateUp = 0.0003f; bool audNorthAudioEngine::sm_IsPlayerSpecialAbilityFadingOut = false; audNorthAudioEngine::DataSetState audNorthAudioEngine::sm_DataSetState = audNorthAudioEngine::Loaded_SP; bool audNorthAudioEngine::sm_IsMPDataRequested = false; u32 audNorthAudioEngine::sm_DataSetStateCount = 0; u8 *audNorthAudioEngine::sm_SPSoundDataPtr = NULL; u32 audNorthAudioEngine::sm_SPSoundDataSize = 0; //u8 *audNorthAudioEngine::sm_ReplayedSoundDataPtr = NULL; //u32 audNorthAudioEngine::sm_ReplayedSoundDataSize = 0; #if GTA_REPLAY bool audNorthAudioEngine::sm_EnableHPF = true; bool audNorthAudioEngine::sm_EnableLPF = true; bool audNorthAudioEngine::sm_UseMonoReverbs = false; float audNorthAudioEngine::sm_AudioFrameTime = 15.0f; bool audNorthAudioEngine::sm_VehicleEffectsBypass = false; bool audNorthAudioEngine::sm_UseSingleListener = false; #endif u32 audNorthAudioEngine::sm_StreamingSoundBucketId = ~0U; bank_float g_SlowMoTrainVol = -9.f; bank_float g_ConversationTrainVol = -0.f; bank_float g_ConversationHeliVol = -6.f; f32 g_FadeValueForSilence = 1.f; bool g_DebugFadeLevels = false; bool audNorthAudioEngine::sm_ApplyMusicSlider = false; audSimpleSmoother audNorthAudioEngine::sm_CutsceneLeakageSmoother; f32 g_CutsceneLeakageSmootherRate = 1.0f; f32 g_CutscenePositionedLeakage = 0.75f; bool g_LeakForRPICutscenes = true; BANK_ONLY(bool g_DebugCutsceneLeakage = false;) bool g_MuteGameWorldAudio = false; bool g_MutePositionedRadio = false; bool g_MuteGameWorldAndPositionedRadioForTV = false; bool g_AudioInitialised = false; f32 g_AttachedToTrainVolume = -9.0f; f32 g_TrainRolloffInSubways = 2.5f; bool audNorthAudioEngine::sm_IsInNetworkLobby = false; bool audNorthAudioEngine::sm_IsRenderingHoodMountedVehicleCam = false; bool audNorthAudioEngine::sm_IsRenderingFirstPersonVehicleCam = false; bool audNorthAudioEngine::sm_IsRenderingFirstPersonVehicleTurretCam = false; REPLAY_ONLY(bool audNorthAudioEngine::sm_IsRenderingReplayFreeCamera = false;) bool audNorthAudioEngine::sm_OverrideLobbyMute = false; bool audNorthAudioEngine::sm_StartingNewGame = false; bool audNorthAudioEngine::sm_CinematicThirdPersonAimCameraActive = false; bool audNorthAudioEngine::sm_IsFirstPersonActiveForPlayer = false; bool audNorthAudioEngine::sm_IsCutsceneActive = false; audMetadataManager audNorthAudioEngine::sm_MetadataMgr; audGameObjectManager audNorthAudioEngine::sm_GameObjectMgr; float g_PIVMusicVolumeFadeInS = 1.0f; float g_PIVMusicVolumeFadeOutS = 2.0f; float g_PIVOpennessFadeInS = 0.1f; float g_PIVOpennessFadeOutS = 5.0f; audSmoother audNorthAudioEngine::sm_PIVMusicVolumeSmoother; audSmoother audNorthAudioEngine::sm_PIVRadioVolumeSmoother; audSmoother audNorthAudioEngine::sm_PIVOpennessSmoother; #if __BANK char audNorthAudioEngine::sm_SoundName[64]; char g_AuditionWaveSlotName[64]; char g_SlowMoModeName[64] = {0}; bool audNorthAudioEngine::sm_ShouldRemoveSoundHierarchy = true; bool audNorthAudioEngine::sm_ShouldAuditionThroughFocusEntity = false; bool audNorthAudioEngine::sm_ShouldAuditionThroughPlayer = false; bool audNorthAudioEngine::sm_ShouldAuditionPannedFrontend = false; bool audNorthAudioEngine::sm_ShouldAuditionSoundOverNetwork = false; float audNorthAudioEngine::sm_DebugDrawYOffset = 0.f; bool audNorthAudioEngine::sm_AuditionSoundUnpausable = true; bool audNorthAudioEngine::sm_AllowAuditionSoundToLoad = true; bool audNorthAudioEngine::sm_AuditionSoundsOnPPU = false; bool audNorthAudioEngine::sm_ForceBaseCategory = false; audRemoteControl::AuditionSoundDrawMode audNorthAudioEngine::sm_AuditionSoundDrawMode = audRemoteControl::kVariablesOnly; char audNorthAudioEngine::sm_AuditionSoundSetName[128] = {0}; char audNorthAudioEngine::sm_AuditionSoundName[128] = {0}; #endif audController audNorthAudioEngine::sm_AudioController; naEnvironment audNorthAudioEngine::sm_Environment; naEnvironmentGroupManager audNorthAudioEngine::sm_EnvironmentGroupManager; naOcclusionManager audNorthAudioEngine::sm_OcclusionManager; audGunFireAudioEntity audNorthAudioEngine::sm_GunFireAudioEntity; audSuperConductor audNorthAudioEngine::sm_SuperConductor; audDynamicMixer audNorthAudioEngine::sm_DynamicMixer; u32 audNorthAudioEngine::sm_LastLoudSoundTime = 0; bool audNorthAudioEngine::sm_ShouldMuteAudio = false; f32 audNorthAudioEngine::sm_EngineVolume = 0.0f; f32 audNorthAudioEngine::sm_PlayerVehicleOpenness = 1.0f; //Matrix34 audNorthAudioEngine::sm_ListenerMatrix; bool audNorthAudioEngine::sm_Paused = false; bool audNorthAudioEngine::sm_PausedLastFrame = false; u32 audNorthAudioEngine::sm_TimeInMs = 0; u32 audNorthAudioEngine::sm_LastTimeInMs = 0; audSmoother audNorthAudioEngine::sm_RadioDuckingSmoother; audSmoother audNorthAudioEngine::sm_GPSDuckingSmoother; audSmoother audNorthAudioEngine::sm_TrainRolloffInSubwaySmoother; f32 audNorthAudioEngine::sm_FrontendRadioVolumeLin; u32 audNorthAudioEngine::sm_LastTimeSpecialAbilityActive = 0; Vec3V audNorthAudioEngine::sm_PedPosLastFrame; float audNorthAudioEngine::sm_GameTimeHours = 0.f; audSmoother audNorthAudioEngine::sm_TimeWarpSmoother; #if GTA_REPLAY audCurve audNorthAudioEngine::sm_ReplayTimeWarpToPitch; audCurve audNorthAudioEngine::sm_ReplayTimeWarpToTimeScale; bool audNorthAudioEngine::sm_AreReplayBanksLoaded = false; #endif audCurve audNorthAudioEngine::sm_TimeWarpToPitch; audCurve audNorthAudioEngine::sm_TimeWarpToTimeScale; audCurve g_TimeWarpToDelayFeedback; sysIpcSema audNorthAudioEngine::sm_RunUpdateSema; sysIpcSema audNorthAudioEngine::sm_UpdateFinishedSema; sysIpcThreadId audNorthAudioEngine::sm_UpdateThread; bool audNorthAudioEngine::sm_RunUpdateInSeperateThread = true; bool audNorthAudioEngine::sm_IsInSlowMo = false; bool audNorthAudioEngine::sm_ForceSlowMoVideoEditor = false; bool audNorthAudioEngine::sm_ForceSuperSlowMoVideoEditor = false; bool audNorthAudioEngine::sm_WaitingForPauseMenuSlowMoToEnd = false; SlowMoType audNorthAudioEngine::sm_SlowMoMode = AUD_SLOWMO_GENERAL; u32 audNorthAudioEngine::sm_ActiveSlowMoModes[NUM_SLOWMOTYPE] = {0}; audScene * audNorthAudioEngine::sm_AmbienceMuted = NULL; audScene * audNorthAudioEngine::sm_CutsceneMuted = NULL; audScene * audNorthAudioEngine::sm_FrontendMuted = NULL; audScene * audNorthAudioEngine::sm_MusicMuted = NULL; audScene * audNorthAudioEngine::sm_RadioMuted = NULL; audScene * audNorthAudioEngine::sm_SfxMuted = NULL; audScene * audNorthAudioEngine::sm_SpeechMuted = NULL; audScene * audNorthAudioEngine::sm_GunsMuted = NULL; audScene * audNorthAudioEngine::sm_VehiclesMuted = NULL; audScene * audNorthAudioEngine::sm_NorthAudioMixScene = NULL; audScene * audNorthAudioEngine::sm_MuteAllScene = NULL; audScene * audNorthAudioEngine::sm_DeathScene = NULL; audScene * audNorthAudioEngine::sm_MpLobbyScene = NULL; audScene * audNorthAudioEngine::sm_ReplayEditorScene = NULL; audScene * audNorthAudioEngine::sm_TvScene = NULL; audScene * audNorthAudioEngine::sm_FrontendScene = NULL; audScene * audNorthAudioEngine::sm_GameWorldScene = NULL; audScene * audNorthAudioEngine::sm_PosRadioMuteScene = NULL; audScene * audNorthAudioEngine::sm_SlowMoScene = NULL; audScene * audNorthAudioEngine::sm_SlowMoVideoEditorScene = NULL; audScene * audNorthAudioEngine::sm_SuperSlowMoVideoEditorScene = NULL; audScene * audNorthAudioEngine::sm_PlayerInVehScene = NULL; audScene * audNorthAudioEngine::sm_SpeechScene = NULL; audScene * audNorthAudioEngine::sm_GameSuspendedScene = NULL; audSound * audNorthAudioEngine::sm_SlowMoSound = NULL; audScene * audNorthAudioEngine::sm_FirstPersonModeScene = NULL; u32 audNorthAudioEngine::sm_TimeSpeechSceneLastStarted = 0; u32 audNorthAudioEngine::sm_TimeSpeechSceneLastStopped = 0; f32 audNorthAudioEngine::sm_SpeechGunfirePatchApplyAtStart = 0.0f; f32 audNorthAudioEngine::sm_SpeechScorePatchApplyAtStart = 0.0f; f32 audNorthAudioEngine::sm_SpeechVehiclesPatchApplyAtStart = 0.0f; f32 audNorthAudioEngine::sm_SpeechVehiclesFirstPersonPatchApplyAtStart = 0.0f; f32 audNorthAudioEngine::sm_SpeechWeatherPatchApplyAtStart = 0.0f; f32 audNorthAudioEngine::sm_SpeechGunfirePatchApplyAtStop = 0.0f; f32 audNorthAudioEngine::sm_SpeechScorePatchApplyAtStop = 0.0f; f32 audNorthAudioEngine::sm_SpeechVehiclesPatchApplyAtStop = 0.0f; f32 audNorthAudioEngine::sm_SpeechVehiclesFirstPersonPatchApplyAtStop = 0.0f; f32 audNorthAudioEngine::sm_SpeechWeatherPatchApplyAtStop = 0.0f; bool audNorthAudioEngine::sm_SpeechSceeneApplied = false; audDynMixPatch * audNorthAudioEngine::sm_SpeechGunfirePatch=NULL; audDynMixPatch * audNorthAudioEngine::sm_SpeechScorePatch=NULL; audDynMixPatch * audNorthAudioEngine::sm_SpeechVehiclesPatch=NULL; audDynMixPatch * audNorthAudioEngine::sm_SpeechVehiclesFirstPersonPatch=NULL; audDynMixPatch * audNorthAudioEngine::sm_SpeechWeatherPatch=NULL; const audCategory *audNorthAudioEngine::sm_ScoreProxyCat = NULL; const audCategory *audNorthAudioEngine::sm_RadioProxyCat = NULL; audCategoryController *audNorthAudioEngine::sm_ScoreVolCategoryController = NULL; audCategoryController *audNorthAudioEngine::sm_OneShotVolCategoryController = NULL; audCategoryController *audNorthAudioEngine::sm_MusicSliderController = NULL; audCategoryController *audNorthAudioEngine::sm_SFXSliderController = NULL; audCategoryController *audNorthAudioEngine::sm_NoFadeVolCategoryController = NULL; audCategoryController *audNorthAudioEngine::sm_ScriptedOverrideFadeVolCategoryController = NULL; #if RSG_PS3 || RSG_ORBIS float g_PulseHPFCutoff = 50.f; bool audNorthAudioEngine::sm_ShouldTriggerPulseHeadset = false; audScene *audNorthAudioEngine::sm_PulseHeadsetScene = NULL; bool audNorthAudioEngine::sm_IsWirelessHeadsetConnected = false; s32 audNorthAudioEngine::sm_PreviousOutputPref = 0; #endif // RSG_PS3 || RSG_ORBIS audScene *audNorthAudioEngine::sm_StonedScene = NULL; naMicrophones audNorthAudioEngine::sm_Microphones; f32 audNorthAudioEngine::sm_SfxVolume = 1.f; f32 audNorthAudioEngine::sm_MusicVolume = 1.f; f32 audNorthAudioEngine::sm_ThirdPersonCameraBlendThreshold = 1.0f; u32 audNorthAudioEngine::sm_LoadingScreenSFXSliderDelay = 0; volatile bool audNorthAudioEngine::sm_IsShuttingDown = false; bool audNorthAudioEngine::sm_HasAppliedARC1BankRemappings = false; bool audNorthAudioEngine::sm_IsFadedToBlack = false; bool audNorthAudioEngine::sm_ScreenFadedOutThisFrame = false; audCurve audNorthAudioEngine::sm_BuiltUpToWeaponTails; u32 audNorthAudioEngine::sm_PauseMenuSlowMoCount = 0; extern CPlayerSwitchInterface g_PlayerSwitch; #if GTA_REPLAY bool g_UseSingleListener = false; bool g_UseMonoReverbs = false; bool g_EnableHPF = true; bool g_EnableLPF = true; f32 g_AudioFrameTime = 15.f; extern bool g_VehicleEffectsBypass; #endif #if __BANK u32 audNorthAudioEngine::sm_CurrentMeterIndex = 0; audMeterList *audNorthAudioEngine::sm_MeterList[g_MaxBufferedMeters]; RegdEnt g_AudioDebugEntity(NULL); audSound *audNorthAudioEngine::sm_DebugSound = NULL; #endif sysMemAllocator *g_AudioPhysicalAllocator; #if RSG_PC || RSG_DURANGO || RSG_ORBIS void *g_AudioPhysicalMem; #endif #if RSG_PC || RSG_DURANGO || RSG_ORBIS #define MAX_WAVE_DATA (24 * 1024 * 1024 * 10) #elif RSG_XENON #define MAX_WAVE_DATA (26 * 1024 * 1024) #else #define MAX_WAVE_DATA (24 * 1024 * 1024) #endif const s32 g_AudioUpdateThreadCPU = 5; // Audio dlc pack order - later packs override previous packs. #define FIXED_DLC_PACK_ORDER_COUNT 20 const char * g_AudioDLCPackOrder[FIXED_DLC_PACK_ORDER_COUNT] = { "SinglePlayer", "GTAOnline", "dlcbeach", "dlcvalentines", "dlcbusiness", "dlcbusi2", "dlchipster", "dlcindependence", "dlcpilotschool", "dlcmpLTS", "dlcxmas2", "dlcmpheist", "dlcpd03", "dlcluxe", "dlcluxe2", "dlcsfx1", "dlclowrider", "dlchalloween", "dlcapartment", "dlcxmas3" }; u32 GetSizeOfLargestVehicleClass() { size_t maxSize = 0; maxSize = Max(sizeof(audCarAudioEntity), maxSize); maxSize = Max(sizeof(audHeliAudioEntity), maxSize); maxSize = Max(sizeof(audTrainAudioEntity), maxSize); maxSize = Max(sizeof(audBoatAudioEntity), maxSize); maxSize = Max(sizeof(audPlaneAudioEntity), maxSize); maxSize = Max(sizeof(audTrailerAudioEntity), maxSize); maxSize = Max(sizeof(audBicycleAudioEntity), maxSize); return (u32) maxSize; } static const int kSizeOfLargestVehicleClassAudio = GetSizeOfLargestVehicleClass(); INSTANTIATE_POOL_ALLOCATOR(audVehicleAudioEntity); audCategoryController *g_BaseCategory; audCategoryController *g_GameWorldCategory; PF_PAGE(AudioEntitiesPage, "GTA Audio Entities"); PF_GROUP(AudioEntities); PF_LINK(AudioEntitiesPage, AudioEntities); PF_VALUE_FLOAT(UpdateLength, AudioEntities); PF_VALUE_FLOAT(SlotUpdateLength, AudioEntities); PF_VALUE_FLOAT(ControllerUpdateLength, AudioEntities); PF_PAGE(NorthAudioPage, "North Audio Engine"); PF_GROUP(NorthAudio); PF_LINK(NorthAudioPage, NorthAudio); PF_VALUE_INT(MaxVoicesPerBucket, NorthAudio); PF_VALUE_INT(MaxSoundsPerBucket, NorthAudio); PF_VALUE_INT(MaxRequestedSettingsPerBucket, NorthAudio); PF_PAGE(NorthAudioUpdatePage, "North Audio Update"); PF_GROUP(NorthAudioUpdate); PF_LINK(NorthAudioUpdatePage, NorthAudioUpdate); PF_TIMER(NorthAudioUpdateTimer, NorthAudioUpdate); PF_TIMER(NorthAudioUpdateTimer_Update, NorthAudioUpdate); PF_TIMER(NorthAudioUpdateTimer_CommandBuffer, NorthAudioUpdate); PF_TIMER(NorthAudioUpdateTimer_FinishUpdate, NorthAudioUpdate); PF_PAGE(TriggerSoundsPage, "TriggeredSounds"); PF_GROUP(TriggerSoundsGroup); PF_LINK(TriggerSoundsPage, TriggerSoundsGroup); PARAM(mute, "[RAGE Audio] Mutes audio."); PARAM(nogameaudio, "[Audio] Disable game audio engine init for offline tools (may not work in-game)"); XPARAM(audiodesigner); XPARAM(audiotag); PARAM(radiohudwidgets, "Activates radio hud widgets"); NOSTRIP_PC_PARAM(minspecaudio, "Force minspec audio processing"); NOSTRIP_PC_PARAM(nominspecaudio, "Force normal audio processing regardless of CPU"); namespace rage { NOSTRIP_XPARAM(audiofolder); } #if !__FINAL XPARAM(allcutsceneaudio); #endif #if __BANK // offline compute audio world sectors PARAM(calculateAudioWorldSectors, "[Audio] Enabled audio world sectors offline computation."); PARAM(inGameAudioWorldSectors, "[Audio] Enabled audio world sectors online info."); namespace rage { XPARAM(rave); XPARAM(raveskipchunks); PARAM(raveSkipReleasedDlcChunks, "[RAGE Audio] Automatically skips a hard coded list of metadata chunks"); XPARAM(fullsoundhierarchy); XPARAM(noaudio); XPARAM(audiowidgets); XPARAM(printlargesounds); XPARAM(loadtestsounds); extern bool g_WarnOnMissingSounds; extern bool g_WarnOnMissingCurves; extern bool g_FullCurveTweakAbility; } XPARAM(Audio_tty); XPARAM(usefatcuts); extern bool g_UseEditedCutscenes; extern bool g_UseMasterCutscenes; #endif #if __DEV namespace rage { extern u32 g_MaxRequestedSettingsSlotsUsed; extern u32 g_MaxSoundSlotsUsed; extern u32 g_MaxVoicesUsed; extern u32 g_MaxSoundsAllocated; extern u32 g_MaxActiveEnvironmentGroups; extern u32 g_MaxActiveAudioEntities; extern u32 g_MaxActiveVirtualVoices; extern u32 g_MaxActiveVoiceGroups; extern bool g_AssertOnSoundPoolFull; extern bool g_PrintSoundPoolWhenFull; } #endif #if !__FINAL PARAM(audiomem, "[Audio] write audio memory report"); class audMemoryReporter { public: audMemoryReporter(const char *destFileName) { m_Stream = ASSET.Create(destFileName, ""); m_Total = 0; } bool HasStream() const { return m_Stream != NULL; } void AddLine(const char *str) { char lineBuf[128]; formatf(lineBuf, "%s\r\n", str); m_Stream->Write(lineBuf, istrlen(lineBuf)); } void AddLine(const char *entry, const u32 sizeBytes) { char lineBuf[128]; u32 sizeKb = sizeBytes >> 10; formatf(lineBuf, "%s,%uKB\r\n", entry, sizeKb); m_Stream->Write(lineBuf, istrlen(lineBuf)); m_Values.PushAndGrow(sizeBytes); m_Total += sizeBytes; } void AddMetadata(const char *entry, const audMetadataManager &metadataMgr) { char lineBuf[128]; u32 size = metadataMgr.GetLoadedDataSize(); m_Total += size; m_Values.PushAndGrow(size); formatf(lineBuf, "%s_Data: %uKB (Source CL %u)\r\n", entry, size >> 10, metadataMgr.GetAssetChangelist()); m_Stream->Write(lineBuf, istrlen(lineBuf)); size = metadataMgr.GetLoadedNameTableSize(); m_Total += size; m_Values.PushAndGrow(size); formatf(lineBuf, "%s_Names: %uKB\r\n", entry, size >> 10); m_Stream->Write(lineBuf, istrlen(lineBuf)); } void Close() { PrintTotal(); PrintCSV(); m_Stream->Close(); } private: void PrintCSV() { char lineBuf[64]; bool needComma = false; for(s32 i = 0 ; i < m_Values.GetCount(); i++) { formatf(lineBuf, "%s%u", needComma ? "," : "", m_Values[i]); m_Stream->Write(lineBuf, istrlen(lineBuf)); needComma = true; } formatf(lineBuf, ",%u\r\n", m_Total); m_Stream->Write(lineBuf, istrlen(lineBuf)); } void PrintTotal() { char lineBuf[128]; formatf(lineBuf, "\r\nTotal: %.2fMB\r\n", m_Total / (1024.f * 1024.f)); m_Stream->Write(lineBuf, istrlen(lineBuf)); } atArray m_Values; u32 m_Total; fiStream *m_Stream; }; void audNorthAudioEngine::GenerateMemoryReport(const char *destFileName) { char lineBuf[128]; audMemoryReporter report(destFileName); if(report.HasStream()) { const char *platform = "None"; #if RSG_XENON platform = "Xbox360"; #elif RSG_PS3 platform = "PS3"; #elif RSG_ORBIS platform = "Orbis"; #elif RSG_DURANGO platform = "Durango"; #elif RSG_PC platform = "PC"; #else #error "Not Implemented" #endif report.AddLine(formatf(lineBuf, "%s Audio memory usage report\r\n", platform)); #if __BANK if(PARAM_rave.Get()) { report.AddLine(formatf(lineBuf, "Warning: running with RAVE - memory usage will be inflated\r\n")); } #endif // __BANK report.AddLine("WaveSlots_Main", audWaveSlot::GetTotalSlotSizeMain()); #if __PS3 report.AddLine("WaveSlots_VRAM", audWaveSlot::GetTotalSlotSizeVRAM()); #endif report.AddMetadata("Category", g_AudioEngine.GetCategoryManager().GetMetadataManager()); report.AddMetadata("Curve", g_AudioEngine.GetCurveRepository().GetMetadataManager()); report.AddMetadata("DynamicMixer", g_AudioEngine.GetDynamicMixManager().GetMetadataManager()); report.AddMetadata("GameObject", audNorthAudioEngine::GetMetadataManager()); report.AddMetadata("Sound", g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager()); report.AddMetadata("ModularSynth", synthSynthesizer::GetMetadataManager()); report.AddMetadata("Speech", audSpeechSound::GetMetadataManager()); report.Close(); } } #endif RAGE_DEFINE_SUBCHANNEL(Audio,NorthAudio) #if __USEDEBUGAUDIO class audNorthAudioEngineThreadVerifier : public audControllerThreadVerifier { public: void OnCreateSound(const audMetadataRef &soundRef) const { if(sysThreadType::IsUpdateThread() && audNorthAudioEngine::IsAudioUpdateCurrentlyRunning()) { const char *soundName = "invalid"; if(soundRef.IsValid()) { const Sound *s = reinterpret_cast(g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetObjectMetadataPtr(soundRef)); if(s) { soundName = g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetObjectNameFromNameTableOffset(s->NameTableOffset); } } naAssertf(false, "Creating a sound (%s) from the main thread while audNorthAudioEngine Update is running.", soundName); } } }; audNorthAudioEngineThreadVerifier g_NorthAudioThreadVerifier; #endif void InitialiseAudioForInstall() { audNorthAudioEngine::InitClass(); } bool audNorthAudioEngine::InitClass() { if(g_AudioInitialised == true) return true; #if !__FINAL if(PARAM_nogameaudio.Get()) return true; #endif #if !RSG_FINAL PARAM_allcutsceneaudio.Set("yes"); #endif #if __BANK if(PARAM_allcutsceneaudio.Get()) { PARAM_loadtestsounds.Set("yes"); } if(PARAM_audiodesigner.Get()) { audEnvironmentSound::SetRecordInvalidCategorySounds(true); naDisplayf("Enabling audio designer support"); if(!PARAM_rave.Get()) { PARAM_rave.Set("Sounds,GameObjects,Curves,Categories,ModularSynth,DynamicMixer,AudioConfig"); } #if RSG_PS3 || RSG_XENON if(!PARAM_raveskipchunks.Get()) { PARAM_raveskipchunks.Set("base,singleplayer,optimised"); } #endif if (PARAM_raveSkipReleasedDlcChunks.Get() && !PARAM_raveskipchunks.Get()) { PARAM_raveskipchunks.Set("dlcbeach,dlcbusiness,dlcbusi2,dlclowrider,dlclow2,dlcImportExport,dlcSpecialRaces,dlcGunrunning,dlcAirraces,dlcSmuggler,dlcChristmas2017,dlcAssault,dlcBattle,dlcAWXM2018,dlchalloween,dlcvalentines,dlchipster,dlcApartment,dlcJanuary2016,mpValentines2,dlcExec1,dlcStunt,dlcBiker,dlcmpheist,dlcpd03,dlcpd02,dlcpilotschool,dlcindependence,dlcmplts,dlcthelab,dlcxmas2,DLC_RADIOSURF,dlcluxe,dlcXmas3,dlcluxe2,dlcsfx1,dlcVinewood,dlcHeist3"); } PARAM_fullsoundhierarchy.Set("yes"); PARAM_printlargesounds.Set("yes"); Channel_Audio_NorthAudio.TtyLevel = DIAG_SEVERITY_DEBUG3; // PARAM_Audio_NorthAudio_tty.Set("debug3"); Channel_Audio.TtyLevel = DIAG_SEVERITY_DEBUG3; // PARAM_Audio_tty.Set("debug3"); PARAM_audiowidgets.Set("yes"); PARAM_radiohudwidgets.Set("yes"); sm_AuditionSoundsOnPPU = true; g_WarnOnMissingCurves = true; // No point warning on missing sounds if -noaudio is specified. g_WarnOnMissingSounds = !PARAM_noaudio.Get(); g_FullCurveTweakAbility = true; // default to ignoring frontend sliders g_IgnoreFrontendVolumeSliders = true; } #endif USE_MEMBUCKET(MEMBUCKET_AUDIO); #if RSG_PC || RSG_DURANGO || RSG_ORBIS u32 memSize = fwConfigManager::GetInstance().GetSizeOfPool(ATSTRINGHASH("AudioHeap", 0x5293FA5), CONFIGURED_FROM_FILE) * 1024 * 1024; #if RSG_DURANGO || RSG_ORBIS g_AudioPhysicalMem = sysMemAllocator::GetMaster().GetAllocator(MEMTYPE_GAME_VIRTUAL)->Allocate(memSize, 16); #else const u32 memForUserMusic = 13 * 1024 * 1024; memSize += memForUserMusic; // url:bugstar:6554866 - Heist 4 : Please increase audio heap for PC dev_ng so that we can have larger Streamed Ambience waveslots const u32 ambientBankCompensation = 4 * 1024 * 1024; memSize += ambientBankCompensation; g_AudioPhysicalMem = sysMemPhysicalAllocate(memSize); #endif Assert(g_AudioPhysicalMem); g_AudioPhysicalAllocator = rage_new sysMemSimpleAllocator(g_AudioPhysicalMem, memSize, MEMTYPE_COUNT+1); #if RAGE_TRACKING diagTracker* t = diagTracker::GetCurrent(); if (t && sysMemVisualize::GetInstance().HasAudio()) { t->InitHeap("Audio Physical", g_AudioPhysicalMem, memSize); } #endif // RAGE_TRACKING #else // RSG_PC || RSG_DURANGO || RSG_ORBIS g_AudioPhysicalAllocator = sysMemAllocator::GetMaster().GetAllocator(MEMTYPE_GAME_VIRTUAL); #endif //RSG_PC || RSG_DURANGO || RSG_ORBIS if(!InitializeAudio(sm_AudioController, g_AudioPhysicalAllocator, sysMemAllocator::GetMaster().GetAllocator(MEMTYPE_GAME_VIRTUAL), g_AudioConfigPath)) { return false; } LoadSPData(); // Now keep MP speech data loaded in SP for reindeer assets audSpeechSound::LoadSpeechMetadata("GTAOnline", "audio:/config/dlc_gtao_speech.dat"); #if !__FINAL static naStreamingDebugInterface s_DebugStreamingInterface; audStreamingWaveSlot::SetDebugInterface(&s_DebugStreamingInterface); #endif PS3_ONLY(CheckForWirelessHeadset(true)); #if RSG_BANK && 0 if(!CFileMgr::ShouldForceReleaseAudioPacklist()) { audDisplayf("Loading placeholder speech lookup"); audSpeechSound::LoadSpeechMetadata("PlaceholderSpeech", "audio:/config/p_speech.dat"); } #endif DEBUGAUDIO_ONLY(sm_AudioController.SetThreadVerifier(&g_NorthAudioThreadVerifier)); #if __DEV g_AssertOnSoundPoolFull = false; #endif // Assert if we've allocated too much memory for wave banks if(audWaveSlot::GetTotalSlotSize() > MAX_WAVE_DATA) { naWarningf("Total wave data size: %d", audWaveSlot::GetTotalSlotSize()); #if !__PPU // This error triggers every single time on PS3, so nerf it for now. naErrorf("Audio: Exceeded memory budget - please inform audio team."); #endif } sm_MetadataMgr.Init("GameObjects", "audio:/config/game.dat", audMetadataManager::External_NameTable_BankOnly, GAMEOBJECTS_SCHEMA_VERSION, true); // Reserve the chunk order for DLC packs. Audio data for some packs will get unmounted on session shutdown then remounted for the next session, whilst // for others it will be persistent, meaning that the order of loaded packs can change. However, we need the audio data order to be consistent so that // we can guarantee that certain packs will override others, regardless of when they were loaded. for(u32 dlcPackIndex = 0; dlcPackIndex < FIXED_DLC_PACK_ORDER_COUNT; dlcPackIndex++) { audDisplayf("Reserving metadata chunks for pack %s at index %d", g_AudioDLCPackOrder[dlcPackIndex], dlcPackIndex); sm_MetadataMgr.ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); g_AudioEngine.GetDynamicMixManager().GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); g_AudioEngine.GetCurveRepository().GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); g_AudioEngine.GetCategoryManager().GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); synthSynthesizer::GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); audSpeechSound::GetMetadataManager().ReserveChunk(g_AudioDLCPackOrder[dlcPackIndex]); } // assert if we've not loaded valid game.dat naAssertf(sm_MetadataMgr.ComputeNumberOfObjects()>0, "Failed to load a valid game.dat in InitClass"); sm_MetadataMgr.SetObjectModifiedCallback(&sm_GameObjectMgr); if(PARAM_mute.Get()) { sm_ShouldMuteAudio = true; } g_AudioEngine.EnableAudio(true); sm_StreamingSoundBucketId = audSound::ReserveBucket(); naDisplayf("Bucket reserved for streaming: %u", sm_StreamingSoundBucketId); VIDEO_PLAYBACK_ONLY( VideoPlayback::SetAudioBucketId( sm_StreamingSoundBucketId ) ); sm_TimeWarpSmoother.Init(5.f/1000.f, 1.f/1000.f, 0.f, 1.f); // need to init emitter audio entity early to catch initial object creation g_EmitterAudioEntity.Init(); sm_AudioController.SetEnvironmentGroupManager(&sm_EnvironmentGroupManager); sm_RadioDuckingSmoother.Init(g_RadioDuckingSmoothRateUp, g_RadioDuckingSmoothRate, 0.0f, 1.5f); sm_GPSDuckingSmoother.Init(g_RadioDuckingSmoothRate, g_RadioDuckingSmoothRate, 0.0f, 1.0f); sm_TrainRolloffInSubwaySmoother.Init(0.0003f, 0.0003f, 0.0f, 10.0f); audCategory *firstSpeechCat; firstSpeechCat = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("GLOBAL_SPEECH", 0xAFDC8D3)); const u32 firstSpeechCatIndex = (u32)g_AudioEngine.GetCategoryManager().GetCategoryIndex(firstSpeechCat); g_AudioEngine.GetEnvironment().SetSpeechCategoryRange(firstSpeechCatIndex, firstSpeechCatIndex + 12); // need a listener g_AudioEngine.GetEnvironment().SetListenerContribution(1.0f,0); g_AudioEngine.GetEnvironment().SetRollOff(1.0f,0); g_AudioEngine.CommitGameSettings(0); // need to force an update so that the controller activates sm_AudioController.PreUpdate(0); sm_AudioController.Update(0); audCategoryControllerManager::Instantiate(); audInteractiveMusicManager::Instantiate(); // need a listener g_AudioEngine.GetEnvironment().SetListenerContribution(1.0f,0); g_AudioEngine.CommitGameSettings(0); // need to force an update so that the controller activates sm_AudioController.PreUpdate(0); sm_AudioController.Update(0); StartUserUpdateFunction(); g_AudioInitialised = true; g_HasInitialisedStaticClasses = false; sm_IsShuttingDown = false; sm_RunUpdateSema = sysIpcCreateSema(0); sm_UpdateFinishedSema = sysIpcCreateSema(0); sm_UpdateThread = sysIpcCreateThread(AudioUpdateThread, NULL, 256*1024, PRIO_AUDIO_THREAD, "North Audio Update", g_AudioUpdateThreadCPU, "NorthAudioUpdate"); audAmbisonics::SetDrawFunction(AmbisonicDraw); sm_Microphones.Init(); #if USE_GUN_TAILS sm_GunFireAudioEntity.Init(); #endif #if USE_CONDUCTORS sm_SuperConductor.Init(); #endif audGlassAudioEntity::InitClass(); audSmashableGlassEvent::InitClass(); audCollisionAudioEntity::InitClass(); sm_DynamicMixer.Init(); g_FrontendAudioEntity.Init(); #if GTA_REPLAY g_ReplayAudioEntity.Init(); #endif #if __BANK if(PARAM_calculateAudioWorldSectors.Get()) { sm_Environment.DrawAudioWorldSectors(true); sm_Environment.ProcessSectors(true); } else if (PARAM_inGameAudioWorldSectors.Get()) { sm_Environment.ProcessSectors(true); } #endif #if !__FINAL const char *reportFileName = "audiomem.txt"; if(PARAM_audiomem.Get(reportFileName)) { GenerateMemoryReport(reportFileName); } #if !__FINAL_LOGGING // Display source asset changelists for all metadata types audDisplayf("Source asset CLs - Sounds: %u, GameObjects: %u, Categories: %u, DynamicMixer: %u, AudioConfig: %u, Curves: %u, Synth: %u Speech %u", g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetAssetChangelist(), sm_MetadataMgr.GetAssetChangelist(), g_AudioEngine.GetCategoryManager().GetMetadataManager().GetAssetChangelist(), g_AudioEngine.GetDynamicMixManager().GetMetadataManager().GetAssetChangelist(), audConfig::GetMetadataManager().GetAssetChangelist(), g_AudioEngine.GetCurveRepository().GetMetadataManager().GetAssetChangelist(), synthSynthesizer::GetMetadataManager().GetAssetChangelist(), audSpeechSound::GetMetadataManager().GetAssetChangelist()); #endif #endif sm_ActiveSlowMoModes[AUD_SLOWMO_GENERAL] = ATSTRINGHASH("SLOWMO_GENERAL", 0x995E46B3); naAudioEntity::SetDefaultAnimHandler((fwAudioAnimHandlerInterface *)&sm_AudAnimHandler); BANK_ONLY(g_AudioEngine.GetCategoryManager().SetTelemetryEnabled(true)); // Hook into the extra content mounting system RegisterDataFileMounters(); /* g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().LoadMetadataChunk("DLC_RADIOSURF", "audio:/config/dlc_radiosurf_sounds.dat"); GetMetadataManager().LoadMetadataChunk("DLC_RADIOSURF", "audio:/config/dlc_radiosurf_game.dat"); audSpeechSound::GetMetadataManager().LoadMetadataChunk("DLC_RADIOSURF", "audio:/config/dlc_radiosurf_speech.dat"); */ // This will be loaded as part of a propper dlc, un comment to force load temporarily. //g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().LoadMetadataChunk("ReplayED", // "audio:/config/dlcsfx1_sounds.dat", // sm_ReplayedSoundDataPtr, // sm_ReplayedSoundDataSize); //GetMetadataManager().LoadMetadataChunk("ReplayEdSFX", "audio:/config/dlcsfx1_game.dat"); //if(g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().FindChunkId("ReplayEdSFX") == -1) //{ // Displayf("Failed to load ReplayED audio data"); //} sm_RadioProxyCat = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("RADIO_VOL_PROXY", 0xA6A84701)); sm_ScoreProxyCat = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("SCORE_VOL_PROXY", 0x3C496EED)); sm_ScoreVolCategoryController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("INTERACTIVE_MUSIC", 0x05db47ec6)); sm_OneShotVolCategoryController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("MUSIC_ONESHOT", 0x020230050)); sm_SFXSliderController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("SFX_SLIDER", 0xBAD598C7)); sm_MusicSliderController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("MUSIC_SLIDER", 0xA4D158B0)); sm_NoFadeVolCategoryController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("FRONTEND_GAME_NOFADE", 0x2C7B342)); sm_ScriptedOverrideFadeVolCategoryController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("SCRIPTED_OVERRIDE_FADE", 0xEB0390D7)); sm_CutsceneLeakageSmoother.Init(g_CutsceneLeakageSmootherRate * 0.001f, true); sm_DataSetState = Loaded_SP; sm_IsMPDataRequested = false; const audMetadataManager &soundMetadataManager = g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager(); const audMetadataChunk &spChunk = soundMetadataManager.GetChunk(soundMetadataManager.FindChunkId("SinglePlayer")); sm_SPSoundDataPtr = spChunk.data; sm_SPSoundDataSize = spChunk.dataSize; #if RSG_BANK if(g_AudioEngine.GetRemoteControl().IsConnected()) { audRemoteControlSerializer serializer(g_AudioEngine.GetRemoteControl().GetPayloadBuffer(), audRemoteControl::kRemoteControlPayloadSizeBytes); g_AudioEngine.GetRemoteControl().SendCommand(serializer, AUDIO_ENGINE_LOADED); } #endif return true; } extern CutsceneSettings *g_DefaultCutsceneSettings; void audNorthAudioEngine::Init(u32 initMode) { if(initMode == INIT_CORE) { if(!InitClass()) { Assertf(FALSE, "Failed to initialise Audio Engine!"); } audController::UpdateEnvironmentGroups(true); } else if(initMode == INIT_AFTER_MAP_LOADED) { // Load additional map specific data for Liberty / Prologue // Alternative maps are DLC packs, so will load/unload any extra metadata via that mechanism //LoadMapData(); } else if(/*initMode == INIT_AFTER_MAP_LOADED || */initMode == INIT_SESSION) { g_AudioEngine.GetEnvironment().InitCurves(); g_BaseCategory = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("BASE", 0x044e21c90)); g_GameWorldCategory = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("GAME_WORLD", 0x02729f75d)); DYNAMICMIXER.StartScene(ATSTRINGHASH("NORTHAUDIO_ENGINE_MIXING", 0xa3657c2c), &sm_NorthAudioMixScene); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("radioVol", 0xe7e3432c), 0.f); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("radioFrontendVol", 0xc00f6acd), 0.f); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("djFrontendVol", 0xc06429e6), 0.f); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("posRadioVol", 0x4be8fa9a), 0.f); //sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("heliVol", 0x5acd3f4a), 0.f); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("interiorRatio", 0x13fc3a70), 0.f); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("scriptedSpeechVol", 0x5b3a463), 0.f); if(!sm_SpeechScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("SPEECH_SCENE", 0x576520E1),&sm_SpeechScene); if(sm_SpeechScene) { sm_SpeechScene->SetVariableValue(ATSTRINGHASH("apply", 0xE865CDE8), 1.f); sm_SpeechGunfirePatch = sm_SpeechScene->GetPatch(ATSTRINGHASH("SPEECH_GUNFIRE_PATCH", 0x82B39AD3)); sm_SpeechScorePatch = sm_SpeechScene->GetPatch(ATSTRINGHASH("SPEECH_SCORE", 0x216E4ABF)); sm_SpeechVehiclesPatch = sm_SpeechScene->GetPatch(ATSTRINGHASH("SPEECH_VEHICLES_PATCH", 0x283253)); sm_SpeechVehiclesFirstPersonPatch = sm_SpeechScene->GetPatch(ATSTRINGHASH("SPEECH_VEHICLES_FIRST_PERSON_PATCH", 0xA2DA442)); sm_SpeechWeatherPatch = sm_SpeechScene->GetPatch(ATSTRINGHASH("SPEECH_WEATHER_PATCH", 0x33B1F2AC)); } } // init the static emitters - this needs to be done after all dlc has been loaded. g_EmitterAudioEntity.InitStaticEmitters(); // tell the emitter audio entity its safe to start triggering audio g_EmitterAudioEntity.SetActive(true); g_EmitterAudioEntity.ResetTimers(); g_WeatherAudioEntity.Init(); // this needs to be after we've loaded all episodic content if(!g_HasInitialisedStaticClasses) { CPacketSoundCreatePos::CalculateValidMetadataOffsets(); naEnvironmentGroup::InitClass(); sm_EnvironmentGroupManager.Init(); sm_AudioController.SetEnvironmentGroupManager(&sm_EnvironmentGroupManager); naAudioEntity::InitClass(); audStreamSlot::InitClass(); NA_RADIO_ENABLED_ONLY(audRadioAudioEntity::InitClass()); audDoorAudioEntity::InitClass(); audScriptAudioEntity::InitClass(); audPedAudioEntity::InitClass(); audSpeechAudioEntity::InitClass(); audVehicleReflectionsEntity::InitClass(); audVehicleAudioEntity::InitClass(); audVehicleEngine::InitClass(); audVehicleElectricEngine::InitClass(); audVehicleTurbo::InitClass(); audVehicleTransmission::InitClass(); audVehicleCollisionAudio::InitClass(); audHeliAudioEntity::InitClass(); audPlaneAudioEntity::InitClass(); audCarAudioEntity::InitClass(); audBicycleAudioEntity::InitClass(); audTrailerAudioEntity::InitClass(); audBoatAudioEntity::InitClass(); audTrainAudioEntity::InitClass(); audAmbientZone::InitClass(); audWeatherAudioEntity::InitClass(); audExplosionAudioEntity::InitClass(); audShoreLine::InitClass(); audShoreLinePool::InitClass(); audShoreLineRiver::InitClass(); audShoreLineOcean::InitClass(); audShoreLineLake::InitClass(); audVehicleFireAudio::InitClass(); audFireAudioEntity::InitClass(); g_FireSoundManager.InitClass(); g_FrontendAudioEntity.InitCurves(); g_HasInitialisedStaticClasses = true; } sm_OcclusionManager.Init(); sm_Environment.Init(); sm_TimeWarpToPitch.Init(ATSTRINGHASH("TIME_WARP_TO_PITCH", 0x61E2DEFA)); sm_TimeWarpToTimeScale.Init(ATSTRINGHASH("TIME_WARP_TO_TIME_SCALE", 0xDDE168FB)); g_TimeWarpToDelayFeedback.Init(ATSTRINGHASH("TIME_WARP_TO_DELAY_FEEDBACK", 0x6E4FCCB0)); #if GTA_REPLAY sm_ReplayTimeWarpToTimeScale.Init(ATSTRINGHASH("REPLAY_TIME_WARP_TO_TIME_SCALE", 0xA2363059)); #endif sm_BuiltUpToWeaponTails.Init(ATSTRINGHASH("BUILT_UP_TO_TAIL_VOLUME", 0xC94C4CC4)); NA_RADIO_ENABLED_ONLY(g_RadioAudioEntity.Init()); NA_POLICESCANNER_ENABLED_ONLY(g_AudioScannerManager.Init()); g_CollisionAudioEntity.Init(); g_CutsceneAudioEntity.Init(); g_SpeechManager.Init(); g_ScriptAudioEntity.Init(); g_WeaponAudioEntity.Init(); g_GlassAudioEntity.Init(); g_AmbientAudioEntity.Init(); g_ReflectionsAudioEntity.Init(); g_InteractiveMusicManager.Init(); g_MuteGameWorldAudio = false; g_MuteGameWorldAndPositionedRadioForTV = false; #if __BANK // cutscene mix editor for Nick bkBank *audioBank = BANKMGR.FindBank("CutsceneAudio"); if(audioBank) { BANKMGR.DestroyBank(*audioBank); } #endif sm_StartingNewGame = false; } sm_PIVMusicVolumeSmoother.Init(0.001f / g_PIVMusicVolumeFadeInS, 0.001f / g_PIVMusicVolumeFadeOutS, 0.f, 1.f); sm_PIVRadioVolumeSmoother.Init(0.001f / g_PIVMusicVolumeFadeInS, 0.001f / g_PIVMusicVolumeFadeOutS, 0.f, 1.f); sm_PIVOpennessSmoother.Init(0.001f / g_PIVOpennessFadeInS, 0.001f / g_PIVOpennessFadeOutS, 0.f, 1.f); } void audNorthAudioEngine::DLCInit(u32 initMode) { if(initMode == INIT_SESSION) { g_EmitterAudioEntity.ReInitStaticEmitters(); g_CollisionAudioEntity.ProcessMacsModelOverrides(); g_AmbientAudioEntity.CheckAndAddZones(); audVehicleConductor::InitForDLC(); NA_RADIO_ENABLED_ONLY(audRadioAudioEntity::DLCInitClass();) } } void audNorthAudioEngine::Shutdown(u32 shutdownMode) { if(shutdownMode == SHUTDOWN_CORE) { ShutdownClass(); } else if(shutdownMode == SHUTDOWN_WITH_MAP_LOADED) { // Alternative maps are DLC packs, so will load/unload any extra metadata via that mechanism //UnloadMapData(); } else if(shutdownMode == SHUTDOWN_SESSION) { sm_Environment.PurgeInteriors(); g_EmitterAudioEntity.SetActive(false); g_FrontendAudioEntity.ShutdownLevel(); g_WeatherAudioEntity.Shutdown(); g_GlassAudioEntity.Shutdown(); g_InteractiveMusicManager.Shutdown(); // this needs to be after we've loaded all episodic content if (false && g_HasInitialisedStaticClasses) { sm_EnvironmentGroupManager.Shutdown(); naEnvironmentGroup::ShutdownClass(); sm_AudioController.SetEnvironmentGroupManager(NULL); audStreamSlot::ShutdownClass(); NA_RADIO_ENABLED_ONLY(audRadioAudioEntity::ShutdownClass()); audScriptAudioEntity::ShutdownClass(); audPedAudioEntity::ShutdownClass(); audVehicleAudioEntity::ShutdownClass(); audWeatherAudioEntity::ShutdownClass(); audShoreLineOcean::ShutDownClass(); audShoreLineRiver::ShutDownClass(); audShoreLineLake::ShutDownClass(); g_FireSoundManager.ShutdownClass(); audInteractiveMusicManager::Destroy(); audInteractiveMusicManager::Destroy(); g_HasInitialisedStaticClasses = false; } sm_OcclusionManager.Shutdown(); sm_Environment.Shutdown(); NA_RADIO_ENABLED_ONLY(g_RadioAudioEntity.Shutdown()); NA_POLICESCANNER_ENABLED_ONLY(g_AudioScannerManager.Shutdown()); g_CollisionAudioEntity.Shutdown(); g_CutsceneAudioEntity.Shutdown(); g_SpeechManager.Shutdown(); g_ScriptAudioEntity.Shutdown(); g_WeaponAudioEntity.Shutdown(); g_AmbientAudioEntity.Shutdown(); audShoreLineOcean::ShutDownClass(); audShoreLineRiver::ShutDownClass(); audShoreLineLake::ShutDownClass(); g_ReflectionsAudioEntity.Shutdown(); #if USE_GUN_TAILS sm_GunFireAudioEntity.Shutdown(); #endif CONDUCTORS_ONLY(SUPERCONDUCTOR.ShutDown()); //This last just in case other things use categories ... AUDCATEGORYCONTROLLERMANAGER.DestroyController(g_BaseCategory); g_BaseCategory = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(g_GameWorldCategory); g_GameWorldCategory = NULL; // don't do this if the game is exiting if(!CSystem::WantToExit()) { // ditch any loads in progress to ensure we don't deadlock the streamer audWaveSlot::Drain(); } // Force a synchronous update to ensure the Stop... calls are actioned immediately (it will be along time until the next update) audNorthAudioEngine::MinimalUpdate(); if(sm_NorthAudioMixScene) { sm_NorthAudioMixScene->Stop(); } if(sm_PlayerInVehScene) { sm_PlayerInVehScene->Stop(); } if(sm_SpeechScene) { sm_SpeechScene->Stop(); } if(sm_MuteAllScene) { sm_MuteAllScene->Stop(); } if(sm_DeathScene) { sm_DeathScene->Stop(); } if(sm_MpLobbyScene) { sm_MpLobbyScene->Stop(); } if(sm_ReplayEditorScene) { sm_ReplayEditorScene->Stop(); } if(sm_TvScene) { sm_TvScene->Stop(); } if(sm_FrontendScene) { sm_FrontendScene->Stop(); } if(sm_GameWorldScene) { sm_GameWorldScene->Stop(); } if(sm_PosRadioMuteScene) { sm_PosRadioMuteScene->Stop(); } if(sm_SlowMoScene) { sm_SlowMoScene->Stop(); } if(sm_SlowMoVideoEditorScene) { sm_SlowMoVideoEditorScene->Stop(); } if(sm_SuperSlowMoVideoEditorScene) { sm_SuperSlowMoVideoEditorScene->Stop(); } if(sm_SlowMoSound) { sm_SlowMoSound->StopAndForget(); } } } void audNorthAudioEngine::ShutdownClass() { // if shutdown already then return if(g_AudioInitialised == false) return; if(sm_ExtraContentPath) { delete[] sm_ExtraContentPath; sm_ExtraContentPath = NULL; } #if GTA_REPLAY g_ReplayAudioEntity.Shutdown(); #endif g_FrontendAudioEntity.Shutdown(); g_EmitterAudioEntity.Shutdown(); audScriptAudioEntity::ShutdownClass(); audPedAudioEntity::ShutdownClass(); audWeatherAudioEntity::ShutdownClass(); audVehicleAudioEntity::ShutdownClass(); sm_DynamicMixer.Shutdown(); sm_RadioProxyCat = NULL; sm_ScoreProxyCat = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_ScoreVolCategoryController); sm_ScoreVolCategoryController = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_OneShotVolCategoryController); sm_OneShotVolCategoryController = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_SFXSliderController); sm_SFXSliderController = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_MusicSliderController); sm_MusicSliderController = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_NoFadeVolCategoryController); sm_NoFadeVolCategoryController = NULL; AUDCATEGORYCONTROLLERMANAGER.DestroyController(sm_ScriptedOverrideFadeVolCategoryController); sm_ScriptedOverrideFadeVolCategoryController = NULL; NA_RADIO_ENABLED_ONLY(audRadioAudioEntity::ShutdownClass()); audStreamSlot::ShutdownClass(); sm_AudioController.Shutdown(); g_AudioEngine.Shutdown(); sm_MetadataMgr.Shutdown(); StopUserUpdateFunction(); //Destroy the category manager audCategoryControllerManager::Destroy(); #if RSG_PC || RSG_DURANGO || RSG_ORBIS delete g_AudioPhysicalAllocator; #if RSG_DURANGO || RSG_ORBIS sysMemAllocator::GetMaster().GetAllocator(MEMTYPE_GAME_VIRTUAL)->Free(g_AudioPhysicalMem); #else sysMemPhysicalFree(g_AudioPhysicalMem); #endif #endif sm_IsShuttingDown = true; sysIpcSignalSema(sm_RunUpdateSema); sysIpcWaitThreadExit(sm_UpdateThread); sysIpcDeleteSema(sm_RunUpdateSema); sysIpcDeleteSema(sm_UpdateFinishedSema); sm_RunUpdateSema = 0; sm_UpdateFinishedSema = 0; sm_UpdateThread = sysIpcThreadIdInvalid; g_AudioInitialised = false; } audMetadataDataFileMounter::audMetadataDataFileMounter(audMetadataManager &metadataManager) : m_MetadataManager(metadataManager) { m_UnloadingChunksCount = 0; for(int i=0; i < k_MaxDlcPacks; i++) { m_FramesToUnload[i] = 0; m_UnloadingChunkNames[i][0] = '\0'; } } bool audMetadataDataFileMounter::LoadDataFile(const CDataFileMgr::DataFile &file) { char chunkName[k_ChunkNameLength]; DeriveChunkName(file.m_filename, chunkName, sizeof(chunkName)); audDisplayf("Loading DLC audio chunk %s from %s, time %d", chunkName, file.m_filename, fwTimer::GetTimeInMilliseconds()); bool alreadyLoaded = false; //If we have a defered unload of this pack, cancel it for(int i=0; i < k_MaxDlcPacks; i++) { if(m_UnloadingChunkNames[i][0] != '\0' && atStringHash(chunkName) == atStringHash(m_UnloadingChunkNames[i])) { audDisplayf("Was unloading %s, cancelling", chunkName); m_UnloadingChunkNames[i][0] = '\0'; m_FramesToUnload[i] = 0; --m_UnloadingChunksCount; alreadyLoaded = true; } } bool success = false; if(alreadyLoaded) { success = true; } else { success = m_MetadataManager.LoadMetadataChunk(chunkName, file.m_filename); } if(file.m_fileType == CDataFileMgr::AUDIO_GAMEDATA) { int chunkId = audNorthAudioEngine::GetMetadataManager().FindChunkId(chunkName); audMetadataObjectInfo objectInfo; if(audNorthAudioEngine::GetMetadataManager().GetObjectInfoFromSpecificChunk(ATSTRINGHASH("RADIO_STATIONS_DLC", 0x953BD40D), static_cast(chunkId), objectInfo)) { audRadioStation::MergeRadioStationList(objectInfo.GetObject()); } } #if !__NO_OUTPUT if(success) { const s32 chunkId = m_MetadataManager.FindChunkId(chunkName); audDisplayf("Successfully loaded DLC audio chunk %s, changlist %u", file.m_filename, m_MetadataManager.GetAssetChangelist(chunkId)); } #endif if(success && file.m_fileType == CDataFileMgr::AUDIO_DYNAMIXDATA) { g_AudioEngine.GetDynamicMixManager().InitMixgroupsForChunk(g_AudioEngine.GetDynamicMixManager().GetMetadataManager().FindChunkId(chunkName)); } return success; } void audMetadataDataFileMounter::UnloadDataFile(const CDataFileMgr::DataFile &file) { char chunkName[k_ChunkNameLength]; DeriveChunkName(file.m_filename, chunkName, sizeof(chunkName)); audDisplayf("Starting unload of DLC audio chunk %s from %s time %d", chunkName, file.m_filename, fwTimer::GetTimeInMilliseconds()); if(file.m_fileType == CDataFileMgr::AUDIO_DYNAMIXDATA) { audNorthAudioEngine::GetDynamicMixer().StopScenesFromChunk(chunkName); } if(file.m_fileType == CDataFileMgr::AUDIO_GAMEDATA) { const s32 chunkId = audNorthAudioEngine::GetMetadataManager().FindChunkId(chunkName); audMetadataObjectInfo objectInfo; if(audNorthAudioEngine::GetMetadataManager().GetObjectInfoFromSpecificChunk(ATSTRINGHASH("RADIO_STATIONS_DLC", 0x953BD40D), static_cast(chunkId), objectInfo)) { audDisplayf("Unloading %s which contained DLC radio stations", chunkName); audRadioStation::RemoveRadioStationList(objectInfo.GetObject()); } g_CollisionAudioEntity.RemoveMacsModelOverridesForChunk(chunkId, ATSTRINGHASH("MACS_MODELS_OVERRIDES", 0x53F9AB71)); g_CollisionAudioEntity.RemoveMacsModelOverridesForChunk(chunkId, ATSTRINGHASH("MACS_MODEL_OVERRIDE_LIST_GEN9", 0x149D39FA)); } u32 indexToAdd = k_MaxDlcPacks; for(int i=0; i < k_MaxDlcPacks; i++) { if(m_UnloadingChunkNames[i][0] == '\0') { indexToAdd = i; break; } } FatalAssertf(indexToAdd < k_MaxDlcPacks, "Increase the max number of dlc packs for audMetadataFileMounter"); m_FramesToUnload[indexToAdd] = 1; formatf(m_UnloadingChunkNames[indexToAdd], k_ChunkNameLength, chunkName); ++m_UnloadingChunksCount; } void audMetadataDataFileMounter::Update() { if(m_UnloadingChunksCount > 0) { for(int i=0; i < k_MaxDlcPacks; i++) { if(m_FramesToUnload[i] > 0) { --m_FramesToUnload[i]; } else if(m_UnloadingChunkNames[i][0] != '\0') { naDebugf1("Attempting unload (deferred) chunk %s metadata type %u, time %d, frame %d", m_UnloadingChunkNames[i], m_MetadataManager.GetMetadataTypeHash(), fwTimer::GetTimeInMilliseconds(), fwTimer::GetFrameCount()); if(m_MetadataManager.GetMetadataTypeHash() == ATSTRINGHASH("Sounds", 0x94FA081B)) { if(!g_AudioEngine.GetSoundManager().IsAnyChunkBeingUnloaded()) { g_AudioEngine.RequestThreadPause(true); g_AudioEngine.EnterUpdateLock(); g_AudioEngine.RequestThreadPause(false); g_AudioEngine.GetSoundManager().StartUnloadingChunk(m_UnloadingChunkNames[i]); u32 initialEngineTimeFrames = g_AudioEngine.GetEngineTimeFrames(); g_AudioEngine.ExitUpdateLock(); // Wait for an update so that any sounds using unloaded metadata automatically stop themselves while(initialEngineTimeFrames == g_AudioEngine.GetEngineTimeFrames()) { audDisplayf("Waiting for audio engine update. chunkname=%s", m_UnloadingChunkNames[i]); sysIpcSleep(5); } m_MetadataManager.UnloadMetadataChunk(m_UnloadingChunkNames[i]); g_AudioEngine.GetSoundManager().ClearDisabledMetadata(); m_UnloadingChunkNames[i][0] = '\0'; --m_UnloadingChunksCount; } else { continue; } } else if(m_MetadataManager.GetMetadataTypeHash() == ATSTRINGHASH("ModularSynth", 0xDFBAF5D4)) { // need to ensure the mixer isn't running while we unload this data synthSynthesizer::UnloadMetadataChunk(m_UnloadingChunkNames[i]); m_UnloadingChunkNames[i][0] = '\0'; --m_UnloadingChunksCount; } else { m_MetadataManager.UnloadMetadataChunk(m_UnloadingChunkNames[i]); m_UnloadingChunkNames[i][0] = '\0'; --m_UnloadingChunksCount; } } } } } void audMetadataDataFileMounter::DeriveChunkName(const char *fileName, char *chunkNameBuffer, const size_t chunkNameBufferLen) { const char *chunkNamePtr = strrchr(fileName, '/') + 1; const size_t chunkNameLen = strchr(chunkNamePtr, '_') - chunkNamePtr; audAssertf(chunkNameLen < chunkNameBufferLen, "Chunk name too long for file %s", fileName); safecpy(chunkNameBuffer, chunkNamePtr, Min(chunkNameBufferLen, chunkNameLen + 1)); } void audNorthAudioEngine::RegisterDataFileMounters() { class audWavePackDataFileMounter : public CDataFileMountInterface { public: virtual bool LoadDataFile(const CDataFileMgr::DataFile &file) { Displayf("Mounting audio pack %s", file.m_filename); #if RSG_BANK // If running with audiofolder, assume all assets are available at audio:/ if(PARAM_audiofolder.Get()) { return true; } #endif // RSG_BANK char packName[32]; DerivePackName(file.m_filename, packName, sizeof(packName)); char prefix[9]; strncpy(prefix, packName, 8); prefix[8] = '\0'; char searchPath[RAGE_MAX_PATH]; DeriveSearchPath(file.m_filename, packName, searchPath, sizeof(searchPath)); audWaveSlot::SetSearchPath(prefix, searchPath); if(atStringHash(prefix) == ATSTRINGHASH("dlc_Sum2", 0x7E30C9B)) { audNorthAudioEngine::ApplyARC1BankRemappings(); } return true; } virtual void UnloadDataFile(const CDataFileMgr::DataFile &file) { Displayf("Unmounting audio pack %s time %d", file.m_filename, fwTimer::GetTimeInMilliseconds()); char packName[32]; DerivePackName(file.m_filename, packName, sizeof(packName)); char prefix[9]; memset(prefix, 0, 9); strncpy(prefix, packName, 8); prefix[8] = '\0'; audWaveSlot::RemoveSearchPath(prefix); } private: static void DeriveSearchPath(const char *fileName, const char *packName, char *searchPathBuffer, const size_t searchPathBufferLen) { safecpy(searchPathBuffer, fileName, searchPathBufferLen); const size_t packStart = strlen(searchPathBuffer) - strlen(packName); audAssert(packStart <= strlen(searchPathBuffer)); searchPathBuffer[packStart] = 0; } static void DerivePackName(const char *fileName, char *chunkNameBuffer, const size_t chunkNameBufferLen) { const char *chunkNamePtr = strrchr(fileName, '/') + 1; const size_t chunkNameLen = strlen(chunkNamePtr); audAssertf(chunkNameLen < chunkNameBufferLen, "Pack name too long for file %s", fileName); safecpy(chunkNameBuffer, chunkNamePtr, Min(chunkNameBufferLen, chunkNameLen + 1)); } }; class audSpeechDataFileMounter : public CDataFileMountInterface { public: audSpeechDataFileMounter() { } virtual bool LoadDataFile(const CDataFileMgr::DataFile &file) { char chunkName[32]; DeriveChunkName(file.m_filename, chunkName, sizeof(chunkName)); audDisplayf("Loading DLC speech audio chunk %s from %s", chunkName, file.m_filename); return audSpeechSound::LoadSpeechMetadata(chunkName, file.m_filename); } virtual void UnloadDataFile(const CDataFileMgr::DataFile &file) { char chunkName[32]; DeriveChunkName(file.m_filename, chunkName, sizeof(chunkName)); audDisplayf("Unloading DLC speech audio chunk %s from %s", chunkName, file.m_filename); audSpeechSound::UnloadSpeechMetadata(chunkName); } private: static void DeriveChunkName(const char *fileName, char *chunkNameBuffer, const size_t chunkNameBufferLen) { const char *chunkNamePtr = strrchr(fileName, '/') + 1; const size_t chunkNameLen = strchr(chunkNamePtr, '_') - chunkNamePtr; audAssertf(chunkNameLen < chunkNameBufferLen, "Chunk name too long for file %s", fileName); safecpy(chunkNameBuffer, chunkNamePtr, Min(chunkNameBufferLen, chunkNameLen + 1)); } }; static audMetadataDataFileMounter s_SoundDataMounter(g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager()); static audMetadataDataFileMounter s_CurveDataMounter(g_AudioEngine.GetCurveRepository().GetMetadataManager()); static audMetadataDataFileMounter s_GameDataMounter(audNorthAudioEngine::GetMetadataManager()); static audMetadataDataFileMounter s_DynamicMixerMounter(g_AudioEngine.GetDynamicMixManager().GetMetadataManager()); static audMetadataDataFileMounter s_SynthDataMounter(synthSynthesizer::GetMetadataManager()); static audSpeechDataFileMounter s_SpeechDataMounter; static audWavePackDataFileMounter s_WavePackMounter; sm_SoundDlcMounter = &s_SoundDataMounter; sm_DynamicMixDlcMounter = &s_DynamicMixerMounter; sm_GameObjectDlcMounter = &s_GameDataMounter; sm_CurveDlcMounter = &s_CurveDataMounter; sm_SynthDlcMounter = &s_SynthDataMounter; CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_SOUNDDATA, &s_SoundDataMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_CURVEDATA, &s_CurveDataMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_GAMEDATA, &s_GameDataMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_SPEECHDATA, &s_SpeechDataMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_DYNAMIXDATA, &s_DynamicMixerMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_SYNTHDATA, &s_SynthDataMounter, eDFMI_UnloadFirst); CDataFileMount::RegisterMountInterface(CDataFileMgr::AUDIO_WAVEPACK, &s_WavePackMounter, eDFMI_UnloadFirst); } void audNorthAudioEngine::StartUserUpdateFunction() { //Set the game specific audio thread update g_AudioEngine.SetUserGameUpdateFunction(&audNorthAudioEngine::UpdateAudioThread); } void audNorthAudioEngine::StopUserUpdateFunction() { //Kill the game update function g_AudioEngine.SetUserGameUpdateFunction(NULL); } void audNorthAudioEngine::UpdateAudioThread() { AUDCATEGORYCONTROLLERMANAGER.Update(); #if AUD_ATOMIC_CATEGORIES // If we re-enable AUD_ATOMIC_CATEGORIES, this seems dodgy. g_AudioEngine.GetCategoryManager().CommitCategorySettings(); #endif } void audNorthAudioEngine::StartEnvironmentLocalObjectListUpdate() { if(!fwTimer::IsGamePaused()) { sm_Environment.LocalObjectsList_StartAsyncUpdate(); s_HasScanStarted = true; } } void audNorthAudioEngine::FinishEnvironmentLocalObjectListUpdate() { if(s_HasScanStarted) { sm_Environment.LocalObjectsList_EndAsyncUpdate(); s_HasScanStarted = false; } } extern bool g_DisableNPCVehicleDSP, g_DisablePlayerVehicleDSP; XPARAM(headphones); void audNorthAudioEngine::StartUpdate() { #if GTA_REPLAY static bool s_HaveInitialisedReplayTracks = false; if(CReplayMgr::IsEditorActive() && !s_HaveInitialisedReplayTracks) { CReplayAudioTrackProvider::InitReplayRadioStations(); s_HaveInitialisedReplayTracks = true; } #endif // GTA_REPLAY #if RSG_PC if(!PARAM_nominspecaudio.Get()) { static bool forceMinSpec = PARAM_minspecaudio.Get(); const u32 uMinCores = 4; const float cfMinClockSpeed = 2.6f; bool isMinSpec = (sysIpcGetProcessorCount() <= uMinCores) || (sysTimerConsts::CpuSpeed < cfMinClockSpeed) || forceMinSpec; #if __BANK if(g_OverrideCPULimitedAudioSetting) { isMinSpec = g_ForceMinSpecMode; } #endif g_DisableNPCVehicleDSP = isMinSpec; audDriver::GetVoiceManager().SetCPULimitedAudio(isMinSpec); } #endif sm_Microphones.UpdatePlayerHeadMatrix(); sm_Environment.ResetHasNaveMeshInfoBeenUpdated(); bool isAlreadyFadedOut = sm_IsFadedToBlack; sm_IsFadedToBlack = camInterface::IsFadedOut(); if(!isAlreadyFadedOut && sm_IsFadedToBlack) { sm_ScreenFadedOutThisFrame = true; } const bool isMixerRunning = audDriver::GetMixer() != NULL; PF_PUSH_TIMEBAR("Audio Wait on Thread"); if(isMixerRunning && !sm_IsShuttingDown) { #if RSG_ORBIS audMixerDeviceOrbis *device = ((audMixerDeviceOrbis*)audDriver::GetMixer()); // We need to have a valid user id to associate the pad device->SetPadSpeakerUserId(g_rlNp.GetUserServiceId(CControlMgr::GetMainPlayerIndex())); // Ensure we have up to date info on the port status device->UpdatePortState(); #endif #if GTA_REPLAY if(audDriver::GetMixer() && audDriver::GetMixer()->IsCapturing() && audDriver::GetMixer()->IsFrameRendering()) { g_AudioEngine.TriggerUpdate(); g_AudioEngine.WaitForAudioFrame(); audDriver::GetMixer()->EnterReplaySwitchLock(); audDriver::GetMixer()->TriggerUpdate(); audDriver::GetMixer()->WaitOnMixBuffers(); audDriver::GetMixer()->ExitReplaySwitchLock(); } #endif audDriver::GetMixer()->WaitOnThreadCommandBufferProcessing(); } PF_POP_TIMEBAR(); if (REPLAY_ONLY(!CReplayMgr::IsPreCachingScene() &&) ((fwTimer::IsUserPaused() && !fwTimer::GetSingleStepThisFrame()) || fwTimer::IsGamePaused() BANK_ONLY(|| g_CutsceneAudioPaused))) { Pause(); } else { UnPause(); } UpdateDataSet(); #if __DEV // JP: This can cause asserts at startup as it can be called before the viewport is set up // Seems to make more sense to just use the focus entity selection stuff. // Could probably get rid of g_AudioDebugEntity altogether and just use the focus entity array //g_AudioDebugEntity = CDebugScene::GetEntityUnderMouse(); g_AudioDebugEntity = CDebugScene::FocusEntities_Get(0); #endif // Cache this as its not safe to query on the audio update thread sm_IsRenderingHoodMountedVehicleCam = camInterface::GetCinematicDirector().IsRenderingCinematicMountedCamera() && !camInterface::GetCinematicDirector().IsRenderingCinematicPointOfViewCamera(); sm_IsRenderingFirstPersonVehicleCam = camInterface::IsRenderedCameraInsideVehicle(); const camBaseCamera* dominantRenderedCamera = camInterface::GetDominantRenderedCamera(); // These vehicles have turrets that are inside the vehicle, so ensure we keep the regular interior scene active if(dominantRenderedCamera) { if(dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_DUNE3", 0x8501FD84) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_APC_CANNON", 0xD3FE954B) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_APC_MISSILE", 0xD4FCAB99)) { sm_IsRenderingFirstPersonVehicleCam = true; sm_IsRenderingFirstPersonVehicleTurretCam = true; } // Special case for vehicle mounted turret cams - player is visually outside the vehicle when manning these so first person vehicle scene occludes things weirdly else if(dominantRenderedCamera && (dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_INSURGENT", 0x3F451CCC) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_INSURGENT3", 0x9722AEFA) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_LIMO2", 0x6CCE4543) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_BOXVILLE", 0xCB2DF32E) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_AATRAILER_DUALAA", 0xE52B5A93) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_HALFTRACK_TWINMG", 0x546EBC04) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_HALFTRACK_QUADMG", 0x5030429E) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_AATRAILER_QUADMG", 0xE53AE034) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_AATRAILER_MISSILE", 0xE9FA695B) || dominantRenderedCamera->GetNameHash() == ATSTRINGHASH("POV_TURRET_CAMERA_TECHNICAL", 0x33DCCD41))) { sm_IsRenderingFirstPersonVehicleCam = false; sm_IsRenderingFirstPersonVehicleTurretCam = true; } else { sm_IsRenderingFirstPersonVehicleTurretCam = false; } } else { sm_IsRenderingFirstPersonVehicleTurretCam = false; } #if GTA_REPLAY if (CReplayMgr::IsEditorActive() && dominantRenderedCamera && dominantRenderedCamera->GetIsClassId(camReplayFreeCamera::GetStaticClassId())) { sm_IsRenderingReplayFreeCamera = true; } else { sm_IsRenderingReplayFreeCamera = false; } if(CReplayMgr::IsEditorActive()) { sm_IsRenderingFirstPersonVehicleCam |= (CReplayMgr::IsRenderedCamInVehicle() && CReplayMgr::GetCamInFirstPersonFlag()); } #endif // World probes to get the water heights, needs to run in the main thread. g_AmbientAudioEntity.UpdateShoreLineWaterHeights(); BANK_ONLY (g_AmbientAudioEntity.UpdateShoreLineEditor();) // Update our occlusion data based on if interiors have streamed in/out sm_OcclusionManager.UpdateInteriorMetadata(); // Update our local environment metrics - this line-scans around the camera to build up a detailed local view of the world // Same's true of the static emitter update that needs to grab interior info for non-linked emitters if(!fwTimer::IsGamePaused()) { sm_OcclusionManager.Update(); sm_Environment.UpdateLocalEnvironment(); g_EmitterAudioEntity.CheckStaticEmittersForInteriorInfo(); } s32 speakerOutputOption = CPauseMenu::GetMenuPreference(PREF_SPEAKER_OUTPUT); bool headphones = false; audOutputMode outputMode = audDriver::GetHardwareOutputMode(); static AmbisonicDecoderMode modeArray[AUD_FRONT_SPEAKER_NUM][AUD_REAR_SPEAKER_NUM] = { {kAmbisonicsFwRr, kAmbisonicsFwRm, kAmbisonicsFwRs}, {kAmbisonicsFmRr, kAmbisonicsFmRm, kAmbisonicsFmRs}, {kAmbisonicsFnRr, kAmbisonicsFnRm, kAmbisonicsFnRs} }; // On PS4 we can't automatically detect the headset, so if the user selects Headphones and then enables Pulse Headset Profile, force surround. #if RSG_PS3 || RSG_ORBIS if(sm_ShouldTriggerPulseHeadset) { // Sony Wireless Headset if(outputMode == AUD_OUTPUT_5_1) { g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(kAmbisonicsFmRr); } else { g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(kAmbisonicsHeadphones); headphones = true; } } else #endif // RSG_PS3 || RSG_ORBIS { switch(speakerOutputOption) { case 0: // Speakers if(outputMode == AUD_OUTPUT_5_1) { s32 frontPos = CPauseMenu::GetMenuPreference(PREF_SS_FRONT); s32 rearPos = CPauseMenu::GetMenuPreference(PREF_SS_REAR); AmbisonicDecoderMode ambiMode = modeArray[frontPos][rearPos]; g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(ambiMode); } else { g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(kAmbisonicsStereo); } break; case 1: // TV case 3: // Stereo Speakers outputMode = AUD_OUTPUT_STEREO; g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(kAmbisonicsStereo); break; case 2: // Headphones headphones = true; outputMode = AUD_OUTPUT_STEREO; g_AudioEngine.GetAmbisonics().SetEnvironmentDecoder(kAmbisonicsHeadphones); break; default: naErrorf("Unknown speaker output option"); CPauseMenu::SetMenuPreference(PREF_SPEAKER_OUTPUT, 0); //Unknown speaker output so set it to speakers break; } } g_AudioEngine.GetEnvironment().SetDownmixMode(outputMode); g_AudioEngine.GetEnvironment().SetUsingHeadphones(headphones); if(!sm_RunUpdateInSeperateThread) { Update(); } // move on the particle thread buffer index if(!fwTimer::IsGamePaused()) { g_AmbientAudioEntity.IncrementAudioEffectWriteIndex(); } //Game updates for audio entities NA_RADIO_ENABLED_ONLY(g_RadioAudioEntity.GameUpdate()); g_SpeechManager.UpdateAnimalBanks(); g_ScriptAudioEntity.UpdateConversation(); g_GlassAudioEntity.Update(); audPedAudioEntity::UpdateClass(); audSoundManager &soundManager = g_AudioEngine.GetSoundManager(); soundManager.SetVariableValue(ATSTRINGHASH("Game.Lighting.CurrentExposure", 0x4FBAC7F6), PostFX::g_adaptation.GetUpdateExposure()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Lighting.TargetExposure", 0x31FC0865), PostFX::g_adaptation.GetUpdateTargetExposure()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Lighting.SunVisibility", 0x6E1B558D), CVisualEffects::GetSunVisibility()); CPed *player = CGameWorld::FindLocalPlayer(); if(player && player->GetSpecialAbility() && player->GetSpecialAbility()->IsFadingOut()) { sm_IsPlayerSpecialAbilityFadingOut = true; } else { sm_IsPlayerSpecialAbilityFadingOut = false; } sm_IsAudioUpdateCurrentlyRunning = true; sysIpcSignalSema(sm_RunUpdateSema); } void audNorthAudioEngine::FinishUpdate() { PF_FUNC(NorthAudioUpdateTimer_FinishUpdate); PF_PUSH_TIMEBAR("Wait on sm_UpdateFinishedSema"); sysIpcWaitSema(sm_UpdateFinishedSema); PF_POP_TIMEBAR(); sm_IsAudioUpdateCurrentlyRunning = false; FinishEnvironmentLocalObjectListUpdate(); UpdateVehicleCategories(); audVehicleAudioEntity::ClassFinishUpdate(); sm_AudioController.PostUpdate(); sm_OcclusionManager.FinishUpdate(); #if __BANK audWaveSlot::DebugDrawSlotSizeErrors(); naEnvironmentGroup::DebugDrawEnvironmentGroupPool(); audEnvironmentSound::DebugDrawInvalidCategorySounds(); g_AmbientAudioEntity.DebugDraw(); g_CollisionAudioEntity.DrawDebug(); g_RadioAudioEntity.DebugDrawStations(); g_InteractiveMusicManager.DebugDraw(); g_ScriptAudioEntity.DrawDebug(); sm_SuperConductor.GetVehicleConductor().VehicleConductorDebugInfo(); audVehicleAudioEntity::UpdateCarRecordingTool(); if(!PARAM_inGameAudioWorldSectors.Get()) { sm_Environment.GenerateAudioWorldSectorsInfo(); } audCarAudioEntity::UpdateVolumeCaptureUpdateThread(); audWarpManager::Update(); #endif if(!fwTimer::IsGamePaused()) { CONDUCTORS_ONLY(sm_SuperConductor.ProcessUpdate()); g_WeaponAudioEntity.ProcessCachedWeaponFireEvents(); #if USE_GUN_TAILS sm_GunFireAudioEntity.Update(fwTimer::GetTimeInMilliseconds()); #endif #if __DEV g_WeaponAudioEntity.DebugDraw(); naEnvironment::DebugDraw(); #endif g_CollisionAudioEntity.TriggerDeferedImpacts(); if( !Water::IsCameraUnderwater()) { sm_Environment.UpdateInterestingObjects(); } } naAudioEntity::ProcessDeferredSounds(); audEntity::ProcessBatchedSoundRequests(0); // 0 timestep for the second update this frame audEntity::ResetDeletedObjectLists(); sm_DynamicMixer.FinishUpdate(); DYNAMICMIXMGR.PostUpdateProcess(); g_InteractiveMusicManager.PostUpdate(); audExplosionAudioEntity::Update(); const bool isMixerRunning = audDriver::GetMixer() != NULL; if(isMixerRunning) audDriver::GetMixer()->FlagThreadCommandBufferReadyToProcess(); sm_ScreenFadedOutThisFrame = false; if(sm_DynamicMixDlcMounter) { sm_DynamicMixDlcMounter->Update(); } if(sm_SoundDlcMounter) { sm_SoundDlcMounter->Update(); } if(sm_GameObjectDlcMounter) { sm_GameObjectDlcMounter->Update(); } if(sm_CurveDlcMounter) { sm_CurveDlcMounter->Update(); } if(sm_SynthDlcMounter) { sm_SynthDlcMounter->Update(); } sm_CinematicThirdPersonAimCameraActive = false; const camThirdPersonAimCamera* thirdPersonAimCamera = camInterface::GetGameplayDirector().GetThirdPersonAimCamera(); if (thirdPersonAimCamera && thirdPersonAimCamera->GetIsClassId(camThirdPersonPedAssistedAimCamera::GetStaticClassId())) { const camThirdPersonPedAssistedAimCamera* assistedAimCamera = static_cast(thirdPersonAimCamera); sm_CinematicThirdPersonAimCameraActive = assistedAimCamera->GetCinematicMomentBlendLevel() >= sm_ThirdPersonCameraBlendThreshold; } #if __BANK if(g_WarpToStaticEmitter && g_RequestedWarpEmitter) { Vector3 warpPos(g_RequestedWarpEmitter->Position.x, g_RequestedWarpEmitter->Position.y, g_RequestedWarpEmitter->Position.z); Vector3 zero(0.f,0.f,0.f); CWarpManager::SetWarp(warpPos, zero, 0.f, true, true); g_RequestedWarpEmitter = NULL; } if(g_WarpToAmbientZone && g_RequestedWarpAmbZone) { Vector3 warpPos(g_RequestedWarpAmbZone->ActivationZone.Centre); Vector3 zero(0.f,0.f,0.f); CWarpManager::SetWarp(warpPos, zero, 0.f, true, true); g_RequestedWarpAmbZone = NULL; } if(g_WarpToInterior && g_RequestedWarpInterior) { Vec3V warpPos = Vec3V(V_ZERO); g_RequestedWarpInterior->GetPosition(warpPos); Vector3 zero(0.f,0.f,0.f); CWarpManager::SetWarp(VEC3V_TO_VECTOR3(warpPos), zero, 0.f, true, true); g_RequestedWarpInterior = NULL; } #endif } void audNorthAudioEngine::ApplyARC1BankRemappings() { if (sm_HasAppliedARC1BankRemappings) { return; } // See url:bugstar:6176865 - Replay : Can we compress the replay editor banks so that they only use one slot, instead of four? SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("DLC_REPLAYED/REPLAY_01", 0x4534DBDD), ATSTRINGHASH("DLC_SUM20/Replay_SFX", 0x977D1731)); SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("DLC_REPLAYED/REPLAY_02", 0x4A57E623), ATSTRINGHASH("DLC_SUM20/Replay_SFX", 0x977D1731)); SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("DLC_REPLAYED/REPLAY_03", 0x63801873), ATSTRINGHASH("DLC_SUM20/Replay_SFX", 0x977D1731)); SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("DLC_REPLAYED/REPLAY_04", 0x69BD24ED), ATSTRINGHASH("DLC_SUM20/Replay_SFX", 0x977D1731)); sm_HasAppliedARC1BankRemappings = true; } void audNorthAudioEngine::UpdateDataSet() { const s32 framesToWait = 5; #if GTA_REPLAY LoadReplayAudioBanks(); #endif if(sm_IsMPDataRequested || g_ScriptAudioEntity.IsFlagSet(audScriptAudioFlags::LoadMPData)) { switch(sm_DataSetState) { case Loaded_SP: UnloadSPData(); sm_DataSetStateCount = 0; sm_DataSetState = Stopping_SP; BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(false);) break; case Stopping_SP: sm_DataSetStateCount++; if(sm_DataSetStateCount > framesToWait) { LoadMPData(); sm_DataSetState = Loaded_MP; BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(true);) } break; case Stopping_MP: sm_DataSetStateCount++; if(sm_DataSetStateCount > framesToWait) { LoadMPData(); sm_DataSetState = Loaded_MP; BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(true);) } break; case Loaded_MP: break; } } else { switch(sm_DataSetState) { case Loaded_SP: break; case Stopping_SP: sm_DataSetStateCount++; if(sm_DataSetStateCount > framesToWait) { LoadSPData(); sm_DataSetState = Loaded_SP; BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(true);) } break; case Stopping_MP: sm_DataSetStateCount++; if(sm_DataSetStateCount > framesToWait) { LoadSPData(); sm_DataSetState = Loaded_SP; BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(true);) } break; case Loaded_MP: BANK_ONLY(g_AudioEngine.GetRemoteControl().SetOutgoingMessagesEnabled(false);) UnloadMPData(); sm_DataSetStateCount = 0; sm_DataSetState = Stopping_MP; break; } } } void audNorthAudioEngine::LoadMPData() { audDisplayf("Loading multiplayer metadata"); // If we enter here in the Stopping_MP state then the data is already loaded if(sm_DataSetState != Stopping_MP) { // Unload SP data (preserve buffer) g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().UnloadMetadataChunk("SinglePlayer", false); g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().LoadMetadataChunk("GTAOnline", "audio:/config/dlc_gtao_sounds.dat", sm_SPSoundDataPtr, sm_SPSoundDataSize); GetMetadataManager().LoadMetadataChunk("GTAOnline", "audio:/config/dlc_gtao_game.dat"); g_AudioEngine.GetDynamicMixManager().GetMetadataManager().LoadMetadataChunk("GTAOnline", "audio:/config/dlc_gtao_mix.dat"); if(g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().FindChunkId("GTAOnline") == -1) { Quitf(ERR_AUD_GTA_ONLINE_LOAD,"Failed to load GTAOnline audio data"); } audDisplayf("Loaded GTAOnline audio assets, source CLs: sounds %u, game objects: %u, dynamic mixer: %u", g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetAssetChangelist(-1), sm_MetadataMgr.GetAssetChangelist(-1), g_AudioEngine.GetDynamicMixManager().GetMetadataManager().GetAssetChangelist(-1)); g_AudioEngine.GetSoundManager().ClearDisabledMetadata(); g_AudioEngine.GetDynamicMixManager().InitMixgroupsForChunk(g_AudioEngine.GetDynamicMixManager().GetMetadataManager().FindChunkId("GTAOnline")); g_EmitterAudioEntity.ReInitStaticEmitters(); g_AmbientAudioEntity.CheckAndAddZones(); audPedAudioEntity::InitMPSpecificSounds(); // See url:bugstar:5745340 - GTAO - Consolidate 321_GO and MP_WASTED banks into GTAO Snacks SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("SCRIPT/HUD_321_GO", 0x1F90E64), ATSTRINGHASH("DLC_GTAO/SNACKS", 0x81CAD0C)); SOUNDFACTORY.AddBankRemapping(ATSTRINGHASH("SCRIPT/MP_WASTED", 0x26ED9800), ATSTRINGHASH("DLC_GTAO/SNACKS", 0x81CAD0C)); #if RSG_PC // Need to manually point the GTA Online pack at the loose files in the titleupdate folder, otherwise the file system // gets confused and tries to read from the original .rpf file that we shipped with. See B*2460076 etc. if(!PARAM_audiofolder.Get()) { audWaveSlot::SetSearchPath("DLC_GTAO", "update:/x64/audio/sfx/"); } #endif g_FrontendAudioEntity.SetMPSpecialAbilityBankId(); // this grabs the bank id for the GTAO/MP_RESIDENT bank } else { g_AudioEngine.GetSoundManager().CancelUnloadingChunk("GTAOnline"); g_AudioEngine.GetDynamicMixManager().CancelUnloadingChunk("GTAOnline"); g_AudioEngine.GetSoundManager().ClearDisabledMetadata(); const s32 chunkId = sm_MetadataMgr.FindChunkId("GTAOnline"); if(naVerifyf(chunkId != -1, "Failed to find loaded gameobject chunk GTAOnline")) { sm_MetadataMgr.SetChunkEnabled(chunkId, true); } g_EmitterAudioEntity.ReInitStaticEmitters(); g_AmbientAudioEntity.CheckAndAddZones(); } audEnvironmentSound::SetMixGroupPitchFrequencyScalingEnabled(true); } void audNorthAudioEngine::LoadSPData() { audDisplayf("Loading singleplayer metadata"); // Unload multiplayer data if we have any loaded (preserve buffer for sounds) g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().UnloadMetadataChunk("GTAOnline",false); GetMetadataManager().UnloadMetadataChunk("GTAOnline"); g_AudioEngine.GetDynamicMixManager().GetMetadataManager().UnloadMetadataChunk("GTAOnline"); g_AudioEngine.GetSoundManager().ClearDisabledMetadata(); // load SP data g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().LoadMetadataChunk("SinglePlayer", "audio:/config/sp_sounds.dat", sm_SPSoundDataPtr, sm_SPSoundDataSize); g_EmitterAudioEntity.ReInitStaticEmitters(); g_AmbientAudioEntity.CheckAndAddZones(); g_FrontendAudioEntity.SetSPSpecialAbilityBankId(); SOUNDFACTORY.RemoveBankRemapping(ATSTRINGHASH("SCRIPT/HUD_321_GO", 0x1F90E64)); SOUNDFACTORY.RemoveBankRemapping(ATSTRINGHASH("SCRIPT/MP_WASTED", 0x26ED9800)); } void audNorthAudioEngine::UnloadMPData() { naDisplayf("Unloading MP Data time %u, frame %u", fwTimer::GetTimeInMilliseconds(), fwTimer::GetFrameCount()); // Ensure no score is playing (it can hold onto Mood object references) #if GTA_REPLAY bool isReplayTransition = (CReplayMgr::IsEditModeActive() && CReplayCoordinator::IsExportingToVideoFile() && CVideoEditorPlayback::IsLoading()); #else bool isReplayTransition = false; #endif if (!isReplayTransition) g_InteractiveMusicManager.Reset(); g_AudioEngine.GetSoundManager().StartUnloadingChunk("GTAOnline"); sm_DynamicMixer.StopOnlineScenes(); g_AudioEngine.GetDynamicMixManager().StartUnloadingChunk("GTAOnline"); const s32 chunkId = sm_MetadataMgr.FindChunkId("GTAOnline"); if(chunkId != -1) { const audMetadataChunk &chunk = sm_MetadataMgr.GetChunk(chunkId); RegisterGameObjectMetadataUnloading(chunk); sm_MetadataMgr.SetChunkEnabled(chunkId, false); } g_EmitterAudioEntity.ReInitStaticEmitters(); g_AmbientAudioEntity.CheckAndAddZones(); #if RSG_PC audWaveSlot::RemoveSearchPath("DLC_GTAO"); #endif audEnvironmentSound::SetMixGroupPitchFrequencyScalingEnabled(false); } void audNorthAudioEngine::UnloadSPData() { naDisplayf("Unloading SP Data time %u, frame %u", fwTimer::GetTimeInMilliseconds(), fwTimer::GetFrameCount()); g_AudioEngine.GetSoundManager().StartUnloadingChunk("SinglePlayer"); } void audNorthAudioEngine::LoadMapData() { #if RSG_BANK if(!PARAM_audiodesigner.Get()) { return; } const char *pLevelName = audNorthAudioEngine::GetCurrentAudioLevelName(); audDisplayf("Current audio level: %s", pLevelName); size_t len = strlen(pLevelName); // ignore "gta5_" if(len > 5) { const char *suffix = pLevelName + 5; char fileName[RAGE_MAX_PATH]; char chunkName[RAGE_MAX_PATH]; formatf(chunkName, "dlc%s", suffix); // Sounds g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().LoadMetadataChunk(chunkName, formatf(fileName, "audio:/config/dlc%s_sounds.dat", suffix)); // Curves g_AudioEngine.GetCurveRepository().GetMetadataManager().LoadMetadataChunk(chunkName, formatf(fileName, "audio:/config/dlc%s_curves.dat", suffix)); // DynamicMixer g_AudioEngine.GetDynamicMixManager().GetMetadataManager().LoadMetadataChunk(chunkName, formatf(fileName, "audio:/config/dlc%s_mix.dat", suffix)); // Synth synthSynthesizer::GetMetadataManager().LoadMetadataChunk(chunkName, formatf(fileName, "audio:/config/dlc%s_amp.dat", suffix)); // Game Objects sm_MetadataMgr.LoadMetadataChunk(chunkName, formatf(fileName, "audio:/config/dlc%s_game.dat", suffix)); } #endif // RSG_BANK } void audNorthAudioEngine::UnloadMapData() { #if RSG_BANK if(!PARAM_audiodesigner.Get()) { return; } const char *pLevelName = audNorthAudioEngine::GetCurrentAudioLevelName(); size_t len = strlen(pLevelName); // ignore "gta5_" if(len > 5) { const char *suffix = pLevelName + 5; char chunkName[RAGE_MAX_PATH]; formatf(chunkName, "dlc%s", suffix); // Sounds g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().UnloadMetadataChunk(chunkName); // Curves g_AudioEngine.GetCurveRepository().GetMetadataManager().UnloadMetadataChunk(chunkName); // DynamicMixer g_AudioEngine.GetDynamicMixManager().GetMetadataManager().UnloadMetadataChunk(chunkName); // Synth synthSynthesizer::GetMetadataManager().UnloadMetadataChunk(chunkName); // Game Objects sm_MetadataMgr.UnloadMetadataChunk(chunkName); } #endif // RSG_BANK } void audNorthAudioEngine::RegisterGameObjectMetadataUnloading(const audMetadataChunk& chunk) { // Clear out all CMloModelInfo's that are referencing any InteriorSettings/InteriorRoom GO we're about to unload CInteriorProxy::Pool* pool = CInteriorProxy::GetPool(); if(pool) { s32 numSlots = pool->GetSize(); for(s32 slot = 0; slot < numSlots; slot++) { CInteriorProxy* intProxy = pool->GetSlot(slot); if(intProxy) { CInteriorInst* intInst = intProxy->GetInteriorInst(); if(intInst && intInst->IsPopulated()) { CMloModelInfo *modelInfo = intInst->GetMloModelInfo(); if(naVerifyf(modelInfo, "NULL CMLOModelInfo")) { const s32 numRooms = intInst->GetNumRooms(); // Start at roomIdx 1 as roomdIdx 0 is always limbo(outside) which we won't have settings for. for(s32 roomIdx = 1; roomIdx < numRooms; roomIdx++) { const InteriorSettings* intSettings; const InteriorRoom* intRoom; modelInfo->GetAudioSettings(roomIdx, intSettings, intRoom); if((intSettings && chunk.IsObjectInChunk(intSettings)) || (intRoom && chunk.IsObjectInChunk(intRoom))) { modelInfo->SetAudioSettings(roomIdx, NULL, NULL); } } } } } } } // Also clear out any references to those InteriorSettings/InteriorRoom GO's in the environmentGroups audNorthAudioEngine::GetAudioController()->RegisterGameObjectMetadataUnloading(chunk); } #if GTA_REPLAY void audNorthAudioEngine::LoadReplayAudioBanks() { BANK_ONLY(bool forceLoad = sm_ForceSuperSlowMoVideoEditor || sm_ForceSlowMoVideoEditor); if((CReplayMgr::IsEditModeActive() BANK_ONLY(||forceLoad)) && !sm_AreReplayBanksLoaded) { sm_AreReplayBanksLoaded = g_ScriptAudioEntity.ReplayLoadScriptBank(ATSTRINGHASH("DLC_SUM20/Replay_SFX", 0x977D1731), 10); } } bool audNorthAudioEngine::PumpReplayAudio() { bool addedAudio = false; if(audDriver::GetMixer() && audDriver::GetMixer()->IsCapturing() && audDriver::GetMixer()->IsFrameRendering()) { const float kfFrameStep = 1.0f / 31.0f; // Only trigger an extra engine update when exporting at 30fps or less to make sure enough audio is generated this frame if(audDriver::GetMixer()->GetTotalAudioTimeNs() < audDriver::GetMixer()->GetTotalVideoTimeNs() && CReplayMgr::GetExportFrameStep() >= kfFrameStep) { g_AudioEngine.TriggerUpdate(); g_AudioEngine.WaitForAudioFrame(); } while(audDriver::GetMixer()->GetTotalAudioTimeNs() < audDriver::GetMixer()->GetTotalVideoTimeNs()) { audDriver::GetMixer()->EnterReplaySwitchLock(); audDriver::GetMixer()->TriggerUpdate(); audDriver::GetMixer()->WaitOnMixBuffers(); audDriver::GetMixer()->ExitReplaySwitchLock(); //Displayf("Catch Up Audio: %LLu chasing (%LLu)", // NANOSECONDS_TO_ONE_H_NS_UNITS(audDriver::GetMixer()->GetTotalAudioTimeNs()), // NANOSECONDS_TO_ONE_H_NS_UNITS(audDriver::GetMixer()->GetTotalVideoTimeNs())); addedAudio = true; } } return addedAudio; } #endif void audNorthAudioEngine::AudioUpdateThread(void*) { CSystem::SetThisThreadId(SYS_THREAD_AUDIO); const bool isMixerRunning = audDriver::GetMixer() != NULL; if(isMixerRunning) { const u32 commandBufferSize = 8192 WIN32PC_ONLY( *COMMAND_BUFFER_SIZE_MUTIPLIER ); audDriver::GetMixer()->InitClientThread("NorthAudioUpdateThread", commandBufferSize); } while(true) { TELEMETRY_START_ZONE(PZONE_NORMAL, __FILE__,__LINE__,"Wait on sm_RunUpdateSema"); sysIpcWaitSema(sm_RunUpdateSema); TELEMETRY_END_ZONE(__FILE__,__LINE__); PF_START(NorthAudioUpdateTimer); if(sm_IsShuttingDown) { return; } if(sm_RunUpdateInSeperateThread) { u32 timestamp = 0; if(isMixerRunning) { PF_START(NorthAudioUpdateTimer_CommandBuffer); TELEMETRY_START_ZONE(PZONE_NORMAL, __FILE__,__LINE__,"WaitOnThreadCommandBufferProcessing"); #if GTA_REPLAY if(audDriver::GetMixer() && audDriver::GetMixer()->IsCapturing() && audDriver::GetMixer()->IsFrameRendering()) { audDriver::GetMixer()->TriggerUpdate(); audDriver::GetMixer()->WaitOnMixBuffers(); } #endif audDriver::GetMixer()->WaitOnThreadCommandBufferProcessing(); timestamp = audDriver::GetMixer()->GetMixerTimeFrames(); TELEMETRY_END_ZONE(__FILE__,__LINE__); PF_STOP(NorthAudioUpdateTimer_CommandBuffer); } #if COMMERCE_CONTAINER if (CLiveManager::GetCommerceMgr().ContainerIsStoreMode()) { MinimalUpdate(); } else #endif { TELEMETRY_START_ZONE(PZONE_NORMAL, __FILE__,__LINE__,"audNorthAudioEngine::Update()"); PF_START(NorthAudioUpdateTimer_Update); Update(); PF_STOP(NorthAudioUpdateTimer_Update); TELEMETRY_END_ZONE(__FILE__,__LINE__); } if(isMixerRunning) { audDriver::GetMixer()->FlagThreadCommandBufferReadyToProcess(timestamp); } } sysIpcSignalSema(sm_UpdateFinishedSema); PF_STOP(NorthAudioUpdateTimer); } } void audNorthAudioEngine::MinimalUpdate() { const bool isMixerRunning = audDriver::GetMixer() != NULL; if(isMixerRunning) { audDriver::GetMixer()->WaitOnThreadCommandBufferProcessing(); } naAudioEntity::ProcessDeferredSounds(); audEntity::ProcessBatchedSoundRequests(static_cast(fwTimer::GetTimeStepInMilliseconds())); audEntity::ResetDeletedObjectLists(); const bool shouldUpdateEnvironmentGroups = sm_AudioController.sm_ShouldUpdateEnvironmentGroups; sm_AudioController.sm_ShouldUpdateEnvironmentGroups = false; sm_AudioController.Update(sm_TimeInMs); sm_AudioController.sm_ShouldUpdateEnvironmentGroups = shouldUpdateEnvironmentGroups; //Update the dynamic mixer sm_DynamicMixer.Update(); AUDCATEGORYCONTROLLERMANAGER.Update(); g_AudioEngine.CommitGameSettings(sm_TimeInMs); if(isMixerRunning) { audDriver::GetMixer()->FlagThreadCommandBufferReadyToProcess(); } } void audNorthAudioEngine::ActivateSlowMoMode(u32 settingsHash) { SlowMoSettings * settings = GetObject(settingsHash); if(settings) { if(naVerifyf(!sm_ActiveSlowMoModes[settings->Priority], "Trying to set SlowMoType %d, but it is already set; deactivate it first", settings->Priority)) { if(settings->Priority > sm_SlowMoMode) { if(sm_IsInSlowMo) { if(sm_SlowMoScene) { sm_SlowMoScene->Stop(); } sm_DynamicMixer.StartScene(settings->Scene, &sm_SlowMoScene); if(sm_SlowMoSound) { sm_SlowMoSound->StopAndForget(); } g_FrontendAudioEntity.CreateAndPlaySound_Persistent(settings->SlowMoSound, &sm_SlowMoSound); } sm_SlowMoMode = (SlowMoType)settings->Priority; } sm_ActiveSlowMoModes[settings->Priority] = settingsHash; } } } void audNorthAudioEngine::DeactivateSlowMoMode(u32 settingsHash) { SlowMoSettings * settings = GetObject(settingsHash); if(settings) { if(sm_SlowMoMode == settings->Priority) { SlowMoType priorityType = AUD_SLOWMO_GENERAL; for(int i=1; iStop(); SlowMoSettings * newSettings = GetObject(sm_ActiveSlowMoModes[priorityType]); if(newSettings) { sm_DynamicMixer.StartScene(newSettings->Scene, &sm_SlowMoScene); } } if(sm_SlowMoSound) { sm_SlowMoSound->StopAndForget(); g_FrontendAudioEntity.CreateAndPlaySound_Persistent(settings->SlowMoSound, &sm_SlowMoSound); } sm_SlowMoMode = priorityType; } sm_ActiveSlowMoModes[settings->Priority] = 0; } } void audNorthAudioEngine::DeactivateSlowMoMode(SlowMoType priority) { if(priority == AUD_SLOWMO_GENERAL) { return; //can't deactivate slowmo general } if(sm_SlowMoMode == priority) { SlowMoType priorityType = AUD_SLOWMO_GENERAL; for(int i=1; i(sm_ActiveSlowMoModes[priorityType]); if(sm_SlowMoScene) { sm_SlowMoScene->Stop(); if(newSettings) { sm_DynamicMixer.StartScene(newSettings->Scene, &sm_SlowMoScene); } } if(sm_SlowMoSound) { sm_SlowMoSound->StopAndForget(); g_FrontendAudioEntity.CreateAndPlaySound_Persistent(newSettings->SlowMoSound, &sm_SlowMoSound); } sm_SlowMoMode = priorityType; } sm_ActiveSlowMoModes[priority] = 0; } bool audNorthAudioEngine::IsAFirstPersonCameraActive(const CPed* ped, const bool bCheckStrafe, const bool bIncludeClone, const bool bDisableForDominantScriptedCams, const bool bDisableForDominantCutsceneCams, const bool bCheckFlags) { if(!ped) { return false; } bool isFirstPerson = FPS_MODE_SUPPORTED_ONLY(ped ? ped->IsFirstPersonShooterModeEnabledForPlayer(bCheckStrafe, bIncludeClone, bDisableForDominantScriptedCams, bDisableForDominantCutsceneCams, bCheckFlags) :) false; #if GTA_REPLAY if(CReplayMgr::IsPlaying()) { return camInterface::IsDominantRenderedCameraAnyFirstPersonCamera(); } #endif return isFirstPerson; } bool audNorthAudioEngine::IsSuperSlowVideoEditor() { #if GTA_REPLAY if(CReplayMgr::IsEditModeActive()) { if(CReplayMgr::IsUserPaused() && CReplayMgr::GetCursorSpeed() > 0.f && CReplayMgr::GetCursorSpeed() <= 0.06f) { return true; } if(!CReplayMgr::IsUserPaused() && CReplayMgr::GetMarkerSpeed() <= 0.06f && CReplayMgr::GetCursorSpeed() == 1.f) { return true; } } #if __BANK if(sm_ForceSuperSlowMoVideoEditor) { return true; } #endif #endif return false; } #if GTA_REPLAY void audNorthAudioEngine::ShutdownReplayEditor() { g_ScriptAudioEntity.CleanUpScriptBankSlotsAfterReplay(); } #endif bool audNorthAudioEngine::IsInCinematicSlowMo() { if(sm_IsInSlowMo && sm_CinematicThirdPersonAimCameraActive) { return true; } return false; } bool audNorthAudioEngine::IsInVideoEditor() { #if GTA_REPLAY if(CReplayMgr::IsEditModeActive()) { return true; } #endif return false; } bool audNorthAudioEngine::IsInSlowMoVideoEditor() { #if GTA_REPLAY if(CReplayMgr::IsEditModeActive()) { if(CReplayMgr::IsUserPaused() && CReplayMgr::GetCursorSpeed() > 0.f && CReplayMgr::GetCursorSpeed() < 1.f) { return true; } if(!CReplayMgr::IsUserPaused() && CReplayMgr::GetMarkerSpeed() < 1.f && CReplayMgr::GetCursorSpeed() == 1.f) { return true; } } #endif #if __BANK if(sm_ForceSlowMoVideoEditor) { return true; } #endif if(sm_IsInSlowMo && sm_CinematicThirdPersonAimCameraActive) { return true; } return false; } SlowMoType audNorthAudioEngine::GetActiveSlowMoMode() { return sm_SlowMoMode; } void audNorthAudioEngine::Update() { USE_MEMBUCKET(MEMBUCKET_AUDIO); #if RSG_PC && __BANK audMixerDeviceXAudio2::SetNumberOfAudioMixBuffers(g_NumberOfMixBuffers); #endif #if __DEV PF_SET(MaxVoicesPerBucket, g_MaxVoicesUsed); PF_SET(MaxSoundsPerBucket, g_MaxSoundSlotsUsed); PF_SET(MaxRequestedSettingsPerBucket, g_MaxRequestedSettingsSlotsUsed); #endif #if __WIN32 sysPerformanceTimer timer("audNorthAudioEngine"); timer.Start(); #endif // __WIN32 PIXBegin(0, "NorthAudioUpdate"); // Do anything specific if we've just been paused. sm_PausedLastFrame = sm_Paused; // If we're paused, don't update the time we pass into camera and controller updates if (!sm_Paused) { sm_LastTimeInMs = sm_TimeInMs; sm_TimeInMs = fwTimer::GetTimeInMilliseconds(); } sm_IsInSlowMo = fwTimer::GetTimeWarpActive() < 1.f REPLAY_ONLY(|| (CReplayMgr::IsEditModeActive() && IsInSlowMoVideoEditor()) || sm_ForceSlowMoVideoEditor || sm_ForceSuperSlowMoVideoEditor); bool isInSpecialAbilitySlowmo = (fwTimer::GetTimeWarpActive() < 1.f && !sm_IsPlayerSpecialAbilityFadingOut) REPLAY_ONLY(|| (CReplayMgr::IsEditModeActive() && IsInSlowMoVideoEditor())); if(!sm_IsInSlowMo && sm_WaitingForPauseMenuSlowMoToEnd) { sm_WaitingForPauseMenuSlowMoToEnd = false; } // Set up the microphones sm_Microphones.SetUpMicrophones(); #if RSG_PS3 || RSG_ORBIS ORBIS_ONLY(sm_IsWirelessHeadsetConnected = CPauseMenu::GetMenuPreference(PREF_SPEAKER_OUTPUT) == 2 && CPauseMenu::GetMenuPreference(PREF_PULSE_HEADSET) == TRUE); if(sm_IsWirelessHeadsetConnected) { if(!sm_ShouldTriggerPulseHeadset) { sm_ShouldTriggerPulseHeadset = true; g_SFXHPFCutoff = g_PulseHPFCutoff; g_SFXHPFBypass = false; if(!sm_PulseHeadsetScene) { DYNAMICMIXER.StartScene("PULSE_HEADSET_SCENE", &sm_PulseHeadsetScene); } } } else if(sm_PulseHeadsetScene) { sm_ShouldTriggerPulseHeadset = false; g_SFXHPFBypass = true; sm_PulseHeadsetScene->Stop(); sm_PulseHeadsetScene = NULL; } #endif if(g_AudioEngine.GetEnvironment().GetSpecialEffectMode() == kSpecialEffectModeStoned) { if(!sm_StonedScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("SPECIAL_EFFECT_MODE_STONED_SCENE", 0x8D342873), &sm_StonedScene); } } else { if(sm_StonedScene) { sm_StonedScene->Stop(); sm_StonedScene = NULL; } } CPed * player = CGameWorld::FindLocalPlayer(); if(player) { if(player->GetSpecialAbility()) { bool specialAbilityActive = player->GetSpecialAbility()->IsActive(); #if GTA_REPLAY if(CReplayMgr::IsEditModeActive()) { specialAbilityActive = false; } #endif if(specialAbilityActive) { sm_LastTimeSpecialAbilityActive = g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0); } //Displayf("specialAbilityActive %d", specialAbilityActive); if(specialAbilityActive && !sm_ActiveSlowMoModes[AUD_SLOWMO_SPECIAL]) { if(CNetwork::IsGameInProgress()) // currently there is no differentiation between local player slowmo and remote player slowmo { ActivateSlowMoMode(ATSTRINGHASH("GTAO_BT_ACTIVATING_PLAYER", 0x3F4DC076)); //ActivateSlowMoMode(ATSTRINGHASH("GTAO_SLOWMO_SPECIAL_BYSTANDER", 0xEBCBB786)); } else { switch(player->GetPedAudioEntity()->GetPedType()) { case PEDTYPE_PLAYER_0: //MICHAEL ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_SPECIAL_MICHAEL", 0xAAADDCBC)); break; case PEDTYPE_PLAYER_1: //FRANKLIN ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_SPECIAL_FRANKLIN", 0x579EE10D)); break; case PEDTYPE_PLAYER_2: //TREVOR ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_SPECIAL_TREVOR", 0xF798196B)); break; default: break; } } } else if(!specialAbilityActive) { g_FrontendAudioEntity.StopSpecialAbility(); if(sm_ActiveSlowMoModes[AUD_SLOWMO_SPECIAL]) { DeactivateSlowMoMode(AUD_SLOWMO_SPECIAL); } } } bool weaponWheelActive = false; if(CNetwork::IsGameInProgress()) { const CPed *playerPed = CGameWorld::FindLocalPlayer(); const bool isUsingVehicleWeaponControls = playerPed && (playerPed->GetIsInVehicle() || playerPed->GetIsParachuting() || playerPed->GetPedResetFlag(CPED_RESET_FLAG_IsUsingJetpack)); weaponWheelActive = CNewHud::IsWeaponWheelVisible() && !isUsingVehicleWeaponControls; } else { weaponWheelActive = CNewHud::IsWeaponWheelActive() && CNewHud::ShouldWheelBlockCamera(); } if(weaponWheelActive) { if(!sm_ActiveSlowMoModes[AUD_SLOWMO_WEAPON]) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_WEAPON", 0xF1D29082)); } } else if(!weaponWheelActive && sm_ActiveSlowMoModes[AUD_SLOWMO_WEAPON]) { DeactivateSlowMoMode(AUD_SLOWMO_WEAPON); } if(CStuntJumpManager::IsAStuntjumpInProgress()) { if(!sm_ActiveSlowMoModes[AUD_SLOWMO_STUNT]) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_STUNT", 0xC7CA5E0C)); } } if(!CStuntJumpManager::IsAStuntjumpInProgress() && sm_ActiveSlowMoModes[AUD_SLOWMO_STUNT]) { DeactivateSlowMoMode(AUD_SLOWMO_STUNT); } if(sm_CinematicThirdPersonAimCameraActive && sm_IsInSlowMo) { if(!sm_ActiveSlowMoModes[AUD_SLOWMO_THIRD_PERSON_CINEMATIC_AIM]) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_THIRD_PERSON_CINEMATIC_AIM", 0xAEDE85AD)); } } else { DeactivateSlowMoMode(AUD_SLOWMO_THIRD_PERSON_CINEMATIC_AIM); } if(camInterface::GetCinematicDirector().IsSlowMoActive()) { if(!sm_ActiveSlowMoModes[AUD_SLOWMO_CINEMATIC]) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_CINEMATIC", 0x929AEE2A)); } } else if(!camInterface::GetCinematicDirector().IsSlowMoActive() && sm_ActiveSlowMoModes[AUD_SLOWMO_CINEMATIC]) { DeactivateSlowMoMode(AUD_SLOWMO_CINEMATIC); } if(g_ScriptAudioEntity.IsFlagSet(audScriptAudioFlags::ActivateSwitchWheelAudio) && !sm_ActiveSlowMoModes[AUD_SLOWMO_SWITCH]) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_SWITCH", 0xC33BCB9F)); } else if(!g_ScriptAudioEntity.IsFlagSet(audScriptAudioFlags::ActivateSwitchWheelAudio) && sm_ActiveSlowMoModes[AUD_SLOWMO_SWITCH]) { DeactivateSlowMoMode(AUD_SLOWMO_SWITCH); } if(sm_SlowMoMode == AUD_SLOWMO_SPECIAL && !sm_ActiveSlowMoModes[AUD_SLOWMO_STUNT]) { sm_IsInSlowMo = isInSpecialAbilitySlowmo; } if(sm_IsInSlowMo && sm_SlowMoMode == AUD_SLOWMO_SPECIAL REPLAY_ONLY( && !CReplayMgr::IsEditorActive())) { if(NetworkInterface::IsGameInProgress()) // currently there is no differentiation between local player slowmo and remote player slowmo { g_FrontendAudioEntity.StartSpecialAbility(ATSTRINGHASH("Multiplayer", 0xDDA1F78)); } else { switch(player->GetPedAudioEntity()->GetPedType()) { case PEDTYPE_PLAYER_0: //MICHAEL g_FrontendAudioEntity.StartSpecialAbility(ATSTRINGHASH("Michael", 0x55932F38)); break; case PEDTYPE_PLAYER_1: //FRANKLIN g_FrontendAudioEntity.StartSpecialAbility(ATSTRINGHASH("Franklin", 0x44C24694)); break; case PEDTYPE_PLAYER_2: //TREVOR g_FrontendAudioEntity.StartSpecialAbility(ATSTRINGHASH("Trevor", 0x2737D5AC)); break; default: break; } } } else { g_FrontendAudioEntity.StopSpecialAbility(); } if(sm_IsInSlowMo && sm_SlowMoMode == AUD_SLOWMO_SWITCH) { g_FrontendAudioEntity.StartSwitch(); } else { g_FrontendAudioEntity.StopSwitch(); } if(weaponWheelActive) { g_FrontendAudioEntity.StartWeaponWheel(); } else { g_FrontendAudioEntity.StopWeaponWheel(); } if(sm_IsInSlowMo && sm_SlowMoMode == AUD_SLOWMO_STUNT) { g_FrontendAudioEntity.StartStunt(); } else { g_FrontendAudioEntity.StopStunt(); } if(sm_IsInSlowMo && sm_SlowMoMode == AUD_SLOWMO_CINEMATIC) { g_FrontendAudioEntity.StartCinematic(); } else { g_FrontendAudioEntity.StopCinematic(); } if(sm_IsInSlowMo && sm_SlowMoMode == AUD_SLOWMO_GENERAL) { g_FrontendAudioEntity.StartGeneralSlowMo(); } else { g_FrontendAudioEntity.StopGeneralSlowMo(); } } // note: using the audio timer, since fwTimer will be warped by the time warp const f32 timeWarp = sm_TimeWarpSmoother.CalculateValue(fwTimer::GetTimeWarpActive(), g_AudioEngine.GetTimeInMilliseconds()); f32 timeScale = sm_TimeWarpToTimeScale.CalculateValue(timeWarp); f32 slowmoTimesWarp = timeWarp; f32 slowmoTimesScale = timeScale; #if GTA_REPLAY if(CReplayMgr::IsEditModeActive() BANK_ONLY(|| sm_ForceSlowMoVideoEditor || sm_ForceSuperSlowMoVideoEditor) ) { #if __BANK if(sm_ForceSlowMoVideoEditor) { timeScale = 0.2f; } if(sm_ForceSuperSlowMoVideoEditor) { timeScale = 0.05f; } if(!sm_ForceSlowMoVideoEditor && !sm_ForceSuperSlowMoVideoEditor) // if we're not forcing just use the timescale from the marker otherwise use whatever was set { timeScale = CReplayMgr::GetMarkerSpeed(); } #else timeScale = CReplayMgr::GetMarkerSpeed(); #endif f32 replayTimeScale = timeScale; if(timeScale < 1.0f) { if(sm_ReplayTimeWarpToTimeScale.IsValid()) { replayTimeScale = sm_ReplayTimeWarpToTimeScale.CalculateValue(timeScale); } else { static const audThreePointPiecewiseLinearCurve replayTimeScaleCurve(0.05f, 0.25f, 0.475f, 0.55f, 1.0f, 1.0f); replayTimeScale = replayTimeScaleCurve.CalculateValue(timeScale); } } g_GameWorldCategory->SetFrequencyRatio(replayTimeScale); slowmoTimesScale = replayTimeScale; slowmoTimesWarp = replayTimeScale; } else { g_GameWorldCategory->SetFrequencyRatio(1.0f); } #endif // lets only slow down pausable stuff g_AudioEngine.GetSoundManager().SetTimeScale(0, sm_SlowMoMode == AUD_SLOWMO_PAUSEMENU ? 1.f : slowmoTimesScale); if(sm_IsInSlowMo) { SlowMoSettings * slowMo = GetObject(sm_ActiveSlowMoModes[sm_SlowMoMode]); if(slowMo) { if(!sm_SlowMoScene) { sm_DynamicMixer.StartScene(slowMo->Scene, &sm_SlowMoScene); } if(!sm_SlowMoSound) { g_FrontendAudioEntity.CreateAndPlaySound_Persistent(slowMo->SlowMoSound, &sm_SlowMoSound); } } if(sm_SlowMoScene) { sm_SlowMoScene->SetVariableValue(ATSTRINGHASH("pitchApply", 0x20E8D2B3), slowmoTimesWarp); } if(sm_SlowMoSound) { sm_SlowMoSound->FindAndSetVariableValue(ATSTRINGHASH("timeWarp", 0xBC6E3F8F), timeWarp); } } else { if(sm_SlowMoScene) { sm_SlowMoScene->Stop(); } if(sm_SlowMoSound) { sm_SlowMoSound->StopAndForget(); } } if(IsInSlowMoVideoEditor() || IsSuperSlowVideoEditor()) { if(IsSuperSlowVideoEditor()) { if(!sm_SuperSlowMoVideoEditorScene) { sm_DynamicMixer.StartScene(ATSTRINGHASH("SLO_MO_VIDEO_EDITOR_05", 0x56A19675), &sm_SuperSlowMoVideoEditorScene); } if(sm_SlowMoVideoEditorScene) { sm_SlowMoVideoEditorScene->Stop(); } } else { if(!sm_SlowMoVideoEditorScene) { sm_DynamicMixer.StartScene(ATSTRINGHASH("SLO_MO_VIDEO_EDITOR", 0xA828B595), &sm_SlowMoVideoEditorScene); } if(sm_SuperSlowMoVideoEditorScene) { sm_SuperSlowMoVideoEditorScene->Stop(); } } } else { if(sm_SlowMoVideoEditorScene) { sm_SlowMoVideoEditorScene->Stop(); } if(sm_SuperSlowMoVideoEditorScene) { sm_SuperSlowMoVideoEditorScene->Stop(); } } if(sm_SlowMoMode == AUD_SLOWMO_RADIOWHEEL && sm_SlowMoScene) { float radioSlowMoFade = 0.0f; float radioOffFade = 1.f; if(g_RadioAudioEntity.GetPlayerRadioStation()) { radioSlowMoFade = 1.f; radioOffFade = 0.f; } sm_SlowMoScene->SetVariableValue(ATSTRINGHASH("onApply", 0x6BDBAC89), radioSlowMoFade); sm_SlowMoScene->SetVariableValue(ATSTRINGHASH("offApply", 0xA7790120), radioOffFade); } sysPerformanceTimer controllerTimer("audController"); controllerTimer.Start(); sm_AudioController.PreUpdate(sm_TimeInMs); controllerTimer.Stop(); audEntity::ProcessBatchedSoundRequests(static_cast(fwTimer::GetTimeStepInMilliseconds())); if(!sm_Paused) { audVehicleAudioEntity::UpdateActivationRanges(); audTrainAudioEntity::UpdateActivationRanges(); } audSoundManager &soundManager = g_AudioEngine.GetSoundManager(); // supply sounds with the game time soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.DayOfWeek", 0x357A17E4), static_cast(CClock::GetDayOfWeek())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Hours", 0x98263E3E), static_cast(CClock::GetHour())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Minutes", 0xF1150725), static_cast(CClock::GetMinute())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Seconds", 0x70D769DA), static_cast(CClock::GetSecond())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Days", 0x147D8EB9), static_cast(CClock::GetDay())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Months", 0x67F650AC), static_cast(CClock::GetMonth())); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.SecsPerMin", 0x266005A7), static_cast(CClock::GetMsPerGameMinute()/1000.f)); // whole hours, decimal mins+secs sm_GameTimeHours = static_cast(CClock::GetHour()) + (static_cast(CClock::GetMinute()) / 60.f) + (static_cast(CClock::GetSecond()) / 3600.f); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.DecimalHours", 0x59664070), sm_GameTimeHours); soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.TimeWarp", 0xDFA2FAF7), sm_TimeWarpSmoother.GetLastValue()); CPed *playerPed = FindPlayerPed(); if(playerPed) { const Vec3V playerPos = playerPed->GetTransform().GetPosition(); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.Position.x", 0xA39016E6), playerPos.GetXf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.Position.y", 0x91297215), playerPos.GetYf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.Position.z", 0x7EE44D8B), playerPos.GetZf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.Speed", 0x8CE50515), VEC3V_TO_VECTOR3(sm_PedPosLastFrame).Dist(VEC3V_TO_VECTOR3(playerPos))/fwTimer::GetTimeStep()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.Health", 0x5CF478F), playerPed->GetHealth()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.MaxHealth", 0x23B3E65D), playerPed->GetMaxHealth()); sm_PedPosLastFrame = playerPos; } const Vec3V panningPos = g_AudioEngine.GetEnvironment().GetPanningListenerPosition(); soundManager.SetVariableValue(ATSTRINGHASH("Game.Microphone.Position.x", 0xE67CF42F), panningPos.GetXf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Microphone.Position.y", 0xA3C06EB7), panningPos.GetYf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Microphone.Position.z", 0x85E73305), panningPos.GetZf()); soundManager.SetVariableValue(ATSTRINGHASH("Game.Water.CameraDepth", 0xD38CC888), Water::GetCameraWaterDepth()); float firstPerson = sm_Microphones.IsFirstPerson() ? 1.f : 0.f; soundManager.SetVariableValue(ATSTRINGHASH("Game.Microphone.FirstPerson", 0x378A1D92),firstPerson); float slowMoVideoEditor = IsInSlowMoVideoEditor() ? 1.f : 0.f; soundManager.SetVariableValue(ATSTRINGHASH("Game.VideoEditor.Slowmo", 0x9FA46F1D), slowMoVideoEditor); float isVideoEditor = IsInVideoEditor() ? 1.f : 0.f; soundManager.SetVariableValue(ATSTRINGHASH("Game.VideoEditor.Replay", 0x5EC0D39A), isVideoEditor); f32 interiorRatio = 0.0f; sm_Environment.AreWeInAnInterior(NULL, &interiorRatio); soundManager.SetVariableValue(ATSTRINGHASH("Game.Player.InteriorRatio", 0x8BE286CD), interiorRatio); float isCopsAndCrooks = NetworkInterface::IsInCopsAndCrooks() ? 1.f : 0.f; soundManager.SetVariableValue(ATSTRINGHASH("Game.Mode.IsCopsAndCrooks", 0xB315260A), isCopsAndCrooks); audDoorAudioEntity::UpdateClass(); audVehicleAudioEntity::UpdateClass(); audCarAudioEntity::UpdateClass(); audSpeechAudioEntity::UpdateClass(); g_FireSoundManager.Update(); g_SpeechManager.Update(); g_ReflectionsAudioEntity.Update(); if(!fwTimer::IsGamePaused()) { g_EmitterAudioEntity.Update(); NA_POLICESCANNER_ENABLED_ONLY(g_AudioScannerManager.Update()); g_AmbientAudioEntity.Update(g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0)); } g_PedScenarioManager.Update(); audStreamSlot::UpdateSlots(sm_TimeInMs); #if __BANK UpdateAuditionSound(); UpdateRAVEVariables(); #endif // calculate updated environment metrics sm_Environment.Update(); // The environment update relies on the state of the microphone ( frozen/unfrozen ) so just in case it was frozen, lets unfreeze it after the environment update. sm_Microphones.UnFreezeMicrophone(); // Needs to be called after sm_Environment.Update() which gives us all the interior info we need sm_OcclusionManager.UpdateOcclusionMetrics(); //Update the dynamic mixer sm_DynamicMixer.Update(); controllerTimer.Start(); sm_AudioController.Update(sm_TimeInMs); controllerTimer.Stop(); //Update length is the time taken to perform update. PF_SET(ControllerUpdateLength, (f32)controllerTimer.GetTimeMS()); UpdateCategories(); g_AudioEngine.CommitGameSettings(sm_TimeInMs); // This call can take ~800uS so we don't want to call it every audio frame // We don't have to call it every game frame either if we can think of something else to run in its place audDriver::GetVoiceManager().UpdateUserMusicState(); #if __WIN32 timer.Stop(); //Update length is the time taken to perform update. PF_SET(UpdateLength, (f32)timer.GetTimeMS()); #endif // __WIN32 PIXEnd(); } void audNorthAudioEngine::MuteGameWorldAndPositionedRadioForTv(bool mute) { if (mute) { if(!sm_TvScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("TV_SCENE", 2327741164), &sm_TvScene); } } else { if(sm_TvScene) { sm_TvScene->Stop(); } } } void audNorthAudioEngine::UpdateVehicleCategories() { CVehicle* playerVehicle = NULL; CPed* playerPed = NULL; if(!playerVehicle) { playerVehicle = audPedAudioEntity::GetBJVehicle(); } if(NetworkInterface::IsInSpectatorMode()) { playerVehicle = CGameWorld::FindFollowPlayerVehicle(); playerPed = CGameWorld::FindFollowPlayer(); } else { playerVehicle = CGameWorld::FindLocalPlayerVehicle(); playerPed = CGameWorld::FindLocalPlayer(); } bool isPlayerHangingOffVehicle = false; if(playerVehicle && playerVehicle->GetSeatManager()) { s32 pedSeatIndex = playerVehicle->GetSeatManager()->GetPedsSeatIndex(playerPed); if(playerVehicle->IsSeatIndexValid(pedSeatIndex)) { const CVehicleSeatAnimInfo* seatAnimInfo = playerVehicle->GetSeatAnimationInfo(pedSeatIndex); if(seatAnimInfo && seatAnimInfo->GetKeepCollisionOnWhenInVehicle()) { isPlayerHangingOffVehicle = true; } } } if (playerVehicle && playerVehicle->GetVehicleAudioEntity()->GetAudioVehicleType() != AUD_VEHICLE_BICYCLE && !isPlayerHangingOffVehicle) { const float smoothedOpenness = sm_PIVOpennessSmoother.CalculateValue(1.f - playerVehicle->GetVehicleAudioEntity()->GetOpenness(false), fwTimer::GetTimeStep()); if(!sm_PlayerInVehScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("PLAYER_IN_VEHICLE_SCENE", 0x201E71F0),&sm_PlayerInVehScene); } if (naVerifyf(sm_PlayerInVehScene, "Failed to create player in vehicle scene, this shouldn't happen")) { sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("openness", 0x2721BC39), smoothedOpenness); sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("musicVolume", 0x499CB684), sm_PIVMusicVolumeSmoother.GetLastValue()); sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("radioVolume", 0x3C12FAC8), sm_PIVRadioVolumeSmoother.GetLastValue()); if (sm_Microphones.IsVehBonnetMic()) { // engine boost for rear engine vehicles Vector3 enginePos; enginePos = VEC3V_TO_VECTOR3(playerVehicle->TransformIntoWorldSpace(playerVehicle->GetVehicleAudioEntity()->GetEngineOffsetPos())); // Check if the engine is behind the vehicle Vector3 directionToEngine = enginePos - VEC3V_TO_VECTOR3(playerVehicle->GetTransform().GetPosition()); f32 frontDot = directionToEngine.Dot(VEC3V_TO_VECTOR3(playerVehicle->GetTransform().GetB())); if (frontDot < 0) { sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("rearEngineApply", 0x6EB37A69), 1.f); } else { sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("rearEngineApply", 0x6EB37A69), 0.f); } } else { sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("rearEngineApply", 0x6EB37A69), 0.f); } } } else { if(sm_PlayerInVehScene) { sm_PlayerInVehScene->Stop(); } sm_PIVOpennessSmoother.CalculateValue(0.f, fwTimer::GetTimeStep()); } // offset radio volume by the current player vehicle engine volume. sm_EngineVolume = 0.0f; sm_PlayerVehicleOpenness = 1.0f; if (playerVehicle) { sm_EngineVolume = playerVehicle->GetVehicleAudioEntity()->GetFrontendRadioVolumeOffset(); sm_PlayerVehicleOpenness = playerVehicle->GetVehicleAudioEntity()->GetOpenness(false); } } void audNorthAudioEngine::UpdateCategories() { naAssertf(sm_NorthAudioMixScene, "No north audio mix scene present, need to create a valid scene in Init()"); if(!sm_NorthAudioMixScene) { return; } #if RSG_DURANGO && 0 if(audDriver::GetMixer()) { if(audDriver::GetMixer()->IsSuspended()) { if(!sm_GameSuspendedScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("GAME_SUSPENDED_SCENE", 0x37EC776), &sm_GameSuspendedScene); } } else { if(sm_GameSuspendedScene) { sm_GameSuspendedScene->Stop(); } } } #endif #if !__BANK && __WIN32PC bool muteForLostFocus = false; bool isCapturing = audDriver::GetMixer() && audDriver::GetMixer()->IsCapturing(); if(!isCapturing && GRCDEVICE.GetLostFocusForAudio() && CPauseMenu::GetMenuPreference(PREF_AUDIO_MUTE_ON_FOCUS_LOSS)) { muteForLostFocus = true; } #else const bool muteForLostFocus = false; #endif if (sm_ShouldMuteAudio || muteForLostFocus) { if(!sm_MuteAllScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("MUTE_ALL_SCENE", 1043566406U), &sm_MuteAllScene); } else { sm_MuteAllScene->SetVariableValue(ATSTRINGHASH("basevol", 0xD10CB74A), 1.0f); } } else { if(sm_MuteAllScene) { sm_MuteAllScene->Stop(); } } // Update Categories if (g_BaseCategory) { // We scale the overall rolloff according to the environment. Makes sense to set it here, so all category changes are done in one place. // Similarly, we scale down occlusion in certain camera modes (cine-cam), so do that here too. naAssertf(audNorthAudioEngine::GetGtaEnvironment(), "In UpdateCategories, could not get the environment; will access a null ptr"); g_BaseCategory->SetDistanceRolloffScale(1.0f);//audNorthAudioEngine::GetGtaEnvironment()->GetRollOffFactor()); audCategory* baseCategory = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("BASE", 0x44E21C90)); if (baseCategory) { baseCategory->SetOcclusionDamping(audNorthAudioEngine::GetOcclusionManager()->GetGlobalOcclusionDampingFactor()); } } // screen fade stuff only mutes the game world - not frontend or radio // fades don't seem to be totally fading out, so we make it silent at a small level f32 fadeLevel = camInterface::GetFadeLevel(); fadeLevel = ClampRange(fadeLevel, 0.0f, g_FadeValueForSilence); fadeLevel /= g_FadeValueForSilence; #if GTA_REPLAY if(CReplayMgr::IsEditorActive()) { if(!CReplayCoordinator::IsExportingToVideoFile()) { if(!CReplayMgr::IsEditModeActive() || CVideoEditorPlayback::IsLoading()) { fadeLevel = 1.f; } } } else #endif if(sm_StartingNewGame || fwTimer::IsUserPaused() || fwTimer::IsGamePaused() BANK_ONLY(|| g_CutsceneAudioPaused)) { BANK_ONLY(if(!fwTimer::IsDebugPause())) fadeLevel = 1.f; } float musicApply = 0.f; #if GTA_REPLAY if(CReplayMgr::IsEditorActive()) { if(!CReplayCoordinator::IsExportingToVideoFile() && !g_InteractiveMusicManager.IsReplayPreviewPlaying()) { musicApply = fadeLevel; } } else #endif if((sm_StartingNewGame || CPauseMenu::IsActive()) && sm_DataSetState != Loaded_MP REPLAY_ONLY(&& !g_InteractiveMusicManager.IsReplayPreviewPlaying() && !CReplayCoordinator::IsExportingToVideoFile())) { musicApply = fadeLevel; } sm_PIVMusicVolumeSmoother.SetRates(0.001f / g_PIVMusicVolumeFadeInS, 0.001f / g_PIVMusicVolumeFadeOutS); sm_PIVRadioVolumeSmoother.SetRates(0.001f / g_PIVMusicVolumeFadeInS, 0.001f / g_PIVMusicVolumeFadeOutS); sm_PIVOpennessSmoother.SetRates(0.001f / g_PIVOpennessFadeInS, 0.001f / g_PIVOpennessFadeOutS); float isFEMusicPlaying = 0.f; float isFERadioPlaying = 0.f; if(g_InteractiveMusicManager.IsMusicPlaying()) { isFEMusicPlaying = 1.f; } if(g_RadioAudioEntity.IsVehicleRadioOn()) { isFEMusicPlaying = 1.f; isFERadioPlaying = 1.f; } isFEMusicPlaying *= Min(1.f, sm_MusicVolume / Max(SMALL_FLOAT, sm_SfxVolume)); sm_PIVMusicVolumeSmoother.CalculateValue(isFEMusicPlaying, fwTimer::GetTimeStep()); isFERadioPlaying *= Min(1.f, sm_MusicVolume / Max(SMALL_FLOAT, sm_SfxVolume)); sm_PIVRadioVolumeSmoother.CalculateValue(isFERadioPlaying, fwTimer::GetTimeStep()); f32 radioVol = 1.f; // when in frontend mode and not paused we don't want to use the screen fade, otherwise we do // unless we're in the network lobby // when playing end credits fade is controlled by script if((!g_ScriptAudioEntity.IsFlagSet(audScriptAudioFlags::AllowRadioOverScreenFade) BANK_ONLY(&& !g_ForceAllowRadioOverScreenFade)) && !audRadioStation::IsPlayingEndCredits() && !(g_RadioAudioEntity.IsInFrontendMode() && !g_AudioEngine.GetSoundManager().IsPaused(2))) { radioVol = (1.f-fadeLevel) * (!NetworkInterface::IsGameInProgress()&&fwTimer::IsGamePaused()?0.0f:1.0f); } if(!audDynamicMixer::FrontendSceneIsOverridden()) { if (fadeLevel > 0.f) { if(!sm_FrontendScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("FRONTEND_SCENE", 1182742998U), &sm_FrontendScene); naAssertf(sm_FrontendScene, "Couldn't create audio frontend scene"); } if(sm_FrontendScene) { sm_FrontendScene->SetVariableValue(ATSTRINGHASH("fade", 1855728566U), fadeLevel); sm_FrontendScene->SetVariableValue(ATSTRINGHASH("musicApply", 0x72758950), musicApply); if(sm_DataSetState == Loaded_MP) { sm_FrontendScene->SetVariableValue(ATSTRINGHASH("posRadioVol", 0x4BE8FA9A), 1.f - radioVol); } } } else { if(sm_FrontendScene) { sm_FrontendScene->Stop(); } } } if (!sm_OverrideLobbyMute && sm_IsInNetworkLobby) { if(!sm_MpLobbyScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("MP_LOBBY_SCENE", 1883148293U), &sm_MpLobbyScene); } } else { if(sm_MpLobbyScene) { sm_MpLobbyScene->Stop(); } } #if GTA_REPLAY // Keep this on permanently when exporting - don't want to risk it flicking on/off around the clip transition points if(CReplayMgr::IsEditModeActive() || CReplayCoordinator::IsExportingToVideoFile()) { if(!sm_ReplayEditorScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("REPLAY_EDITOR_PLAYBACK_SCENE", 0x6B579349), &sm_ReplayEditorScene); } } else { if(sm_ReplayEditorScene) { sm_ReplayEditorScene->Stop(); } } #endif bool bFirstPerson = IsAFirstPersonCameraActive(CGameWorld::FindLocalPlayer(), false, false, true, true) || audNorthAudioEngine::IsRenderingFirstPersonTurretCam(); sm_IsFirstPersonActiveForPlayer = bFirstPerson; sm_IsCutsceneActive = (gVpMan.AreWidescreenBordersActive() || ((CutSceneManager::GetInstance() && CutSceneManager::GetInstance()->IsStreamedCutScene()) && CGameWorld::GetMainPlayerInfo()->AreControlsDisabled())); bool isSniping = audNorthAudioEngine::GetMicrophones().IsSniping(); bool isSwitchingPlayer = g_PlayerSwitch.IsActive(); if(bFirstPerson && !sm_IsCutsceneActive && !isSniping && !isSwitchingPlayer && !audVehicleAudioEntity::IsVehicleInteriorSceneActive() && !audVehicleAudioEntity::IsVehicleFirstPersonTurretSceneActive() && !audVehicleAudioEntity::IsBonnetCamSceneActive()) { if(!sm_FirstPersonModeScene) { DYNAMICMIXER.StartScene(ATSTRINGHASH("FIRST_PERSON_MODE_SCENE", 0xAB0410F1), &sm_FirstPersonModeScene); } } else { if(sm_FirstPersonModeScene) { sm_FirstPersonModeScene->Stop(); } } #if NA_RADIO_ENABLED sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("radioVol", 0xe7e3432c), 1.f-radioVol); #endif // Update the radio/music volume - primarily to duck it for a variety of reasons f32 musicVolLin = 0.f; const f32 frontendLinearScaling = 1.f/10.f; // Director mode loads MP data, but we want it to use the SP music slider (unless we end up with a MP director mode at some point in the future!) if(CPauseMenu::IsMP() || (sm_DataSetState == Loaded_MP && (!CTheScripts::GetIsInDirectorMode() || NetworkInterface::IsGameInProgress()))) { // duck the radio quicker in network games sm_RadioDuckingSmoother.SetRates(g_RadioDuckingSmoothRate*1.67f, g_RadioDuckingSmoothRate*1.67f); musicVolLin = ((f32)CPauseMenu::GetMenuPreference(PREF_MUSIC_VOLUME_IN_MP)) * frontendLinearScaling; } else { sm_RadioDuckingSmoother.SetRates(g_RadioDuckingSmoothRateUp, g_RadioDuckingSmoothRate); musicVolLin = ((f32)CPauseMenu::GetMenuPreference(PREF_MUSIC_VOLUME)) * frontendLinearScaling; } // Don't apply the music slider during the initial game load if(!sm_ApplyMusicSlider) { musicVolLin = 1.f; } float sfxSliderVolume = 0.0f; if(sm_DataSetState == Loaded_MP) { #if RSG_PC if(NetworkInterface::GetVoice().IsAnyRemoteGamerTalking()) { f32 sfxAudioSliderVolume = ((f32)CPauseMenu::GetMenuPreference(PREF_SFX_VOLUME)) * frontendLinearScaling; f32 voiceChatSoundSliderVolume = ((f32)CPauseMenu::GetMenuPreference(PREF_VOICE_SOUND_VOLUME)) * frontendLinearScaling; sfxSliderVolume = sfxAudioSliderVolume * voiceChatSoundSliderVolume; //f32 sfxVolDb = audDriverUtil::ComputeDbVolumeFromLinear(sfxAudioSliderVolume); //f32 voiceVolDb = audDriverUtil::ComputeDbVolumeFromLinear(voiceChatSoundSliderVolume); //f32 totalVolDb = sfxVolDb + voiceVolDb; //Displayf("sfx %f(%f) - voice %f(%f) - total %f(%f)(%f)", sfxAudioSliderVolume, sfxVolDb, voiceChatSoundSliderVolume, voiceVolDb, sfxSliderVolume, audDriverUtil::ComputeLinearVolumeFromDb(totalVolDb), totalVolDb); } else #endif // RSG_PC { sfxSliderVolume = ((f32)CPauseMenu::GetMenuPreference(PREF_SFX_VOLUME)) * frontendLinearScaling; } } else { sfxSliderVolume = ((f32)CPauseMenu::GetMenuPreference(PREF_SFX_VOLUME)) * frontendLinearScaling; } #if __BANK if(g_IgnoreFrontendVolumeSliders) { // Only override if not muted if(sfxSliderVolume != 0.f) sfxSliderVolume = 1.f; if(musicVolLin != 0.f) musicVolLin = 1.f; } #endif #if GTA_REPLAY if(CReplayMgr::IsEditModeActive() && (CReplayCoordinator::IsExportingToVideoFile() || CReplayMgr::IsPlaying())) { // In replay, the user uses replay markers to control music/volume so ignore // the frontend ones. The exception is when the user has manually paused the replay and // is doing stuff with the menus - in this case, use the same menu sfx volume as the main game if(CReplayCoordinator::IsExportingToVideoFile()) { sfxSliderVolume = 1.f; } else if(CReplayMgr::IsPlaying() && !CReplayMgr::IsScrubbing() && !CReplayMgr::IsJumping() && !CReplayMgr::IsUserPaused() && !CReplayMgr::GetNextPlayBackState().IsSet(REPLAY_STATE_PAUSE)) { sfxSliderVolume = 1.f; } musicVolLin = 1.f; } else if(CReplayMgr::IsEditorActive() && VideoPlayback::IsPlaybackActive(false)) { // Unmute audio when watching an already-recorded video sfxSliderVolume = 1.f; } else if(g_RadioAudioEntity.IsReplayMusicPreviewPlaying()) { musicVolLin = 1.f; } #endif #if RSG_ORBIS // Scale pad speaker volume from 0 to 2, map bottom 50% to pad speaker volume, anything above starts sending to SFX float controlPadSpeakerVol = ((f32)CPauseMenu::GetMenuPreference(PREF_CTRL_SPEAKER_VOL)) * frontendLinearScaling * 2.f; // Don't bother scaling to silence, and tweak the curve to make the most out of the six volume steps we have available const float s_PadExp = 1.4f; const float padSpeakerRescaledVol = powf((0.2f + Clamp(controlPadSpeakerVol, 0.f, 1.f)) * 0.8333333f, s_PadExp); g_AudioEngine.GetEnvironment().SetPadSpeakerVolume(sfxSliderVolume * padSpeakerRescaledVol); g_AudioEngine.GetEnvironment().SetPadSpeakerSFXVolume(sfxSliderVolume * Clamp(controlPadSpeakerVol - 1.f, 0.f, 1.f)); audMixerDeviceOrbis *device = ((audMixerDeviceOrbis*)audDriver::GetMixer()); // Choose which pref to apply based on the Output option: ie we use a separate pref when the user is in Headphone mode const s32 controlPadSpeaker = CPauseMenu::AreHeadphonesEnabled() ? PREF_CTRL_SPEAKER_HEADPHONE : PREF_CTRL_SPEAKER; g_AudioEngine.GetEnvironment().SetPadSpeakerEnabled(CPauseMenu::GetMenuPreference(controlPadSpeaker) != 0 && device->IsPadSpeakerEnabled()); #endif // RSG_ORBIS u32 sfxSliderCurrentTime = g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(1); if(g_FrontendAudioEntity.IsLoadingSceneActive()) { if(sm_LoadingScreenSFXSliderDelay == 0) { sm_LoadingScreenSFXSliderDelay = sfxSliderCurrentTime + 2000; } if(sm_LoadingScreenSFXSliderDelay != 0 && sfxSliderCurrentTime > sm_LoadingScreenSFXSliderDelay) { // Mute SFX during loads sfxSliderVolume = 0.f; } } else { sm_LoadingScreenSFXSliderDelay = 0; } // mute if lost focus PC only #if __WIN32PC if(muteForLostFocus) { sfxSliderVolume = 0.f; musicVolLin = 0.f; } #endif SetSfxVolume(sfxSliderVolume); SetMusicVolume(musicVolLin); // In the pause menu, we boost scripted speech const f32 audSettingsScriptBoostScale = ((f32)CPauseMenu::GetMenuPreference(PREF_DIAG_BOOST)) * frontendLinearScaling; sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("scriptedSpeechVol", 0x5b3a463), audSettingsScriptBoostScale); #if NA_RADIO_ENABLED // the amount we duck depends on whether we're in stereo/prologic mode or not - we duck less if we're not f32 duckVolDb = g_RadioDuckingVolumeStereo; if (audDriver::GetDownmixOutputMode() >= AUD_OUTPUT_5_1) { duckVolDb = g_RadioDuckingVolume; } const audRadioStation* station = g_RadioAudioEntity.GetPlayerRadioStation(); // duck more for talk stations if (station && station->IsTalkStation()) { duckVolDb = g_TalkRadioDuckingVolume; } else { if (station) { // or if dj, adverts, idents, etc are playing const audRadioTrack &track = station->GetCurrentTrack(); if (track.IsInitialised()) { u32 trackCategory = track.GetCategory(); if(trackCategory != RADIO_TRACK_CAT_MUSIC && trackCategory != RADIO_TRACK_CAT_TAKEOVER_MUSIC) { // duck it some more duckVolDb += g_RadioNonMusicAdditionalDucking; } } } } // Increase ducking with the engine volume offset duckVolDb -= sm_EngineVolume; float radioProxyDuckVolDb = 0.f; if(sm_RadioProxyCat) { radioProxyDuckVolDb += sm_RadioProxyCat->GetVolume(); } float scoreDuckVolDb = 0.f; if(sm_ScoreProxyCat) { scoreDuckVolDb += sm_ScoreProxyCat->GetVolume(); } if(GetSfxVolume() == 0.f || g_RadioAudioEntity.IsInFrontendMode()) { // dont duck when Sfx are muted or we are in frontend radio mode duckVolDb = 0.f; scoreDuckVolDb = radioProxyDuckVolDb = 0.f; } else { const f32 musicVoldB = audDriverUtil::ComputeDbVolumeFromLinear(GetMusicVolume()); const f32 sfxVoldB = audDriverUtil::ComputeDbVolumeFromLinear(GetSfxVolume()); // preserve relative balance between sfx and music // Clamp to ensure we don't apply positive gain duckVolDb = Min(duckVolDb - (musicVoldB - sfxVoldB), 0.0f); // Don't duck radio/score if sfx is down (ie proximity effect ducking radio, which sounds weird if engine sounds are quiet) scoreDuckVolDb = Clamp(scoreDuckVolDb + (musicVoldB - sfxVoldB), scoreDuckVolDb, 0.0f); radioProxyDuckVolDb = Clamp(radioProxyDuckVolDb + (musicVoldB - sfxVoldB), radioProxyDuckVolDb, 0.0f); } if(sm_ScoreVolCategoryController && sm_OneShotVolCategoryController) { sm_ScoreVolCategoryController->SetVolumeDB(scoreDuckVolDb); sm_OneShotVolCategoryController->SetVolumeDB(scoreDuckVolDb); } f32 desiredRadioDuckingVolume = 0.f; // Is there a scripted conversation ongoing? if (!g_ScriptAudioEntity.ShouldNotDuckRadioThisLine() && (g_ScriptAudioEntity.ShouldDuckForScriptedConversation() || sm_ShouldDuckRadio || g_AudioScannerManager.ShouldDuckRadio())) { desiredRadioDuckingVolume = duckVolDb; } else if(audPedAudioEntity::GetShouldDuckRadioForPlayerRingtone()) { desiredRadioDuckingVolume = duckVolDb; } #if RSG_PC if(sm_DataSetState == Loaded_MP) { if(NetworkInterface::GetVoice().IsAnyRemoteGamerTalking()) { desiredRadioDuckingVolume = audDriverUtil::ComputeDbVolumeFromLinear( ((f32)CPauseMenu::GetMenuPreference(PREF_VOICE_MUSIC_VOLUME)) * frontendLinearScaling ); //Displayf("Radio Duck %f", desiredRadioDuckingVolume); } } #else if(CPauseMenu::GetMenuPreference(PREF_VOICE_OUTPUT) == 0 && #if __XENON CProfileSettings::GetInstance().GetInt(CProfileSettings::VOICE_VOLUME)>0 && CProfileSettings::GetInstance().GetInt(CProfileSettings::VOICE_THRU_SPEAKERS) && #endif (NetworkInterface::GetVoice().IsAnyRemoteGamerTalking()/* || NetworkInterface::GetVoice().IsAnyRemoteGamerAboutToTalk()*/)) { desiredRadioDuckingVolume = g_RadioDuckingVolumeVoiceChat; } #endif // use unpausable timer so that it unducks radio in pause menu f32 smoothedRadioDuckingVolumeLin = sm_RadioDuckingSmoother.CalculateValue(audDriverUtil::ComputeLinearVolumeFromDb(desiredRadioDuckingVolume), g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(1)); const f32 missionCompleteDuckingVolDb = g_ScriptAudioEntity.ComputeRadioVolumeForMissionComplete(); const f32 missionCompleteDuckingVolLin = audDriverUtil::ComputeLinearVolumeFromDb(missionCompleteDuckingVolDb); sm_FrontendRadioVolumeLin = missionCompleteDuckingVolLin * smoothedRadioDuckingVolumeLin * audDriverUtil::ComputeLinearVolumeFromDb(radioProxyDuckVolDb); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("radioFrontendVol", 0xc00f6acd), 1.f-sm_FrontendRadioVolumeLin); if(sm_PlayerInVehScene) { sm_PlayerInVehScene->SetVariableValue(ATSTRINGHASH("musicVol", 0x7F9D4065),1.f- GetMusicVolume()); } // this is relatively nasty - if the music volume (controlled via the frontend) is fully silenced then set the radio category to silence, so that // emitters (which don't go via the music effect route) are also muted // also have to explicitly mute positioned radio in the frontend, since the radio can be unpaused in the audio menu // Note posRadioVol is a linear volume the wrong way round; 1 is silent, 0 is full volume if(GetMusicVolume() == 0.f) { sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("posRadioVol", 0x4be8fa9a), 1.f); } else { sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("posRadioVol", 0x4be8fa9a), 0.f); } #endif // NA_RADIO_ENABLED /* f32 desiredGPSDuckingVolume = 0.0f; // Is there a scripted conversation ongoing? if (g_ScriptAudioEntity.ShouldDuckForScriptedConversation()) { desiredGPSDuckingVolume = g_RadioDuckingVolume; } f32 smoothedGPSDuckingVolume = sm_GPSDuckingSmoother.CalculateValue(audDriverUtil::ComputeLinearVolumeFromDb(desiredGPSDuckingVolume), sm_TimeInMs); g_GpsCategory->SetVolumeLinear(smoothedGPSDuckingVolume); */ // Duck all things train if we're riding on it or in it /*f32 trainVolume = 1.0f; if (camInterface::IsAttachedToTrain()) - CDE: Removed custom camera code for trains. { trainVolume = g_AttachedToTrainVolume; } // also duck the train if we're in slowmo as its rather prone to clipping if(fwTimer::GetTimeWarpActive() < 0.9f) { trainVolume *= audDriverUtil::ComputeLinearVolumeFromDb(g_SlowMoTrainVol); } if (g_TrainCategory) { g_TrainCategory->SetVolumeLinear(trainVolume); } */ u32 currentTime = g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0); f32 applyValue = 1.0f; f32 weatherApply = sm_PlayerVehicleOpenness; if(g_ScriptAudioEntity.ShouldDuckForScriptedConversation()) { if (sm_SpeechScene ) { if(!sm_SpeechSceeneApplied) { naDisplayf("SPEECH_SCENE apply set to 1."); sm_TimeSpeechSceneLastStarted = currentTime; sm_SpeechSceeneApplied = true; sm_SpeechGunfirePatchApplyAtStart = (sm_SpeechGunfirePatch ? sm_SpeechGunfirePatch->GetApplyFactor() : 0.f); sm_SpeechScorePatchApplyAtStart = (sm_SpeechScorePatch ? sm_SpeechScorePatch->GetApplyFactor() : 0.f); sm_SpeechVehiclesPatchApplyAtStart = (sm_SpeechVehiclesPatch ? sm_SpeechVehiclesPatch->GetApplyFactor() : 0.f); sm_SpeechVehiclesFirstPersonPatchApplyAtStart = (sm_SpeechVehiclesFirstPersonPatch ? sm_SpeechVehiclesFirstPersonPatch->GetApplyFactor() : 0.f); sm_SpeechWeatherPatchApplyAtStart = (sm_SpeechWeatherPatch ? sm_SpeechWeatherPatch->GetApplyFactor() : 0.f); } u32 timeSinceSceneStarted = (currentTime - sm_TimeSpeechSceneLastStarted); if(sm_SpeechGunfirePatch && sm_SpeechGunfirePatch->GetApplyFactor() != 1.0f) { applyValue = (sm_SpeechGunfirePatch->GetFadeInTime() == 0) ? 1.0f: Clamp(sm_SpeechGunfirePatchApplyAtStart + ((float)timeSinceSceneStarted/(float)sm_SpeechGunfirePatch->GetFadeInTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("gunfireApply", applyValue); } if(sm_SpeechScorePatch && sm_SpeechScorePatch->GetApplyFactor() != 1.0f) { applyValue = (sm_SpeechScorePatch->GetFadeInTime() == 0) ? 1.0f: Clamp(sm_SpeechScorePatchApplyAtStart + ((float)timeSinceSceneStarted/(float)sm_SpeechScorePatch->GetFadeInTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("scoreApply", applyValue); } if(sm_SpeechVehiclesPatch && sm_SpeechVehiclesPatch->GetApplyFactor() != 1.0f) { applyValue = (sm_SpeechVehiclesPatch->GetFadeInTime() == 0) ? 1.0f: Clamp(sm_SpeechVehiclesPatchApplyAtStart + ((float)timeSinceSceneStarted/(float)sm_SpeechVehiclesPatch->GetFadeInTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("vehiclesApply", applyValue); } if(sm_SpeechVehiclesFirstPersonPatch) { applyValue = (sm_SpeechVehiclesFirstPersonPatch->GetFadeInTime() == 0) ? 1.0f: Clamp(sm_SpeechVehiclesFirstPersonPatchApplyAtStart + ((float)timeSinceSceneStarted/(float)sm_SpeechVehiclesFirstPersonPatch->GetFadeInTime()), 0.0f, 1.0f); // the apply factor it's only 1 when in 1st person camera : if( !sm_Microphones.IsVehBonnetMic() ) { applyValue = (sm_SpeechVehiclesFirstPersonPatch->GetFadeInTime() == 0) ? 0.0f: Clamp(sm_SpeechVehiclesFirstPersonPatchApplyAtStop - ((float)timeSinceSceneStarted/(float)sm_SpeechVehiclesFirstPersonPatch->GetFadeOutTime()), 0.0f, 1.0f); } sm_SpeechScene->SetVariableValue("vehiclesFirstPersonApply", applyValue); } if(sm_SpeechWeatherPatch && sm_SpeechWeatherPatch->GetApplyFactor() != weatherApply) { applyValue = (sm_SpeechWeatherPatch->GetFadeInTime() == 0) ? 1.0f: Clamp(sm_SpeechWeatherPatchApplyAtStart + ((float)timeSinceSceneStarted/(float)sm_SpeechWeatherPatch->GetFadeInTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("weatherApply", applyValue * weatherApply); } } } else { if(sm_SpeechScene) { if(sm_SpeechSceeneApplied) { naDisplayf("SPEECH_SCENE apply set to 0."); sm_TimeSpeechSceneLastStopped = currentTime; sm_SpeechSceeneApplied = false; sm_SpeechGunfirePatchApplyAtStop = (sm_SpeechGunfirePatch ? sm_SpeechGunfirePatch->GetApplyFactor() : 0.f); sm_SpeechScorePatchApplyAtStop = (sm_SpeechScorePatch ? sm_SpeechScorePatch->GetApplyFactor() : 0.f); sm_SpeechVehiclesPatchApplyAtStop = (sm_SpeechVehiclesPatch ? sm_SpeechVehiclesPatch->GetApplyFactor() : 0.f); sm_SpeechVehiclesFirstPersonPatchApplyAtStop = (sm_SpeechVehiclesFirstPersonPatch ? sm_SpeechVehiclesFirstPersonPatch->GetApplyFactor() : 0.f); sm_SpeechWeatherPatchApplyAtStop = (sm_SpeechWeatherPatch ? sm_SpeechWeatherPatch->GetApplyFactor() : 0.f); } u32 timeSinceSceneStopped = (currentTime - sm_TimeSpeechSceneLastStopped); if(sm_SpeechGunfirePatch && sm_SpeechGunfirePatch->GetApplyFactor() != 0.0f) { applyValue = (sm_SpeechGunfirePatch->GetFadeOutTime() == 0) ? 0.0f : Clamp(sm_SpeechGunfirePatchApplyAtStop - ((float)timeSinceSceneStopped/(float)sm_SpeechGunfirePatch->GetFadeOutTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("gunfireApply", applyValue); } if(sm_SpeechScorePatch && sm_SpeechScorePatch->GetApplyFactor() != 0.0f) { applyValue = (sm_SpeechScorePatch->GetFadeOutTime() == 0) ? 0.0f: Clamp(sm_SpeechScorePatchApplyAtStop - ((float)timeSinceSceneStopped/(float)sm_SpeechScorePatch->GetFadeOutTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("scoreApply", applyValue); } if(sm_SpeechVehiclesPatch && sm_SpeechVehiclesPatch->GetApplyFactor() != 0.0f) { applyValue = (sm_SpeechVehiclesPatch->GetFadeOutTime() == 0) ? 0.0f: Clamp(sm_SpeechVehiclesPatchApplyAtStop - ((float)timeSinceSceneStopped/(float)sm_SpeechVehiclesPatch->GetFadeOutTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("vehiclesApply", applyValue); } if(sm_SpeechVehiclesFirstPersonPatch && sm_SpeechVehiclesFirstPersonPatch->GetApplyFactor() != 0.0f) { applyValue = (sm_SpeechVehiclesFirstPersonPatch->GetFadeOutTime() == 0) ? 0.0f: Clamp(sm_SpeechVehiclesFirstPersonPatchApplyAtStop - ((float)timeSinceSceneStopped/(float)sm_SpeechVehiclesFirstPersonPatch->GetFadeOutTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("vehiclesFirstPersonApply", applyValue); } if(sm_SpeechWeatherPatch && sm_SpeechWeatherPatch->GetApplyFactor() != weatherApply) { applyValue = (sm_SpeechWeatherPatch->GetFadeOutTime() == 0) ? 0.0f: Clamp(sm_SpeechWeatherPatchApplyAtStop - ((float)timeSinceSceneStopped/(float)sm_SpeechWeatherPatch->GetFadeOutTime()), 0.0f, 1.0f); sm_SpeechScene->SetVariableValue("weatherApply", applyValue * weatherApply); } } } // Get rid of waves in interiors. And church bells. f32 playerInteriorRatio = 0.0f; //bool isInteriorASubway = false; //bool inInterior = audNorthAudioEngine::GetGtaEnvironment()->AreWeInAnInterior(&isInteriorASubway, &playerInteriorRatio); sm_NorthAudioMixScene->SetVariableValue(ATSTRINGHASH("interiorRatio", 0x13fc3a70), playerInteriorRatio); /* if (g_AmbienceJetsCategory) { g_AmbienceJetsCategory->SetVolumeLinear(waveVolumeDB); } // If we're in a subway, increase the rolloff on trains - need to smooth it, over at least a second f32 desiredTrainRolloff = 1.0f; if (inInterior && isInteriorASubway) { desiredTrainRolloff = g_TrainRolloffInSubways; } f32 trainRolloffSmoothed = sm_TrainRolloffInSubwaySmoother.CalculateValue(desiredTrainRolloff, sm_TimeInMs); if (g_TrainCategory) { g_TrainCategory->BeginDistRolloffScaleApproach(trainRolloffSmoothed); } */ // We don't want to smooth leakage when going from black as it's a hard cut, so reset the smoother if(IsScreenFadedOut()) { sm_CutsceneLeakageSmoother.Reset(); } // Also do the mocap cutscene leakage here, because it vaguely fits f32 leakage; if (sm_IsCutsceneActive) { leakage = sm_CutsceneLeakageSmoother.CalculateValue(g_CutscenePositionedLeakage, g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0)); g_AudioEngine.GetEnvironment().SetGlobalPositionedLeakage(leakage); } else { leakage = sm_CutsceneLeakageSmoother.CalculateValue(0.0f, g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(0)); g_AudioEngine.GetEnvironment().SetGlobalPositionedLeakage(leakage); } #if __BANK if(g_DebugCutsceneLeakage) { sm_CutsceneLeakageSmoother.SetRate(g_CutsceneLeakageSmootherRate * 0.001f); static audMeterList leakageMeter; static const char* leakageMeterName = "Cutscene Leakage"; static f32 leakageMeterValue; leakageMeterValue = leakage; leakageMeter.left = 150.f; leakageMeter.width = 50.f; leakageMeter.bottom = 350.f; leakageMeter.height = 50.f; leakageMeter.names = &leakageMeterName; leakageMeter.values = &leakageMeterValue; leakageMeter.numValues = 1; DrawLevelMeters(&leakageMeter); } #endif #if __BANK if(g_ShouldMuteWind) { if(!g_WindMuteController) { g_WindMuteController = AUDCATEGORYCONTROLLERMANAGER.CreateController(ATSTRINGHASH("AMBIENCE_WEATHER", 0xB26931C3)); if(g_WindMuteController) { g_WindMuteController->SetVolumeLinear(0.f); } } } else if(g_WindMuteController) { AUDCATEGORYCONTROLLERMANAGER.DestroyController(g_WindMuteController); g_WindMuteController = NULL; } #endif } void audNorthAudioEngine::Pause() { // Timer 0 is the normal timer, timer 5 is the slow-mo timer // Both should pause/unpause together if((sm_FrontendScene && sm_FrontendScene->IsFullyAppliedForPause())) { sm_Paused = true; g_AudioEngine.GetSoundManager().Pause(0); g_AudioEngine.GetSoundManager().Pause(5); } else if(fwTimer::IsUserPaused() BANK_ONLY(|| fwTimer::IsDebugPause())) { // When pausing via the debug keyboard we don't want to apply the fade, but we do want to pause sm_Paused = true; g_AudioEngine.GetSoundManager().Pause(0); g_AudioEngine.GetSoundManager().Pause(5); } g_AudioEngine.SetGamePaused(true); } void audNorthAudioEngine::UnPause() { sm_Paused = false; g_AudioEngine.GetSoundManager().UnPause(0); g_AudioEngine.GetSoundManager().UnPause(5); g_AudioEngine.SetGamePaused(false); } void audNorthAudioEngine::RegisterLoudSound(Vector3 &pos, bool playerShot) { Vector3 dist = pos - VEC3V_TO_VECTOR3(g_AudioEngine.GetEnvironment().GetVolumeListenerPosition()); if(dist.Mag2() <= (g_audLoudSoundDistanceMag*g_audLoudSoundDistanceMag)) { audNorthAudioEngine::sm_LastLoudSoundTime = fwTimer::GetTimeInMilliseconds(); g_EmitterAudioEntity.NotifyLoudSound(); // Send message to the superconductor to stop the QUITE_SCENE if(audSuperConductor::sm_StopQSOnLoudSounds && !playerShot && !NetworkInterface::IsGameInProgress()) { ConductorMessageData message; message.conductorName = SuperConductor; message.message = StopQuietScene; message.bExtraInfo = false; message.vExtraInfo = Vector3((f32)audSuperConductor::sm_LoudSoundQSFadeOutTime ,(f32)audSuperConductor::sm_LoudSoundQSDelayTime ,(f32)audSuperConductor::sm_LoudSoundQSFadeInTime); SUPERCONDUCTOR.SendConductorMessage(message); } } } u32 audNorthAudioEngine::GetLastLoudSoundTime() { return audNorthAudioEngine::sm_LastLoudSoundTime; } const char* audNorthAudioEngine::GetCurrentAudioLevelName() { // Game level index value defaults to level 1 even with 0 levels loaded... s32 levelIndex = CGameLogic::GetCurrentLevelIndex(); if(levelIndex < CScene::GetLevelsData().GetCount()) { const char* levelNameString = CScene::GetLevelsData().GetFilename(levelIndex); s32 baseFolderStart = atString(levelNameString).LastIndexOf('\\'); if(baseFolderStart >= 0) { return &levelNameString[baseFolderStart + 1]; } } return "gta5"; } bool audNorthAudioEngine::IsScreenFadedOut() { return sm_IsFadedToBlack; } void audNorthAudioEngine::DebugDraw() { #if __BANK g_RadioAudioEntity.DrawDebug(); DrawBufferedLevelMeters(); g_AudioEngine.DrawDebug(); g_AudioEngine.GetSoundManager().DebugDrawSounds(); audSpeechAudioEntity::DebugDraw(); if(audGrainPlayer::s_DebugDrawGrainPlayer) { audGrainPlayer::s_DebugDrawGrainPlayer->DebugDraw(); } sm_DynamicMixer.DrawDebugScenes(); g_PoliceScanner.DrawDebug(); DebugDrawSlowMo(); audSoundDebugDrawManager waveSlotDrawMgr(100.f, 50.f, 50.f, 720.f); audWaveSlot::DebugDraw(waveSlotDrawMgr); #endif } void *audNorthAudioEngine::GetObject(const u32 nameHash, const u32 TYPE_ID) { u8 *ptr = static_cast(sm_MetadataMgr.GetObjectMetadataPtr(nameHash)); if(ptr) { naCErrorf(TYPE_ID == (*ptr), "In GetObject, we've found an object for nameHash (%d) but it's type id (%d) doesn't match the one we expected (%d)", nameHash, (*ptr), TYPE_ID); if(TYPE_ID != (*ptr)) { ptr = NULL; } } return ptr; } void audNorthAudioEngine::AmbisonicDraw(ambisonicDrawData data[90]) { #if __BANK Vector2 unit = grcDebugDraw::Get2DAspect(); Vector2 origin(0.5f, 0.5f); Vector2 startA(0.f, 0.f); Vector2 prevA(0.f, 0.f); Vector2 ang(0.f, 0.f); Vector2 angE(0.f, 0.f); Vector2 angV(0.f, 0.f); Vector2 vecE(0.f, 0.f); Vector2 vecV(0.f, 0.f); Vector2 vecEPrev(0.f, 0.f); Vector2 vecVPrev(0.f, 0.f); Vector2 energy(0.f, 0.f); Vector2 energyPrev(0.f, 0.f); Color32 colour; startA.Set(0.2f*Cosf(0.f), 0.2f*Sinf(DtoR*(0.f))); angE.Set(0.15f*Cosf(data[0].reproducedAngE), 0.15f*Sinf(data[0].reproducedAngE)); angV.Set(0.1f*Cosf(data[0].reproducedAngV), 0.1f*Sinf(data[0].reproducedAngV)); startA.Multiply(unit); angE.Multiply(unit); angV.Multiply(unit); startA.Add(origin); angE.Add(origin); angV.Add(origin); vecE.Set(0.2f*data[0].vecLengthE*Cosf(0.f), 0.2f*data[0].vecLengthE*Sinf(0.f)); vecE.Multiply(unit); vecE.Add(origin); vecV.Set(0.2f*data[0].vecLengthV*Cosf(0.f), 0.2f*data[0].vecLengthV*Sinf(0.f)); vecV.Multiply(unit); vecV.Add(origin); energy.Set(0.05f*data[0].energy*Cosf(0.f), 0.05f*data[0].energy*Sinf(0.f)); energy.Multiply(unit); energy.Add(origin); colour.Set(255, 0, 0); grcDebugDraw::Line(origin, startA, colour); colour.Set(0, 255, 0); grcDebugDraw::Line(origin, angE, colour); colour.Set(0, 0, 255); grcDebugDraw::Line(origin, angV, colour); prevA.Set(startA); vecVPrev.Set(vecV); vecEPrev.Set(vecE); energyPrev.Set(energy); for(s32 i=1; i<90; i++) { f32 curAngle = DtoR*((float)(i*4)); f32 curCos = Cosf(curAngle); f32 curSin = Sinf(curAngle); ang.Set(0.2f*curCos, 0.2f*curSin); ang.Multiply(unit); ang.Add(origin); vecE.Set(0.2f*data[i].vecLengthE*curCos, 0.2f*data[i].vecLengthE*curSin); vecE.Multiply(unit); vecE.Add(origin); vecV.Set(0.2f*data[i].vecLengthV*curCos, 0.2f*data[i].vecLengthV*curSin); vecV.Multiply(unit); vecV.Add(origin); energy.Set(0.05f*data[i].energy*curCos, 0.05f*data[i].energy*curSin); energy.Multiply(unit); energy.Add(origin); colour.Set(255, 255, 255); grcDebugDraw::Line(prevA, ang, colour); colour.Set(100, 50, 100); grcDebugDraw::Line(vecEPrev, vecE, colour); colour.Set(100, 150, 0); grcDebugDraw::Line(vecVPrev, vecV, colour); colour.Set(0, 0, 0); grcDebugDraw::Line(energyPrev, energy, colour); vecVPrev.Set(vecV); vecEPrev.Set(vecE); energyPrev.Set(energy); //Compare incident angles to reproduced angles if(i == 15 || i ==22 || i == 30 || i == 45 || i == 60 || i == 75) { angE.Set(0.15f*Cosf(data[i].reproducedAngE), 0.15f*Sinf(data[i].reproducedAngE)); angV.Set(0.1f*Cosf(data[i].reproducedAngV), 0.1f*Sinf(data[i].reproducedAngV)); angE.Multiply(unit); angV.Multiply(unit); angE.Add(origin); angV.Add(origin); colour.Set(255, 255, 255); grcDebugDraw::Line(origin, ang, colour); colour.Set(0, 255, 0); grcDebugDraw::Line(origin, angE, colour); colour.Set(0, 0, 255); grcDebugDraw::Line(origin, angV, colour); } prevA.Set(ang); } ang.Set(0.2f*Cosf(2.f*PI), 0.2f*Sinf(2*PI)); ang.Multiply(unit); ang.Add(origin); vecE.Set(0.2f*data[0].vecLengthE*Cosf(2.f*PI), 0.2f*data[0].vecLengthE*Sinf(2.f*PI)); vecE.Multiply(unit); vecE.Add(origin); vecV.Set(0.2f*data[0].vecLengthV*Cosf(2.f*PI), 0.2f*data[0].vecLengthV*Sinf(2.f*PI)); vecV.Multiply(unit); vecV.Add(origin); energy.Set(0.05f*data[0].energy*Cosf(2*PI), 0.05f*data[0].energy*Sinf(2*PI)); energy.Multiply(unit); energy.Add(origin); colour.Set(255, 255, 255); grcDebugDraw::Line(prevA, ang, colour); colour.Set(100, 50, 100); grcDebugDraw::Line(vecEPrev, vecE, colour); colour.Set(100, 150, 0); grcDebugDraw::Line(vecVPrev, vecV, colour); colour.Set(0, 0, 0); grcDebugDraw::Line(energyPrev, energy, colour); #else // __BANK (void)data; #endif // __BANK } void audNorthAudioEngine::AmbisonicSave() { CProfileSettings& settings = CProfileSettings::GetInstance(); if(settings.AreSettingsValid()) { ambisonicDecodeData decoderData; g_AudioEngine.GetAmbisonics().SaveDecoder(decoderData); s32 i = static_cast(CProfileSettings::AMBISONIC_DECODER); for(s32 sp = 0; sp < AMBISONICS_SPEAKER_MAX; sp++) { for(s32 a = 0; a < AMB_ORDER; a++) { settings.Set(static_cast(i), decoderData.decoder[sp].Co[a]); ++i; settings.Set(static_cast(i), decoderData.decoder[sp].Si[a]); ++i; } settings.Set(static_cast(i), decoderData.decoder[sp].w); ++i; } settings.Set(CProfileSettings::AMBISONIC_DECODER_TYPE, decoderData.decoderType); settings.Write(); Displayf("Ambisonic Decoder Saved"); } } void audNorthAudioEngine::AmbisonicLoad() { CProfileSettings& settings = CProfileSettings::GetInstance(); if(settings.AreSettingsValid()) { ambisonicDecodeData decodeData; s32 i = static_cast(CProfileSettings::AMBISONIC_DECODER); for(s32 sp = 0; sp < AMBISONICS_SPEAKER_MAX; sp++) { for(s32 a = 0; a < AMB_ORDER; a++) { if(settings.Exists(static_cast(i))) { decodeData.decoder[sp].Co[a] = settings.GetFloat(static_cast(i)); } ++i; if(settings.Exists(static_cast(i))) { decodeData.decoder[sp].Si[a] = settings.GetFloat(static_cast(i)); } ++i; } if(settings.Exists(static_cast(i))) { decodeData.decoder[sp].w = settings.GetFloat(static_cast(i)); } ++i; } if(settings.Exists(CProfileSettings::AMBISONIC_DECODER_TYPE)) { decodeData.decoderType = static_cast(settings.GetInt(CProfileSettings::AMBISONIC_DECODER_TYPE)); } g_AudioEngine.GetAmbisonics().LoadDecoder(decodeData); Displayf("Ambisonic Decoder Loaded"); } } void audNorthAudioEngine::MuteCategory(audScene ** scene, const char * settings, bool mute) { if(mute && !*scene) { naDisplayf("[NorthAudio] Muting %s", settings); sm_DynamicMixer.StartScene(settings, scene); } else if(!mute && *scene) { naDisplayf("[NorthAudio] Unmuting %s", settings); (*scene)->Stop(); } #if ! __FINAL else if(mute) { naDisplayf("[NorthAudio] Mute %s is already on", settings); } else { naDisplayf("[NorthAudio] Mute %s is already off", settings); } #endif } void audNorthAudioEngine::MuteAmbience(bool mute) { MuteCategory(&sm_AmbienceMuted, "MUTES_AMBIENCE_SCENE", mute); } void audNorthAudioEngine::MuteCutscene(bool mute) { MuteCategory(&sm_CutsceneMuted, "MUTES_CUTSCENE_SCENE", mute); } void audNorthAudioEngine::MuteFrontend(bool mute) { MuteCategory(&sm_FrontendMuted, "MUTES_FRONTEND_SCENE", mute); } void audNorthAudioEngine::MuteMusic(bool mute) { MuteCategory(&sm_MusicMuted, "MUTES_MUSIC_SCENE", mute); } void audNorthAudioEngine::MuteRadio(bool mute) { MuteCategory(&sm_RadioMuted, "MUTES_RADIO_SCENE", mute); } void audNorthAudioEngine::MuteSfx(bool mute) { MuteCategory(&sm_SfxMuted, "MUTES_SFX_SCENE", mute); } void audNorthAudioEngine::MuteSpeech(bool mute) { MuteCategory(&sm_SpeechMuted, "MUTES_SPEECH_SCENE", mute); } void audNorthAudioEngine::MuteGuns(bool mute) { MuteCategory(&sm_GunsMuted, "MUTES_GUNS_SCENE", mute); } void audNorthAudioEngine::MuteVehicles(bool mute) { MuteCategory(&sm_VehiclesMuted, "MUTES_VEHICLES_SCENE", mute); } void audNorthAudioEngine::ToggleMuteAmbience() { MuteAmbience(sm_AmbienceMuted ? false:true); } void audNorthAudioEngine::ToggleMuteCutscene() { MuteCutscene(sm_CutsceneMuted ? false:true); } void audNorthAudioEngine::ToggleMuteFrontend() { MuteFrontend(sm_FrontendMuted ? false:true); } void audNorthAudioEngine::ToggleMuteMusic() { MuteMusic(sm_MusicMuted ? false:true); } void audNorthAudioEngine::ToggleMuteRadio() { MuteMusic(sm_RadioMuted ? false:true); } void audNorthAudioEngine::ToggleMuteSfx() { MuteSfx(sm_SfxMuted ? false:true); } void audNorthAudioEngine::ToggleMuteSpeech() { MuteSpeech(sm_SpeechMuted ? false:true); } void audNorthAudioEngine::ToggleMuteGuns() { MuteGuns(sm_GunsMuted ? false:true); } void audNorthAudioEngine::ToggleMuteVehicles() { MuteVehicles(sm_VehiclesMuted ? false:true); } void audNorthAudioEngine::NotifyLocalPlayerArrested() { NA_POLICESCANNER_ENABLED_ONLY(g_PoliceScanner.ReportSuspectArrested()); g_InteractiveMusicManager.GetWantedMusic().NotifyArrested(); } void audNorthAudioEngine::NotifyLocalPlayerDied() { /*if(!CTheScripts::GetPlayerIsOnAMission() && !g_ScriptAudioEntity.IsPlayingMissionComplete() && g_ScriptAudioEntity.CanPlayDeathJingle()) { // Before Triggering it check if we have to cancel if there is one preparing ( We have seen this happening when you fail a stuntjump and die at the same time). if( g_ScriptAudioEntity.IsPreparingMissionComplete()) { g_ScriptAudioEntity.StopMissionCompleteSound(); } g_ScriptAudioEntity.TriggerMissionComplete("DEAD_OFFMISSION", 3); }*/ g_InteractiveMusicManager.GetWantedMusic().NotifyDied(); } void audNorthAudioEngine::NotifyLocalPlayerPlaneCrashed() { g_InteractiveMusicManager.GetVehicleMusic().NotifyPlaneCrashed(); } void audNorthAudioEngine::NotifyLocalPlayerBailedFromAircraft() { g_InteractiveMusicManager.GetVehicleMusic().NotifyPlayerBailed(); } void audNorthAudioEngine::NotifyOpenNetwork() { sm_IsMPDataRequested = true; } void audNorthAudioEngine::NotifyCloseNetwork(const bool fullClose) { g_InteractiveMusicManager.GetWantedMusic().NotifyCloseNetwork(); if(fullClose) { sm_IsMPDataRequested = false; } } void audNorthAudioEngine::StartLongPlayerSwitch(const CPed &UNUSED_PARAM(oldPed), const CPed &UNUSED_PARAM(newPed)) { g_RadioAudioEntity.SetForcePlayerCharacterStation(true); } void audNorthAudioEngine::StopLongPlayerSwitch() { g_RadioAudioEntity.SetForcePlayerCharacterStation(false); g_FrontendAudioEntity.StopLongSwitchSkyLoop(); } void audNorthAudioEngine::StartPauseMenuSlowMo() { if(sm_PauseMenuSlowMoCount == 0) { ActivateSlowMoMode(ATSTRINGHASH("SLOWMO_PAUSEMENU", 0xFAFBB6BF)); } sm_PauseMenuSlowMoCount++; } void audNorthAudioEngine::StopPauseMenuSlowMo() { if(sm_PauseMenuSlowMoCount > 0) { sm_PauseMenuSlowMoCount--; if(sm_PauseMenuSlowMoCount == 0) { sm_WaitingForPauseMenuSlowMoToEnd = true; DeactivateSlowMoMode(AUD_SLOWMO_PAUSEMENU); } } } void audNorthAudioEngine::SetSfxVolume(const float volLinear) { sm_SfxVolume = volLinear; if(sm_SFXSliderController) { sm_SFXSliderController->SetVolumeLinear(volLinear); } if(sm_NoFadeVolCategoryController) { sm_NoFadeVolCategoryController->SetVolumeLinear(volLinear); } if(sm_ScriptedOverrideFadeVolCategoryController) { sm_ScriptedOverrideFadeVolCategoryController->SetVolumeLinear(volLinear); } g_AudioEngine.GetSoundManager().SetVariableValue(ATSTRINGHASH("Game.Audio.Sliders.SFXSlider", 0x2432BB37), volLinear); } void audNorthAudioEngine::SetMusicVolume(const float volLinear) { sm_MusicVolume = volLinear; if(sm_MusicSliderController) { sm_MusicSliderController->SetVolumeLinear(volLinear); } g_AudioEngine.GetSoundManager().SetVariableValue(ATSTRINGHASH("Game.Audio.Sliders.MusicSlider", 0xFB69E838), volLinear); } #if RSG_PS3 void audNorthAudioEngine::CheckForWirelessHeadset(const bool loadPRX /*=false*/) { sm_IsWirelessHeadsetConnected = ((audMixerDevicePs3*)audDriver::GetMixer())->IsPulseHeadsetConnected(loadPRX); } #endif #if __BANK void audNorthAudioEngine::UpdateRAVEVariables() { if((fwTimer::GetFrameCount() & 7) == 7) { if(g_AudioEngine.GetRemoteControl().IsConnected()) { static char messageBuf[4096]; formatf(messageBuf, "", g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(1)); // Focus Entity variables CEntity *ent = CDebugScene::FocusEntities_Get(0); if(ent && ent->GetAudioEntity()) { safecat(messageBuf, ""); audVariableBlock *vars = ent->GetAudioEntity()->GetVariableBlock(); if(vars) { for(u32 i = 0; i < vars->GetMetadata()->numVariables; i++) { safecatf(messageBuf, "", vars->GetMetadata()->Variable[i].Name, vars->GetValueByIndex(i)); } } safecat(messageBuf, ""); } // Global variables ravesimpletypes::VariableList *list = audConfig::GetMetadataManager().GetObject("GlobalVariableList"); safecat(messageBuf, ""); if(list) { for(u32 i = 0; i < list->numVariables; i++) { safecatf(messageBuf, "", list->Variable[i].Name, g_AudioEngine.GetSoundManager().GetVariableByIndex(i)); } } safecat(messageBuf, ""); safecat(messageBuf, ""); g_AudioEngine.GetRemoteControl().SendXmlMessage(messageBuf); } } } void audNorthAudioEngine::UpdateAuditionSound() { g_AudioEngine.GetRemoteControl().SetAuditionSoundDrawMode(sm_AuditionSoundDrawMode); g_AudioEngine.GetRemoteControl().SetAuditionSoundDrawOffsetY(sm_DebugDrawYOffset); u32 soundNameHash; if(SOUNDFACTORY.GetAuditionStartSound(soundNameHash)) { audMetadataObjectInfo info; if(SOUNDFACTORY.GetMetadataManager().GetObjectInfo(soundNameHash, info)) { if(gSoundsIsOfType(info.GetType(), Sound::TYPE_ID)) { AuditionSound(soundNameHash); } } else { audWarningf("RAVE Auditioning: Failed to find sound with hash %u", soundNameHash); } } u32 auditionStopNameHash; if(SOUNDFACTORY.GetAuditionStopSound(auditionStopNameHash)) { audSound *auditionSound = *g_AudioEngine.GetRemoteControl().GetAuditionSoundPtr(); if(auditionSound) { auditionSound->StopAndForget(); } } } void audNorthAudioEngine::AuditionSound(const u32 soundNameHash) { audSound **auditionSoundPtr = g_AudioEngine.GetRemoteControl().GetAuditionSoundPtr(); if(*auditionSoundPtr) { (*auditionSoundPtr)->StopAndForget(); } audSoundInitParams initParams; initParams.RemoveHierarchy = false; initParams.IsAuditioning = true; if(sm_AuditionSoundsOnPPU) { // stick it in the last bucket, which should be reserved Assign(initParams.BucketId, audSound::GetStaticPool().GetNumBuckets()-1); } audWaveSlot *auditionWaveSlot = audWaveSlot::FindWaveSlot(g_AuditionWaveSlotName); initParams.WaveSlot = auditionWaveSlot; initParams.AllowLoad = sm_AllowAuditionSoundToLoad; initParams.TimerId = sm_AuditionSoundUnpausable ? 1 : 0; if(sm_ForceBaseCategory) { initParams.Category = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("BASE", 0x44E21C90)); } CEntity *auditioningEntity = NULL; if(sm_ShouldAuditionThroughPlayer) { auditioningEntity = FindPlayerPed(); } else if(sm_ShouldAuditionThroughFocusEntity) { auditioningEntity = CDebugScene::FocusEntities_Get(0); } if(auditioningEntity && !sm_ShouldAuditionPannedFrontend) { initParams.Tracker = auditioningEntity->GetPlaceableTracker(); initParams.EnvironmentGroup = auditioningEntity->GetAudioEnvironmentGroup(); } else { initParams.Pan = 0; } if(auditioningEntity && auditioningEntity->GetAudioEntity()) { auditioningEntity->GetAudioEntity()->CreateSound_PersistentReference(soundNameHash, auditionSoundPtr, &initParams); } else { g_FrontendAudioEntity.CreateSound_PersistentReference(soundNameHash, auditionSoundPtr, &initParams); } if(*auditionSoundPtr == NULL) { audWarningf("Couldn't instantiate auditioned sound with hash %u / name %s", soundNameHash, SOUNDFACTORY.GetMetadataManager().GetObjectName(soundNameHash)); return; } else { audSound *auditionSound = *auditionSoundPtr; auditionSound->PrepareAndPlay(auditionWaveSlot, sm_AllowAuditionSoundToLoad, 3000); } } void audNorthAudioEngine::AuditionSound(const audMetadataRef soundRef) { audSound **auditionSoundPtr = g_AudioEngine.GetRemoteControl().GetAuditionSoundPtr(); if(*auditionSoundPtr) { (*auditionSoundPtr)->StopAndForget(); } audSoundInitParams initParams; initParams.RemoveHierarchy = false; initParams.IsAuditioning = true; if(sm_AuditionSoundsOnPPU) { // stick it in the last bucket, which should be reserved Assign(initParams.BucketId, audSound::GetStaticPool().GetNumBuckets()-1); } audWaveSlot *auditionWaveSlot = audWaveSlot::FindWaveSlot(g_AuditionWaveSlotName); initParams.WaveSlot = auditionWaveSlot; initParams.AllowLoad = sm_AllowAuditionSoundToLoad; initParams.TimerId = sm_AuditionSoundUnpausable ? 1 : 0; if(sm_ForceBaseCategory) { initParams.Category = g_AudioEngine.GetCategoryManager().GetCategoryPtr(ATSTRINGHASH("BASE", 0x44E21C90)); } CEntity *auditioningEntity = NULL; if(sm_ShouldAuditionThroughPlayer) { auditioningEntity = FindPlayerPed(); } else if(sm_ShouldAuditionThroughFocusEntity) { auditioningEntity = CDebugScene::FocusEntities_Get(0); } if(auditioningEntity && !sm_ShouldAuditionPannedFrontend) { initParams.Tracker = auditioningEntity->GetPlaceableTracker(); initParams.EnvironmentGroup = auditioningEntity->GetAudioEnvironmentGroup(); } else { initParams.Pan = 0; } if(auditioningEntity && auditioningEntity->GetAudioEntity()) { auditioningEntity->GetAudioEntity()->CreateSound_PersistentReference(soundRef, auditionSoundPtr, &initParams); } else { g_FrontendAudioEntity.CreateSound_PersistentReference(soundRef, auditionSoundPtr, &initParams); } if(*auditionSoundPtr == NULL) { audWarningf("Couldn't instantiate auditioned sound %u / name %s",soundRef.Get(), SOUNDFACTORY.GetMetadataManager().GetObjectName(soundRef)); return; } else { audSound *auditionSound = *auditionSoundPtr; auditionSound->PrepareAndPlay(auditionWaveSlot, sm_AllowAuditionSoundToLoad, 3000); } } void audNorthAudioEngine::DrawBufferedLevelMeters() { if(sm_CurrentMeterIndex > 0) { PUSH_DEFAULT_SCREEN(); audDriver::SetDebugDrawRenderStates(); for(u32 ml = 0; ml < sm_CurrentMeterIndex; ml++) { const float elemWidth = sm_MeterList[ml]->width / (float)sm_MeterList[ml]->numValues; // draw alpha'd background grcBegin(drawTriStrip, 4); grcColor(sm_MeterList[ml]->bgColour); grcVertex2f(sm_MeterList[ml]->left,sm_MeterList[ml]->bottom); grcVertex2f(sm_MeterList[ml]->left,sm_MeterList[ml]->bottom-sm_MeterList[ml]->height); grcVertex2f(sm_MeterList[ml]->left+sm_MeterList[ml]->width,sm_MeterList[ml]->bottom); grcVertex2f(sm_MeterList[ml]->left+sm_MeterList[ml]->width,sm_MeterList[ml]->bottom-sm_MeterList[ml]->height); grcEnd(); for(u32 i = 0; i < sm_MeterList[ml]->numValues; i++) { const f32 x = sm_MeterList[ml]->left + (elemWidth * (float)i); const f32 value = Clamp(sm_MeterList[ml]->values[i] / sm_MeterList[ml]->rangeMax, 0.f, 1.f); const f32 y = sm_MeterList[ml]->bottom - (value * sm_MeterList[ml]->height); grcBegin(drawTriStrip, 4); grcColor(sm_MeterList[ml]->bottomColour); grcVertex2f(x, sm_MeterList[ml]->bottom); grcColor(sm_MeterList[ml]->topColour); grcVertex2f(x, y); grcColor(sm_MeterList[ml]->bottomColour); grcVertex2f(x + elemWidth, sm_MeterList[ml]->bottom); grcColor(sm_MeterList[ml]->topColour); grcVertex2f(x + elemWidth, y); grcEnd(); grcBegin(drawLineStrip, 2); grcColor(sm_MeterList[ml]->bgColour); grcVertex2f(x, sm_MeterList[ml]->bottom); grcVertex2f(x, y); grcEnd(); grcColor(sm_MeterList[ml]->textColour); grcDraw2dText(x, sm_MeterList[ml]->bottom + 10.f, sm_MeterList[ml]->names[i], true); if(sm_MeterList[ml]->drawValues) { char valueString[32]; formatf(valueString, "%.02f", sm_MeterList[ml]->values[i]); grcDraw2dText(x, sm_MeterList[ml]->bottom + 20.f, valueString, true); } } if(sm_MeterList[ml]->title) { grcDraw2dText(sm_MeterList[ml]->left, sm_MeterList[ml]->bottom - sm_MeterList[ml]->height - 20.0f, sm_MeterList[ml]->title, true); } } sm_CurrentMeterIndex = 0; POP_DEFAULT_SCREEN(); } } void audNorthAudioEngine::TriggerSound() { audSoundInitParams initParams; initParams.RemoveHierarchy = sm_ShouldRemoveSoundHierarchy; initParams.WaveSlot = audWaveSlot::FindWaveSlot(g_AuditionWaveSlotName); initParams.AllowLoad = true; initParams.PrepareTimeLimit = 3000; initParams.IsAuditioning = true; if(sm_ShouldAuditionThroughPlayer) { initParams.Tracker = (FindPlayerPed()->GetPlaceableTracker()); initParams.EnvironmentGroup = FindPlayerPed()->GetPedAudioEntity()->GetEnvironmentGroup(true); } if(sm_DebugSound) { sm_DebugSound->StopAndForget(); } g_FrontendAudioEntity.CreateSound_PersistentReference(sm_SoundName, &sm_DebugSound, &initParams); if(sm_DebugSound) { sm_DebugSound->PrepareAndPlay(); } else { naDisplayf("Couldn't play sound %s", sm_SoundName); } } void audNorthAudioEngine::StopSound() { if(sm_DebugSound) { sm_DebugSound->StopAndForget(); } } void audNorthAudioEngine::AuditionWaveSlotChanged() { /*audWaveSlot* waveSlot = NULL; waveSlot = audWaveSlot::FindWaveSlot(g_AuditionWaveSlotName); g_AudioEngine.SetAuditionWaveSlot(waveSlot);*/ } extern bank_bool g_DisableExplosionSFX; void audNorthAudioEngine::InitWidgets() { if (PARAM_audiodesigner.Get()) { BANKMGR.CreateOutputWindow("Audio", "NamedColor:Black"); } sprintf(g_AuditionWaveSlotName, "AMBIENT_SCRIPT_SLOT_0"); AuditionWaveSlotChanged(); if(PARAM_audiowidgets.Get()) { CreateWidgets(); } else { bkBank *bankPtr = BANKMGR.FindBank("Audio"); if(bankPtr) { bankPtr->Destroy(); } bkBank& bank = BANKMGR.CreateBank("Audio"); bank.AddButton("Create Audio Widgets", CFA(CreateWidgets)); } } void audNorthAudioEngine::StopSoundFromWidget() { audSound **auditionSoundPtr = g_AudioEngine.GetRemoteControl().GetAuditionSoundPtr(); if(*auditionSoundPtr) { (*auditionSoundPtr)->StopAndForget(); } } void audNorthAudioEngine::TriggerSoundFromWidget() { audMetadataObjectInfo info; audSoundSet soundSet; soundSet.Init(sm_AuditionSoundSetName); if(soundSet.IsInitialised()) { AuditionSound(soundSet.Find(sm_AuditionSoundName)); } else { if(SOUNDFACTORY.GetMetadataManager().GetObjectInfo(atStringHash(sm_AuditionSoundName), info)) { if(gSoundsIsOfType(info.GetType(), Sound::TYPE_ID)) { AuditionSound(atStringHash(sm_AuditionSoundName)); } } } if(sm_ShouldAuditionSoundOverNetwork) { Vec3V position = Vec3V(V_ZERO); if(CEntity *auditioningEntity = sm_ShouldAuditionThroughPlayer ? FindPlayerPed() : CDebugScene::FocusEntities_Get(0)) { position = auditioningEntity->GetTransform().GetPosition(); } CGameScriptId scriptId; CPlaySoundEvent::Trigger(VEC3V_TO_VECTOR3(position), atStringHash(sm_AuditionSoundSetName), atStringHash(sm_AuditionSoundName), 0xff, scriptId, 50); } } void ActivateSlowMoCB() { audNorthAudioEngine::ActivateSlowMoMode(atStringHash(g_SlowMoModeName)); } void DeactivateSlowMoCB() { audNorthAudioEngine::DeactivateSlowMoMode(atStringHash(g_SlowMoModeName)); } u32 g_CutsceneSkipTime = 0; void SkipCutsceneCB() { g_CutsceneAudioEntity.SkipCutsceneToTime(g_CutsceneSkipTime); } void TriggerCutsceneCB() { g_CutsceneAudioEntity.TriggerCutscene(); } void EnableMPSpeechExclusionCB() { audDisplayf("Enabling NFG speech exclusion"); audSpeechSound::SetExclusionPrefix("NFG"); } void DisableMPSpeechExclusionCB() { audDisplayf("Disabling speech exclusion"); audSpeechSound::SetExclusionPrefix(NULL); } void StopCutsceneAudioCB() { g_CutsceneAudioEntity.StopOverunAudio(); } void audNorthAudioEngine::CreateWidgets() { bkBank *bankPtr = BANKMGR.FindBank("Audio"); if(bankPtr) { bankPtr->Destroy(); } bkBank& bank = BANKMGR.CreateBank("Audio"); #if RSG_PS3 || RSG_ORBIS bank.AddToggle("PulseHeadsetSupport", &sm_ShouldTriggerPulseHeadset); #endif bank.AddToggle("g_UseInteriorCarFilter", &g_UseInteriorCarFilter); #if RSG_PC bank.AddToggle("Show Audio Frame Debug Info", &g_ShowAudioFrameDebugInfo); bank.AddSlider("Number of mix buffers", &g_NumberOfMixBuffers, 8, 16, 1); bank.AddToggle("Override CPU Limited Audio Setting ", &g_OverrideCPULimitedAudioSetting); bank.AddToggle("Force Min Spec Mode", &g_ForceMinSpecMode); #endif bank.AddButton("EnableSpeechExcl", CFA(EnableMPSpeechExclusionCB)); bank.AddButton("DisableSpeechExcl", CFA(DisableMPSpeechExclusionCB)); bank.AddToggle("StrVisMarkers", &sm_ShouldAddStrVisMarkers); bank.AddSlider("Cutscene time offset ms", &g_CutsceneTimeOffset, 0, 1000, 1); bank.AddSlider("Cutscene time scale", &g_CutsceneTimeScale, 0.0001f, 2.f, 0.1f); bank.AddButton("Stop Cutscene Audio", CFA(StopCutsceneAudioCB)); bank.AddToggle("Use game time for cutscenes", &g_GameTimerCutscenes); bank.AddToggle("IgnoreFrontendVolumeSliders", &g_IgnoreFrontendVolumeSliders); DEV_ONLY(bank.AddToggle("AssertOnSoundPoolFull", &g_AssertOnSoundPoolFull);) DEV_ONLY(bank.AddToggle("PrintSoundPoolWhenFull", &g_PrintSoundPoolWhenFull);) bank.AddToggle("Warn on missing sounds", &g_WarnOnMissingSounds); bank.AddToggle("Warn on missing curves", &g_WarnOnMissingCurves); bank.AddToggle("Mute audio", &sm_ShouldMuteAudio); bank.AddToggle("Mute wind", &g_ShouldMuteWind); bank.AddToggle("DisableExplosionSFX", &g_DisableExplosionSFX); bank.AddToggle("Force SlowMo Video Editor", &sm_ForceSlowMoVideoEditor); bank.AddToggle("Force Super SlowMo Video Editor", &sm_ForceSuperSlowMoVideoEditor); bank.AddSlider("Slow Mo Camera Blend Threshold", &sm_ThirdPersonCameraBlendThreshold, 0.0f, 1.f, 0.01f); bank.AddToggle("Force Allow Radio Over Screen Fade", &g_ForceAllowRadioOverScreenFade); bank.PushGroup("Sound Auditioning", true); bank.AddToggle("Audition through player entity", &sm_ShouldAuditionThroughPlayer); bank.AddToggle("Audition through focus entity", &sm_ShouldAuditionThroughFocusEntity); bank.AddToggle("Audition panned frontend", &sm_ShouldAuditionPannedFrontend); bank.AddToggle("Audition over network", &sm_ShouldAuditionSoundOverNetwork); bank.AddText("AuditionWaveSlot", &g_AuditionWaveSlotName[0], sizeof(g_AuditionWaveSlotName),false, &audNorthAudioEngine::AuditionWaveSlotChanged); bank.AddToggle("AuditionSoundsOnPPU", &sm_AuditionSoundsOnPPU); bank.AddToggle("AuditionSoundUnpausable", &sm_AuditionSoundUnpausable); bank.AddToggle("AllowAuditionSoundToLoad", &sm_AllowAuditionSoundToLoad); audRemoteControl::AddWidgets(bank); const char *nameList[] = { "Nothing", "Everything", "HierarchyOnly", "NoDynamicChildren", "VariablesOnly" }; bank.AddCombo("AuditionSoundDrawMode", (s32*)&sm_AuditionSoundDrawMode, audRemoteControl::kNumDrawModes, nameList, 0); bank.AddSlider("VerticalScroll", &sm_DebugDrawYOffset, 0.f, 2000.f, 1.f); bank.AddText("SoundSet Name", sm_AuditionSoundSetName, sizeof(sm_AuditionSoundSetName), false); bank.AddText("SoundName", sm_AuditionSoundName, sizeof(sm_AuditionSoundName), false); bank.AddButton("Play Sound", CFA(TriggerSoundFromWidget)); bank.AddButton("Stop Sound", CFA(StopSoundFromWidget)); bank.PopGroup(); audSoundManager::AddSoundDebuggingWidgets(bank); bank.AddToggle("Use Edited Cutscenes", &g_UseEditedCutscenes); bank.AddToggle("Use Master Cutscenes", &g_UseMasterCutscenes); bank.AddSlider("Cutscene skip time", &g_CutsceneSkipTime, 0, 90000, 10); bank.AddButton("Skip Cutscene", CFA(SkipCutsceneCB)); bank.AddButton("Trigger Cutscene", CFA(TriggerCutsceneCB)); bank.AddToggle("Debug playing script sounds", &g_DebugPlayingScriptSounds); bank.PushGroup("audNorthAudioEngine", false); bank.AddText("Sound Name", &sm_SoundName[0], sizeof(sm_SoundName),false); bank.AddToggle("Remove sound hierarchy", &sm_ShouldRemoveSoundHierarchy); bank.AddButton("Play Sound", CFA(TriggerSound)); bank.AddButton("Stop Sound", CFA(StopSound)); bank.AddText("SloMoModeName", g_SlowMoModeName, sizeof(g_SlowMoModeName), false); bank.AddButton("Activate SlowMo Mode", CFA(ActivateSlowMoCB)); bank.AddButton("Deactivate SlowMo Mode", CFA(DeactivateSlowMoCB)); bank.AddToggle("Display SloMo", &g_DisplaySlowMo); #if NA_RADIO_ENABLED bank.AddSlider("Radio ducking volume",&g_RadioDuckingVolume, -100.0f, 0.0f, 0.1f); bank.AddSlider("Radio ducking volume stereo",&g_RadioDuckingVolumeStereo, -100.0f, 0.0f, 0.1f); bank.AddSlider("g_RadioDuckingVolumeVoiceChat",&g_RadioDuckingVolumeVoiceChat, -100.0f, 0.0f, 0.1f); bank.AddSlider("Talk Radio ducking volume",&g_TalkRadioDuckingVolume, -100.0f, 0.0f, 0.1f); bank.AddSlider("Radio gps ducking volume",&g_RadioGPSDuckingVolume, -100.0f, 0.0f, 0.1f); bank.AddToggle("Duck radio", &sm_ShouldDuckRadio); #endif bank.AddSlider("Radio ducking smooth rate",&g_RadioDuckingSmoothRate, 0.0f, 100.0f, 0.1f); bank.AddToggle("ThreadedAudioUpdate", &sm_RunUpdateInSeperateThread); bank.AddToggle("g_MuteGameWorldAudio", &g_MuteGameWorldAudio); bank.AddToggle("g_MutePositionedRadio", &g_MutePositionedRadio); bank.AddSlider("g_FadeValueForSilence",&g_FadeValueForSilence, 0.05f, 1.0f, 0.05f); bank.AddToggle("g_DebugFadeLevels", &g_DebugFadeLevels); bank.AddSlider("g_CutsceneLeakageSmootherRate", &g_CutsceneLeakageSmootherRate, 0.0f, 1.0f, 0.0001f); bank.AddSlider("g_CutscenePositionedLeakage",&g_CutscenePositionedLeakage, 0.0f, 1.0f, 0.05f); bank.AddToggle("g_LeakForRPICutscenes", &g_LeakForRPICutscenes); bank.AddToggle("g_DebugCutsceneLeakage", &g_DebugCutsceneLeakage); bank.AddSlider("g_AttachedToTrainVolume",&g_AttachedToTrainVolume, -100.0f, 0.0f, 0.1f); bank.AddSlider("SlowMoTrainVol",&g_SlowMoTrainVol, -100.0f, 0.0f, 0.1f); bank.AddSlider("g_ConversationTrainVol",&g_ConversationTrainVol, -100.0f, 0.0f, 0.1f); bank.AddSlider("g_ConversationHeliVol",&g_ConversationHeliVol, -100.0f, 0.0f, 0.1f); bank.AddSlider("g_TrainRolloffInSubways",&g_TrainRolloffInSubways, 1.0f, 10.0f, 0.1f); bank.PushGroup("Ambisonics"); bank.AddButton("Save decoder", CFA(AmbisonicSave)); bank.AddButton("Load decoder", CFA(AmbisonicLoad)); bank.PopGroup(); bank.PushGroup("Category Mutes"); bank.AddButton("Mute ambience", CFA(ToggleMuteAmbience)); bank.AddButton("Mute cutscene", datCallback(ToggleMuteCutscene)); bank.AddButton("Mute frontend", datCallback(ToggleMuteFrontend)); bank.AddButton("Mute music", datCallback(ToggleMuteMusic)); bank.AddButton("Mute sfx", datCallback(ToggleMuteSfx)); bank.AddButton("Mute speech", datCallback(ToggleMuteSpeech)); bank.AddButton("Mute guns", datCallback(ToggleMuteGuns)); bank.AddButton("Mute vehicles", datCallback(ToggleMuteVehicles)); bank.PopGroup(); bank.PopGroup(); bank.PushGroup("RAGE Audio", false); g_AudioEngine.AddWidgets(bank); bank.PopGroup(); #if USE_GUN_TAILS audGunFireAudioEntity::AddWidgets(bank); #endif #if USE_CONDUCTORS audSuperConductor::AddWidgets(bank); #endif audObjectAudioEntity::AddWidgets(bank); audExplosionAudioEntity::AddWidgets(bank); audFireAudioEntity::AddWidgets(bank); audDoorAudioEntity::AddWidgets(bank); audVehicleAudioEntity::AddWidgets(bank); audCarAudioEntity::AddWidgets(bank); audHeliAudioEntity::AddWidgets(bank); audTrainAudioEntity::AddWidgets(bank); audPlaneAudioEntity::AddWidgets(bank); audBoatAudioEntity::AddWidgets(bank); audBicycleAudioEntity::AddWidgets(bank); audTrailerAudioEntity::AddWidgets(bank); audPedAudioEntity::AddWidgets(bank); audSpeechAudioEntity::AddWidgets(bank); audScriptAudioEntity::AddWidgets(bank); bank.PushGroup("Environment", false); bank.AddSlider("PIVMusicVolumeFadeInS", &g_PIVMusicVolumeFadeInS, 0.f, 30.f, 0.01f); bank.AddSlider("PIVMusicVolumeFadeOutS", &g_PIVMusicVolumeFadeOutS, 0.f, 30.f, 0.01f); bank.AddSlider("PIVOpennessFadeInS", &g_PIVOpennessFadeInS, 0.f, 30.f, 0.01f); bank.AddSlider("PIVOpennessFadeOutS", &g_PIVOpennessFadeOutS, 0.f, 30.f, 0.01f); naEnvironment::AddWidgets(bank); naEnvironmentGroupManager::AddWidgets(bank); naEnvironmentGroup::AddWidgets(bank); naOcclusionManager::AddWidgets(bank); naMicrophones::AddWidgets(bank); bank.PopGroup(); audGlassAudioEntity::AddWidgets(bank); audVehicleFireAudio::AddWidgets(bank); NA_RADIO_ENABLED_ONLY(audRadioAudioEntity::AddWidgets(bank)); audCollisionAudioEntity::AddWidgets(bank); audEmitterAudioEntity::AddWidgets(bank); audWeaponAudioEntity::AddWidgets(bank); audWeatherAudioEntity::AddWidgets(bank); audFrontendAudioEntity::AddWidgets(bank); #if GTA_REPLAY audReplayAudioEntity::AddWidgets(bank); #endif NA_POLICESCANNER_ENABLED_ONLY(g_AudioScannerManager.AddWidgets(bank)); g_AmbientAudioEntity.AddWidgets(bank); g_ReflectionsAudioEntity.AddWidgets(bank); g_InteractiveMusicManager.AddWidgets(bank); AUDCATEGORYCONTROLLERMANAGER.AddWidgets(bank); sm_DynamicMixer.AddWidgets(bank); // NA_RADIO_ENABLED_ONLY(CRadioHud::InitWidgets()); } void audNorthAudioEngine::DebugDrawSlowMo() { if(!g_DisplaySlowMo) { return; } PUSH_DEFAULT_SCREEN(); audNorthDebugDrawManager drawMgr(100.f, 50.f, 50.f, 720.f); Color32 prevColor = grcFont::GetCurrent().GetInternalColor(); bool bOldLighting = grcLighting( false ); grcFont::GetCurrent().SetInternalColor( Color32( 250, 250, 250 ) ); char sectionHeader[128]; formatf(sectionHeader, "Active SlowMo Modes"); drawMgr.PushSection(sectionHeader); for(int i=0; iGetSceneSettings()->NameTableOffset): NULL, sm_SlowMoSound ? g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetObjectNameFromNameTableOffset(sm_SlowMoSound->GetNameTableOffset()): NULL); drawMgr.DrawLine(sectionHeader); drawMgr.PopSection(); #endif grcFont::GetCurrent().SetInternalColor( prevColor ); grcLighting(bOldLighting); POP_DEFAULT_SCREEN(); } #endif void audGameObjectManager::OnObjectViewed(const u32 BANK_ONLY(nameHash)) { #if __BANK audMetadataObjectInfo info; if(audNorthAudioEngine::GetMetadataManager().GetObjectInfo(nameHash,info)) { if(info.GetType() == ModelAudioCollisionSettings::TYPE_ID) { ModelAudioCollisionSettings * macs = audNorthAudioEngine::GetObject(nameHash); if(macs) { g_CollisionAudioEntity.HandleRaveSelectedMaterial(macs); } } else if(info.GetType() == StaticEmitter::TYPE_ID) { g_RequestedWarpEmitter = info.GetObject(); } else if(g_WarpToInterior && info.GetType() == InteriorSettings::TYPE_ID) { CInteriorProxy::Pool* proxyPool = CInteriorProxy::GetPool(); if(proxyPool) { for(int i =0; i < proxyPool->GetSize(); i++) { CInteriorProxy* pProxy = proxyPool->GetSlot(i); if(pProxy && pProxy->GetNameHash() == nameHash) { g_RequestedWarpInterior = pProxy; } } } } else if(info.GetType() == AmbientZone::TYPE_ID) { g_RequestedWarpAmbZone = info.GetObject(); } } #endif } void audGameObjectManager::OnObjectOverridden(const u32 BANK_ONLY(nameHash)) { #if __BANK audMetadataObjectInfo info; if(audNorthAudioEngine::GetMetadataManager().GetObjectInfo(nameHash,info)) { if(info.GetType() == AmbientZone::TYPE_ID) { const AmbientZone* ambientZone = info.GetObject(); g_AmbientAudioEntity.HandleRaveZoneCreatedNotification(const_cast(ambientZone)); } else if(info.GetType() == StaticEmitter::TYPE_ID) { g_EmitterAudioEntity.HandleRaveStaticEmitterCreatedNotification(nameHash); } else if (info.GetType() == ShoreLinePoolAudioSettings::TYPE_ID) { ShoreLinePoolAudioSettings* settings = audNorthAudioEngine::GetObject(nameHash); g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast(settings)); } else if (info.GetType() == ShoreLineRiverAudioSettings::TYPE_ID) { ShoreLineRiverAudioSettings* settings = audNorthAudioEngine::GetObject(nameHash); g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast(settings)); } else if (info.GetType() == ShoreLineOceanAudioSettings::TYPE_ID) { ShoreLineOceanAudioSettings* settings = audNorthAudioEngine::GetObject(nameHash); g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast(settings)); } else if (info.GetType() == ShoreLineLakeAudioSettings::TYPE_ID) { ShoreLineLakeAudioSettings* settings = audNorthAudioEngine::GetObject(nameHash); g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast(settings)); } } OnObjectEdit(nameHash); #endif } void audGameObjectManager::OnObjectModified(const u32 BANK_ONLY(nameHash)) { #if __BANK OnObjectEdit(nameHash); #endif } void audGameObjectManager::OnObjectEdit(const u32 BANK_ONLY(nameHash)) { #if __BANK audMetadataObjectInfo info; if(audNorthAudioEngine::GetMetadataManager().GetObjectInfo(nameHash,info)) { if(info.GetType() == VehicleCollisionSettings::TYPE_ID) { audVehicleCollisionAudio::UpdateCollisionSettings(); } else if(info.GetType() == CollisionMaterialSettings::TYPE_ID) { audVehicleCollisionAudio::UpdateCollisionSettings(); } else if (gGameObjectsIsOfType(info.GetType(),ShoreLineAudioSettings::TYPE_ID)) { g_AmbientAudioEntity.HandleRaveShoreLineEditedNotification(); } } #endif } void audGameObjectManager::OnObjectAuditionStart(const u32 BANK_ONLY(nameHash)) { #if __BANK audMetadataObjectInfo info; audNorthAudioEngine::GetMetadataManager().GetObjectInfo(nameHash,info); if(gGameObjectsIsOfType(info.GetType(), MusicAction::TYPE_ID) || info.GetType() == MusicEvent::TYPE_ID) { g_InteractiveMusicManager.GetEventManager().TriggerEvent(info.GetName(), nameHash); } #endif } void naAnimHandler::HandleEvent(const audAnimEvent &event,fwEntity *entity) { CEntity *pEnt = (CEntity* ) entity; if(pEnt->GetIsTypeObject()) { CObject *pObject = (CObject *)entity; if(pObject) { CWeapon *pWeapon = pObject->GetWeapon(); if(pWeapon) { g_WeaponAudioEntity.AddWeaponAnimEvent(event,pObject); } else { g_EmitterAudioEntity.AddBuildingAnimEvent(event.hash, pEnt->GetTransform().GetPosition()); } } } else if(pEnt->GetIsTypeBuilding()) { g_EmitterAudioEntity.AddBuildingAnimEvent(event.hash, pEnt->GetTransform().GetPosition()); } }