2 ===========================================================================
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
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.
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.
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/>.
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.
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.
26 ===========================================================================
29 #ifndef __SND_LOCAL_H__
30 #define __SND_LOCAL_H__
32 // you need the OpenAL headers for build, even if AL is not enabled - http://www.openal.org/
33 #include "../openal/include/al.h"
34 #include "../openal/include/alc.h"
35 // !!! FIXME: #include "../openal/idal.h"
36 // broken OpenAL SDK ?
37 #define ID_ALCHAR (ALubyte *)
38 #include "../openal/include/efxlib.h"
40 // demo sound commands
42 SCMD_STATE, // followed by a load game state
54 const int SOUND_MAX_CHANNELS = 8;
55 const int SOUND_DECODER_FREE_DELAY = 1000 * MIXBUFFER_SAMPLES / USERCMD_MSEC; // four seconds
57 const int PRIMARYFREQ = 44100; // samples per second
58 const float SND_EPSILON = 1.0f / 32768.0f; // if volume is below this, it will always multiply to zero
60 const int ROOM_SLICES_IN_BUFFER = 10;
62 class idAudioHardware;
67 class idSampleDecoder;
68 class idSoundWorldLocal;
72 ===================================================================================
74 General extended waveform format structure.
75 Use this for all NON PCM formats.
77 ===================================================================================
84 #pragma pack (push, 1)
86 struct waveformatex_s {
87 word wFormatTag; /* format type */
88 word nChannels; /* number of channels (i.e. mono, stereo...) */
89 dword nSamplesPerSec; /* sample rate */
90 dword nAvgBytesPerSec; /* for buffer estimation */
91 word nBlockAlign; /* block size of data */
92 word wBitsPerSample; /* Number of bits per sample of mono data */
93 word cbSize; /* The count in bytes of the size of
94 extra information (after cbSize) */
97 typedef waveformatex_s waveformatex_t;
99 /* OLD general waveform format structure (information common to all formats) */
100 struct waveformat_s {
101 word wFormatTag; /* format type */
102 word nChannels; /* number of channels (i.e. mono, stereo, etc.) */
103 dword nSamplesPerSec; /* sample rate */
104 dword nAvgBytesPerSec; /* for buffer estimation */
105 word nBlockAlign; /* block size of data */
108 typedef waveformat_s waveformat_t;
110 /* flags for wFormatTag field of WAVEFORMAT */
112 WAVE_FORMAT_TAG_PCM = 1,
113 WAVE_FORMAT_TAG_OGG = 2
116 /* specific waveform format structure for PCM data */
117 struct pcmwaveformat_s {
122 typedef pcmwaveformat_s pcmwaveformat_t;
125 #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
126 ( (dword)(byte)(ch0) | ( (dword)(byte)(ch1) << 8 ) | \
127 ( (dword)(byte)(ch2) << 16 ) | ( (dword)(byte)(ch3) << 24 ) )
130 #define fourcc_riff mmioFOURCC('R', 'I', 'F', 'F')
132 struct waveformatextensible_s {
133 waveformatex_t Format;
135 word wValidBitsPerSample; /* bits of precision */
136 word wSamplesPerBlock; /* valid if wBitsPerSample==0*/
137 word wReserved; /* If neither applies, set to zero*/
139 dword dwChannelMask; /* which channels are */
140 /* present in stream */
144 typedef waveformatextensible_s waveformatextensible_t;
146 typedef dword fourcc;
148 /* RIFF chunk information data structure */
150 fourcc ckid; /* chunk ID */
151 dword cksize; /* chunk size */
152 fourcc fccType; /* form type or list type */
153 dword dwDataOffset; /* offset of data portion of chunk */
156 typedef mminfo_s mminfo_t;
166 ===================================================================================
170 ===================================================================================
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 );
183 int ResetFile( void );
185 int GetOutputSize( void ) { return mdwSize; }
186 int GetMemorySize( void ) { return mMemSize; }
188 waveformatextensible_t mpwfx; // Pointer to waveformatex structure
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
199 bool mbIsReadingFromMemory;
204 void * ogg; // only !NULL when !s_realTimeDecoding
208 int ReadMMIO( void );
210 int OpenOGG( const char* strFileName, waveformatex_t* pwfx = NULL );
211 int ReadOGG( byte* pBuffer, int dwSizeToRead, int *pdwSizeRead );
212 int CloseOGG( void );
217 ===================================================================================
221 ===================================================================================
224 class idAudioHardware {
226 static idAudioHardware *Alloc();
228 virtual ~idAudioHardware();
230 virtual bool Initialize( ) = 0;
232 virtual bool Lock( void **pDSLockedBuffer, ulong *dwDSLockedBufferSize ) = 0;
233 virtual bool Unlock( void *pDSLockedBuffer, dword dwDSLockedBufferSize ) = 0;
234 virtual bool GetCurrentPosition( ulong *pdwCurrentWriteCursor ) = 0;
236 // try to write as many sound samples to the device as possible without blocking and prepare for a possible new mixing call
237 // returns wether there is *some* space for writing available
238 virtual bool Flush( void ) = 0;
240 virtual void Write( bool flushing ) = 0;
242 virtual int GetNumberOfSpeakers( void )= 0;
243 virtual int GetMixBufferSize( void ) = 0;
244 virtual short* GetMixBuffer( void ) = 0;
249 ===================================================================================
251 Encapsulates functionality of a DirectSound buffer.
253 ===================================================================================
256 class idAudioBuffer {
258 virtual int Play( dword dwPriority=0, dword dwFlags=0 ) = 0;
259 virtual int Stop( void ) = 0;
260 virtual int Reset( void ) = 0;
261 virtual bool IsSoundPlaying( void ) = 0;
262 virtual void SetVolume( float x ) = 0;
267 ===================================================================================
271 ===================================================================================
275 REMOVE_STATUS_INVALID = -1,
276 REMOVE_STATUS_ALIVE = 0,
277 REMOVE_STATUS_WAITSAMPLEFINISHED = 1,
278 REMOVE_STATUS_SAMPLEFINISHED = 2
285 float fadeStartVolume; // in dB
286 float fadeEndVolume; // in dB
289 float FadeDbAt44kHz( int current44kHz );
300 float continuitySamples[4];
305 SoundFX() { channel = 0; buffer = NULL; initialized = false; maxlen = 0; memset( continuitySamples, 0, sizeof( float ) * 4 ); };
306 virtual ~SoundFX() { if ( buffer ) delete buffer; };
308 virtual void Initialize() { };
309 virtual void ProcessSample( float* in, float* out ) = 0;
311 void SetChannel( int chan ) { channel = chan; };
312 int GetChannel() { return channel; };
314 void SetContinuitySamples( float in1, float in2, float out1, float out2 ) { continuitySamples[0] = in1; continuitySamples[1] = in2; continuitySamples[2] = out1; continuitySamples[3] = out2; }; // FIXME?
315 void GetContinuitySamples( float& in1, float& in2, float& out1, float& out2 ) { in1 = continuitySamples[0]; in2 = continuitySamples[1]; out1 = continuitySamples[2]; out2 = continuitySamples[3]; };
317 void SetParameter( float val ) { param = val; };
320 class SoundFX_Lowpass : public SoundFX {
322 virtual void ProcessSample( float* in, float* out );
325 class SoundFX_LowpassFast : public SoundFX {
332 virtual void ProcessSample( float* in, float* out );
333 void SetParms( float p1 = 0, float p2 = 0, float p3 = 0 );
336 class SoundFX_Comb : public SoundFX {
340 virtual void Initialize();
341 virtual void ProcessSample( float* in, float* out );
349 void Set( int val ) { time = val; frac = 0; };
350 void Increment( float val ) { frac += val; while ( frac >= 1.f ) { time++; frac--; } };
358 class idSoundChannel;
360 class idSlowChannel {
362 const idSoundChannel* chan;
367 FracTime newPosition;
370 FracTime curPosition;
373 SoundFX_LowpassFast lowpass;
376 void GenerateSlowChannel( FracTime& playPos, int sampleCount44k, float* finalBuffer );
378 float GetSlowmoSpeed();
382 void AttachSoundChannel( const idSoundChannel *chan );
385 void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest );
387 bool IsActive() { return active; };
388 FracTime GetCurrentPosition() { return curPosition; };
391 class idSoundChannel {
393 idSoundChannel( void );
394 ~idSoundChannel( void );
399 void GatherChannelSamples( int sampleOffset44k, int sampleCount44k, float *dest ) const;
400 void ALStop( void ); // free OpenAL resources if any
403 int trigger44kHzTime; // hardware time sample the channel started
404 int triggerGame44kHzTime; // game time sample time the channel started
405 soundShaderParms_t parms; // combines the shader parms and the per-channel overrides
406 idSoundSample * leadinSample; // if not looped, this is the only sample
407 s_channelType triggerChannel;
408 const idSoundShader *soundShader;
409 idSampleDecoder * decoder;
411 float lastVolume; // last calculated volume based on distance
412 float lastV[6]; // last calculated volume for each speaker, so we can smoothly fade
413 idSoundFade channelFade;
416 ALuint openalStreamingOffset;
417 ALuint openalStreamingBuffer[3];
418 ALuint lastopenalStreamingBuffer[3];
424 class idSoundEmitterLocal : public idSoundEmitter {
427 idSoundEmitterLocal( void );
428 virtual ~idSoundEmitterLocal( void );
430 //----------------------------------------------
432 // the "time" parameters should be game time in msec, which is used to make queries
433 // return deterministic values regardless of async buffer scheduling
435 // a non-immediate free will let all currently playing sounds complete
436 virtual void Free( bool immediate );
438 // the parms specified will be the default overrides for all sounds started on this emitter.
439 // NULL is acceptable for parms
440 virtual void UpdateEmitter( const idVec3 &origin, int listenerId, const soundShaderParms_t *parms );
442 // returns the length of the started sound in msec
443 virtual int StartSound( const idSoundShader *shader, const s_channelType channel, float diversity = 0, int shaderFlags = 0, bool allowSlow = true /* D3XP */ );
445 // can pass SCHANNEL_ANY
446 virtual void ModifySound( const s_channelType channel, const soundShaderParms_t *parms );
447 virtual void StopSound( const s_channelType channel );
448 virtual void FadeSound( const s_channelType channel, float to, float over );
450 virtual bool CurrentlyPlaying( void ) const;
452 // can pass SCHANNEL_ANY
453 virtual float CurrentAmplitude( void );
455 // used for save games
456 virtual int Index( void ) const;
458 //----------------------------------------------
462 void OverrideParms( const soundShaderParms_t *base, const soundShaderParms_t *over, soundShaderParms_t *out );
463 void CheckForCompletion( int current44kHzTime );
464 void Spatialize( idVec3 listenerPos, int listenerArea, idRenderWorld *rw );
466 idSoundWorldLocal * soundWorld; // the world that holds this emitter
468 int index; // in world emitter list
469 removeStatus_t removeStatus;
473 soundShaderParms_t parms; // default overrides for all channels
476 // the following are calculated in UpdateEmitter, and don't need to be archived
477 float maxDistance; // greatest of all playing channel distances
478 int lastValidPortalArea; // so an emitter that slides out of the world continues playing
479 bool playing; // if false, no channel is active
481 idVec3 spatializedOrigin; // the virtual sound origin, either the real sound origin,
482 // or a point through a portal chain
483 float realDistance; // in meters
484 float distance; // in meters, this may be the straight-line distance, or
485 // it may go through a chain of portals. If there
486 // is not an open-portal path, distance will be > maxDistance
488 // a single soundEmitter can have many channels playing from the same point
489 idSoundChannel channels[SOUND_MAX_CHANNELS];
491 idSlowChannel slowChannels[SOUND_MAX_CHANNELS];
493 idSlowChannel GetSlowChannel( const idSoundChannel *chan );
494 void SetSlowChannel( const idSoundChannel *chan, idSlowChannel slow );
495 void ResetSlowChannel( const idSoundChannel *chan );
497 // this is just used for feedback to the game or rendering system:
498 // flashing lights and screen shakes. Because the material expression
499 // evaluation doesn't do common subexpression removal, we cache the
500 // last generated value
507 ===================================================================================
511 ===================================================================================
521 missedUpdateWindow = 0;
528 int missedUpdateWindow;
532 typedef struct soundPortalTrace_s {
534 const struct soundPortalTrace_s *prevStack;
535 } soundPortalTrace_t;
537 class idSoundWorldLocal : public idSoundWorld {
539 virtual ~idSoundWorldLocal( void );
541 // call at each map start
542 virtual void ClearAllSoundEmitters( void );
543 virtual void StopAllSounds( void );
545 // get a new emitter that can play sounds in this world
546 virtual idSoundEmitter *AllocSoundEmitter( void );
549 virtual idSoundEmitter *EmitterForIndex( int index );
551 // query data from all emitters in the world
552 virtual float CurrentShakeAmplitudeForPosition( const int time, const idVec3 &listererPosition );
554 // where is the camera/microphone
555 // listenerId allows listener-private sounds to be added
556 virtual void PlaceListener( const idVec3 &origin, const idMat3 &axis, const int listenerId, const int gameTime, const idStr& areaName );
558 // fade all sounds in the world with a given shader soundClass
559 // to is in Db (sigh), over is in seconds
560 virtual void FadeSoundClasses( const int soundClass, const float to, const float over );
562 // dumps the current state and begins archiving commands
563 virtual void StartWritingDemo( idDemoFile *demo );
564 virtual void StopWritingDemo( void );
566 // read a sound command from a demo file
567 virtual void ProcessDemoCommand( idDemoFile *readDemo );
570 virtual void PlayShaderDirectly( const char *name, int channel = -1 );
572 // pause and unpause the sound world
573 virtual void Pause( void );
574 virtual void UnPause( void );
575 virtual bool IsPaused( void );
578 virtual void AVIOpen( const char *path, const char *name );
579 virtual void AVIClose( void );
582 virtual void WriteToSaveGame( idFile *savefile );
583 virtual void ReadFromSaveGame( idFile *savefile );
585 virtual void ReadFromSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch );
586 virtual void ReadFromSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params );
587 virtual void WriteToSaveGameSoundChannel( idFile *saveGame, idSoundChannel *ch );
588 virtual void WriteToSaveGameSoundShaderParams( idFile *saveGame, soundShaderParms_t *params );
590 virtual void SetSlowmo( bool active );
591 virtual void SetSlowmoSpeed( float speed );
592 virtual void SetEnviroSuit( bool active );
594 //=======================================
596 idSoundWorldLocal( void );
598 void Shutdown( void );
599 void Init( idRenderWorld *rw );
600 void ClearBuffer( void );
603 void ForegroundUpdate( int currentTime );
604 void OffsetSoundTime( int offset44kHz );
606 idSoundEmitterLocal * AllocLocalSoundEmitter();
607 void CalcEars( int numSpeakers, idVec3 realOrigin, idVec3 listenerPos, idMat3 listenerAxis, float ears[6], float spatialize );
608 void AddChannelContribution( idSoundEmitterLocal *sound, idSoundChannel *chan,
609 int current44kHz, int numSpeakers, float *finalMixBuffer );
610 void MixLoop( int current44kHz, int numSpeakers, float *finalMixBuffer );
611 void AVIUpdate( void );
612 void ResolveOrigin( const int stackDepth, const soundPortalTrace_t *prevStack, const int soundArea, const float dist, const idVec3& soundOrigin, idSoundEmitterLocal *def );
613 float FindAmplitude( idSoundEmitterLocal *sound, const int localTime, const idVec3 *listenerPosition, const s_channelType channel, bool shakesOnly );
615 //============================================
617 idRenderWorld * rw; // for portals and debug drawing
618 idDemoFile * writeDemo; // if not NULL, archive commands here
621 idVec3 listenerPos; // position in meters
622 int listenerPrivateId;
623 idVec3 listenerQU; // position in "quake units"
625 idStr listenerAreaName;
626 int listenerEnvironmentID;
631 int lastAVI44kHz; // determine when we need to mix and write another block
633 idList<idSoundEmitterLocal *>emitters;
635 idSoundFade soundClassFade[SOUND_MAX_CLASSES]; // for global sound fading
642 idSoundEmitterLocal * localSound; // just for playShaderDirectly()
646 bool enviroSuitActive;
650 ===================================================================================
654 ===================================================================================
660 idSoundChannel *chan;
666 class idSoundSystemLocal : public idSoundSystem {
668 idSoundSystemLocal( ) {
669 isInitialized = false;
672 // all non-hardware initialization
673 virtual void Init( void );
676 virtual void Shutdown( void );
677 virtual void ClearBuffer( void );
679 // sound is attached to the window, and must be recreated when the window is changed
680 virtual bool ShutdownHW( void );
681 virtual bool InitHW( void );
683 // async loop, called at 60Hz
684 virtual int AsyncUpdate( int time );
685 // async loop, when the sound driver uses a write strategy
686 virtual int AsyncUpdateWrite( int time );
687 // direct mixing called from the sound driver thread for OSes that support it
688 virtual int AsyncMix( int soundTime, float *mixBuffer );
690 virtual void SetMute( bool mute );
692 virtual cinData_t ImageForTime( const int milliseconds, const bool waveform );
694 int GetSoundDecoderInfo( int index, soundDecoderInfo_t &decoderInfo );
696 // if rw == NULL, no portal occlusion or rendered debugging is available
697 virtual idSoundWorld *AllocSoundWorld( idRenderWorld *rw );
699 // specifying NULL will cause silence to be played
700 virtual void SetPlayingSoundWorld( idSoundWorld *soundWorld );
702 // some tools, like the sound dialog, may be used in both the game and the editor
703 // This can return NULL, so check!
704 virtual idSoundWorld *GetPlayingSoundWorld( void );
706 virtual void BeginLevelLoad( void );
707 virtual void EndLevelLoad( const char *mapString );
709 virtual void PrintMemInfo( MemInfo_t *mi );
711 virtual int IsEAXAvailable( void );
713 //-------------------------
715 int GetCurrent44kHzTime( void ) const;
716 float dB2Scale( const float val ) const;
717 int SamplesToMilliseconds( int samples ) const;
718 int MillisecondsToSamples( int ms ) const;
720 void DoEnviroSuit( float* samples, int numSamples, int numSpeakers );
722 ALuint AllocOpenALSource( idSoundChannel *chan, bool looping, bool stereo );
723 void FreeOpenALSource( ALuint handle );
725 idAudioHardware * snd_audio_hw;
726 idSoundCache * soundCache;
728 idSoundWorldLocal * currentSoundWorld; // the one to mix each async tic
730 int olddwCurrentWritePos; // statistics
731 int buffers; // statistics
732 int CurrentSoundTime; // set by the async thread and only used by the main thread
734 unsigned int nextWriteBlock;
736 float realAccum[6*MIXBUFFER_SAMPLES+16];
737 float * finalMixBuffer; // points inside realAccum at a 16 byte aligned boundary
743 s_stats soundStats; // NOTE: updated throughout the code, not displayed anywhere
746 int meterTopsTime[256];
750 float volumesDB[1200]; // dB to float volume conversion
752 idList<SoundFX*> fxList;
754 ALCdevice *openalDevice;
755 ALCcontext *openalContext;
756 ALsizei openalSourceCount;
757 openalSource_t openalSources[256];
760 EAXSetBufferMode alEAXSetBufferMode;
761 EAXGetBufferMode alEAXGetBufferMode;
762 idEFXFile EFXDatabase;
765 static bool useOpenAL;
766 static bool useEAXReverb;
767 // mark available during initialization, or through an explicit test
768 static int EAXAvailable;
771 static idCVar s_noSound;
772 static idCVar s_quadraticFalloff;
773 static idCVar s_drawSounds;
774 static idCVar s_minVolume6;
775 static idCVar s_dotbias6;
776 static idCVar s_minVolume2;
777 static idCVar s_dotbias2;
778 static idCVar s_spatializationDecay;
779 static idCVar s_showStartSound;
780 static idCVar s_maxSoundsPerShader;
781 static idCVar s_reverse;
782 static idCVar s_showLevelMeter;
783 static idCVar s_meterTopTime;
784 static idCVar s_volume;
785 static idCVar s_constantAmplitude;
786 static idCVar s_playDefaultSound;
787 static idCVar s_useOcclusion;
788 static idCVar s_subFraction;
789 static idCVar s_globalFraction;
790 static idCVar s_doorDistanceAdd;
791 static idCVar s_singleEmitter;
792 static idCVar s_numberOfSpeakers;
793 static idCVar s_force22kHz;
794 static idCVar s_clipVolumes;
795 static idCVar s_realTimeDecoding;
796 static idCVar s_libOpenAL;
797 static idCVar s_useOpenAL;
798 static idCVar s_useEAXReverb;
799 static idCVar s_muteEAXReverb;
800 static idCVar s_decompressionLimit;
802 static idCVar s_slowAttenuate;
804 static idCVar s_enviroSuitCutoffFreq;
805 static idCVar s_enviroSuitCutoffQ;
806 static idCVar s_enviroSuitSkipLowpass;
807 static idCVar s_enviroSuitSkipReverb;
809 static idCVar s_reverbTime;
810 static idCVar s_reverbFeedback;
811 static idCVar s_enviroSuitVolumeScale;
812 static idCVar s_skipHelltimeFX;
815 extern idSoundSystemLocal soundSystemLocal;
819 ===================================================================================
821 This class holds the actual wavefile bitmap, size, and info.
823 ===================================================================================
826 const int SCACHE_SIZE = MIXBUFFER_SAMPLES*20; // 1/2 of a second (aroundabout)
828 class idSoundSample {
833 idStr name; // name of the sample file
834 ID_TIME_T timestamp; // the most recent of all images used in creation, for reloadImages command
836 waveformatex_t objectInfo; // what are we caching
837 int objectSize; // size of waveform in samples, excludes the header
838 int objectMemSize; // object size in memory
839 byte * nonCacheData; // if it's not cached
840 byte * amplitudeData; // precomputed min,max amplitude pairs
841 ALuint openalBuffer; // openal buffer
846 bool levelLoadReferenced; // so we can tell which samples aren't needed any more
848 int LengthIn44kHzSamples() const;
849 ID_TIME_T GetNewTimeStamp( void ) const;
850 void MakeDefault(); // turns it into a beep
851 void Load(); // loads the current sound based on name
852 void Reload( bool force ); // reloads if timestamp has changed, or always if force
853 void PurgeSoundSample(); // frees all data
854 void CheckForDownSample(); // down sample if required
855 bool FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO );
860 ===================================================================================
862 Sound sample decoder.
864 ===================================================================================
867 class idSampleDecoder {
869 static void Init( void );
870 static void Shutdown( void );
871 static idSampleDecoder *Alloc( void );
872 static void Free( idSampleDecoder *decoder );
873 static int GetNumUsedBlocks( void );
874 static int GetUsedBlockMemory( void );
876 virtual ~idSampleDecoder( void ) {}
877 virtual void Decode( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) = 0;
878 virtual void ClearDecoder( void ) = 0;
879 virtual idSoundSample * GetSample( void ) const = 0;
880 virtual int GetLastDecodeTime( void ) const = 0;
885 ===================================================================================
887 The actual sound cache.
889 ===================================================================================
897 idSoundSample * FindSound( const idStr &fname, bool loadOnDemandOnly );
899 const int GetNumObjects( void ) { return listCache.Num(); }
900 const idSoundSample * GetObject( const int index ) const;
902 void ReloadSounds( bool force );
904 void BeginLevelLoad();
907 void PrintMemInfo( MemInfo_t *mi );
910 bool insideLevelLoad;
911 idList<idSoundSample*> listCache;
914 #endif /* !__SND_LOCAL_H__ */