GameAudio.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. //----------------------------------------------------------------------------
  24. //
  25. // Westwood Studios Pacific.
  26. //
  27. // Confidential Information
  28. // Copyright (C) 2001 - All Rights Reserved
  29. //
  30. //----------------------------------------------------------------------------
  31. //
  32. // Project: RTS 3
  33. //
  34. // File name: Common/GameAudio.h
  35. //
  36. // Created: 5/01/01
  37. //
  38. //----------------------------------------------------------------------------
  39. #pragma once
  40. #ifndef __COMMON_GAMEAUDIO_H_
  41. #define __COMMON_GAMEAUDIO_H_
  42. // Includes
  43. #include "Lib/BaseType.h"
  44. #include "Common/STLTypedefs.h"
  45. #include "Common/SubsystemInterface.h"
  46. // Forward Declarations
  47. class AsciiString;
  48. class AudioEventRTS;
  49. class DebugDisplayInterface;
  50. class Drawable;
  51. class MusicManager;
  52. class Object;
  53. class SoundManager;
  54. enum AudioAffect;
  55. enum AudioType;
  56. struct AudioEventInfo;
  57. struct AudioRequest;
  58. struct AudioSettings;
  59. struct MiscAudio;
  60. typedef std::hash_map<AsciiString, AudioEventInfo*, rts::hash<AsciiString>, rts::equal_to<AsciiString> > AudioEventInfoHash;
  61. typedef AudioEventInfoHash::iterator AudioEventInfoHashIt;
  62. typedef UnsignedInt AudioHandle;
  63. // Defines
  64. enum
  65. {
  66. PROVIDER_ERROR = 0xFFFFFFFF
  67. };
  68. // Class AudioManager
  69. /**
  70. The life of audio.
  71. When audio is requested to play, it is done so in the following manner:
  72. 1) An AudioEventRTS is created on the stack.
  73. 2) Its guts are copied from elsewhere (for instance, a ThingTemplate, or MiscAudio).
  74. 3) It is added to TheAudio via TheAudio->addAudioEvent(...)
  75. The return value from addAudioEvent can be saved in case the sound needs to loop and/or be
  76. terminated at some point.
  77. To reomve a playing sound, the call TheAudio->removeAudioEvent(...) is used. This will search
  78. the list of currently playing audio for the specified handle, and kill the attached sound. It
  79. will play a decay sound, if one is specified.
  80. The important functions of TheAudio, are therefore
  81. GameAudio::addAudioEvent()
  82. GameAudio::removeAudioEvent()
  83. All other functions exist to support these two basic requirements.
  84. In addition to the fundamental requirements, the audio has a fairly complicated sound management
  85. scheme. If all units were always allowed to sound off, the sound engine would be overwhelmed and
  86. would sound awful. Therefore, when an audio event is requested, it goes through a series of
  87. checks to determine if it is near enough to the camera, if it should be heard based on shroud,
  88. local player affiliation, etc. (The entire list of checks is contained in shouldPlayLocally()).
  89. In addition, the world and unit audio are never allowed to exceed their footprint, as specified
  90. in the audio settings INI file. In order to accomodate this, the audio uses an audio cache. The
  91. audio cache will attempt to load a sample, assuming there is enough room. If there is not enough
  92. room, then it goes through and finds any samples that are lower priority, and kills them until
  93. enough room is present for the sample. If it cannot free enough room, nothing happens to the
  94. cache.
  95. Although the audio is multithreaded, most of the operations are performed such that the worst
  96. case scenario for thread miscommunication is that the main thread misses an event for one frame.
  97. One specific case of this is the status of playing audio. Because audio is playing
  98. asynchronously, it can complete at any time. When most audio completes, it sets a flag on the
  99. event noting that it has completed. During the next update (from the main thread), anything with
  100. that flag set is moved to the stopped list, and then is cleaned up. (Basically, the audio uses
  101. a push model for its multithreadedness, which doesn't require thread safety such as mutexes or
  102. semaphores).
  103. All in all, the best way to learn how the audio works is to track the lifetime of an event
  104. through the system. This will give a better understanding than all the documentation I could
  105. write.
  106. -jkmcd
  107. -December 2002
  108. */
  109. class AudioManager : public SubsystemInterface
  110. {
  111. public:
  112. AudioManager();
  113. virtual ~AudioManager();
  114. #if defined(_DEBUG) || defined(_INTERNAL)
  115. virtual void audioDebugDisplay(DebugDisplayInterface *dd, void *userData, FILE *fp = NULL ) = 0;
  116. #endif
  117. // From SubsystemInterface
  118. virtual void init();
  119. virtual void postProcessLoad();
  120. virtual void reset();
  121. virtual void update();
  122. // device dependent stop, pause and resume
  123. virtual void stopAudio( AudioAffect which ) = 0;
  124. virtual void pauseAudio( AudioAffect which ) = 0;
  125. virtual void resumeAudio( AudioAffect which ) = 0;
  126. virtual void pauseAmbient( Bool shouldPause ) = 0;
  127. // device dependent stops.
  128. virtual void stopAllAmbientsBy( Object* obj ) = 0;
  129. virtual void stopAllAmbientsBy( Drawable* draw ) = 0;
  130. // for focus issues
  131. virtual void loseFocus( void );
  132. virtual void regainFocus( void );
  133. // control for AudioEventsRTS
  134. virtual AudioHandle addAudioEvent( const AudioEventRTS *eventToAdd ); ///< Add an audio event (event must be declared in an INI file)
  135. virtual void removeAudioEvent( AudioHandle audioEvent ); ///< Remove an audio event, stop for instance.
  136. virtual void killAudioEventImmediately( AudioHandle audioEvent ) = 0;
  137. virtual Bool isValidAudioEvent( const AudioEventRTS *eventToCheck ) const; ///< validate that this piece of audio exists
  138. virtual Bool isValidAudioEvent( AudioEventRTS *eventToCheck ) const; ///< validate that this piece of audio exists
  139. // add tracks during INIification
  140. void addTrackName( const AsciiString& trackName );
  141. AsciiString nextTrackName(const AsciiString& currentTrack );
  142. AsciiString prevTrackName(const AsciiString& currentTrack );
  143. // changing music tracks
  144. virtual void nextMusicTrack( void ) = 0;
  145. virtual void prevMusicTrack( void ) = 0;
  146. virtual Bool isMusicPlaying( void ) const = 0;
  147. virtual Bool hasMusicTrackCompleted( const AsciiString& trackName, Int numberOfTimes ) const = 0;
  148. virtual AsciiString getMusicTrackName( void ) const = 0;
  149. virtual void setAudioEventEnabled( AsciiString eventToAffect, Bool enable );
  150. virtual void setAudioEventVolumeOverride( AsciiString eventToAffect, Real newVolume );
  151. virtual void removeAudioEvent( AsciiString eventToRemove );
  152. virtual void removeDisabledEvents();
  153. // Really meant for internal purposes only, but cannot be protected.
  154. virtual void getInfoForAudioEvent( const AudioEventRTS *eventToFindAndFill ) const; // Note: m_eventInfo is Mutable, and so this function will overwrite it if found
  155. ///< Return whether the current audio is playing or not.
  156. ///< NOTE NOTE NOTE !!DO NOT USE THIS IN FOR GAMELOGIC PURPOSES!! NOTE NOTE NOTE
  157. virtual Bool isCurrentlyPlaying( AudioHandle handle );
  158. // Device Dependent open and close functions
  159. virtual void openDevice( void ) = 0;
  160. virtual void closeDevice( void ) = 0;
  161. virtual void *getDevice( void ) = 0;
  162. // Debice Dependent notification functions
  163. virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags ) = 0;
  164. // Device Dependent enumerate providers functions. It is okay for there to be only 1 provider (Miles provides a maximum of 64.
  165. virtual UnsignedInt getProviderCount( void ) const = 0;
  166. virtual AsciiString getProviderName( UnsignedInt providerNum ) const = 0;
  167. virtual UnsignedInt getProviderIndex( AsciiString providerName ) const = 0;
  168. virtual void selectProvider( UnsignedInt providerNdx ) = 0;
  169. virtual void unselectProvider( void ) = 0;
  170. virtual UnsignedInt getSelectedProvider( void ) const = 0;
  171. virtual void setSpeakerType( UnsignedInt speakerType ) = 0;
  172. virtual UnsignedInt getSpeakerType( void ) = 0;
  173. virtual UnsignedInt translateSpeakerTypeToUnsignedInt( const AsciiString& speakerType );
  174. virtual AsciiString translateUnsignedIntToSpeakerType( UnsignedInt speakerType );
  175. // Device Dependent calls to get the number of channels for each type of audio (2-D, 3-D, Streams)
  176. virtual UnsignedInt getNum2DSamples( void ) const = 0;
  177. virtual UnsignedInt getNum3DSamples( void ) const = 0;
  178. virtual UnsignedInt getNumStreams( void ) const = 0;
  179. // Device Dependent calls to determine sound prioritization info
  180. virtual Bool doesViolateLimit( AudioEventRTS *event ) const = 0;
  181. virtual Bool isPlayingLowerPriority( AudioEventRTS *event ) const = 0;
  182. virtual Bool isPlayingAlready( AudioEventRTS *event ) const = 0;
  183. virtual Bool isObjectPlayingVoice( UnsignedInt objID ) const = 0;
  184. virtual void adjustVolumeOfPlayingAudio(AsciiString eventName, Real newVolume) = 0;
  185. virtual void removePlayingAudio( AsciiString eventName ) = 0;
  186. virtual void removeAllDisabledAudio() = 0;
  187. // Is the audio device on? We can skip a lot of audio processing if not.
  188. virtual Bool isOn( AudioAffect whichToGet ) const;
  189. virtual void setOn( Bool turnOn, AudioAffect whichToAffect );
  190. // Set and get the device Volume
  191. virtual void setVolume( Real volume, AudioAffect whichToAffect );
  192. virtual Real getVolume( AudioAffect whichToGet );
  193. // To get a more 3-D feeling from the universe, we adjust the volume of the 3-D samples based
  194. // on zoom.
  195. virtual void set3DVolumeAdjustment( Real volumeAdjustment );
  196. virtual void *getHandleForBink( void ) = 0;
  197. virtual void releaseHandleForBink( void ) = 0;
  198. // this function will play an audio event rts by loading it into memory. It should not be used
  199. // by anything except for the load screens.
  200. virtual void friend_forcePlayAudioEventRTS(const AudioEventRTS* eventToPlay) = 0;
  201. // Update Listener position information
  202. virtual void setListenerPosition( const Coord3D *newListenerPos, const Coord3D *newListenerOrientation );
  203. virtual const Coord3D *getListenerPosition( void ) const;
  204. virtual AudioRequest *allocateAudioRequest( Bool useAudioEvent );
  205. virtual void releaseAudioRequest( AudioRequest *requestToRelease );
  206. virtual void appendAudioRequest( AudioRequest *m_request );
  207. virtual void processRequestList( void );
  208. virtual AudioEventInfo *newAudioEventInfo( AsciiString newEventName );
  209. virtual AudioEventInfo *findAudioEventInfo( AsciiString eventName ) const;
  210. const AudioSettings *getAudioSettings( void ) const;
  211. const MiscAudio *getMiscAudio( void ) const;
  212. // This function should only be called by AudioManager, MusicManager and SoundManager
  213. virtual void releaseAudioEventRTS( AudioEventRTS *eventToRelease );
  214. // For INI
  215. AudioSettings *friend_getAudioSettings( void );
  216. MiscAudio *friend_getMiscAudio( void );
  217. const FieldParse *getFieldParseTable( void ) const;
  218. const AudioEventRTS *getValidSilentAudioEvent() const { return m_silentAudioEvent; }
  219. virtual void setHardwareAccelerated(Bool accel) { m_hardwareAccel = accel; }
  220. virtual Bool getHardwareAccelerated() { return m_hardwareAccel; }
  221. virtual void setSpeakerSurround(Bool surround) { m_surroundSpeakers = surround; }
  222. virtual Bool getSpeakerSurround() { return m_surroundSpeakers; }
  223. virtual void refreshCachedVariables();
  224. virtual void setPreferredProvider(AsciiString providerNdx) = 0;
  225. virtual void setPreferredSpeaker(AsciiString speakerType) = 0;
  226. // For Scripting
  227. virtual Real getAudioLengthMS( const AudioEventRTS *event );
  228. virtual Real getFileLengthMS( AsciiString strToLoad ) const = 0;
  229. // For the file cache to know when to remove files.
  230. virtual void closeAnySamplesUsingFile( const void *fileToClose ) = 0;
  231. virtual Bool isMusicAlreadyLoaded(void) const;
  232. virtual Bool isMusicPlayingFromCD(void) const { return m_musicPlayingFromCD; }
  233. Bool getDisallowSpeech( void ) const { return m_disallowSpeech; }
  234. void setDisallowSpeech( Bool disallowSpeech ) { m_disallowSpeech = disallowSpeech; }
  235. // For Worldbuilder, to build lists from which to select
  236. virtual void findAllAudioEventsOfType( AudioType audioType, std::vector<AudioEventInfo*>& allEvents );
  237. Real getZoomVolume() const { return m_zoomVolume; }
  238. protected:
  239. // Is the currently selected provider actually HW accelerated?
  240. virtual Bool isCurrentProviderHardwareAccelerated();
  241. // Is the currently selected speaker type Surround sound?
  242. virtual Bool isCurrentSpeakerTypeSurroundSound();
  243. // Should this piece of audio play on the local machine?
  244. virtual Bool shouldPlayLocally(const AudioEventRTS *audioEvent);
  245. // Set the Listening position for the device
  246. virtual void setDeviceListenerPosition( void ) = 0;
  247. // For tracking purposes
  248. virtual AudioHandle allocateNewHandle( void );
  249. protected:
  250. AudioSettings *m_audioSettings;
  251. MiscAudio *m_miscAudio;
  252. MusicManager *m_music;
  253. SoundManager *m_sound;
  254. Coord3D m_listenerPosition;
  255. Coord3D m_listenerOrientation;
  256. std::list<AudioRequest*> m_audioRequests;
  257. std::vector<AsciiString> m_musicTracks;
  258. AudioEventInfoHash m_allAudioEventInfo;
  259. AudioHandle theAudioHandlePool;
  260. std::list<std::pair<AsciiString, Real> > m_adjustedVolumes;
  261. Real m_musicVolume;
  262. Real m_soundVolume;
  263. Real m_sound3DVolume;
  264. Real m_speechVolume;
  265. Real m_scriptMusicVolume;
  266. Real m_scriptSoundVolume;
  267. Real m_scriptSound3DVolume;
  268. Real m_scriptSpeechVolume;
  269. Real m_systemMusicVolume;
  270. Real m_systemSoundVolume;
  271. Real m_systemSound3DVolume;
  272. Real m_systemSpeechVolume;
  273. Real m_zoomVolume;
  274. AudioEventRTS *m_silentAudioEvent;
  275. enum { NUM_VOLUME_TYPES = 4 };
  276. Real *m_savedValues;
  277. // Group of 8
  278. Bool m_speechOn : 1;
  279. Bool m_soundOn : 1;
  280. Bool m_sound3DOn : 1;
  281. Bool m_musicOn : 1;
  282. Bool m_volumeHasChanged : 1;
  283. Bool m_hardwareAccel : 1;
  284. Bool m_surroundSpeakers : 1;
  285. Bool m_musicPlayingFromCD : 1;
  286. // Next 8
  287. Bool m_disallowSpeech : 1;
  288. };
  289. extern AudioManager *TheAudio;
  290. #endif // __COMMON_GAMEAUDIO_H_