doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
snd_cache.cpp
Go to the documentation of this file.
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 #include "../idlib/precompiled.h"
29 #pragma hdrstop
30 
31 #include "snd_local.h"
32 
33 #define USE_SOUND_CACHE_ALLOCATOR
34 
35 #ifdef USE_SOUND_CACHE_ALLOCATOR
36 static idDynamicBlockAlloc<byte, 1<<20, 1<<10> soundCacheAllocator;
37 #else
38 static idDynamicAlloc<byte, 1<<20, 1<<10> soundCacheAllocator;
39 #endif
40 
41 
42 /*
43 ===================
44 idSoundCache::idSoundCache()
45 ===================
46 */
48  soundCacheAllocator.Init();
49  soundCacheAllocator.SetLockMemory( true );
50  listCache.AssureSize( 1024, NULL );
52  insideLevelLoad = false;
53 }
54 
55 /*
56 ===================
57 idSoundCache::~idSoundCache()
58 ===================
59 */
61  listCache.DeleteContents( true );
62  soundCacheAllocator.Shutdown();
63 }
64 
65 /*
66 ===================
67 idSoundCache::::GetObject
68 
69 returns a single cached object pointer
70 ===================
71 */
72 const idSoundSample* idSoundCache::GetObject( const int index ) const {
74  return NULL;
75  }
76  return listCache[index];
77 }
78 
79 /*
80 ===================
81 idSoundCache::FindSound
82 
83 Adds a sound object to the cache and returns a handle for it.
84 ===================
85 */
86 idSoundSample *idSoundCache::FindSound( const idStr& filename, bool loadOnDemandOnly ) {
87  idStr fname;
88 
89  fname = filename;
90  fname.BackSlashesToSlashes();
91  fname.ToLower();
92 
93  declManager->MediaPrint( "%s\n", fname.c_str() );
94 
95  // check to see if object is already in cache
96  for( int i = 0; i < listCache.Num(); i++ ) {
97  idSoundSample *def = listCache[i];
98  if ( def && def->name == fname ) {
99  def->levelLoadReferenced = true;
100  if ( def->purged && !loadOnDemandOnly ) {
101  def->Load();
102  }
103  return def;
104  }
105  }
106 
107  // create a new entry
108  idSoundSample *def = new idSoundSample;
109 
110  int shandle = listCache.FindNull();
111  if ( shandle != -1 ) {
112  listCache[shandle] = def;
113  } else {
114  shandle = listCache.Append( def );
115  }
116 
117  def->name = fname;
118  def->levelLoadReferenced = true;
119  def->onDemand = loadOnDemandOnly;
120  def->purged = true;
121 
122  if ( !loadOnDemandOnly ) {
123  // this may make it a default sound if it can't be loaded
124  def->Load();
125  }
126 
127  return def;
128 }
129 
130 /*
131 ===================
132 idSoundCache::ReloadSounds
133 
134 Completely nukes the current cache
135 ===================
136 */
137 void idSoundCache::ReloadSounds( bool force ) {
138  int i;
139 
140  for( i = 0; i < listCache.Num(); i++ ) {
141  idSoundSample *def = listCache[i];
142  if ( def ) {
143  def->Reload( force );
144  }
145  }
146 }
147 
148 /*
149 ====================
150 BeginLevelLoad
151 
152 Mark all file based images as currently unused,
153 but don't free anything. Calls to ImageFromFile() will
154 either mark the image as used, or create a new image without
155 loading the actual data.
156 ====================
157 */
159  insideLevelLoad = true;
160 
161  for ( int i = 0 ; i < listCache.Num() ; i++ ) {
162  idSoundSample *sample = listCache[ i ];
163  if ( !sample ) {
164  continue;
165  }
166 
167  if ( com_purgeAll.GetBool() ) {
168  sample->PurgeSoundSample();
169  }
170 
171  sample->levelLoadReferenced = false;
172  }
173 
174  soundCacheAllocator.FreeEmptyBaseBlocks();
175 }
176 
177 /*
178 ====================
179 EndLevelLoad
180 
181 Free all samples marked as unused
182 ====================
183 */
185  int useCount, purgeCount;
186  common->Printf( "----- idSoundCache::EndLevelLoad -----\n" );
187 
188  insideLevelLoad = false;
189 
190  // purge the ones we don't need
191  useCount = 0;
192  purgeCount = 0;
193  for ( int i = 0 ; i < listCache.Num() ; i++ ) {
194  idSoundSample *sample = listCache[ i ];
195  if ( !sample ) {
196  continue;
197  }
198  if ( sample->purged ) {
199  continue;
200  }
201  if ( !sample->levelLoadReferenced ) {
202 // common->Printf( "Purging %s\n", sample->name.c_str() );
203  purgeCount += sample->objectMemSize;
204  sample->PurgeSoundSample();
205  } else {
206  useCount += sample->objectMemSize;
207  }
208  }
209 
210  soundCacheAllocator.FreeEmptyBaseBlocks();
211 
212  common->Printf( "%5ik referenced\n", useCount / 1024 );
213  common->Printf( "%5ik purged\n", purgeCount / 1024 );
214  common->Printf( "----------------------------------------\n" );
215 }
216 
217 /*
218 ===================
219 idSoundCache::PrintMemInfo
220 ===================
221 */
223  int i, j, num = 0, total = 0;
224  int *sortIndex;
225  idFile *f;
226 
227  f = fileSystem->OpenFileWrite( mi->filebase + "_sounds.txt" );
228  if ( !f ) {
229  return;
230  }
231 
232  // count
233  for ( i = 0; i < listCache.Num(); i++, num++ ) {
234  if ( !listCache[i] ) {
235  break;
236  }
237  }
238 
239  // sort first
240  sortIndex = new int[num];
241 
242  for ( i = 0; i < num; i++ ) {
243  sortIndex[i] = i;
244  }
245 
246  for ( i = 0; i < num - 1; i++ ) {
247  for ( j = i + 1; j < num; j++ ) {
248  if ( listCache[sortIndex[i]]->objectMemSize < listCache[sortIndex[j]]->objectMemSize ) {
249  int temp = sortIndex[i];
250  sortIndex[i] = sortIndex[j];
251  sortIndex[j] = temp;
252  }
253  }
254  }
255 
256  // print next
257  for ( i = 0; i < num; i++ ) {
258  idSoundSample *sample = listCache[sortIndex[i]];
259 
260  // this is strange
261  if ( !sample ) {
262  continue;
263  }
264 
265  total += sample->objectMemSize;
266  f->Printf( "%s %s\n", idStr::FormatNumber( sample->objectMemSize ).c_str(), sample->name.c_str() );
267  }
268 
269  mi->soundAssetsTotal = total;
270 
271  f->Printf( "\nTotal sound bytes allocated: %s\n", idStr::FormatNumber( total ).c_str() );
272  fileSystem->CloseFile( f );
273 }
274 
275 
276 /*
277 ==========================================================================
278 
279 idSoundSample
280 
281 ==========================================================================
282 */
283 
284 /*
285 ===================
286 idSoundSample::idSoundSample
287 ===================
288 */
290  memset( &objectInfo, 0, sizeof(waveformatex_t) );
291  objectSize = 0;
292  objectMemSize = 0;
293  nonCacheData = NULL;
295  openalBuffer = NULL;
296  hardwareBuffer = false;
297  defaultSound = false;
298  onDemand = false;
299  purged = false;
300  levelLoadReferenced = false;
301 }
302 
303 /*
304 ===================
305 idSoundSample::~idSoundSample
306 ===================
307 */
310 }
311 
312 /*
313 ===================
314 idSoundSample::LengthIn44kHzSamples
315 ===================
316 */
318  // objectSize is samples
319  if ( objectInfo.nSamplesPerSec == 11025 ) {
320  return objectSize << 2;
321  } else if ( objectInfo.nSamplesPerSec == 22050 ) {
322  return objectSize << 1;
323  } else {
324  return objectSize << 0;
325  }
326 }
327 
328 /*
329 ===================
330 idSoundSample::MakeDefault
331 ===================
332 */
334  int i;
335  float v;
336  int sample;
337 
338  memset( &objectInfo, 0, sizeof( objectInfo ) );
339 
340  objectInfo.nChannels = 1;
342  objectInfo.nSamplesPerSec = 44100;
343 
345  objectMemSize = objectSize * sizeof( short );
346 
347  nonCacheData = (byte *)soundCacheAllocator.Alloc( objectMemSize );
348 
349  short *ncd = (short *)nonCacheData;
350 
351  for ( i = 0; i < MIXBUFFER_SAMPLES; i ++ ) {
352  v = sin( idMath::PI * 2 * i / 64 );
353  sample = v * 0x4000;
354  ncd[i*2+0] = sample;
355  ncd[i*2+1] = sample;
356  }
357 
359  alGetError();
360  alGenBuffers( 1, &openalBuffer );
361  if ( alGetError() != AL_NO_ERROR ) {
362  common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
363  }
364 
365  alGetError();
367  if ( alGetError() != AL_NO_ERROR ) {
368  common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
369  } else {
370  hardwareBuffer = true;
371  }
372  }
373 
374  defaultSound = true;
375 }
376 
377 /*
378 ===================
379 idSoundSample::CheckForDownSample
380 ===================
381 */
383  if ( !idSoundSystemLocal::s_force22kHz.GetBool() ) {
384  return;
385  }
387  return;
388  }
389  int shortSamples = objectSize >> 1;
390  short *converted = (short *)soundCacheAllocator.Alloc( shortSamples * sizeof( short ) );
391 
392  if ( objectInfo.nChannels == 1 ) {
393  for ( int i = 0; i < shortSamples; i++ ) {
394  converted[i] = ((short *)nonCacheData)[i*2];
395  }
396  } else {
397  for ( int i = 0; i < shortSamples; i += 2 ) {
398  converted[i+0] = ((short *)nonCacheData)[i*2+0];
399  converted[i+1] = ((short *)nonCacheData)[i*2+1];
400  }
401  }
402  soundCacheAllocator.Free( nonCacheData );
403  nonCacheData = (byte *)converted;
404  objectSize >>= 1;
405  objectMemSize >>= 1;
408 }
409 
410 /*
411 ===================
412 idSoundSample::GetNewTimeStamp
413 ===================
414 */
415 ID_TIME_T idSoundSample::GetNewTimeStamp( void ) const {
416  ID_TIME_T timestamp;
417 
418  fileSystem->ReadFile( name, NULL, &timestamp );
419  if ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) {
420  idStr oggName = name;
421  oggName.SetFileExtension( ".ogg" );
422  fileSystem->ReadFile( oggName, NULL, &timestamp );
423  }
424  return timestamp;
425 }
426 
427 /*
428 ===================
429 idSoundSample::Load
430 
431 Loads based on name, possibly doing a MakeDefault if necessary
432 ===================
433 */
434 void idSoundSample::Load( void ) {
435  defaultSound = false;
436  purged = false;
437  hardwareBuffer = false;
438 
440 
441  if ( timestamp == FILE_NOT_FOUND_TIMESTAMP ) {
442  common->Warning( "Couldn't load sound '%s' using default", name.c_str() );
443  MakeDefault();
444  return;
445  }
446 
447  // load it
448  idWaveFile fh;
449  waveformatex_t info;
450 
451  if ( fh.Open( name, &info ) == -1 ) {
452  common->Warning( "Couldn't load sound '%s' using default", name.c_str() );
453  MakeDefault();
454  return;
455  }
456 
457  if ( info.nChannels != 1 && info.nChannels != 2 ) {
458  common->Warning( "idSoundSample: %s has %i channels, using default", name.c_str(), info.nChannels );
459  fh.Close();
460  MakeDefault();
461  return;
462  }
463 
464  if ( info.wBitsPerSample != 16 ) {
465  common->Warning( "idSoundSample: %s is %dbits, expected 16bits using default", name.c_str(), info.wBitsPerSample );
466  fh.Close();
467  MakeDefault();
468  return;
469  }
470 
471  if ( info.nSamplesPerSec != 44100 && info.nSamplesPerSec != 22050 && info.nSamplesPerSec != 11025 ) {
472  common->Warning( "idSoundCache: %s is %dHz, expected 11025, 22050 or 44100 Hz. Using default", name.c_str(), info.nSamplesPerSec );
473  fh.Close();
474  MakeDefault();
475  return;
476  }
477 
478  objectInfo = info;
479  objectSize = fh.GetOutputSize();
481 
482  nonCacheData = (byte *)soundCacheAllocator.Alloc( objectMemSize );
484 
485  // optionally convert it to 22kHz to save memory
487 
488  // create hardware audio buffers
490  // PCM loads directly
492  alGetError();
493  alGenBuffers( 1, &openalBuffer );
494  if ( alGetError() != AL_NO_ERROR )
495  common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
496  if ( alIsBuffer( openalBuffer ) ) {
497  alGetError();
499  if ( alGetError() != AL_NO_ERROR ) {
500  common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
501  } else {
502  // Compute amplitude block size
503  int blockSize = 512 * objectInfo.nSamplesPerSec / 44100 ;
504 
505  // Allocate amplitude data array
506  amplitudeData = (byte *)soundCacheAllocator.Alloc( ( objectSize / blockSize + 1 ) * 2 * sizeof( short) );
507 
508  // Creating array of min/max amplitude pairs per blockSize samples
509  int i;
510  for ( i = 0; i < objectSize; i+=blockSize ) {
511  short min = 32767;
512  short max = -32768;
513 
514  int j;
515  for ( j = 0; j < Min( objectSize - i, blockSize ); j++ ) {
516  min = ((short *)nonCacheData)[ i + j ] < min ? ((short *)nonCacheData)[ i + j ] : min;
517  max = ((short *)nonCacheData)[ i + j ] > max ? ((short *)nonCacheData)[ i + j ] : max;
518  }
519 
520  ((short *)amplitudeData)[ ( i / blockSize ) * 2 ] = min;
521  ((short *)amplitudeData)[ ( i / blockSize ) * 2 + 1 ] = max;
522  }
523 
524  hardwareBuffer = true;
525  }
526  }
527  }
528 
529  // OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default)
531 #if defined(MACOS_X)
533 #else
535 #endif
536  alGetError();
537  alGenBuffers( 1, &openalBuffer );
538  if ( alGetError() != AL_NO_ERROR )
539  common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
540  if ( alIsBuffer( openalBuffer ) ) {
542  float *destData = (float *)soundCacheAllocator.Alloc( ( LengthIn44kHzSamples() + 1 ) * sizeof( float ) );
543 
544  // Decoder *always* outputs 44 kHz data
545  decoder->Decode( this, 0, LengthIn44kHzSamples(), destData );
546 
547  // Downsample back to original frequency (save memory)
548  if ( objectInfo.nSamplesPerSec == 11025 ) {
549  for ( int i = 0; i < objectSize; i++ ) {
550  if ( destData[i*4] < -32768.0f )
551  ((short *)destData)[i] = -32768;
552  else if ( destData[i*4] > 32767.0f )
553  ((short *)destData)[i] = 32767;
554  else
555  ((short *)destData)[i] = idMath::FtoiFast( destData[i*4] );
556  }
557  } else if ( objectInfo.nSamplesPerSec == 22050 ) {
558  for ( int i = 0; i < objectSize; i++ ) {
559  if ( destData[i*2] < -32768.0f )
560  ((short *)destData)[i] = -32768;
561  else if ( destData[i*2] > 32767.0f )
562  ((short *)destData)[i] = 32767;
563  else
564  ((short *)destData)[i] = idMath::FtoiFast( destData[i*2] );
565  }
566  } else {
567  for ( int i = 0; i < objectSize; i++ ) {
568  if ( destData[i] < -32768.0f )
569  ((short *)destData)[i] = -32768;
570  else if ( destData[i] > 32767.0f )
571  ((short *)destData)[i] = 32767;
572  else
573  ((short *)destData)[i] = idMath::FtoiFast( destData[i] );
574  }
575  }
576 
577  alGetError();
579  if ( alGetError() != AL_NO_ERROR )
580  common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
581  else {
582  // Compute amplitude block size
583  int blockSize = 512 * objectInfo.nSamplesPerSec / 44100 ;
584 
585  // Allocate amplitude data array
586  amplitudeData = (byte *)soundCacheAllocator.Alloc( ( objectSize / blockSize + 1 ) * 2 * sizeof( short ) );
587 
588  // Creating array of min/max amplitude pairs per blockSize samples
589  int i;
590  for ( i = 0; i < objectSize; i+=blockSize ) {
591  short min = 32767;
592  short max = -32768;
593 
594  int j;
595  for ( j = 0; j < Min( objectSize - i, blockSize ); j++ ) {
596  min = ((short *)destData)[ i + j ] < min ? ((short *)destData)[ i + j ] : min;
597  max = ((short *)destData)[ i + j ] > max ? ((short *)destData)[ i + j ] : max;
598  }
599 
600  ((short *)amplitudeData)[ ( i / blockSize ) * 2 ] = min;
601  ((short *)amplitudeData)[ ( i / blockSize ) * 2 + 1 ] = max;
602  }
603 
604  hardwareBuffer = true;
605  }
606 
607  soundCacheAllocator.Free( (byte *)destData );
608  idSampleDecoder::Free( decoder );
609  }
610  }
611  }
612 
613  // Free memory if sample was loaded into hardware
614  if ( hardwareBuffer ) {
615  soundCacheAllocator.Free( nonCacheData );
616  nonCacheData = NULL;
617  }
618  }
619 
620  fh.Close();
621 }
622 
623 /*
624 ===================
625 idSoundSample::PurgeSoundSample
626 ===================
627 */
629  purged = true;
630 
632  alGetError();
634  if ( alGetError() != AL_NO_ERROR ) {
635  common->Error( "idSoundCache: error unloading data from OpenAL hardware buffer" );
636  } else {
637  openalBuffer = 0;
638  hardwareBuffer = false;
639  }
640  }
641 
642  if ( amplitudeData ) {
643  soundCacheAllocator.Free( amplitudeData );
645  }
646 
647  if ( nonCacheData ) {
648  soundCacheAllocator.Free( nonCacheData );
649  nonCacheData = NULL;
650  }
651 }
652 
653 /*
654 ===================
655 idSoundSample::Reload
656 ===================
657 */
658 void idSoundSample::Reload( bool force ) {
659  if ( !force ) {
660  ID_TIME_T newTimestamp;
661 
662  // check the timestamp
663  newTimestamp = GetNewTimeStamp();
664 
665  if ( newTimestamp == FILE_NOT_FOUND_TIMESTAMP ) {
666  if ( !defaultSound ) {
667  common->Warning( "Couldn't load sound '%s' using default", name.c_str() );
668  MakeDefault();
669  }
670  return;
671  }
672  if ( newTimestamp == timestamp ) {
673  return; // don't need to reload it
674  }
675  }
676 
677  common->Printf( "reloading %s\n", name.c_str() );
679  Load();
680 }
681 
682 /*
683 ===================
684 idSoundSample::FetchFromCache
685 
686 Returns true on success.
687 ===================
688 */
689 bool idSoundSample::FetchFromCache( int offset, const byte **output, int *position, int *size, const bool allowIO ) {
690  offset &= 0xfffffffe;
691 
692  if ( objectSize == 0 || offset < 0 || offset > objectSize * (int)sizeof( short ) || !nonCacheData ) {
693  return false;
694  }
695 
696  if ( output ) {
697  *output = nonCacheData + offset;
698  }
699  if ( position ) {
700  *position = 0;
701  }
702  if ( size ) {
703  *size = objectSize * sizeof( short ) - offset;
704  if ( *size > SCACHE_SIZE ) {
705  *size = SCACHE_SIZE;
706  }
707  }
708  return true;
709 }
int GetMemorySize(void)
Definition: snd_local.h:196
static idCVar s_force22kHz
Definition: snd_local.h:803
#define min(a, b)
static idSampleDecoder * Alloc(void)
idStr & SetFileExtension(const char *extension)
Definition: Str.cpp:743
word nChannels
Definition: snd_local.h:98
void ToLower(void)
Definition: Str.h:817
bool FetchFromCache(int offset, const byte **output, int *position, int *size, const bool allowIO)
Definition: snd_cache.cpp:689
const GLdouble * v
Definition: glext.h:2936
type * Alloc(const int num)
Definition: Heap.h:303
const int MIXBUFFER_SAMPLES
Definition: Simd.h:84
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
bool hardwareBuffer
Definition: snd_local.h:852
idCVar com_purgeAll("com_purgeAll","0", CVAR_BOOL|CVAR_ARCHIVE|CVAR_SYSTEM,"purge everything between level loads")
void AssureSize(int newSize)
Definition: List.h:445
static const float PI
Definition: Math.h:205
bool levelLoadReferenced
Definition: snd_local.h:856
#define alGenBuffers
Definition: idal.h:37
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
void SetGranularity(int newgranularity)
Definition: List.h:305
int objectMemSize
Definition: snd_local.h:848
void ReloadSounds(bool force)
Definition: snd_cache.cpp:137
void Init(void)
Definition: Heap.h:294
void EndLevelLoad()
Definition: snd_cache.cpp:184
#define AL_NO_ERROR
Errors: No Error.
Definition: altypes.h:265
idSoundSample * FindSound(const idStr &fname, bool loadOnDemandOnly)
Definition: snd_cache.cpp:86
static idCVar s_decompressionLimit
Definition: snd_local.h:810
int i
Definition: process.py:33
GLintptr offset
Definition: glext.h:3113
GLuint GLuint num
Definition: glext.h:5390
int Open(const char *strFileName, waveformatex_t *pwfx=NULL)
#define ID_ALCHAR
Definition: snd_local.h:46
void SetLockMemory(bool lock)
Definition: Heap.h:256
#define AL_FORMAT_STEREO16
Definition: altypes.h:241
idStr & BackSlashesToSlashes(void)
Definition: Str.cpp:727
idList< idSoundSample * > listCache
Definition: snd_local.h:921
#define AL_TRUE
Definition: altypes.h:75
Definition: File.h:50
int LengthIn44kHzSamples() const
Definition: snd_cache.cpp:317
void BeginLevelLoad()
Definition: snd_cache.cpp:158
void PrintMemInfo(MemInfo_t *mi)
Definition: snd_cache.cpp:222
GLuint index
Definition: glext.h:3476
static idStr FormatNumber(int number)
Definition: Str.cpp:1682
static int FtoiFast(float f)
Definition: Math.h:801
idCommon * common
Definition: Common.cpp:206
#define NULL
Definition: Lib.h:88
dword nSamplesPerSec
Definition: snd_local.h:99
int Close(void)
bool insideLevelLoad
Definition: snd_local.h:920
int GetInteger(void) const
Definition: CVarSystem.h:143
virtual idFile * OpenFileWrite(const char *relativePath, const char *basePath="fs_savepath")=0
static void Free(idSampleDecoder *decoder)
void MakeDefault()
Definition: snd_cache.cpp:333
void DeleteContents(bool clear)
Definition: List.h:207
int Read(byte *pBuffer, int dwSizeToRead, int *pdwSizeRead)
ALuint openalBuffer
Definition: snd_local.h:851
word wBitsPerSample
Definition: snd_local.h:102
virtual void Printf(const char *fmt,...) id_attribute((format(printf
idStr filebase
Definition: Common.h:94
const int SCACHE_SIZE
Definition: snd_local.h:836
void Reload(bool force)
Definition: snd_cache.cpp:658
#define alIsExtensionPresent
Definition: idal.h:49
void Free(type *ptr)
Definition: Heap.h:332
virtual void MediaPrint(const char *fmt,...) id_attribute((format(printf
idDeclManager * declManager
void Shutdown(void)
Definition: Heap.h:298
void FreeEmptyBaseBlocks(void)
Definition: Heap.h:257
bool defaultSound
Definition: snd_local.h:853
int soundAssetsTotal
Definition: Common.h:109
#define alDeleteBuffers
Definition: idal.h:48
int Append(const type &obj)
Definition: List.h:646
ID_TIME_T GetNewTimeStamp(void) const
Definition: snd_cache.cpp:415
bool GetBool(void) const
Definition: CVarSystem.h:142
tuple f
Definition: idal.py:89
int Num(void) const
Definition: List.h:265
int FindNull(void) const
Definition: List.h:804
unsigned char byte
Definition: Lib.h:75
const GLcharARB * name
Definition: glext.h:3629
GLsizeiptr size
Definition: glext.h:3112
const idSoundSample * GetObject(const int index) const
Definition: snd_cache.cpp:72
Definition: Str.h:116
static bool useOpenAL
Definition: snd_local.h:775
#define alGetError
Definition: idal.h:36
#define AL_FORMAT_MONO16
Definition: altypes.h:239
const char * c_str(void) const
Definition: Str.h:487
int GetOutputSize(void)
Definition: snd_local.h:195
dword nAvgBytesPerSec
Definition: snd_local.h:100
void PurgeSoundSample()
Definition: snd_cache.cpp:628
virtual void Decode(idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest)=0
void CheckForDownSample()
Definition: snd_cache.cpp:382
GLint j
Definition: qgl.h:264
#define alBufferData
Definition: idal.h:47
virtual void CloseFile(idFile *f)=0
waveformatex_t objectInfo
Definition: snd_local.h:846
#define max(x, y)
Definition: os.h:70
virtual void Error(const char *fmt,...) id_attribute((format(printf
ID_TIME_T timestamp
Definition: snd_local.h:844
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
ID_INLINE T Min(T x, T y)
Definition: Lib.h:159
byte * amplitudeData
Definition: snd_local.h:850
byte * nonCacheData
Definition: snd_local.h:849
virtual int Printf(const char *fmt,...) id_attribute((format(printf
Definition: File.cpp:260
#define alIsBuffer
Definition: idal.h:60
word wFormatTag
Definition: snd_local.h:97