Annotation of quake1/snd_mem.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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