/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #pragma once #include #include #if !AUDIO_ENABLE_CRY_PHYSICS #include #include #endif // !AUDIO_ENABLE_CRY_PHYSICS #include #include #include #include #include #include namespace Audio { /////////////////////////////////////////////////////////////////////////////////////////////////// class AudioObjectIDFactory { public: static TAudioObjectID GetNextID(); static const TAudioObjectID s_invalidAudioObjectID; static const TAudioObjectID s_globalAudioObjectID; static const TAudioObjectID s_minValidAudioObjectID; static const TAudioObjectID s_maxValidAudioObjectID; }; /////////////////////////////////////////////////////////////////////////////////////////////////// class CAudioEventManager { public: CAudioEventManager(); ~CAudioEventManager(); CAudioEventManager(const CAudioEventManager&) = delete; // not defined; calls will fail at compile time CAudioEventManager& operator=(const CAudioEventManager&) = delete; // not defined; calls will fail at compile time void Initialize(); void Release(); void Update(const float fUpdateIntervalMS); CATLEvent* GetEvent(const EATLSubsystem eSender); CATLEvent* LookupID(const TAudioEventID nID) const; void ReleaseEvent(CATLEvent* const pEvent); size_t GetNumActive() const; private: CATLEvent* GetImplInstance(); void ReleaseImplInstance(CATLEvent* const pOldEvent); CATLEvent* GetInternalInstance(); void ReleaseInternalInstance(CATLEvent* const pOldEvent); using TActiveEventMap = ATLMapLookupType; TActiveEventMap m_cActiveAudioEvents; CInstanceManager m_oAudioEventPool; #if defined(INCLUDE_AUDIO_PRODUCTION_CODE) public: void SetDebugNameStore(const CATLDebugNameStore* const pDebugNameStore); void DrawDebugInfo(IRenderAuxGeom& rAuxGeom, float fPosX, float fPosY) const; private: const CATLDebugNameStore* m_pDebugNameStore; #endif //INCLUDE_AUDIO_PRODUCTION_CODE }; #if !AUDIO_ENABLE_CRY_PHYSICS /////////////////////////////////////////////////////////////////////////////////////////////////// class AudioRaycastManager : public AudioRaycastRequestBus::Handler , public Physics::WorldNotificationBus::Handler { public: AudioRaycastManager() { Physics::WorldNotificationBus::Handler::BusConnect(Physics::DefaultPhysicsWorldId); AudioRaycastRequestBus::Handler::BusConnect(); } ~AudioRaycastManager() override { AudioRaycastRequestBus::Handler::BusDisconnect(); Physics::WorldNotificationBus::Handler::BusDisconnect(); } // AudioRaycastRequestBus::Handler interface void PushAudioRaycastRequest(const AudioRaycastRequest& request) override; // Physics::WorldNotificationBus::Handler interface void OnPostPhysicsUpdate(float fixedDeltaTimeSeconds) override; int GetPhysicsTickOrder() override { return Physics::WorldNotifications::Audio; } // Additional functionality related to processing raycasts... void ProcessRaycastResults(float updateIntervalMs); using AudioRaycastRequestQueueType = AZStd::vector; using AudioRaycastResultQueueType = AZStd::vector; protected: AZStd::mutex m_raycastRequestsMutex; AZStd::mutex m_raycastResultsMutex; AudioRaycastRequestQueueType m_raycastRequests; AudioRaycastResultQueueType m_raycastResults; }; #endif // !AUDIO_ENABLE_CRY_PHYSICS /////////////////////////////////////////////////////////////////////////////////////////////////// class CAudioObjectManager { public: CAudioObjectManager(CAudioEventManager& refAudioEventManager); ~CAudioObjectManager(); CAudioObjectManager(const CAudioObjectManager&) = delete; // not defined; calls will fail at compile time CAudioObjectManager& operator=(const CAudioObjectManager&) = delete; // not defined; calls will fail at compile time void Initialize(); void Release(); void Update(const float fUpdateIntervalMS, const SATLWorldPosition& rListenerPosition); bool ReserveID(TAudioObjectID& rAudioObjectID); bool ReleaseID(const TAudioObjectID nAudioObjectID); CATLAudioObject* LookupID(const TAudioObjectID nAudioObjectID) const; void ReportStartedEvent(const CATLEvent* const pEvent); void ReportFinishedEvent(const CATLEvent* const pEvent, const bool bSuccess); #if AUDIO_ENABLE_CRY_PHYSICS void ReportObstructionRay(const TAudioObjectID nAudioObjectID, const size_t nRayID); void ReleasePendingRays(); #endif // AUDIO_ENABLE_CRY_PHYSICS #if defined(INCLUDE_AUDIO_PRODUCTION_CODE) using TActiveObjectMap = ATLMapLookupType; bool ReserveID(TAudioObjectID& rAudioObjectID, const char* const sAudioObjectName); void SetDebugNameStore(CATLDebugNameStore* const pDebugNameStore); size_t GetNumAudioObjects() const; size_t GetNumActiveAudioObjects() const; const TActiveObjectMap& GetActiveAudioObjects() const { return m_cAudioObjects; } void DrawPerObjectDebugInfo(IRenderAuxGeom& rAuxGeom, const AZ::Vector3& rListenerPos) const; void DrawDebugInfo(IRenderAuxGeom& rAuxGeom, float fPosX, float fPosY) const; private: CATLDebugNameStore* m_pDebugNameStore; #else private: using TActiveObjectMap = ATLMapLookupType; #endif //INCLUDE_AUDIO_PRODUCTION_CODE static float s_fVelocityUpdateIntervalMS; CATLAudioObject* GetInstance(); bool ReleaseInstance(CATLAudioObject* const pOldObject); TActiveObjectMap m_cAudioObjects; CInstanceManager m_cObjectPool; float m_fTimeSinceLastVelocityUpdateMS; CAudioEventManager& m_refAudioEventManager; #if !AUDIO_ENABLE_CRY_PHYSICS AudioRaycastManager m_raycastManager; #endif // !AUDIO_ENABLE_CRY_PHYSICS }; /////////////////////////////////////////////////////////////////////////////////////////////////// class CAudioListenerManager { public: CAudioListenerManager(); ~CAudioListenerManager(); CAudioListenerManager(const CAudioListenerManager&) = delete; // not defined; calls will fail at compile time CAudioListenerManager& operator=(const CAudioListenerManager&) = delete; // not defined; calls will fail at compile time void Initialize(); void Release(); void Update(const float fUpdateIntervalMS); bool ReserveID(TAudioObjectID& rAudioObjectID); bool ReleaseID(const TAudioObjectID nAudioObjectID); CATLListenerObject* LookupID(const TAudioObjectID nAudioObjectID) const; size_t GetNumActive() const; void GetDefaultListenerPosition(SATLWorldPosition& oPosition); TAudioObjectID GetDefaultListenerID() const { return m_nDefaultListenerID; } bool SetOverrideListenerID(const TAudioObjectID nAudioObjectID); TAudioObjectID GetOverrideListenerID() const { return m_listenerOverrideID; } #if defined(INCLUDE_AUDIO_PRODUCTION_CODE) void DrawDebugInfo(IRenderAuxGeom& rAuxGeom) const; #endif // INCLUDE_AUDIO_PRODUCTION_CODE private: using TListenerPtrContainer = AZStd::vector; using TActiveListenerMap = ATLMapLookupType; TActiveListenerMap m_cActiveListeners; TListenerPtrContainer m_cListenerPool; CATLListenerObject* m_pDefaultListenerObject; const TAudioObjectID m_nDefaultListenerID; TAudioObjectID m_listenerOverrideID; // No longer have a maximum, but we can create a number of additional listeners at startup. // TODO: Control this by a cvar const size_t m_numReservedListeners = 8; }; /////////////////////////////////////////////////////////////////////////////////////////////////// class CAudioEventListenerManager { public: CAudioEventListenerManager(); ~CAudioEventListenerManager(); CAudioEventListenerManager(const CAudioEventListenerManager& other) = delete; // Copy protection CAudioEventListenerManager& operator=(const CAudioEventListenerManager& other) = delete; // Copy protection void AddRequestListener(const SAudioEventListener& listener); void RemoveRequestListener(const SAudioEventListener& listener); void NotifyListener(const SAudioRequestInfo* const pRequestInfo); #if defined(INCLUDE_AUDIO_PRODUCTION_CODE) size_t GetNumEventListeners() const { return m_cListeners.size(); } #endif //INCLUDE_AUDIO_PRODUCTION_CODE private: using TListenerArray = AZStd::vector; TListenerArray m_cListeners; }; /////////////////////////////////////////////////////////////////////////////////////////////////// class CATLXmlProcessor { public: CATLXmlProcessor( TATLTriggerLookup& rTriggers, TATLRtpcLookup& rRtpcs, TATLSwitchLookup& rSwitches, TATLEnvironmentLookup& rEnvironments, TATLPreloadRequestLookup& rPreloadRequests, CFileCacheManager& rFileCacheMgr); ~CATLXmlProcessor(); void Initialize(); void Release(); void ParseControlsData(const char* const sFolderPath, const EATLDataScope eDataScope); void ClearControlsData(const EATLDataScope eDataScope); void ParsePreloadsData(const char* const sFolderPath, const EATLDataScope eDataScope); void ClearPreloadsData(const EATLDataScope eDataScope); private: void ParseAudioTriggers(const AZ::rapidxml::xml_node* triggersXmlRoot, const EATLDataScope dataScope); void ParseAudioSwitches(const AZ::rapidxml::xml_node* switchesXmlRoot, const EATLDataScope dataScope); void ParseAudioRtpcs(const AZ::rapidxml::xml_node* rtpcsXmlRoot, const EATLDataScope dataScope); void ParseAudioPreloads(const AZ::rapidxml::xml_node* preloadsXmlRoot, const EATLDataScope dataScope, const char* const folderName); void ParseAudioEnvironments(const AZ::rapidxml::xml_node* environmentsXmlRoot, const EATLDataScope dataScope); CATLPreloadRequest::TFileEntryIDs LegacyParseFileEntries(const AZ::rapidxml::xml_node* preloadNode, const EATLDataScope dataScope, bool autoLoad); CATLPreloadRequest::TFileEntryIDs ParseFileEntries(const AZ::rapidxml::xml_node* preloadNode, const EATLDataScope dataScope, bool autoLoad); IATLTriggerImplData* NewAudioTriggerImplDataInternal(const AZ::rapidxml::xml_node* triggerXmlRoot); IATLRtpcImplData* NewAudioRtpcImplDataInternal(const AZ::rapidxml::xml_node* rtpcXmlRoot); IATLSwitchStateImplData* NewAudioSwitchStateImplDataInternal(const AZ::rapidxml::xml_node* switchXmlRoot); IATLEnvironmentImplData* NewAudioEnvironmentImplDataInternal(const AZ::rapidxml::xml_node* environmentXmlRoot); void DeleteAudioTrigger(CATLTrigger* const pOldTrigger); void DeleteAudioRtpc(CATLRtpc* const pOldRtpc); void DeleteAudioSwitch(CATLSwitch* const pOldSwitch); void DeleteAudioPreloadRequest(CATLPreloadRequest* const pOldPreloadRequest); void DeleteAudioEnvironment(CATLAudioEnvironment* const pOldEnvironment); TATLTriggerLookup& m_rTriggers; TATLRtpcLookup& m_rRtpcs; TATLSwitchLookup& m_rSwitches; TATLEnvironmentLookup& m_rEnvironments; TATLPreloadRequestLookup& m_rPreloadRequests; CFileCacheManager& m_rFileCacheMgr; TAudioTriggerImplID m_nTriggerImplIDCounter; AZStd::string m_rootPath; #if defined(INCLUDE_AUDIO_PRODUCTION_CODE) public: void SetDebugNameStore(CATLDebugNameStore* const pDebugNameStore); void SetRootPath(const char* path); private: CATLDebugNameStore* m_pDebugNameStore; #endif //INCLUDE_AUDIO_PRODUCTION_CODE }; /////////////////////////////////////////////////////////////////////////////////////////////////// struct SATLSharedData { SATLSharedData(); ~SATLSharedData(); SATLWorldPosition m_oActiveListenerPosition; }; } // namespace Audio