snd_local.h (14936B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition 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 BFG Edition 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 __SND_LOCAL_H__ 30 #define __SND_LOCAL_H__ 31 32 #include "WaveFile.h" 33 34 // Maximum number of voices we can have allocated 35 #define MAX_HARDWARE_VOICES 48 36 37 // A single voice can play multiple channels (up to 5.1, but most commonly stereo) 38 // This is the maximum number of channels which can play simultaneously 39 // This is limited primarily by seeking on the optical drive, secondarily by memory consumption, and tertiarily by CPU time spent mixing 40 #define MAX_HARDWARE_CHANNELS 64 41 42 // We may need up to 3 buffers for each hardware voice if they are all long sounds 43 #define MAX_SOUND_BUFFERS ( MAX_HARDWARE_VOICES * 3 ) 44 45 // Maximum number of channels in a sound sample 46 #define MAX_CHANNELS_PER_VOICE 8 47 48 /* 49 ======================== 50 MsecToSamples 51 SamplesToMsec 52 ======================== 53 */ 54 ID_INLINE_EXTERN uint32 MsecToSamples( uint32 msec, uint32 sampleRate ) { return ( msec * ( sampleRate / 100 ) ) / 10; } 55 ID_INLINE_EXTERN uint32 SamplesToMsec( uint32 samples, uint32 sampleRate ) { return sampleRate < 100 ? 0 : ( samples * 10 ) / ( sampleRate / 100 ); } 56 57 /* 58 ======================== 59 DBtoLinear 60 LinearToDB 61 ======================== 62 */ 63 ID_INLINE_EXTERN float DBtoLinear( float db ) { return idMath::Pow( 2.0f, db * ( 1.0f / 6.0f ) ); } 64 ID_INLINE_EXTERN float LinearToDB( float linear ) { return ( linear > 0.0f ) ? ( idMath::Log( linear ) * ( 6.0f / 0.693147181f ) ) : -999.0f; } 65 66 // demo sound commands 67 typedef enum { 68 SCMD_STATE, // followed by a load game state 69 SCMD_PLACE_LISTENER, 70 SCMD_ALLOC_EMITTER, 71 72 SCMD_FREE, 73 SCMD_UPDATE, 74 SCMD_START, 75 SCMD_MODIFY, 76 SCMD_STOP, 77 SCMD_FADE 78 } soundDemoCommand_t; 79 80 #include "SoundVoice.h" 81 82 83 #define OPERATION_SET 1 84 85 #include <dxsdkver.h> 86 87 #include <xaudio2.h> 88 #include <xaudio2fx.h> 89 #include <X3DAudio.h> 90 #include <xma2defs.h> 91 #include "XAudio2/XA2_SoundSample.h" 92 #include "XAudio2/XA2_SoundVoice.h" 93 #include "XAudio2/XA2_SoundHardware.h" 94 95 96 97 //------------------------ 98 // Listener data 99 //------------------------ 100 struct listener_t { 101 idMat3 axis; // orientation of the listener 102 idVec3 pos; // position in meters 103 int id; // the entity number, used to detect when a sound is local 104 int area; // area number the listener is in 105 }; 106 107 class idSoundFade { 108 public: 109 int fadeStartTime; 110 int fadeEndTime; 111 float fadeStartVolume; 112 float fadeEndVolume; 113 114 115 public: 116 idSoundFade() { Clear(); } 117 118 void Clear(); 119 void SetVolume( float to ); 120 void Fade( float to, int length, int soundTime ); 121 122 float GetVolume( int soundTime ) const; 123 }; 124 125 /* 126 ================================================ 127 idSoundChannel 128 ================================================ 129 */ 130 class idSoundChannel { 131 public: 132 bool CanMute() const; 133 134 void Mute(); 135 bool CheckForCompletion( int currentTime ); 136 137 void UpdateVolume( int currentTime ); 138 void UpdateHardware( float volumeAdd, int currentTime ); 139 140 // returns true if this channel is marked as looping 141 bool IsLooping() const; 142 143 class idSoundEmitterLocal * emitter; 144 145 int startTime; 146 int endTime; 147 int logicalChannel; 148 bool allowSlow; 149 150 soundShaderParms_t parms; // combines shader parms and per-channel overrides 151 const idSoundShader * soundShader; 152 idSoundSample * leadinSample; 153 idSoundSample * loopingSample; 154 idSoundFade volumeFade; 155 156 float volumeDB; // last volume at which this channel will play (calculated in UpdateVolume) 157 float currentAmplitude; // current amplitude on the hardware voice 158 159 // hardwareVoice will be freed and NULL'd when a sound is out of range, 160 // and reallocated when it comes back in range 161 idSoundVoice * hardwareVoice; 162 163 // only allocated by the soundWorld block allocator 164 idSoundChannel(); 165 ~idSoundChannel(); 166 }; 167 168 // Maximum number of SoundChannels for a single SoundEmitter. 169 // This is probably excessive... 170 const int MAX_CHANNELS_PER_EMITTER = 16; 171 172 /* 173 =================================================================================== 174 175 idSoundWorldLocal 176 177 =================================================================================== 178 */ 179 180 class idSoundWorldLocal : public idSoundWorld { 181 public: 182 idSoundWorldLocal(); 183 virtual ~idSoundWorldLocal(); 184 185 //------------------------ 186 // Functions from idSoundWorld, implemented in SoundWorld.cpp 187 //------------------------ 188 189 // Called at map start 190 virtual void ClearAllSoundEmitters(); 191 192 // stop all playing sounds 193 virtual void StopAllSounds(); 194 195 // get a new emitter that can play sounds in this world 196 virtual idSoundEmitter *AllocSoundEmitter(); 197 198 // for load games 199 virtual idSoundEmitter *EmitterForIndex( int index ); 200 201 // query data from all emitters in the world 202 virtual float CurrentShakeAmplitude(); 203 204 // where is the camera 205 virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId ); 206 207 // fade all sounds in the world with a given shader soundClass 208 // to is in Db, over is in seconds 209 virtual void FadeSoundClasses( const int soundClass, const float to, const float over ); 210 211 // dumps the current state and begins archiving commands 212 virtual void StartWritingDemo( idDemoFile *demo ); 213 virtual void StopWritingDemo(); 214 215 // read a sound command from a demo file 216 virtual void ProcessDemoCommand( idDemoFile *readDemo ); 217 218 // menu sounds 219 virtual int PlayShaderDirectly( const char *name, int channel = -1 ); 220 221 virtual void Skip( int time ); 222 223 virtual void Pause(); 224 virtual void UnPause(); 225 virtual bool IsPaused() { return isPaused; } 226 227 virtual int GetSoundTime(); 228 229 // avidump 230 virtual void AVIOpen( const char *path, const char *name ); 231 virtual void AVIClose(); 232 233 // SaveGame Support 234 virtual void WriteToSaveGame( idFile *savefile ); 235 virtual void ReadFromSaveGame( idFile *savefile ); 236 237 virtual void SetSlowmoSpeed( float speed ); 238 virtual void SetEnviroSuit( bool active ); 239 240 //======================================= 241 242 //------------------------ 243 // Random stuff that's not exposed outside the sound system 244 //------------------------ 245 void Update(); 246 void OnReloadSound( const idDecl *decl ); 247 248 idSoundChannel * AllocSoundChannel(); 249 void FreeSoundChannel( idSoundChannel * ); 250 251 public: 252 // even though all these variables are public, nobody outside the sound system includes SoundWorld_local.h 253 // so this is equivalent to making it private and friending all the other classes in the sound system 254 255 idSoundFade volumeFade; // master volume knob for the entire world 256 idSoundFade soundClassFade[SOUND_MAX_CLASSES]; 257 258 idRenderWorld * renderWorld; // for debug visualization and light amplitude sampling 259 idDemoFile * writeDemo; // if not NULL, archive commands here 260 261 float currentCushionDB; // channels at or below this level will be faded to 0 262 float shakeAmp; // last calculated shake amplitude 263 264 listener_t listener; 265 idList<idSoundEmitterLocal *, TAG_AUDIO> emitters; 266 267 idSoundEmitter * localSound; // for PlayShaderDirectly() 268 269 idBlockAlloc<idSoundEmitterLocal, 16> emitterAllocator; 270 idBlockAlloc<idSoundChannel, 16> channelAllocator; 271 272 idSoundFade pauseFade; 273 int pausedTime; 274 int accumulatedPauseTime; 275 bool isPaused; 276 277 float slowmoSpeed; 278 bool enviroSuitActive; 279 280 public: 281 struct soundPortalTrace_t { 282 int portalArea; 283 const soundPortalTrace_t * prevStack; 284 }; 285 286 void ResolveOrigin( const int stackDepth, const soundPortalTrace_t * prevStack, const int soundArea, const float dist, const idVec3 & soundOrigin, idSoundEmitterLocal * def ); 287 }; 288 289 290 /* 291 ================================================ 292 idSoundEmitterLocal 293 ================================================ 294 */ 295 class idSoundEmitterLocal : public idSoundEmitter { 296 public: 297 virtual void Free( bool immediate ); 298 299 virtual void Reset(); 300 301 virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ); 302 303 virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true ); 304 305 virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms ); 306 virtual void StopSound( const s_channelType channel ); 307 308 virtual void FadeSound( const s_channelType channel, float to, float over ); 309 310 virtual bool CurrentlyPlaying( const s_channelType channel = SCHANNEL_ANY ) const; 311 312 virtual float CurrentAmplitude(); 313 314 virtual int Index() const; 315 316 //---------------------------------------------- 317 318 void Init( int i, idSoundWorldLocal * sw ); 319 320 // Returns true if the emitter should be freed. 321 bool CheckForCompletion( int currentTime ); 322 323 void OverrideParms( const soundShaderParms_t * base, const soundShaderParms_t * over, soundShaderParms_t * out ); 324 325 void Update( int currentTime ); 326 void OnReloadSound( const idDecl *decl ); 327 328 //---------------------------------------------- 329 330 idSoundWorldLocal * soundWorld; // the world that holds this emitter 331 332 int index; // in world emitter list 333 bool canFree; // if true, this emitter can be canFree (once channels.Num() == 0) 334 335 // a single soundEmitter can have many channels playing from the same point 336 idStaticList<idSoundChannel *, MAX_CHANNELS_PER_EMITTER> channels; 337 338 //----- set by UpdateEmitter ----- 339 idVec3 origin; 340 soundShaderParms_t parms; 341 int emitterId; // sounds will be full volume when emitterId == listenerId 342 343 //----- set by Update ----- 344 int lastValidPortalArea; 345 float directDistance; 346 float spatializedDistance; 347 idVec3 spatializedOrigin; 348 349 // sound emitters are only allocated by the soundWorld block allocator 350 idSoundEmitterLocal(); 351 virtual ~idSoundEmitterLocal(); 352 }; 353 354 355 /* 356 =================================================================================== 357 358 idSoundSystemLocal 359 360 =================================================================================== 361 */ 362 class idSoundSystemLocal : public idSoundSystem { 363 public: 364 // all non-hardware initialization 365 virtual void Init(); 366 367 // shutdown routine 368 virtual void Shutdown(); 369 370 virtual idSoundWorld * AllocSoundWorld( idRenderWorld *rw ); 371 virtual void FreeSoundWorld( idSoundWorld *sw ); 372 373 // specifying NULL will cause silence to be played 374 virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld ); 375 376 // some tools, like the sound dialog, may be used in both the game and the editor 377 // This can return NULL, so check! 378 virtual idSoundWorld * GetPlayingSoundWorld(); 379 380 // sends the current playing sound world information to the sound hardware 381 virtual void Render(); 382 383 // Mutes the SSG_MUSIC group 384 virtual void MuteBackgroundMusic( bool mute ) { musicMuted = mute; } 385 386 // sets the final output volume to 0 387 // This should only be used when the app is deactivated 388 // Since otherwise there will be problems with different subsystems muting and unmuting at different times 389 virtual void SetMute( bool mute ) { muted = mute; } 390 virtual bool IsMuted() { return muted; } 391 392 virtual void OnReloadSound( const idDecl * sound ); 393 394 virtual void StopAllSounds(); 395 396 virtual void InitStreamBuffers(); 397 virtual void FreeStreamBuffers(); 398 399 virtual void * GetIXAudio2() const; 400 401 // for the sound level meter window 402 virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ); 403 404 // Free all sounds loaded during the last map load 405 virtual void BeginLevelLoad(); 406 407 // We might want to defer the loading of new sounds to this point 408 virtual void EndLevelLoad(); 409 410 // prints memory info 411 virtual void PrintMemInfo( MemInfo_t *mi ); 412 413 //------------------------- 414 415 // Before a sound is reloaded, any active voices using it must 416 // be stopped. Returns true if any were playing, and should be 417 // restarted after the sound is reloaded. 418 void StopVoicesWithSample( const idSoundSample * const sample ); 419 420 void Restart(); 421 void SetNeedsRestart() { needsRestart = true; } 422 423 int SoundTime() const; 424 425 // may return NULL if there are no more voices left 426 idSoundVoice * AllocateVoice( const idSoundSample * leadinSample, const idSoundSample * loopingSample ); 427 void FreeVoice( idSoundVoice * ); 428 429 idSoundSample * LoadSample( const char * name ); 430 431 virtual void Preload( idPreloadManifest & preload ); 432 433 struct bufferContext_t { 434 bufferContext_t() : 435 voice( NULL ), 436 sample( NULL ), 437 bufferNumber( 0 ) 438 { } 439 idSoundVoice_XAudio2 * voice; 440 idSoundSample_XAudio2 * sample; 441 int bufferNumber; 442 }; 443 444 // Get a stream buffer from the free pool, returns NULL if none are available 445 bufferContext_t * ObtainStreamBufferContext(); 446 void ReleaseStreamBufferContext( bufferContext_t * p ); 447 448 idSysMutex streamBufferMutex; 449 idStaticList< bufferContext_t *, MAX_SOUND_BUFFERS > freeStreamBufferContexts; 450 idStaticList< bufferContext_t *, MAX_SOUND_BUFFERS > activeStreamBufferContexts; 451 idStaticList< bufferContext_t, MAX_SOUND_BUFFERS > bufferContexts; 452 453 idSoundWorldLocal * currentSoundWorld; 454 idStaticList<idSoundWorldLocal *, 32> soundWorlds; 455 456 idList<idSoundSample *, TAG_AUDIO> samples; 457 idHashIndex sampleHash; 458 459 idSoundHardware hardware; 460 461 idRandom2 random; 462 463 int soundTime; 464 bool muted; 465 bool musicMuted; 466 bool needsRestart; 467 468 bool insideLevelLoad; 469 470 //------------------------- 471 472 idSoundSystemLocal() : 473 soundTime( 0 ), 474 currentSoundWorld( NULL ), 475 muted( false ), 476 musicMuted( false ), 477 needsRestart( false ) 478 {} 479 }; 480 481 extern idSoundSystemLocal soundSystemLocal; 482 483 #endif /* !__SND_LOCAL_H__ */