Annotation of quake2/client/snd_mem.c, revision 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.