1 /* 2 =========================================================================== 3 4 Doom 3 GPL Source Code 5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). 8 9 Doom 3 Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #ifndef __SOUND__ 30 #define __SOUND__ 31 32 #include "idlib/math/Vector.h" 33 #include "framework/DeclManager.h" 34 #include "framework/DemoFile.h" 35 #include "renderer/Cinematic.h" 36 37 /* 38 =============================================================================== 39 40 SOUND SHADER DECL 41 42 =============================================================================== 43 */ 44 45 // unfortunately, our minDistance / maxDistance is specified in meters, and 46 // we have far too many of them to change at this time. 47 const float DOOM_TO_METERS = 0.0254f; // doom to meters 48 const float METERS_TO_DOOM = (1.0f/DOOM_TO_METERS); // meters to doom 49 50 class idSoundSample; 51 52 // sound shader flags 53 static const int SSF_PRIVATE_SOUND = BIT(0); // only plays for the current listenerId 54 static const int SSF_ANTI_PRIVATE_SOUND =BIT(1); // plays for everyone but the current listenerId 55 static const int SSF_NO_OCCLUSION = BIT(2); // don't flow through portals, only use straight line 56 static const int SSF_GLOBAL = BIT(3); // play full volume to all speakers and all listeners 57 static const int SSF_OMNIDIRECTIONAL = BIT(4); // fall off with distance, but play same volume in all speakers 58 static const int SSF_LOOPING = BIT(5); // repeat the sound continuously 59 static const int SSF_PLAY_ONCE = BIT(6); // never restart if already playing on any channel of a given emitter 60 static const int SSF_UNCLAMPED = BIT(7); // don't clamp calculated volumes at 1.0 61 static const int SSF_NO_FLICKER = BIT(8); // always return 1.0 for volume queries 62 static const int SSF_NO_DUPS = BIT(9); // try not to play the same sound twice in a row 63 64 // these options can be overriden from sound shader defaults on a per-emitter and per-channel basis 65 typedef struct { 66 float minDistance; 67 float maxDistance; 68 float volume; // in dB, unfortunately. Negative values get quieter 69 float shakes; 70 int soundShaderFlags; // SSF_* bit flags 71 int soundClass; // for global fading of sounds 72 } soundShaderParms_t; 73 74 75 const int SOUND_MAX_LIST_WAVS = 32; 76 77 // sound classes are used to fade most sounds down inside cinematics, leaving dialog 78 // flagged with a non-zero class full volume 79 const int SOUND_MAX_CLASSES = 4; 80 81 // it is somewhat tempting to make this a virtual class to hide the private 82 // details here, but that doesn't fit easily with the decl manager at the moment. 83 class idSoundShader : public idDecl { 84 public: 85 idSoundShader( void ); 86 virtual ~idSoundShader( void ); 87 88 virtual size_t Size( void ) const; 89 virtual bool SetDefaultText( void ); 90 virtual const char * DefaultDefinition( void ) const; 91 virtual bool Parse( const char *text, const int textLength ); 92 virtual void FreeData( void ); 93 virtual void List( void ) const; 94 95 virtual const char * GetDescription() const; 96 97 // so the editor can draw correct default sound spheres 98 // this is currently defined as meters, which sucks, IMHO. 99 virtual float GetMinDistance() const; // FIXME: replace this with a GetSoundShaderParms() 100 virtual float GetMaxDistance() const; 101 102 // returns NULL if an AltSound isn't defined in the shader. 103 // we use this for pairing a specific broken light sound with a normal light sound 104 virtual const idSoundShader *GetAltSound() const; 105 106 virtual bool HasDefaultSound() const; 107 108 virtual const soundShaderParms_t *GetParms() const; 109 virtual int GetNumSounds() const; 110 virtual const char * GetSound( int index ) const; 111 112 virtual bool CheckShakesAndOgg( void ) const; 113 114 private: 115 friend class idSoundWorldLocal; 116 friend class idSoundEmitterLocal; 117 friend class idSoundChannel; 118 friend class idSoundCache; 119 120 // options from sound shader text 121 soundShaderParms_t parms; // can be overriden on a per-channel basis 122 123 bool onDemand; // only load when played, and free when finished 124 int speakerMask; 125 const idSoundShader * altSound; 126 idStr desc; // description 127 bool errorDuringParse; 128 float leadinVolume; // allows light breaking leadin sounds to be much louder than the broken loop 129 130 idSoundSample * leadins[SOUND_MAX_LIST_WAVS]; 131 int numLeadins; 132 idSoundSample * entries[SOUND_MAX_LIST_WAVS]; 133 int numEntries; 134 135 private: 136 void Init( void ); 137 bool ParseShader( idLexer &src ); 138 }; 139 140 /* 141 =============================================================================== 142 143 SOUND EMITTER 144 145 =============================================================================== 146 */ 147 148 // sound channels 149 static const int SCHANNEL_ANY = 0; // used in queries and commands to effect every channel at once, in 150 // startSound to have it not override any other channel 151 static const int SCHANNEL_ONE = 1; // any following integer can be used as a channel number 152 typedef int s_channelType; // the game uses its own series of enums, and we don't want to require casts 153 154 155 class idSoundEmitter { 156 public: ~idSoundEmitter(void)157 virtual ~idSoundEmitter( void ) {} 158 159 // a non-immediate free will let all currently playing sounds complete 160 // soundEmitters are not actually deleted, they are just marked as 161 // reusable by the soundWorld 162 virtual void Free( bool immediate ) = 0; 163 164 // the parms specified will be the default overrides for all sounds started on this emitter. 165 // NULL is acceptable for parms 166 virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ) = 0; 167 168 // returns the length of the started sound in msec 169 virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true ) = 0; 170 171 // pass SCHANNEL_ANY to effect all channels 172 virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms ) = 0; 173 virtual void StopSound( const s_channelType channel ) = 0; 174 // to is in Db (sigh), over is in seconds 175 virtual void FadeSound( const s_channelType channel, float to, float over ) = 0; 176 177 // returns true if there are any sounds playing from this emitter. There is some conservative 178 // slop at the end to remove inconsistent race conditions with the sound thread updates. 179 // FIXME: network game: on a dedicated server, this will always be false 180 virtual bool CurrentlyPlaying( void ) const = 0; 181 182 // returns a 0.0 to 1.0 value based on the current sound amplitude, allowing 183 // graphic effects to be modified in time with the audio. 184 // just samples the raw wav file, it doesn't account for volume overrides in the 185 virtual float CurrentAmplitude( void ) = 0; 186 187 // for save games. Index will always be > 0 188 virtual int Index( void ) const = 0; 189 }; 190 191 /* 192 =============================================================================== 193 194 SOUND WORLD 195 196 There can be multiple independent sound worlds, just as there can be multiple 197 independent render worlds. The prime example is the editor sound preview 198 option existing simultaniously with a live game. 199 =============================================================================== 200 */ 201 202 class idSoundWorld { 203 public: ~idSoundWorld(void)204 virtual ~idSoundWorld( void ) {} 205 206 // call at each map start 207 virtual void ClearAllSoundEmitters( void ) = 0; 208 virtual void StopAllSounds( void ) = 0; 209 210 // get a new emitter that can play sounds in this world 211 virtual idSoundEmitter *AllocSoundEmitter( void ) = 0; 212 213 // for load games, index 0 will return NULL 214 virtual idSoundEmitter *EmitterForIndex( int index ) = 0; 215 216 // query sound samples from all emitters reaching a given position 217 virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listenerPosition ) = 0; 218 219 // where is the camera/microphone 220 // listenerId allows listener-private and antiPrivate sounds to be filtered 221 // gameTime is in msec, and is used to time sound queries and removals so that they are independent 222 // of any race conditions with the async update 223 virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName ) = 0; 224 225 // fade all sounds in the world with a given shader soundClass 226 // to is in Db (sigh), over is in seconds 227 virtual void FadeSoundClasses( const int soundClass, const float to, const float over ) = 0; 228 229 // background music 230 virtual void PlayShaderDirectly( const char *name, int channel = -1 ) = 0; 231 232 // dumps the current state and begins archiving commands 233 virtual void StartWritingDemo( idDemoFile *demo ) = 0; 234 virtual void StopWritingDemo() = 0; 235 236 // read a sound command from a demo file 237 virtual void ProcessDemoCommand( idDemoFile *demo ) = 0; 238 239 // pause and unpause the sound world 240 virtual void Pause( void ) = 0; 241 virtual void UnPause( void ) = 0; 242 virtual bool IsPaused( void ) = 0; 243 244 // Write the sound output to multiple wav files. Note that this does not use the 245 // work done by AsyncUpdate, it mixes explicitly in the foreground every PlaceOrigin(), 246 // under the assumption that we are rendering out screenshots and the gameTime is going 247 // much slower than real time. 248 // path should not include an extension, and the generated filenames will be: 249 // <path>_left.raw, <path>_right.raw, or <path>_51left.raw, <path>_51right.raw, 250 // <path>_51center.raw, <path>_51lfe.raw, <path>_51backleft.raw, <path>_51backright.raw, 251 // If only two channel mixing is enabled, the left and right .raw files will also be 252 // combined into a stereo .wav file. 253 virtual void AVIOpen( const char *path, const char *name ) = 0; 254 virtual void AVIClose( void ) = 0; 255 256 // SaveGame / demo Support 257 virtual void WriteToSaveGame( idFile *savefile ) = 0; 258 virtual void ReadFromSaveGame( idFile *savefile ) = 0; 259 260 virtual void SetSlowmo( bool active ) = 0; 261 virtual void SetSlowmoSpeed( float speed ) = 0; 262 virtual void SetEnviroSuit( bool active ) = 0; 263 }; 264 265 266 /* 267 =============================================================================== 268 269 SOUND SYSTEM 270 271 =============================================================================== 272 */ 273 274 typedef struct { 275 idStr name; 276 idStr format; 277 int numChannels; 278 int numSamplesPerSecond; 279 int num44kHzSamples; 280 int numBytes; 281 bool looping; 282 float lastVolume; 283 int start44kHzTime; 284 int current44kHzTime; 285 } soundDecoderInfo_t; 286 287 288 class idSoundSystem { 289 public: ~idSoundSystem(void)290 virtual ~idSoundSystem( void ) {} 291 292 // all non-hardware initialization 293 virtual void Init( void ) = 0; 294 295 // shutdown routine 296 virtual void Shutdown( void ) = 0; 297 298 // sound is attached to the window, and must be recreated when the window is changed 299 virtual bool InitHW( void ) = 0; 300 virtual bool ShutdownHW( void ) = 0; 301 302 // asyn loop, called at 60Hz 303 virtual int AsyncUpdate( int time ) = 0; 304 305 // async loop, when the sound driver uses a write strategy 306 virtual int AsyncUpdateWrite( int time ) = 0; 307 308 // it is a good idea to mute everything when starting a new level, 309 // because sounds may be started before a valid listener origin 310 // is specified 311 virtual void SetMute( bool mute ) = 0; 312 313 // for the sound level meter window 314 virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ) = 0; 315 316 // get sound decoder info 317 virtual int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo ) = 0; 318 319 // if rw == NULL, no portal occlusion or rendered debugging is available 320 virtual idSoundWorld * AllocSoundWorld( idRenderWorld *rw ) = 0; 321 322 // specifying NULL will cause silence to be played 323 virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld ) = 0; 324 325 // some tools, like the sound dialog, may be used in both the game and the editor 326 // This can return NULL, so check! 327 virtual idSoundWorld * GetPlayingSoundWorld( void ) = 0; 328 329 // Mark all soundSamples as currently unused, 330 // but don't free anything. 331 virtual void BeginLevelLoad( void ) = 0; 332 333 // Free all soundSamples marked as unused 334 // We might want to defer the loading of new sounds to this point, 335 // as we do with images, to avoid having a union in memory at one time. 336 virtual void EndLevelLoad( const char *mapString ) = 0; 337 338 // direct mixing for OSes that support it 339 virtual int AsyncMix( int soundTime, float *mixBuffer ) = 0; 340 341 // prints memory info 342 virtual void PrintMemInfo( MemInfo_t *mi ) = 0; 343 344 // is EFX support present - -1: disabled at compile time, 0: no suitable hardware, 1: ok 345 virtual int IsEFXAvailable( void ) = 0; 346 }; 347 348 extern idSoundSystem *soundSystem; 349 350 #endif /* !__SOUND__ */ 351