Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

snd_mem.c File Reference

#include "snd_local.h"

Include dependency graph for snd_mem.c:

Include dependency graph

Go to the source code of this file.

Defines

#define DEF_COMSOUNDMEGS   "8"

Functions

void FindChunk (char *name)
void FindNextChunk (char *name)
int GetLittleLong (void)
short GetLittleShort (void)
wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data, qboolean compressed)
int ResampleSfxRaw (short *sfx, int inrate, int inwidth, int samples, byte *data)
void S_DisplayFreeMemory ()
qboolean S_LoadSound (sfx_t *sfx)
void SND_free (sndBuffer *v)
sndBufferSND_malloc ()
void SND_setup ()

Variables

sndBufferbuffer = NULL
bytedata_p
sndBufferfreelist = NULL
int iff_chunk_len
byteiff_data
byteiff_end
int inUse = 0
bytelast_chunk
short * sfxScratchBuffer = NULL
int sfxScratchIndex = 0
sfx_tsfxScratchPointer = NULL
int totalInUse = 0


Define Documentation

#define DEF_COMSOUNDMEGS   "8"
 

Definition at line 34 of file snd_mem.c.

Referenced by SND_setup().


Function Documentation

void FindChunk char *  name  )  [static]
 

Definition at line 162 of file snd_mem.c.

References FindNextChunk(), last_chunk, and name.

Referenced by GetWavinfo().

00163 {
00164     last_chunk = iff_data;
00165     FindNextChunk (name);
00166 }

Here is the call graph for this function:

void FindNextChunk char *  name  )  [static]
 

Definition at line 136 of file snd_mem.c.

References data_p, GetLittleLong(), iff_chunk_len, last_chunk, name, and strncmp().

Referenced by FindChunk().

00137 {
00138     while (1)
00139     {
00140         data_p=last_chunk;
00141 
00142         if (data_p >= iff_end)
00143         {   // didn't find the chunk
00144             data_p = NULL;
00145             return;
00146         }
00147         
00148         data_p += 4;
00149         iff_chunk_len = GetLittleLong();
00150         if (iff_chunk_len < 0)
00151         {
00152             data_p = NULL;
00153             return;
00154         }
00155         data_p -= 8;
00156         last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
00157         if (!strncmp((char *)data_p, name, 4))
00158             return;
00159     }
00160 }

Here is the call graph for this function:

int GetLittleLong void   )  [static]
 

Definition at line 125 of file snd_mem.c.

References data_p.

Referenced by FindNextChunk(), and GetWavinfo().

00126 {
00127     int val = 0;
00128     val = *data_p;
00129     val = val + (*(data_p+1)<<8);
00130     val = val + (*(data_p+2)<<16);
00131     val = val + (*(data_p+3)<<24);
00132     data_p += 4;
00133     return val;
00134 }

short GetLittleShort void   )  [static]
 

Definition at line 116 of file snd_mem.c.

References data_p.

Referenced by GetWavinfo().

00117 {
00118     short val = 0;
00119     val = *data_p;
00120     val = val + (*(data_p+1)<<8);
00121     data_p += 2;
00122     return val;
00123 }

wavinfo_t GetWavinfo char *  name,
byte wav,
int  wavlength
[static]
 

Definition at line 173 of file snd_mem.c.

References byte, wavinfo_t::channels, Com_Memset(), Com_Printf(), data_p, wavinfo_t::dataofs, FindChunk(), wavinfo_t::format, GetLittleLong(), GetLittleShort(), iff_data, iff_end, wavinfo_t::rate, wavinfo_t::samples, strncmp(), and wavinfo_t::width.

Referenced by S_LoadSound().

00174 {
00175     wavinfo_t   info;
00176 
00177     Com_Memset (&info, 0, sizeof(info));
00178 
00179     if (!wav)
00180         return info;
00181         
00182     iff_data = wav;
00183     iff_end = wav + wavlength;
00184 
00185 // find "RIFF" chunk
00186     FindChunk("RIFF");
00187     if (!(data_p && !strncmp((char *)data_p+8, "WAVE", 4)))
00188     {
00189         Com_Printf("Missing RIFF/WAVE chunks\n");
00190         return info;
00191     }
00192 
00193 // get "fmt " chunk
00194     iff_data = data_p + 12;
00195 // DumpChunks ();
00196 
00197     FindChunk("fmt ");
00198     if (!data_p)
00199     {
00200         Com_Printf("Missing fmt chunk\n");
00201         return info;
00202     }
00203     data_p += 8;
00204     info.format = GetLittleShort();
00205     info.channels = GetLittleShort();
00206     info.rate = GetLittleLong();
00207     data_p += 4+2;
00208     info.width = GetLittleShort() / 8;
00209 
00210     if (info.format != 1)
00211     {
00212         Com_Printf("Microsoft PCM format only\n");
00213         return info;
00214     }
00215 
00216 
00217 // find data chunk
00218     FindChunk("data");
00219     if (!data_p)
00220     {
00221         Com_Printf("Missing data chunk\n");
00222         return info;
00223     }
00224 
00225     data_p += 4;
00226     info.samples = GetLittleLong () / info.width;
00227     info.dataofs = data_p - wav;
00228 
00229     return info;
00230 }

Here is the call graph for this function:

void ResampleSfx sfx_t sfx,
int  inrate,
int  inwidth,
byte data,
qboolean  compressed
[static]
 

Definition at line 240 of file snd_mem.c.

References byte, data, dma, i, LittleShort(), sndBuffer_s::next, sfx_t, SND_CHUNK_SIZE, SND_malloc(), sndBuffer, sndBuffer_s::sndChunk, sfx_s::soundData, sfx_s::soundLength, and dma_t::speed.

Referenced by S_LoadSound().

00240                                                                                                 {
00241     int     outcount;
00242     int     srcsample;
00243     float   stepscale;
00244     int     i;
00245     int     sample, samplefrac, fracstep;
00246     int         part;
00247     sndBuffer   *chunk;
00248     
00249     stepscale = (float)inrate / dma.speed;  // this is usually 0.5, 1, or 2
00250 
00251     outcount = sfx->soundLength / stepscale;
00252     sfx->soundLength = outcount;
00253 
00254     samplefrac = 0;
00255     fracstep = stepscale * 256;
00256     chunk = sfx->soundData;
00257 
00258     for (i=0 ; i<outcount ; i++)
00259     {
00260         srcsample = samplefrac >> 8;
00261         samplefrac += fracstep;
00262         if( inwidth == 2 ) {
00263             sample = LittleShort ( ((short *)data)[srcsample] );
00264         } else {
00265             sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
00266         }
00267         part  = (i&(SND_CHUNK_SIZE-1));
00268         if (part == 0) {
00269             sndBuffer   *newchunk;
00270             newchunk = SND_malloc();
00271             if (chunk == NULL) {
00272                 sfx->soundData = newchunk;
00273             } else {
00274                 chunk->next = newchunk;
00275             }
00276             chunk = newchunk;
00277         }
00278 
00279         chunk->sndChunk[part] = sample;
00280     }
00281 }

Here is the call graph for this function:

int ResampleSfxRaw short *  sfx,
int  inrate,
int  inwidth,
int  samples,
byte data
[static]
 

Definition at line 290 of file snd_mem.c.

References byte, data, dma, i, LittleShort(), and dma_t::speed.

Referenced by S_LoadSound().

00290                                                                                           {
00291     int         outcount;
00292     int         srcsample;
00293     float       stepscale;
00294     int         i;
00295     int         sample, samplefrac, fracstep;
00296     
00297     stepscale = (float)inrate / dma.speed;  // this is usually 0.5, 1, or 2
00298 
00299     outcount = samples / stepscale;
00300 
00301     samplefrac = 0;
00302     fracstep = stepscale * 256;
00303 
00304     for (i=0 ; i<outcount ; i++)
00305     {
00306         srcsample = samplefrac >> 8;
00307         samplefrac += fracstep;
00308         if( inwidth == 2 ) {
00309             sample = LittleShort ( ((short *)data)[srcsample] );
00310         } else {
00311             sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
00312         }
00313         sfx[i] = sample;
00314     }
00315     return outcount;
00316 }

Here is the call graph for this function:

void S_DisplayFreeMemory void   ) 
 

Definition at line 402 of file snd_mem.c.

References Com_Printf(), inUse, and totalInUse.

Referenced by S_SoundList_f().

00402                            {
00403     Com_Printf("%d bytes free sound buffer memory, %d total used\n", inUse, totalInUse);
00404 }

Here is the call graph for this function:

qboolean S_LoadSound sfx_t sfx  ) 
 

Definition at line 329 of file snd_mem.c.

References byte, wavinfo_t::channels, Com_DPrintf(), Com_Milliseconds(), Com_Printf(), data, wavinfo_t::dataofs, encodeMuLaw(), encodeWavelet(), FS_FreeFile(), FS_ReadFile(), GetWavinfo(), Hunk_AllocateTempMemory(), Hunk_FreeTempMemory(), sfx_s::lastTimeUsed, qboolean, qfalse, wavinfo_t::rate, ResampleSfx(), ResampleSfxRaw(), S_AdpcmEncodeSound(), S_COLOR_YELLOW, wavinfo_t::samples, sfx_t, SND_CHUNK_SIZE, sfx_s::soundCompressed, sfx_s::soundCompressionMethod, sfx_s::soundData, sfx_s::soundLength, sfx_s::soundName, and wavinfo_t::width.

Referenced by S_memoryLoad().

00330 {
00331     byte    *data;
00332     short   *samples;
00333     wavinfo_t   info;
00334     int     size;
00335 
00336     // player specific sounds are never directly loaded
00337     if ( sfx->soundName[0] == '*') {
00338         return qfalse;
00339     }
00340 
00341     // load it in
00342     size = FS_ReadFile( sfx->soundName, (void **)&data );
00343     if ( !data ) {
00344         return qfalse;
00345     }
00346 
00347     info = GetWavinfo( sfx->soundName, data, size );
00348     if ( info.channels != 1 ) {
00349         Com_Printf ("%s is a stereo wav file\n", sfx->soundName);
00350         FS_FreeFile (data);
00351         return qfalse;
00352     }
00353 
00354     if ( info.width == 1 ) {
00355         Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName);
00356     }
00357 
00358     if ( info.rate != 22050 ) {
00359         Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName);
00360     }
00361 
00362     samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2);
00363 
00364     sfx->lastTimeUsed = Com_Milliseconds()+1;
00365 
00366     // each of these compression schemes works just fine
00367     // but the 16bit quality is much nicer and with a local
00368     // install assured we can rely upon the sound memory
00369     // manager to do the right thing for us and page
00370     // sound in as needed
00371 
00372     if( sfx->soundCompressed == qtrue) {
00373         sfx->soundCompressionMethod = 1;
00374         sfx->soundData = NULL;
00375         sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00376         S_AdpcmEncodeSound(sfx, samples);
00377 #if 0
00378     } else if (info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
00379         sfx->soundCompressionMethod = 3;
00380         sfx->soundData = NULL;
00381         sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00382         encodeMuLaw( sfx, samples);
00383     } else if (info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
00384         sfx->soundCompressionMethod = 2;
00385         sfx->soundData = NULL;
00386         sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
00387         encodeWavelet( sfx, samples);
00388 #endif
00389     } else {
00390         sfx->soundCompressionMethod = 0;
00391         sfx->soundLength = info.samples;
00392         sfx->soundData = NULL;
00393         ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse );
00394     }
00395     
00396     Hunk_FreeTempMemory(samples);
00397     FS_FreeFile( data );
00398 
00399     return qtrue;
00400 }

Here is the call graph for this function:

void SND_free sndBuffer v  ) 
 

Definition at line 53 of file snd_mem.c.

References freelist, inUse, sndBuffer, and v.

Referenced by S_FreeOldestSound().

00053                                {
00054     *(sndBuffer **)v = freelist;
00055     freelist = (sndBuffer*)v;
00056     inUse += sizeof(sndBuffer);
00057 }

sndBuffer* SND_malloc  ) 
 

Definition at line 59 of file snd_mem.c.

References freelist, inUse, sndBuffer_s::next, S_FreeOldestSound(), sndBuffer, totalInUse, and v.

Referenced by encodeMuLaw(), encodeWavelet(), ResampleSfx(), S_AdpcmEncodeSound(), and S_DefaultSound().

00059                          {
00060     sndBuffer *v;
00061 redo:
00062     if (freelist == NULL) {
00063         S_FreeOldestSound();
00064         goto redo;
00065     }
00066 
00067     inUse -= sizeof(sndBuffer);
00068     totalInUse += sizeof(sndBuffer);
00069 
00070     v = freelist;
00071     freelist = *(sndBuffer **)freelist;
00072     v->next = NULL;
00073     return v;
00074 }

Here is the call graph for this function:

void SND_setup  ) 
 

Definition at line 76 of file snd_mem.c.

References buffer, Com_Printf(), CVAR_ARCHIVE, Cvar_Get(), CVAR_LATCH, cvar_t, DEF_COMSOUNDMEGS, freelist, cvar_s::integer, inUse, malloc(), p, q, sfxScratchBuffer, sfxScratchPointer, SND_CHUNK_SIZE, and sndBuffer.

Referenced by S_BeginRegistration().

00076                  {
00077     sndBuffer *p, *q;
00078     cvar_t  *cv;
00079     int scs;
00080 
00081     cv = Cvar_Get( "com_soundMegs", DEF_COMSOUNDMEGS, CVAR_LATCH | CVAR_ARCHIVE );
00082 
00083     scs = (cv->integer*1536);
00084 
00085     buffer = malloc(scs*sizeof(sndBuffer) );
00086     // allocate the stack based hunk allocator
00087     sfxScratchBuffer = malloc(SND_CHUNK_SIZE * sizeof(short) * 4);  //Hunk_Alloc(SND_CHUNK_SIZE * sizeof(short) * 4);
00088     sfxScratchPointer = NULL;
00089 
00090     inUse = scs*sizeof(sndBuffer);
00091     p = buffer;;
00092     q = p + scs;
00093     while (--q > p)
00094         *(sndBuffer **)q = q-1;
00095     
00096     *(sndBuffer **)q = NULL;
00097     freelist = p + scs - 1;
00098 
00099     Com_Printf("Sound memory manager started\n");
00100 }

Here is the call graph for this function:


Variable Documentation

sndBuffer* buffer = NULL [static]
 

Definition at line 44 of file snd_mem.c.

Referenced by SND_setup().

byte* data_p [static]
 

Definition at line 110 of file snd_mem.c.

Referenced by FindNextChunk(), GetLittleLong(), GetLittleShort(), and GetWavinfo().

sndBuffer* freelist = NULL [static]
 

Definition at line 45 of file snd_mem.c.

Referenced by SND_free(), SND_malloc(), and SND_setup().

int iff_chunk_len [static]
 

Definition at line 114 of file snd_mem.c.

Referenced by FindNextChunk().

byte* iff_data [static]
 

Definition at line 113 of file snd_mem.c.

Referenced by GetWavinfo().

byte* iff_end [static]
 

Definition at line 111 of file snd_mem.c.

Referenced by GetWavinfo().

int inUse = 0 [static]
 

Definition at line 46 of file snd_mem.c.

Referenced by S_DisplayFreeMemory(), SND_free(), SND_malloc(), and SND_setup().

byte* last_chunk [static]
 

Definition at line 112 of file snd_mem.c.

Referenced by FindChunk(), and FindNextChunk().

short* sfxScratchBuffer = NULL
 

Definition at line 49 of file snd_mem.c.

Referenced by S_PaintChannelFromADPCM(), S_PaintChannelFromWavelet(), and SND_setup().

int sfxScratchIndex = 0
 

Definition at line 51 of file snd_mem.c.

Referenced by S_PaintChannelFromADPCM(), and S_PaintChannelFromWavelet().

sfx_t* sfxScratchPointer = NULL
 

Definition at line 50 of file snd_mem.c.

Referenced by S_PaintChannelFromADPCM(), S_PaintChannelFromWavelet(), and SND_setup().

int totalInUse = 0 [static]
 

Definition at line 47 of file snd_mem.c.

Referenced by S_DisplayFreeMemory(), and SND_malloc().


Generated on Thu Aug 25 13:39:53 2005 for Quake III Arena by  doxygen 1.3.9.1