Annotation of quake2/client/snd_mem.c, revision 1.1.1.1

1.1       root        1: // snd_mem.c: sound caching
                      2: 
                      3: #include "client.h"
                      4: #include "snd_loc.h"
                      5: 
                      6: int                    cache_full_cycle;
                      7: 
                      8: byte *S_Alloc (int size);
                      9: 
                     10: /*
                     11: ================
                     12: ResampleSfx
                     13: ================
                     14: */
                     15: void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data)
                     16: {
                     17:        int             outcount;
                     18:        int             srcsample;
                     19:        float   stepscale;
                     20:        int             i;
                     21:        int             sample, samplefrac, fracstep;
                     22:        sfxcache_t      *sc;
                     23:        
                     24:        sc = sfx->cache;
                     25:        if (!sc)
                     26:                return;
                     27: 
                     28:        stepscale = (float)inrate / dma.speed;  // this is usually 0.5, 1, or 2
                     29: 
                     30:        outcount = sc->length / stepscale;
                     31:        sc->length = outcount;
                     32:        if (sc->loopstart != -1)
                     33:                sc->loopstart = sc->loopstart / stepscale;
                     34: 
                     35:        sc->speed = dma.speed;
                     36:        if (s_loadas8bit->value)
                     37:                sc->width = 1;
                     38:        else
                     39:                sc->width = inwidth;
                     40:        sc->stereo = 0;
                     41: 
                     42: // resample / decimate to the current source rate
                     43: 
                     44:        if (stepscale == 1 && inwidth == 1 && sc->width == 1)
                     45:        {
                     46: // fast special case
                     47:                for (i=0 ; i<outcount ; i++)
                     48:                        ((signed char *)sc->data)[i]
                     49:                        = (int)( (unsigned char)(data[i]) - 128);
                     50:        }
                     51:        else
                     52:        {
                     53: // general case
                     54:                samplefrac = 0;
                     55:                fracstep = stepscale*256;
                     56:                for (i=0 ; i<outcount ; i++)
                     57:                {
                     58:                        srcsample = samplefrac >> 8;
                     59:                        samplefrac += fracstep;
                     60:                        if (inwidth == 2)
                     61:                                sample = LittleShort ( ((short *)data)[srcsample] );
                     62:                        else
                     63:                                sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
                     64:                        if (sc->width == 2)
                     65:                                ((short *)sc->data)[i] = sample;
                     66:                        else
                     67:                                ((signed char *)sc->data)[i] = sample >> 8;
                     68:                }
                     69:        }
                     70: }
                     71: 
                     72: //=============================================================================
                     73: 
                     74: /*
                     75: ==============
                     76: S_LoadSound
                     77: ==============
                     78: */
                     79: sfxcache_t *S_LoadSound (sfx_t *s)
                     80: {
                     81:     char       namebuffer[MAX_QPATH];
                     82:        byte    *data;
                     83:        wavinfo_t       info;
                     84:        int             len;
                     85:        float   stepscale;
                     86:        sfxcache_t      *sc;
                     87:        int             size;
                     88: 
                     89:        if (s->name[0] == '*')
                     90:                return NULL;
                     91: 
                     92: // see if still in memory
                     93:        sc = s->cache;
                     94:        if (sc)
                     95:                return sc;
                     96: 
                     97: //Com_Printf ("S_LoadSound: %x\n", (int)stackbuf);
                     98: // load it in
                     99:        if (s->name[0] == '#')
                    100:                strcpy(namebuffer, &s->name[1]);
                    101:        else
                    102:                Com_sprintf (namebuffer, sizeof(namebuffer), "sound/%s", s->name);
                    103: 
                    104: //     Com_Printf ("loading %s\n",namebuffer);
                    105: 
                    106:        size = FS_LoadFile (namebuffer, (void **)&data);
                    107: 
                    108:        if (!data)
                    109:        {
                    110:                Com_Printf ("Couldn't load %s\n", namebuffer);
                    111:                return NULL;
                    112:        }
                    113: 
                    114:        info = GetWavinfo (s->name, data, size);
                    115:        if (info.channels != 1)
                    116:        {
                    117:                Com_Printf ("%s is a stereo sample\n",s->name);
                    118:                FS_FreeFile (data);
                    119:                return NULL;
                    120:        }
                    121: 
                    122:        stepscale = (float)info.rate / dma.speed;       
                    123:        len = info.samples / stepscale;
                    124: 
                    125:        len = len * info.width * info.channels;
                    126: 
                    127:        sc = s->cache = Z_Malloc (len + sizeof(sfxcache_t));
                    128:        if (!sc)
                    129:        {
                    130:                FS_FreeFile (data);
                    131:                return NULL;
                    132:        }
                    133:        
                    134:        sc->length = info.samples;
                    135:        sc->loopstart = info.loopstart;
                    136:        sc->speed = info.rate;
                    137:        sc->width = info.width;
                    138:        sc->stereo = info.channels;
                    139: 
                    140:        ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);
                    141: 
                    142:        FS_FreeFile (data);
                    143: 
                    144:        return sc;
                    145: }
                    146: 
                    147: 
                    148: 
                    149: /*
                    150: ===============================================================================
                    151: 
                    152: WAV loading
                    153: 
                    154: ===============================================================================
                    155: */
                    156: 
                    157: 
                    158: byte   *data_p;
                    159: byte   *iff_end;
                    160: byte   *last_chunk;
                    161: byte   *iff_data;
                    162: int    iff_chunk_len;
                    163: 
                    164: 
                    165: short GetLittleShort(void)
                    166: {
                    167:        short val = 0;
                    168:        val = *data_p;
                    169:        val = val + (*(data_p+1)<<8);
                    170:        data_p += 2;
                    171:        return val;
                    172: }
                    173: 
                    174: int GetLittleLong(void)
                    175: {
                    176:        int val = 0;
                    177:        val = *data_p;
                    178:        val = val + (*(data_p+1)<<8);
                    179:        val = val + (*(data_p+2)<<16);
                    180:        val = val + (*(data_p+3)<<24);
                    181:        data_p += 4;
                    182:        return val;
                    183: }
                    184: 
                    185: void FindNextChunk(char *name)
                    186: {
                    187:        while (1)
                    188:        {
                    189:                data_p=last_chunk;
                    190: 
                    191:                if (data_p >= iff_end)
                    192:                {       // didn't find the chunk
                    193:                        data_p = NULL;
                    194:                        return;
                    195:                }
                    196:                
                    197:                data_p += 4;
                    198:                iff_chunk_len = GetLittleLong();
                    199:                if (iff_chunk_len < 0)
                    200:                {
                    201:                        data_p = NULL;
                    202:                        return;
                    203:                }
                    204: //             if (iff_chunk_len > 1024*1024)
                    205: //                     Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
                    206:                data_p -= 8;
                    207:                last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
                    208:                if (!strncmp(data_p, name, 4))
                    209:                        return;
                    210:        }
                    211: }
                    212: 
                    213: void FindChunk(char *name)
                    214: {
                    215:        last_chunk = iff_data;
                    216:        FindNextChunk (name);
                    217: }
                    218: 
                    219: 
                    220: void DumpChunks(void)
                    221: {
                    222:        char    str[5];
                    223:        
                    224:        str[4] = 0;
                    225:        data_p=iff_data;
                    226:        do
                    227:        {
                    228:                memcpy (str, data_p, 4);
                    229:                data_p += 4;
                    230:                iff_chunk_len = GetLittleLong();
                    231:                Com_Printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
                    232:                data_p += (iff_chunk_len + 1) & ~1;
                    233:        } while (data_p < iff_end);
                    234: }
                    235: 
                    236: /*
                    237: ============
                    238: GetWavinfo
                    239: ============
                    240: */
                    241: wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
                    242: {
                    243:        wavinfo_t       info;
                    244:        int     i;
                    245:        int     format;
                    246:        int             samples;
                    247: 
                    248:        memset (&info, 0, sizeof(info));
                    249: 
                    250:        if (!wav)
                    251:                return info;
                    252:                
                    253:        iff_data = wav;
                    254:        iff_end = wav + wavlength;
                    255: 
                    256: // find "RIFF" chunk
                    257:        FindChunk("RIFF");
                    258:        if (!(data_p && !strncmp(data_p+8, "WAVE", 4)))
                    259:        {
                    260:                Com_Printf("Missing RIFF/WAVE chunks\n");
                    261:                return info;
                    262:        }
                    263: 
                    264: // get "fmt " chunk
                    265:        iff_data = data_p + 12;
                    266: // DumpChunks ();
                    267: 
                    268:        FindChunk("fmt ");
                    269:        if (!data_p)
                    270:        {
                    271:                Com_Printf("Missing fmt chunk\n");
                    272:                return info;
                    273:        }
                    274:        data_p += 8;
                    275:        format = GetLittleShort();
                    276:        if (format != 1)
                    277:        {
                    278:                Com_Printf("Microsoft PCM format only\n");
                    279:                return info;
                    280:        }
                    281: 
                    282:        info.channels = GetLittleShort();
                    283:        info.rate = GetLittleLong();
                    284:        data_p += 4+2;
                    285:        info.width = GetLittleShort() / 8;
                    286: 
                    287: // get cue chunk
                    288:        FindChunk("cue ");
                    289:        if (data_p)
                    290:        {
                    291:                data_p += 32;
                    292:                info.loopstart = GetLittleLong();
                    293: //             Com_Printf("loopstart=%d\n", sfx->loopstart);
                    294: 
                    295:        // if the next chunk is a LIST chunk, look for a cue length marker
                    296:                FindNextChunk ("LIST");
                    297:                if (data_p)
                    298:                {
                    299:                        if (!strncmp (data_p + 28, "mark", 4))
                    300:                        {       // this is not a proper parse, but it works with cooledit...
                    301:                                data_p += 24;
                    302:                                i = GetLittleLong ();   // samples in loop
                    303:                                info.samples = info.loopstart + i;
                    304: //                             Com_Printf("looped length: %i\n", i);
                    305:                        }
                    306:                }
                    307:        }
                    308:        else
                    309:                info.loopstart = -1;
                    310: 
                    311: // find data chunk
                    312:        FindChunk("data");
                    313:        if (!data_p)
                    314:        {
                    315:                Com_Printf("Missing data chunk\n");
                    316:                return info;
                    317:        }
                    318: 
                    319:        data_p += 4;
                    320:        samples = GetLittleLong () / info.width;
                    321: 
                    322:        if (info.samples)
                    323:        {
                    324:                if (samples < info.samples)
                    325:                        Com_Error (ERR_DROP, "Sound %s has a bad loop length", name);
                    326:        }
                    327:        else
                    328:                info.samples = samples;
                    329: 
                    330:        info.dataofs = data_p - wav;
                    331:        
                    332:        return info;
                    333: }
                    334: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.