5721 lines
184 KiB
C++
5721 lines
184 KiB
C++
//
|
|
// 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<u32> 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 __ASSERT
|
|
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<const Sound*>(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
|
|
|
|
ASSERT_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<u32>(chunkId), objectInfo))
|
|
{
|
|
audRadioStation::MergeRadioStationList(objectInfo.GetObject<RadioStationList>());
|
|
}
|
|
}
|
|
|
|
#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<u32>(chunkId), objectInfo))
|
|
{
|
|
audDisplayf("Unloading %s which contained DLC radio stations", chunkName);
|
|
audRadioStation::RemoveRadioStationList(objectInfo.GetObject<RadioStationList>());
|
|
}
|
|
|
|
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<const camThirdPersonPedAssistedAimCamera*>(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<s32>(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<SlowMoSettings>(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<SlowMoSettings>(settingsHash);
|
|
if(settings)
|
|
{
|
|
if(sm_SlowMoMode == settings->Priority)
|
|
{
|
|
SlowMoType priorityType = AUD_SLOWMO_GENERAL;
|
|
for(int i=1; i<sm_SlowMoMode; i++)
|
|
{
|
|
if(sm_ActiveSlowMoModes[i])
|
|
{
|
|
priorityType = (SlowMoType)i;
|
|
}
|
|
}
|
|
if(sm_SlowMoScene)
|
|
{
|
|
sm_SlowMoScene->Stop();
|
|
SlowMoSettings * newSettings = GetObject<SlowMoSettings>(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_SlowMoMode; i++)
|
|
{
|
|
if(sm_ActiveSlowMoModes[i])
|
|
{
|
|
priorityType = (SlowMoType)i;
|
|
}
|
|
}
|
|
|
|
SlowMoSettings * newSettings = GetObject<SlowMoSettings>(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<SlowMoSettings>(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<s32>(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<f32>(CClock::GetDayOfWeek()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Hours", 0x98263E3E), static_cast<f32>(CClock::GetHour()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Minutes", 0xF1150725), static_cast<f32>(CClock::GetMinute()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Seconds", 0x70D769DA), static_cast<f32>(CClock::GetSecond()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Days", 0x147D8EB9), static_cast<f32>(CClock::GetDay()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.Months", 0x67F650AC), static_cast<f32>(CClock::GetMonth()));
|
|
soundManager.SetVariableValue(ATSTRINGHASH("Game.Clock.SecsPerMin", 0x266005A7), static_cast<f32>(CClock::GetMsPerGameMinute()/1000.f));
|
|
|
|
// whole hours, decimal mins+secs
|
|
sm_GameTimeHours = static_cast<float>(CClock::GetHour()) + (static_cast<float>(CClock::GetMinute()) / 60.f) + (static_cast<float>(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<u8*>(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<s32>(CProfileSettings::AMBISONIC_DECODER);
|
|
for(s32 sp = 0; sp < AMBISONICS_SPEAKER_MAX; sp++)
|
|
{
|
|
for(s32 a = 0; a < AMB_ORDER; a++)
|
|
{
|
|
settings.Set(static_cast<CProfileSettings::ProfileSettingId>(i), decoderData.decoder[sp].Co[a]);
|
|
++i;
|
|
settings.Set(static_cast<CProfileSettings::ProfileSettingId>(i), decoderData.decoder[sp].Si[a]);
|
|
++i;
|
|
}
|
|
settings.Set(static_cast<CProfileSettings::ProfileSettingId>(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<s32>(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<CProfileSettings::ProfileSettingId>(i)))
|
|
{
|
|
decodeData.decoder[sp].Co[a] = settings.GetFloat(static_cast<CProfileSettings::ProfileSettingId>(i));
|
|
}
|
|
++i;
|
|
if(settings.Exists(static_cast<CProfileSettings::ProfileSettingId>(i)))
|
|
{
|
|
decodeData.decoder[sp].Si[a] = settings.GetFloat(static_cast<CProfileSettings::ProfileSettingId>(i));
|
|
}
|
|
++i;
|
|
}
|
|
if(settings.Exists(static_cast<CProfileSettings::ProfileSettingId>(i)))
|
|
{
|
|
decodeData.decoder[sp].w = settings.GetFloat(static_cast<CProfileSettings::ProfileSettingId>(i));
|
|
}
|
|
++i;
|
|
}
|
|
|
|
if(settings.Exists(CProfileSettings::AMBISONIC_DECODER_TYPE))
|
|
{
|
|
decodeData.decoderType = static_cast<EDecoderType>(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, "<RAVEMessage timeStamp=\"%u\">", g_AudioEngine.GetSoundManager().GetTimeInMilliseconds(1));
|
|
|
|
// Focus Entity variables
|
|
CEntity *ent = CDebugScene::FocusEntities_Get(0);
|
|
|
|
if(ent && ent->GetAudioEntity())
|
|
{
|
|
safecat(messageBuf, "<FocusEntityVariables>");
|
|
|
|
audVariableBlock *vars = ent->GetAudioEntity()->GetVariableBlock();
|
|
if(vars)
|
|
{
|
|
for(u32 i = 0; i < vars->GetMetadata()->numVariables; i++)
|
|
{
|
|
safecatf(messageBuf, "<Variable nameHash=\"%u\" value=\"%f\"/>", vars->GetMetadata()->Variable[i].Name, vars->GetValueByIndex(i));
|
|
}
|
|
}
|
|
|
|
safecat(messageBuf, "</FocusEntityVariables>");
|
|
}
|
|
|
|
// Global variables
|
|
ravesimpletypes::VariableList *list = audConfig::GetMetadataManager().GetObject<ravesimpletypes::VariableList>("GlobalVariableList");
|
|
safecat(messageBuf, "<GlobalVariables>");
|
|
if(list)
|
|
{
|
|
for(u32 i = 0; i < list->numVariables; i++)
|
|
{
|
|
safecatf(messageBuf, "<Variable nameHash=\"%u\" value=\"%f\"/>", list->Variable[i].Name, g_AudioEngine.GetSoundManager().GetVariableByIndex(i));
|
|
}
|
|
}
|
|
safecat(messageBuf, "</GlobalVariables>");
|
|
|
|
safecat(messageBuf, "</RAVEMessage>");
|
|
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; i<NUM_SLOWMOTYPE; i++)
|
|
{
|
|
grcFont::GetCurrent().SetInternalColor( Color32( 250, 250, 250 ) );
|
|
|
|
const char *slowMoName = GetMetadataManager().GetObjectName(sm_ActiveSlowMoModes[i]);
|
|
|
|
formatf(sectionHeader, "%s: %s", SlowMoType_ToString((SlowMoType)i), slowMoName);
|
|
drawMgr.DrawLine(sectionHeader);
|
|
}
|
|
|
|
drawMgr.PopSection();
|
|
|
|
formatf(sectionHeader, "Current SlowMo Mode");
|
|
drawMgr.PushSection(sectionHeader);
|
|
formatf(sectionHeader, "%s: %s : %s", SlowMoType_ToString(sm_SlowMoMode), sm_SlowMoScene ? DYNAMICMIXMGR.GetMetadataManager().GetObjectNameFromNameTableOffset(sm_SlowMoScene->GetSceneSettings()->NameTableOffset): NULL, sm_SlowMoSound ? g_AudioEngine.GetSoundManager().GetFactory().GetMetadataManager().GetObjectNameFromNameTableOffset(sm_SlowMoSound->GetNameTableOffset()): NULL);
|
|
|
|
drawMgr.DrawLine(sectionHeader);
|
|
|
|
drawMgr.PopSection();
|
|
|
|
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<ModelAudioCollisionSettings>(nameHash);
|
|
if(macs)
|
|
{
|
|
g_CollisionAudioEntity.HandleRaveSelectedMaterial(macs);
|
|
}
|
|
}
|
|
else if(info.GetType() == StaticEmitter::TYPE_ID)
|
|
{
|
|
g_RequestedWarpEmitter = info.GetObject<StaticEmitter>();
|
|
}
|
|
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<AmbientZone>();
|
|
}
|
|
}
|
|
#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<AmbientZone>();
|
|
g_AmbientAudioEntity.HandleRaveZoneCreatedNotification(const_cast<AmbientZone*>(ambientZone));
|
|
}
|
|
else if(info.GetType() == StaticEmitter::TYPE_ID)
|
|
{
|
|
g_EmitterAudioEntity.HandleRaveStaticEmitterCreatedNotification(nameHash);
|
|
}
|
|
else if (info.GetType() == ShoreLinePoolAudioSettings::TYPE_ID)
|
|
{
|
|
ShoreLinePoolAudioSettings* settings = audNorthAudioEngine::GetObject<ShoreLinePoolAudioSettings>(nameHash);
|
|
g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast<ShoreLineAudioSettings*>(settings));
|
|
}
|
|
else if (info.GetType() == ShoreLineRiverAudioSettings::TYPE_ID)
|
|
{
|
|
ShoreLineRiverAudioSettings* settings = audNorthAudioEngine::GetObject<ShoreLineRiverAudioSettings>(nameHash);
|
|
g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast<ShoreLineAudioSettings*>(settings));
|
|
}
|
|
else if (info.GetType() == ShoreLineOceanAudioSettings::TYPE_ID)
|
|
{
|
|
ShoreLineOceanAudioSettings* settings = audNorthAudioEngine::GetObject<ShoreLineOceanAudioSettings>(nameHash);
|
|
g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast<ShoreLineAudioSettings*>(settings));
|
|
}
|
|
else if (info.GetType() == ShoreLineLakeAudioSettings::TYPE_ID)
|
|
{
|
|
ShoreLineLakeAudioSettings* settings = audNorthAudioEngine::GetObject<ShoreLineLakeAudioSettings>(nameHash);
|
|
g_AmbientAudioEntity.HandleRaveShoreLineCreatedNotification(static_cast<ShoreLineAudioSettings*>(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());
|
|
}
|
|
}
|
|
|
|
|