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

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;
1.1.1.2 ! root       88:        char    *name;
1.1       root       89: 
                     90:        if (s->name[0] == '*')
                     91:                return NULL;
                     92: 
                     93: // see if still in memory
                     94:        sc = s->cache;
                     95:        if (sc)
                     96:                return sc;
                     97: 
                     98: //Com_Printf ("S_LoadSound: %x\n", (int)stackbuf);
                     99: // load it in
1.1.1.2 ! root      100:        if (s->truename)
        !           101:                name = s->truename;
1.1       root      102:        else
1.1.1.2 ! root      103:                name = s->name;
        !           104: 
        !           105:        if (name[0] == '#')
        !           106:                strcpy(namebuffer, &name[1]);
        !           107:        else
        !           108:                Com_sprintf (namebuffer, sizeof(namebuffer), "sound/%s", name);
1.1       root      109: 
                    110: //     Com_Printf ("loading %s\n",namebuffer);
                    111: 
                    112:        size = FS_LoadFile (namebuffer, (void **)&data);
                    113: 
                    114:        if (!data)
                    115:        {
1.1.1.2 ! root      116:                Com_DPrintf ("Couldn't load %s\n", namebuffer);
1.1       root      117:                return NULL;
                    118:        }
                    119: 
                    120:        info = GetWavinfo (s->name, data, size);
                    121:        if (info.channels != 1)
                    122:        {
                    123:                Com_Printf ("%s is a stereo sample\n",s->name);
                    124:                FS_FreeFile (data);
                    125:                return NULL;
                    126:        }
                    127: 
                    128:        stepscale = (float)info.rate / dma.speed;       
                    129:        len = info.samples / stepscale;
                    130: 
                    131:        len = len * info.width * info.channels;
                    132: 
                    133:        sc = s->cache = Z_Malloc (len + sizeof(sfxcache_t));
                    134:        if (!sc)
                    135:        {
                    136:                FS_FreeFile (data);
                    137:                return NULL;
                    138:        }
                    139:        
                    140:        sc->length = info.samples;
                    141:        sc->loopstart = info.loopstart;
                    142:        sc->speed = info.rate;
                    143:        sc->width = info.width;
                    144:        sc->stereo = info.channels;
                    145: 
                    146:        ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);
                    147: 
                    148:        FS_FreeFile (data);
                    149: 
                    150:        return sc;
                    151: }
                    152: 
                    153: 
                    154: 
                    155: /*
                    156: ===============================================================================
                    157: 
                    158: WAV loading
                    159: 
                    160: ===============================================================================
                    161: */
                    162: 
                    163: 
                    164: byte   *data_p;
                    165: byte   *iff_end;
                    166: byte   *last_chunk;
                    167: byte   *iff_data;
                    168: int    iff_chunk_len;
                    169: 
                    170: 
                    171: short GetLittleShort(void)
                    172: {
                    173:        short val = 0;
                    174:        val = *data_p;
                    175:        val = val + (*(data_p+1)<<8);
                    176:        data_p += 2;
                    177:        return val;
                    178: }
                    179: 
                    180: int GetLittleLong(void)
                    181: {
                    182:        int val = 0;
                    183:        val = *data_p;
                    184:        val = val + (*(data_p+1)<<8);
                    185:        val = val + (*(data_p+2)<<16);
                    186:        val = val + (*(data_p+3)<<24);
                    187:        data_p += 4;
                    188:        return val;
                    189: }
                    190: 
                    191: void FindNextChunk(char *name)
                    192: {
                    193:        while (1)
                    194:        {
                    195:                data_p=last_chunk;
                    196: 
                    197:                if (data_p >= iff_end)
                    198:                {       // didn't find the chunk
                    199:                        data_p = NULL;
                    200:                        return;
                    201:                }
                    202:                
                    203:                data_p += 4;
                    204:                iff_chunk_len = GetLittleLong();
                    205:                if (iff_chunk_len < 0)
                    206:                {
                    207:                        data_p = NULL;
                    208:                        return;
                    209:                }
                    210: //             if (iff_chunk_len > 1024*1024)
                    211: //                     Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len);
                    212:                data_p -= 8;
                    213:                last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 );
                    214:                if (!strncmp(data_p, name, 4))
                    215:                        return;
                    216:        }
                    217: }
                    218: 
                    219: void FindChunk(char *name)
                    220: {
                    221:        last_chunk = iff_data;
                    222:        FindNextChunk (name);
                    223: }
                    224: 
                    225: 
                    226: void DumpChunks(void)
                    227: {
                    228:        char    str[5];
                    229:        
                    230:        str[4] = 0;
                    231:        data_p=iff_data;
                    232:        do
                    233:        {
                    234:                memcpy (str, data_p, 4);
                    235:                data_p += 4;
                    236:                iff_chunk_len = GetLittleLong();
                    237:                Com_Printf ("0x%x : %s (%d)\n", (int)(data_p - 4), str, iff_chunk_len);
                    238:                data_p += (iff_chunk_len + 1) & ~1;
                    239:        } while (data_p < iff_end);
                    240: }
                    241: 
                    242: /*
                    243: ============
                    244: GetWavinfo
                    245: ============
                    246: */
                    247: wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
                    248: {
                    249:        wavinfo_t       info;
                    250:        int     i;
                    251:        int     format;
                    252:        int             samples;
                    253: 
                    254:        memset (&info, 0, sizeof(info));
                    255: 
                    256:        if (!wav)
                    257:                return info;
                    258:                
                    259:        iff_data = wav;
                    260:        iff_end = wav + wavlength;
                    261: 
                    262: // find "RIFF" chunk
                    263:        FindChunk("RIFF");
                    264:        if (!(data_p && !strncmp(data_p+8, "WAVE", 4)))
                    265:        {
                    266:                Com_Printf("Missing RIFF/WAVE chunks\n");
                    267:                return info;
                    268:        }
                    269: 
                    270: // get "fmt " chunk
                    271:        iff_data = data_p + 12;
                    272: // DumpChunks ();
                    273: 
                    274:        FindChunk("fmt ");
                    275:        if (!data_p)
                    276:        {
                    277:                Com_Printf("Missing fmt chunk\n");
                    278:                return info;
                    279:        }
                    280:        data_p += 8;
                    281:        format = GetLittleShort();
                    282:        if (format != 1)
                    283:        {
                    284:                Com_Printf("Microsoft PCM format only\n");
                    285:                return info;
                    286:        }
                    287: 
                    288:        info.channels = GetLittleShort();
                    289:        info.rate = GetLittleLong();
                    290:        data_p += 4+2;
                    291:        info.width = GetLittleShort() / 8;
                    292: 
                    293: // get cue chunk
                    294:        FindChunk("cue ");
                    295:        if (data_p)
                    296:        {
                    297:                data_p += 32;
                    298:                info.loopstart = GetLittleLong();
                    299: //             Com_Printf("loopstart=%d\n", sfx->loopstart);
                    300: 
                    301:        // if the next chunk is a LIST chunk, look for a cue length marker
                    302:                FindNextChunk ("LIST");
                    303:                if (data_p)
                    304:                {
                    305:                        if (!strncmp (data_p + 28, "mark", 4))
                    306:                        {       // this is not a proper parse, but it works with cooledit...
                    307:                                data_p += 24;
                    308:                                i = GetLittleLong ();   // samples in loop
                    309:                                info.samples = info.loopstart + i;
                    310: //                             Com_Printf("looped length: %i\n", i);
                    311:                        }
                    312:                }
                    313:        }
                    314:        else
                    315:                info.loopstart = -1;
                    316: 
                    317: // find data chunk
                    318:        FindChunk("data");
                    319:        if (!data_p)
                    320:        {
                    321:                Com_Printf("Missing data chunk\n");
                    322:                return info;
                    323:        }
                    324: 
                    325:        data_p += 4;
                    326:        samples = GetLittleLong () / info.width;
                    327: 
                    328:        if (info.samples)
                    329:        {
                    330:                if (samples < info.samples)
                    331:                        Com_Error (ERR_DROP, "Sound %s has a bad loop length", name);
                    332:        }
                    333:        else
                    334:                info.samples = samples;
                    335: 
                    336:        info.dataofs = data_p - wav;
                    337:        
                    338:        return info;
                    339: }
                    340: 

unix.superglobalmegacorp.com

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