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 __SND_LOCAL_H__ 30 #define __SND_LOCAL_H__ 31 32 #ifdef ID_DEDICATED 33 // stub-only mode: AL_API and ALC_API shouldn't refer to any dll-stuff 34 // because the implemenations are in openal_stub.cpp 35 // this is ensured by defining AL_LIBTYPE_STATIC before including the AL headers 36 #define AL_LIBTYPE_STATIC 37 #endif 38 39 #include <AL/al.h> 40 #include <AL/alc.h> 41 #include <AL/alext.h> 42 43 #include "framework/UsercmdGen.h" 44 #include "sound/efxlib.h" 45 #include "sound/sound.h" 46 47 // demo sound commands 48 typedef enum { 49 SCMD_STATE, // followed by a load game state 50 SCMD_PLACE_LISTENER, 51 SCMD_ALLOC_EMITTER, 52 53 SCMD_FREE, 54 SCMD_UPDATE, 55 SCMD_START, 56 SCMD_MODIFY, 57 SCMD_STOP, 58 SCMD_FADE 59 } soundDemoCommand_t; 60 61 const int SOUND_MAX_CHANNELS = 8; 62 const int SOUND_DECODER_FREE_DELAY = 1000 * MIXBUFFER_SAMPLES / USERCMD_MSEC; // four seconds 63 64 const int PRIMARYFREQ = 44100; // samples per second 65 const float SND_EPSILON = 1.0f / 32768.0f; // if volume is below this, it will always multiply to zero 66 67 const int ROOM_SLICES_IN_BUFFER = 10; 68 69 class idAudioBuffer; 70 class idWaveFile; 71 class idSoundCache; 72 class idSoundSample; 73 class idSampleDecoder; 74 class idSoundWorldLocal; 75 76 77 /* 78 =================================================================================== 79 80 General extended waveform format structure. 81 Use this for all NON PCM formats. 82 83 =================================================================================== 84 */ 85 86 #ifdef WIN32 87 #pragma pack(1) 88 #endif 89 struct waveformatex_s { 90 word wFormatTag; /* format type */ 91 word nChannels; /* number of channels (i.e. mono, stereo...) */ 92 dword nSamplesPerSec; /* sample rate */ 93 dword nAvgBytesPerSec; /* for buffer estimation */ 94 word nBlockAlign; /* block size of data */ 95 word wBitsPerSample; /* Number of bits per sample of mono data */ 96 word cbSize; /* The count in bytes of the size of 97 extra information (after cbSize) */ 98 } PACKED; 99 100 typedef waveformatex_s waveformatex_t; 101 102 /* OLD general waveform format structure (information common to all formats) */ 103 struct waveformat_s { 104 word wFormatTag; /* format type */ 105 word nChannels; /* number of channels (i.e. mono, stereo, etc.) */ 106 dword nSamplesPerSec; /* sample rate */ 107 dword nAvgBytesPerSec; /* for buffer estimation */ 108 word nBlockAlign; /* block size of data */ 109 } PACKED; 110 111 typedef waveformat_s waveformat_t; 112 113 /* flags for wFormatTag field of WAVEFORMAT */ 114 enum { 115 WAVE_FORMAT_TAG_PCM = 1, 116 WAVE_FORMAT_TAG_OGG = 2 117 }; 118 119 /* specific waveform format structure for PCM data */ 120 struct pcmwaveformat_s { 121 waveformat_t wf; 122 word wBitsPerSample; 123 } PACKED; 124 125 typedef pcmwaveformat_s pcmwaveformat_t; 126 127 #ifndef mmioFOURCC 128 #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ 129 ( (dword)(byte)(ch0) | ( (dword)(byte)(ch1) << 8 ) | \ 130 ( (dword)(byte)(ch2) << 16 ) | ( (dword)(byte)(ch3) << 24 ) ) 131 #endif 132 133 #define fourcc_riff mmioFOURCC('R', 'I', 'F', 'F') 134 135 struct waveformatextensible_s { 136 waveformatex_t Format; 137 union { 138 word wValidBitsPerSample; /* bits of precision */ 139 word wSamplesPerBlock; /* valid if wBitsPerSample==0*/ 140 word wReserved; /* If neither applies, set to zero*/ 141 } Samples; 142 dword dwChannelMask; /* which channels are */ 143 /* present in stream */ 144 int SubFormat; 145 } PACKED; 146 147 typedef waveformatextensible_s waveformatextensible_t; 148 149 typedef dword fourcc; 150 151 /* RIFF chunk information data structure */ 152 struct mminfo_s { 153 fourcc ckid; /* chunk ID */ 154 dword cksize; /* chunk size */ 155 fourcc fccType; /* form type or list type */ 156 dword dwDataOffset; /* offset of data portion of chunk */ 157 } PACKED; 158 159 typedef mminfo_s mminfo_t; 160 161 #ifdef WIN32 162 #pragma pack() 163 #endif 164 165 /* 166 =================================================================================== 167 168 idWaveFile 169 170 =================================================================================== 171 */ 172 173 class idWaveFile { 174 public: 175 idWaveFile( void ); 176 ~idWaveFile( void ); 177 178 int Open( const char* strFileName, waveformatex_t* pwfx = NULL ); 179 int OpenFromMemory( short* pbData, int ulDataSize, waveformatextensible_t* pwfx ); 180 int Read( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ); 181 int Seek( int offset ); 182 int Close( void ); 183 int ResetFile( void ); 184 GetOutputSize(void)185 int GetOutputSize( void ) { return mdwSize; } GetMemorySize(void)186 int GetMemorySize( void ) { return mMemSize; } 187 188 waveformatextensible_t mpwfx; // Pointer to waveformatex structure 189 190 private: 191 idFile * mhmmio; // I/O handle for the WAVE 192 mminfo_t mck; // Multimedia RIFF chunk 193 mminfo_t mckRiff; // used when opening a WAVE file 194 dword mdwSize; // size in samples 195 dword mMemSize; // size of the wave data in memory 196 dword mseekBase; 197 ID_TIME_T mfileTime; 198 199 bool mbIsReadingFromMemory; 200 short * mpbData; 201 short * mpbDataCur; 202 dword mulDataSize; 203 204 void * ogg; // only !NULL when !s_realTimeDecoding 205 bool isOgg; 206 207 private: 208 int ReadMMIO( void ); 209 210 int OpenOGG( const char* strFileName, waveformatex_t* pwfx = NULL ); 211 int ReadOGG( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead ); 212 int CloseOGG( void ); 213 }; 214 215 216 /* 217 =================================================================================== 218 219 Encapsulates functionality of a DirectSound buffer. 220 221 =================================================================================== 222 */ 223 224 class idAudioBuffer { 225 public: 226 virtual int Play( dword dwPriority=0, dword dwFlags=0 ) = 0; 227 virtual int Stop( void ) = 0; 228 virtual int Reset( void ) = 0; 229 virtual bool IsSoundPlaying( void ) = 0; 230 virtual void SetVolume( float x ) = 0; 231 }; 232 233 234 /* 235 =================================================================================== 236 237 idSoundEmitterLocal 238 239 =================================================================================== 240 */ 241 242 typedef enum { 243 REMOVE_STATUS_INVALID = -1, 244 REMOVE_STATUS_ALIVE = 0, 245 REMOVE_STATUS_WAITSAMPLEFINISHED = 1, 246 REMOVE_STATUS_SAMPLEFINISHED = 2 247 } removeStatus_t; 248 249 class idSoundFade { 250 public: 251 int fadeStart44kHz; 252 int fadeEnd44kHz; 253 float fadeStartVolume; // in dB 254 float fadeEndVolume; // in dB 255 256 void Clear(); 257 float FadeDbAt44kHz( int current44kHz ); 258 }; 259 260 class SoundFX { 261 protected: 262 bool initialized; 263 264 int channel; 265 int maxlen; 266 267 float* buffer; 268 float continuitySamples[4]; 269 270 float param; 271 272 public: SoundFX()273 SoundFX() { channel = 0; buffer = NULL; initialized = false; maxlen = 0; memset( continuitySamples, 0, sizeof( float ) * 4 ); }; ~SoundFX()274 virtual ~SoundFX() { if ( buffer ) delete buffer; }; 275 Initialize()276 virtual void Initialize() { }; 277 virtual void ProcessSample( float* in, float* out ) = 0; 278 SetChannel(int chan)279 void SetChannel( int chan ) { channel = chan; }; GetChannel()280 int GetChannel() { return channel; }; 281 SetContinuitySamples(float in1,float in2,float out1,float out2)282 void SetContinuitySamples( float in1, float in2, float out1, float out2 ) { continuitySamples[0] = in1; continuitySamples[1] = in2; continuitySamples[2] = out1; continuitySamples[3] = out2; }; // FIXME? GetContinuitySamples(float & in1,float & in2,float & out1,float & out2)283 void GetContinuitySamples( float& in1, float& in2, float& out1, float& out2 ) { in1 = continuitySamples[0]; in2 = continuitySamples[1]; out1 = continuitySamples[2]; out2 = continuitySamples[3]; }; 284 SetParameter(float val)285 void SetParameter( float val ) { param = val; }; 286 }; 287 288 class SoundFX_Lowpass : public SoundFX { 289 public: 290 virtual void ProcessSample( float* in, float* out ); 291 }; 292 293 class SoundFX_LowpassFast : public SoundFX { 294 float freq; 295 float res; 296 float a1, a2, a3; 297 float b1, b2; 298 299 public: 300 virtual void ProcessSample( float* in, float* out ); 301 void SetParms( float p1 = 0, float p2 = 0, float p3 = 0 ); 302 }; 303 304 class SoundFX_Comb : public SoundFX { 305 int currentTime; 306 307 public: 308 virtual void Initialize(); 309 virtual void ProcessSample( float* in, float* out ); 310 }; 311 312 class FracTime { 313 public: 314 int time; 315 float frac; 316 Set(int val)317 void Set( int val ) { time = val; frac = 0; }; Increment(float val)318 void Increment( float val ) { frac += val; while ( frac >= 1.f ) { time++; frac--; } }; 319 }; 320 321 enum { 322 PLAYBACK_RESET, 323 PLAYBACK_ADVANCING 324 }; 325 326 class idSoundChannel; 327 328 class idSlowChannel { 329 bool active; 330 const idSoundChannel* chan; 331 332 int playbackState; 333 int triggerOffset; 334 335 FracTime newPosition; 336 int newSampleOffset; 337 338 FracTime curPosition; 339 int curSampleOffset; 340 341 SoundFX_LowpassFast lowpass; 342 343 // functions 344 void GenerateSlowChannel( FracTime& playPos, int sampleCount44k, float* finalBuffer ); 345 346 float GetSlowmoSpeed(); 347 348 public: 349 350 void AttachSoundChannel( const idSoundChannel *chan ); 351 void Reset(); 352 353 void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ); 354 IsActive()355 bool IsActive() { return active; }; GetCurrentPosition()356 FracTime GetCurrentPosition() { return curPosition; }; 357 }; 358 359 class idSoundChannel { 360 public: 361 idSoundChannel( void ); 362 ~idSoundChannel( void ); 363 364 void Clear( void ); 365 void Start( void ); 366 void Stop( void ); 367 void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) const; 368 void ALStop( void ); // free OpenAL resources if any 369 370 bool triggerState; 371 int trigger44kHzTime; // hardware time sample the channel started 372 int triggerGame44kHzTime; // game time sample time the channel started 373 soundShaderParms_t parms; // combines the shader parms and the per-channel overrides 374 idSoundSample * leadinSample; // if not looped, this is the only sample 375 s_channelType triggerChannel; 376 const idSoundShader *soundShader; 377 idSampleDecoder * decoder; 378 float diversity; 379 float lastVolume; // last calculated volume based on distance 380 float lastV[6]; // last calculated volume for each speaker, so we can smoothly fade 381 idSoundFade channelFade; 382 bool triggered; 383 ALuint openalSource; 384 ALuint openalStreamingOffset; 385 ALuint openalStreamingBuffer[3]; 386 ALuint lastopenalStreamingBuffer[3]; 387 bool stopped; 388 389 bool disallowSlow; 390 391 }; 392 393 class idSoundEmitterLocal : public idSoundEmitter { 394 public: 395 396 idSoundEmitterLocal( void ); 397 virtual ~idSoundEmitterLocal( void ); 398 399 //---------------------------------------------- 400 401 // the "time" parameters should be game time in msec, which is used to make queries 402 // return deterministic values regardless of async buffer scheduling 403 404 // a non-immediate free will let all currently playing sounds complete 405 virtual void Free( bool immediate ); 406 407 // the parms specified will be the default overrides for all sounds started on this emitter. 408 // NULL is acceptable for parms 409 virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms ); 410 411 // returns the length of the started sound in msec 412 virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true /* D3XP */ ); 413 414 // can pass SCHANNEL_ANY 415 virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms ); 416 virtual void StopSound( const s_channelType channel ); 417 virtual void FadeSound( const s_channelType channel, float to, float over ); 418 419 virtual bool CurrentlyPlaying( void ) const; 420 421 // can pass SCHANNEL_ANY 422 virtual float CurrentAmplitude( void ); 423 424 // used for save games 425 virtual int Index( void ) const; 426 427 //---------------------------------------------- 428 429 void Clear( void ); 430 431 void OverrideParms( const soundShaderParms_t *base, const soundShaderParms_t *over, soundShaderParms_t *out ); 432 void CheckForCompletion( int current44kHzTime ); 433 void Spatialize( idVec3 listenerPos, int listenerArea, idRenderWorld *rw ); 434 435 idSoundWorldLocal * soundWorld; // the world that holds this emitter 436 437 int index; // in world emitter list 438 removeStatus_t removeStatus; 439 440 idVec3 origin; 441 int listenerId; 442 soundShaderParms_t parms; // default overrides for all channels 443 444 445 // the following are calculated in UpdateEmitter, and don't need to be archived 446 float maxDistance; // greatest of all playing channel distances 447 int lastValidPortalArea; // so an emitter that slides out of the world continues playing 448 bool playing; // if false, no channel is active 449 bool hasShakes; 450 idVec3 spatializedOrigin; // the virtual sound origin, either the real sound origin, 451 // or a point through a portal chain 452 float realDistance; // in meters 453 float distance; // in meters, this may be the straight-line distance, or 454 // it may go through a chain of portals. If there 455 // is not an open-portal path, distance will be > maxDistance 456 457 // a single soundEmitter can have many channels playing from the same point 458 idSoundChannel channels[SOUND_MAX_CHANNELS]; 459 460 idSlowChannel slowChannels[SOUND_MAX_CHANNELS]; 461 462 idSlowChannel GetSlowChannel( const idSoundChannel *chan ); 463 void SetSlowChannel( const idSoundChannel *chan, idSlowChannel slow ); 464 void ResetSlowChannel( const idSoundChannel *chan ); 465 466 // this is just used for feedback to the game or rendering system: 467 // flashing lights and screen shakes. Because the material expression 468 // evaluation doesn't do common subexpression removal, we cache the 469 // last generated value 470 int ampTime; 471 float amplitude; 472 }; 473 474 475 /* 476 =================================================================================== 477 478 idSoundWorldLocal 479 480 =================================================================================== 481 */ 482 483 class s_stats { 484 public: s_stats(void)485 s_stats( void ) { 486 rinuse = 0; 487 runs = 1; 488 timeinprocess = 0; 489 missedWindow = 0; 490 missedUpdateWindow = 0; 491 activeSounds = 0; 492 } 493 int rinuse; 494 int runs; 495 int timeinprocess; 496 int missedWindow; 497 int missedUpdateWindow; 498 int activeSounds; 499 }; 500 501 typedef struct soundPortalTrace_s { 502 int portalArea; 503 const struct soundPortalTrace_s *prevStack; 504 } soundPortalTrace_t; 505 506 class idSoundWorldLocal : public idSoundWorld { 507 public: 508 virtual ~idSoundWorldLocal( void ); 509 510 // call at each map start 511 virtual void ClearAllSoundEmitters( void ); 512 virtual void StopAllSounds( void ); 513 514 // get a new emitter that can play sounds in this world 515 virtual idSoundEmitter *AllocSoundEmitter( void ); 516 517 // for load games 518 virtual idSoundEmitter *EmitterForIndex( int index ); 519 520 // query data from all emitters in the world 521 virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listererPosition ); 522 523 // where is the camera/microphone 524 // listenerId allows listener-private sounds to be added 525 virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName ); 526 527 // fade all sounds in the world with a given shader soundClass 528 // to is in Db (sigh), over is in seconds 529 virtual void FadeSoundClasses( const int soundClass, const float to, const float over ); 530 531 // dumps the current state and begins archiving commands 532 virtual void StartWritingDemo( idDemoFile *demo ); 533 virtual void StopWritingDemo( void ); 534 535 // read a sound command from a demo file 536 virtual void ProcessDemoCommand( idDemoFile *readDemo ); 537 538 // background music 539 virtual void PlayShaderDirectly( const char *name, int channel = -1 ); 540 541 // pause and unpause the sound world 542 virtual void Pause( void ); 543 virtual void UnPause( void ); 544 virtual bool IsPaused( void ); 545 546 // avidump 547 virtual void AVIOpen( const char *path, const char *name ); 548 virtual void AVIClose( void ); 549 550 // SaveGame Support 551 virtual void WriteToSaveGame( idFile *savefile ); 552 virtual void ReadFromSaveGame( idFile *savefile ); 553 554 virtual void ReadFromSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ); 555 virtual void ReadFromSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ); 556 virtual void WriteToSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch ); 557 virtual void WriteToSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params ); 558 559 virtual void SetSlowmo( bool active ); 560 virtual void SetSlowmoSpeed( float speed ); 561 virtual void SetEnviroSuit( bool active ); 562 563 //======================================= 564 565 idSoundWorldLocal( void ); 566 567 void Shutdown( void ); 568 void Init( idRenderWorld *rw ); 569 570 // update 571 void ForegroundUpdate( int currentTime ); 572 void OffsetSoundTime( int offset44kHz ); 573 574 idSoundEmitterLocal * AllocLocalSoundEmitter(); 575 void CalcEars( int numSpeakers, idVec3 realOrigin, idVec3 listenerPos, idMat3 listenerAxis, float ears[6], float spatialize ); 576 void AddChannelContribution( idSoundEmitterLocal *sound, idSoundChannel *chan, 577 int current44kHz, int numSpeakers, float *finalMixBuffer ); 578 void MixLoop( int current44kHz, int numSpeakers, float *finalMixBuffer ); 579 void AVIUpdate( void ); 580 void ResolveOrigin( const int stackDepth, const soundPortalTrace_t *prevStack, const int soundArea, const float dist, const idVec3& soundOrigin, idSoundEmitterLocal *def ); 581 float FindAmplitude( idSoundEmitterLocal *sound, const int localTime, const idVec3 *listenerPosition, const s_channelType channel, bool shakesOnly ); 582 583 //============================================ 584 585 idRenderWorld * rw; // for portals and debug drawing 586 idDemoFile * writeDemo; // if not NULL, archive commands here 587 588 idMat3 listenerAxis; 589 idVec3 listenerPos; // position in meters 590 int listenerPrivateId; 591 idVec3 listenerQU; // position in "quake units" 592 int listenerArea; 593 idStr listenerAreaName; 594 ALuint listenerEffect; 595 ALuint listenerSlot; 596 bool listenerAreFiltersInitialized; 597 ALuint listenerFilters[2]; // 0 - direct; 1 - send. 598 599 int gameMsec; 600 int game44kHz; 601 int pause44kHz; 602 int lastAVI44kHz; // determine when we need to mix and write another block 603 604 idList<idSoundEmitterLocal *>emitters; 605 606 idSoundFade soundClassFade[SOUND_MAX_CLASSES]; // for global sound fading 607 608 // avi stuff 609 idFile * fpa[6]; 610 idStr aviDemoPath; 611 idStr aviDemoName; 612 613 idSoundEmitterLocal * localSound; // just for playShaderDirectly() 614 615 bool slowmoActive; 616 float slowmoSpeed; 617 bool enviroSuitActive; 618 }; 619 620 /* 621 =================================================================================== 622 623 idSoundSystemLocal 624 625 =================================================================================== 626 */ 627 628 typedef struct { 629 ALuint handle; 630 int startTime; 631 idSoundChannel *chan; 632 bool inUse; 633 bool looping; 634 bool stereo; 635 } openalSource_t; 636 637 class idSoundSystemLocal : public idSoundSystem { 638 public: idSoundSystemLocal()639 idSoundSystemLocal( ) { 640 isInitialized = false; 641 } 642 643 // all non-hardware initialization 644 virtual void Init( void ); 645 646 // shutdown routine 647 virtual void Shutdown( void ); 648 649 // sound is attached to the window, and must be recreated when the window is changed 650 virtual bool ShutdownHW( void ); 651 virtual bool InitHW( void ); 652 653 // async loop, called at 60Hz 654 virtual int AsyncUpdate( int time ); 655 // async loop, when the sound driver uses a write strategy 656 virtual int AsyncUpdateWrite( int time ); 657 // direct mixing called from the sound driver thread for OSes that support it 658 virtual int AsyncMix( int soundTime, float *mixBuffer ); 659 660 virtual void SetMute( bool mute ); 661 662 virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ); 663 664 int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo ); 665 666 // if rw == NULL, no portal occlusion or rendered debugging is available 667 virtual idSoundWorld *AllocSoundWorld( idRenderWorld *rw ); 668 669 // specifying NULL will cause silence to be played 670 virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld ); 671 672 // some tools, like the sound dialog, may be used in both the game and the editor 673 // This can return NULL, so check! 674 virtual idSoundWorld *GetPlayingSoundWorld( void ); 675 676 virtual void BeginLevelLoad( void ); 677 virtual void EndLevelLoad( const char *mapString ); 678 679 virtual void PrintMemInfo( MemInfo_t *mi ); 680 681 virtual int IsEFXAvailable( void ); 682 683 //------------------------- 684 685 int GetCurrent44kHzTime( void ) const; 686 float dB2Scale( const float val ) const; 687 int SamplesToMilliseconds( int samples ) const; 688 int MillisecondsToSamples( int ms ) const; 689 690 void DoEnviroSuit( float* samples, int numSamples, int numSpeakers ); 691 692 ALuint AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo ); 693 void FreeOpenALSource( ALuint handle ); 694 695 // returns true if openalDevice is still available, 696 // otherwise it will try to recover the device and return false while it's gone 697 // (display audio sound devices sometimes disappear for a few seconds when switching resolution) 698 bool CheckDeviceAndRecoverIfNeeded(); 699 700 idSoundCache * soundCache; 701 702 idSoundWorldLocal * currentSoundWorld; // the one to mix each async tic 703 704 int olddwCurrentWritePos; // statistics 705 int buffers; // statistics 706 int CurrentSoundTime; // set by the async thread and only used by the main thread 707 708 unsigned int nextWriteBlock; 709 710 float realAccum[6*MIXBUFFER_SAMPLES+16]; 711 float * finalMixBuffer; // points inside realAccum at a 16 byte aligned boundary 712 713 bool isInitialized; 714 bool muted; 715 bool shutdown; 716 717 s_stats soundStats; // NOTE: updated throughout the code, not displayed anywhere 718 719 int meterTops[256]; 720 int meterTopsTime[256]; 721 722 dword * graph; 723 724 float volumesDB[1200]; // dB to float volume conversion 725 726 idList<SoundFX*> fxList; 727 728 ALCdevice *openalDevice; 729 ALCcontext *openalContext; 730 ALsizei openalSourceCount; 731 openalSource_t openalSources[256]; 732 733 LPALGENEFFECTS alGenEffects; 734 LPALDELETEEFFECTS alDeleteEffects; 735 LPALISEFFECT alIsEffect; 736 LPALEFFECTI alEffecti; 737 LPALEFFECTF alEffectf; 738 LPALEFFECTFV alEffectfv; 739 LPALGENFILTERS alGenFilters; 740 LPALDELETEFILTERS alDeleteFilters; 741 LPALISFILTER alIsFilter; 742 LPALFILTERI alFilteri; 743 LPALFILTERF alFilterf; 744 LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; 745 LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; 746 LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; 747 LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; 748 749 idEFXFile EFXDatabase; 750 bool efxloaded; 751 // latches 752 static bool useEFXReverb; 753 // mark available during initialization, or through an explicit test 754 static int EFXAvailable; 755 756 // DG: for CheckDeviceAndRecoverIfNeeded() 757 LPALCRESETDEVICESOFT alcResetDeviceSOFT; // needs ALC_SOFT_HRTF extension 758 int resetRetryCount; 759 unsigned int lastCheckTime; 760 761 static idCVar s_noSound; 762 static idCVar s_device; 763 static idCVar s_quadraticFalloff; 764 static idCVar s_drawSounds; 765 static idCVar s_minVolume6; 766 static idCVar s_dotbias6; 767 static idCVar s_minVolume2; 768 static idCVar s_dotbias2; 769 static idCVar s_spatializationDecay; 770 static idCVar s_showStartSound; 771 static idCVar s_maxSoundsPerShader; 772 static idCVar s_reverse; 773 static idCVar s_showLevelMeter; 774 static idCVar s_meterTopTime; 775 static idCVar s_volume; 776 static idCVar s_constantAmplitude; 777 static idCVar s_playDefaultSound; 778 static idCVar s_useOcclusion; 779 static idCVar s_subFraction; 780 static idCVar s_globalFraction; 781 static idCVar s_doorDistanceAdd; 782 static idCVar s_singleEmitter; 783 static idCVar s_numberOfSpeakers; 784 static idCVar s_force22kHz; 785 static idCVar s_clipVolumes; 786 static idCVar s_realTimeDecoding; 787 static idCVar s_useEAXReverb; 788 static idCVar s_decompressionLimit; 789 790 static idCVar s_slowAttenuate; 791 792 static idCVar s_enviroSuitCutoffFreq; 793 static idCVar s_enviroSuitCutoffQ; 794 static idCVar s_enviroSuitSkipLowpass; 795 static idCVar s_enviroSuitSkipReverb; 796 797 static idCVar s_reverbTime; 798 static idCVar s_reverbFeedback; 799 static idCVar s_enviroSuitVolumeScale; 800 static idCVar s_skipHelltimeFX; 801 }; 802 803 extern idSoundSystemLocal soundSystemLocal; 804 805 806 /* 807 =================================================================================== 808 809 This class holds the actual wavefile bitmap, size, and info. 810 811 =================================================================================== 812 */ 813 814 const int SCACHE_SIZE = MIXBUFFER_SAMPLES*20; // 1/2 of a second (aroundabout) 815 816 class idSoundSample { 817 public: 818 idSoundSample(); 819 ~idSoundSample(); 820 821 idStr name; // name of the sample file 822 ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command 823 824 waveformatex_t objectInfo; // what are we caching 825 int objectSize; // size of waveform in samples, excludes the header 826 int objectMemSize; // object size in memory 827 byte * nonCacheData; // if it's not cached 828 byte * amplitudeData; // precomputed min,max amplitude pairs 829 ALuint openalBuffer; // openal buffer 830 bool hardwareBuffer; 831 bool defaultSound; 832 bool onDemand; 833 bool purged; 834 bool levelLoadReferenced; // so we can tell which samples aren't needed any more 835 836 int LengthIn44kHzSamples() const; 837 ID_TIME_T GetNewTimeStamp( void ) const; 838 void MakeDefault(); // turns it into a beep 839 void Load(); // loads the current sound based on name 840 void Reload( bool force ); // reloads if timestamp has changed, or always if force 841 void PurgeSoundSample(); // frees all data 842 void CheckForDownSample(); // down sample if required 843 bool FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO ); 844 }; 845 846 847 /* 848 =================================================================================== 849 850 Sound sample decoder. 851 852 =================================================================================== 853 */ 854 855 class idSampleDecoder { 856 public: 857 static void Init( void ); 858 static void Shutdown( void ); 859 static idSampleDecoder *Alloc( void ); 860 static void Free( idSampleDecoder *decoder ); 861 static int GetNumUsedBlocks( void ); 862 static int GetUsedBlockMemory( void ); 863 ~idSampleDecoder(void)864 virtual ~idSampleDecoder( void ) {} 865 virtual void Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) = 0; 866 virtual void ClearDecoder( void ) = 0; 867 virtual idSoundSample * GetSample( void ) const = 0; 868 virtual int GetLastDecodeTime( void ) const = 0; 869 }; 870 871 872 /* 873 =================================================================================== 874 875 The actual sound cache. 876 877 =================================================================================== 878 */ 879 880 class idSoundCache { 881 public: 882 idSoundCache(); 883 ~idSoundCache(); 884 885 idSoundSample * FindSound( const idStr &fname, bool loadOnDemandOnly ); 886 GetNumObjects(void)887 const int GetNumObjects( void ) { return listCache.Num(); } 888 const idSoundSample * GetObject( const int index ) const; 889 890 void ReloadSounds( bool force ); 891 892 void BeginLevelLoad(); 893 void EndLevelLoad(); 894 895 void PrintMemInfo( MemInfo_t *mi ); 896 897 private: 898 bool insideLevelLoad; 899 idList<idSoundSample*> listCache; 900 }; 901 902 #endif /* !__SND_LOCAL_H__ */ 903