X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=snd_mem.c;h=4e2a94ec26d91c0511d6da07e4739387bd5efcfb;hp=5420d303d8d7403f8dd31816224d2b131a374b09;hb=e8258ac9cb094cb3f1f61335c06220fd148043a0;hpb=f33a4d62e18e829238932f4aa55ad1fc7279b2cb diff --git a/snd_mem.c b/snd_mem.c index 5420d303..4e2a94ec 100644 --- a/snd_mem.c +++ b/snd_mem.c @@ -8,7 +8,7 @@ of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -21,102 +21,59 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -int cache_full_cycle; - -byte *S_Alloc (int size); +qbyte *S_Alloc (int size); /* ================ ResampleSfx ================ */ -void ResampleSfx (sfx_t *sfx, int inrate, byte *data) +void ResampleSfx (sfxcache_t *sc, qbyte *data, char *name) { - int outcount; - int srcsample; - float stepscale; - int i; - int samplefrac, fracstep; - sfxcache_t *sc; - - sc = Cache_Check (&sfx->cache); - if (!sc) - return; + int i, outcount, srcsample, srclength, samplefrac, fracstep; - stepscale = (float)inrate / shm->speed; // this is usually 0.5, 1, or 2 + // this is usually 0.5 (128), 1 (256), or 2 (512) + fracstep = ((double) sc->speed / (double) shm->speed) * 256.0; - outcount = sc->length / stepscale; + srclength = sc->length << sc->stereo; + + outcount = (double) sc->length * (double) shm->speed / (double) sc->speed; sc->length = outcount; if (sc->loopstart != -1) - sc->loopstart = sc->loopstart / stepscale; + sc->loopstart = (double) sc->loopstart * (double) shm->speed / (double) sc->speed; sc->speed = shm->speed; -// if (loadas8bit.value) -// sc->width = 1; -// else -// sc->width = inwidth; -// sc->stereo = 0; // resample / decimate to the current source rate - if (stepscale == 1/* && inwidth == 1*/ && sc->width == 1) - { -// fast special case - // LordHavoc: I do not serve the readability gods... - int *indata, *outdata; - int count4, count1; - count1 = outcount << sc->stereo; - count4 = count1 >> 2; - indata = (void *)data; - outdata = (void *)sc->data; - while (count4--) - *outdata++ = *indata++ ^ 0x80808080; - if (count1 & 2) - ((short*)outdata)[0] = ((short*)indata)[0] ^ 0x8080; - if (count1 & 1) - ((char*)outdata)[2] = ((char*)indata)[2] ^ 0x80; - /* - if (sc->stereo) // LordHavoc: stereo sound support - { - for (i=0 ; i<(outcount<<1) ; i++) - ((signed char *)sc->data)[i] = (int)( (unsigned char)(data[i]) - 128); - } - else - { - for (i=0 ; idata)[i] = (int)( (unsigned char)(data[i]) - 128); - } - */ - } - else if (stepscale == 1/* && inwidth == 2*/ && sc->width == 2) // LordHavoc: quick case for 16bit + if (fracstep == 256) { - if (sc->stereo) // LordHavoc: stereo sound support - for (i=0 ; idata)[i] = LittleShort (((short *)data)[i]); - else - for (i=0 ; iwidth == 1) // 8bit + for (i = 0;i < srclength;i++) + ((signed char *)sc->data)[i] = ((unsigned char *)data)[i] - 128; + else //if (sc->width == 2) // 16bit + for (i = 0;i < srclength;i++) ((short *)sc->data)[i] = LittleShort (((short *)data)[i]); } else { // general case - Con_DPrintf("ResampleSfx: resampling sound %s\n", sfx->name); + Con_DPrintf("ResampleSfx: resampling sound %s\n", name); samplefrac = 0; - fracstep = stepscale*256; if ((fracstep & 255) == 0) // skipping points on perfect multiple { - samplefrac >> 8; srcsample = 0; + fracstep >>= 8; if (sc->width == 2) { short *out = (void *)sc->data, *in = (void *)data; if (sc->stereo) // LordHavoc: stereo sound support { fracstep <<= 1; - for (i=0 ; idata, *in = (void *)data; + signed char *out = (void *)sc->data; + unsigned char *in = (void *)data; if (sc->stereo) // LordHavoc: stereo sound support { fracstep <<= 1; - for (i=0 ; iwidth == 2) { short *out = (void *)sc->data, *in = (void *)data; if (sc->stereo) // LordHavoc: stereo sound support { - for (i=0 ; i> 7) & ~1; + srcsample = (samplefrac >> 8) << 1; + a = in[srcsample ]; + if (srcsample+2 >= srclength) + b = 0; + else + b = in[srcsample+2]; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (short) sample; + a = in[srcsample+1]; + if (srcsample+2 >= srclength) + b = 0; + else + b = in[srcsample+3]; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (short) sample; samplefrac += fracstep; - *out++ = (short) ((int) ((LittleShort (in[srcsample ]) * (256 - (samplefrac & 255)) + LittleShort (in[srcsample+2]) * (samplefrac & 255)) >> 8)); - *out++ = (short) ((int) ((LittleShort (in[srcsample+1]) * (256 - (samplefrac & 255)) + LittleShort (in[srcsample+3]) * (samplefrac & 255)) >> 8)); } } else @@ -172,22 +144,41 @@ void ResampleSfx (sfx_t *sfx, int inrate, byte *data) for (i=0 ; i> 8; + a = in[srcsample ]; + if (srcsample+1 >= srclength) + b = 0; + else + b = in[srcsample+1]; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (short) sample; samplefrac += fracstep; - *out++ = (short) ((int) ((LittleShort (in[srcsample] ) * (256 - (samplefrac & 255)) + LittleShort (in[srcsample+1]) * (samplefrac & 255)) >> 8)); } } } else { - signed char *out = (void *)sc->data, *in = (void *)data; + signed char *out = (void *)sc->data; + unsigned char *in = (void *)data; if (sc->stereo) // LordHavoc: stereo sound support { - for (i=0 ; i> 7) & ~1; + srcsample = (samplefrac >> 8) << 1; + a = (int) in[srcsample ] - 128; + if (srcsample+2 >= srclength) + b = 0; + else + b = (int) in[srcsample+2] - 128; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (signed char) sample; + a = (int) in[srcsample+1] - 128; + if (srcsample+2 >= srclength) + b = 0; + else + b = (int) in[srcsample+3] - 128; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (signed char) sample; samplefrac += fracstep; - *out++ = (signed char) ((int) (((((unsigned char) in[srcsample ] - 128) * (256 - (samplefrac & 255))) + (((unsigned char) in[srcsample+2] - 128) * (samplefrac & 255))) >> 8)); - *out++ = (signed char) ((int) (((((unsigned char) in[srcsample+1] - 128) * (256 - (samplefrac & 255))) + (((unsigned char) in[srcsample+3] - 128) * (samplefrac & 255))) >> 8)); } } else @@ -195,13 +186,22 @@ void ResampleSfx (sfx_t *sfx, int inrate, byte *data) for (i=0 ; i> 8; + a = (int) in[srcsample ] - 128; + if (srcsample+1 >= srclength) + b = 0; + else + b = (int) in[srcsample+1] - 128; + sample = (((b - a) * (samplefrac & 255)) >> 8) + a; + *out++ = (signed char) sample; samplefrac += fracstep; - *out++ = (signed char) ((int) (((((unsigned char) in[srcsample ] - 128) * (256 - (samplefrac & 255))) + (((unsigned char) in[srcsample+1] - 128) * (samplefrac & 255))) >> 8)); } } } } } + + // LordHavoc: use this for testing if it ever becomes useful again +// COM_WriteFile (va("sound/%s.pcm", name), sc->data, (sc->length << sc->stereo) * sc->width); } //============================================================================= @@ -214,26 +214,20 @@ S_LoadSound sfxcache_t *S_LoadSound (sfx_t *s) { char namebuffer[256]; - byte *data; + qbyte *data; wavinfo_t info; int len; - float stepscale; sfxcache_t *sc; - byte stackbuf[1*1024]; // avoid dirtying the cache heap // see if still in memory - sc = Cache_Check (&s->cache); - if (sc) - return sc; + if (s->sfxcache) + return s->sfxcache; -//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); // load it in strcpy(namebuffer, "sound/"); strcat(namebuffer, s->name); -// Con_Printf ("loading %s\n",namebuffer); - - data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf), false); + data = COM_LoadFile(namebuffer, false); if (!data) { @@ -246,33 +240,34 @@ sfxcache_t *S_LoadSound (sfx_t *s) if (info.channels < 1 || info.channels > 2) { Con_Printf ("%s has an unsupported number of channels (%i)\n",s->name, info.channels); + Mem_Free(data); return NULL; } - /* - if (info.channels != 1) - { - Con_Printf ("%s is a stereo sample\n",s->name); - return NULL; - } - */ - - stepscale = (float)info.rate / shm->speed; - len = info.samples / stepscale; + // calculate resampled length + len = (int) ((double) info.samples * (double) shm->speed / (double) info.rate); len = len * info.width * info.channels; - sc = Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name); + // FIXME: add S_UnloadSounds or something? + Mem_FreePool(&s->mempool); + s->mempool = Mem_AllocPool(s->name); + sc = s->sfxcache = Mem_Alloc(s->mempool, len + sizeof(sfxcache_t)); if (!sc) + { + Mem_FreePool(&s->mempool); + Mem_Free(data); return NULL; - + } + sc->length = info.samples; sc->loopstart = info.loopstart; sc->speed = info.rate; sc->width = info.width; sc->stereo = info.channels == 2; - ResampleSfx (s, sc->speed, data + info.dataofs); + ResampleSfx (sc, data + info.dataofs, s->name); + Mem_Free(data); return sc; } @@ -287,10 +282,10 @@ WAV loading */ -byte *data_p; -byte *iff_end; -byte *last_chunk; -byte *iff_data; +qbyte *data_p; +qbyte *iff_end; +qbyte *last_chunk; +qbyte *iff_data; int iff_chunk_len; @@ -325,7 +320,7 @@ void FindNextChunk(char *name) data_p = NULL; return; } - + data_p += 4; iff_chunk_len = GetLittleLong(); if (iff_chunk_len < 0) @@ -333,8 +328,6 @@ void FindNextChunk(char *name) data_p = NULL; return; } -// if (iff_chunk_len > 1024*1024) -// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); data_p -= 8; last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); if (!strncmp(data_p, name, 4)) @@ -370,7 +363,7 @@ void DumpChunks(void) GetWavinfo ============ */ -wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) +wavinfo_t GetWavinfo (char *name, qbyte *wav, int wavlength) { wavinfo_t info; int i; @@ -381,7 +374,7 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) if (!wav) return info; - + iff_data = wav; iff_end = wav + wavlength; @@ -422,7 +415,6 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) { data_p += 32; info.loopstart = GetLittleLong(); -// Con_Printf("loopstart=%d\n", sfx->loopstart); // if the next chunk is a LIST chunk, look for a cue length marker FindNextChunk ("LIST"); @@ -433,7 +425,6 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) data_p += 24; i = GetLittleLong (); // samples in loop info.samples = info.loopstart + i; -// Con_Printf("looped length: %i\n", i); } } } @@ -449,7 +440,7 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) } data_p += 4; - samples = GetLittleLong () / info.width; + samples = GetLittleLong () / info.width / info.channels; if (info.samples) { @@ -460,7 +451,7 @@ wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) info.samples = samples; info.dataofs = data_p - wav; - + return info; }