From b67a5991dc48b905302e4449b940cd7d7067ff83 Mon Sep 17 00:00:00 2001 From: TimeServ Date: Sun, 4 Jun 2006 01:43:52 +0000 Subject: [PATCH] sound resampling rehash, added snd_linearsample_stream, 1 will use linear resampling with RoQ/CIN playback (ogg resampling fix not there yet), defaults to 0 git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2311 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/clq2_cin.c | 5 + engine/client/keys.c | 80 +++--- engine/client/snd_dma.c | 115 ++------ engine/client/snd_mem.c | 556 ++++++++++++++++++++++++++++----------- engine/client/sound.h | 2 + engine/common/common.c | 29 ++ engine/common/common.h | 3 + engine/common/fs.c | 4 +- 8 files changed, 510 insertions(+), 284 deletions(-) diff --git a/engine/client/clq2_cin.c b/engine/client/clq2_cin.c index fd0dbae9b..7b726e5e4 100644 --- a/engine/client/clq2_cin.c +++ b/engine/client/clq2_cin.c @@ -361,6 +361,11 @@ qbyte *CIN_ReadNextFrame (void) VFS_READ (cin.cinematic_file, samples, count*cin.s_width*cin.s_channels); + if (cin.s_width == 1) + COM_CharBias(samples, count*cin.s_channels); + else if (cin.s_width == 2) + COM_SwapLittleShortBlock(samples, count*cin.s_channels); + S_RawAudio (0, samples, cin.s_rate, count, cin.s_channels, cin.s_width); in.data = compressed; diff --git a/engine/client/keys.c b/engine/client/keys.c index 59d8656e0..60bb054b2 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -395,44 +395,58 @@ void Con_Selectioncolour_Callback(struct cvar_s *var, char *oldvalue) SCR_StringToRGB(var->string, sccolor, 1); } +/* +// TODO: fix this to be used as the common coord function for selection logic +void GetSelectionCoords(int *selectcoords) +{ + extern cvar_t vid_conwidth, vid_conheight; + extern int mousecursor_x, mousecursor_y; + int xpos, ypos; + + // convert to console coords + xpos = (int)(mousecursor_x*vid_conwidth.value)/vid.width; + ypos = (int)(mousecursor_y*vid_conheight.value)/vid.height; +} +*/ + void Key_ConsoleDrawSelectionBox(void) { - extern cvar_t vid_conwidth, vid_conheight; - extern int mousecursor_x, mousecursor_y; - int xpos, ypos, temp; - int xpos2, ypos2; - - if (!con_mousedown[2]) - return; + extern cvar_t vid_conwidth, vid_conheight; + extern int mousecursor_x, mousecursor_y; + int xpos, ypos, temp; + int xpos2, ypos2; + + if (!con_mousedown[2]) + return; - xpos2 = con_mousedown[0]; - ypos2 = con_mousedown[1]; + xpos2 = con_mousedown[0]; + ypos2 = con_mousedown[1]; - xpos = (int)((mousecursor_x*vid_conwidth.value)/(vid.width*8)); - ypos = (int)((mousecursor_y*vid_conheight.value)/(vid.height*8)); + xpos = (int)((mousecursor_x*vid_conwidth.value)/(vid.width*8)); + ypos = (int)((mousecursor_y*vid_conheight.value)/(vid.height*8)); - if (xpos2 < 1) - xpos2 = 1; - if (xpos < 1) - xpos = 1; - if (xpos2 > con_current->linewidth) - xpos2 = con_current->linewidth; - if (xpos > con_current->linewidth) - xpos = con_current->linewidth; - if (xpos2 > xpos) - { - temp = xpos; - xpos = xpos2; - xpos2 = temp; - } - xpos++; - if (ypos2 > ypos) - { - temp = ypos; - ypos = ypos2; - ypos2 = temp; - } - ypos++; + if (xpos2 < 1) + xpos2 = 1; + if (xpos < 1) + xpos = 1; + if (xpos2 > con_current->linewidth) + xpos2 = con_current->linewidth; + if (xpos > con_current->linewidth) + xpos = con_current->linewidth; + if (xpos2 > xpos) + { + temp = xpos; + xpos = xpos2; + xpos2 = temp; + } + xpos++; + if (ypos2 > ypos) + { + temp = ypos; + ypos = ypos2; + ypos2 = temp; + } + ypos++; Draw_FillRGB(xpos2*8, ypos2*8, (xpos - xpos2)*8, (ypos - ypos2)*8, sccolor[0], sccolor[1], sccolor[2]); } diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 486edfa30..fa9e3b1d9 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -80,10 +80,11 @@ cvar_t snd_eax = SCVAR("snd_eax", "0"); cvar_t snd_speakers = SCVAR("snd_numspeakers", "2"); cvar_t snd_buffersize = SCVAR("snd_buffersize", "0"); cvar_t snd_samplebits = SCVARF("snd_samplebits", "16", CVAR_ARCHIVE); -cvar_t snd_playersoundvolume = SCVAR("snd_localvolume", "1"); //sugested by crunch +cvar_t snd_playersoundvolume = SCVAR("snd_localvolume", "1"); //sugested by crunch -cvar_t snd_capture = SCVAR("snd_capture", "0"); -cvar_t snd_linearresample = SCVAR("snd_linearresample", "1"); +cvar_t snd_capture = SCVAR("snd_capture", "0"); +cvar_t snd_linearresample = SCVAR("snd_linearresample", "1"); +cvar_t snd_linearresample_stream = SCVAR("snd_linearresample_stream", "0"); cvar_t snd_usemultipledevices = SCVAR("snd_multipledevices", "0"); @@ -596,6 +597,7 @@ void S_Init (void) Cvar_Register(&snd_usemultipledevices, "Sound controls"); Cvar_Register(&snd_linearresample, "Sound controls"); + Cvar_Register(&snd_linearresample_stream, "Sound controls"); if (COM_CheckParm("-nosound")) { @@ -1560,7 +1562,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, int oldlength; int spare; int outsamples; - float speedfactor; + double speedfactor; sfxcache_t *newcache; streaming_t *s, *free=NULL; for (s = s_streamers, i = 0; i < MAX_RAW_SOURCES; i++, s++) @@ -1671,100 +1673,19 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, newcache->length = spare + outsamples; - // move this whole operation to a seperate function? - if (channels == 1) { - if (width == 2) - { - short sample; - short *indata = (short *)data; - short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width); - if (speedfactor==1) //fast - { - while (samples--) - { - sample = *indata++; - *outpos++ = sample; - } - } - else - { - int src=0; - int pos=0; - - while (pos++ < outsamples) - { - src = pos*speedfactor; - sample = indata[src]; - *outpos++ = sample; - } - } - } - else if (width == 1) - { - char sample; - char *indata = (char *)data; - char *outpos = (char *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width); - if (speedfactor==1) //fast - { - while (samples--) - { - sample = *indata++; - *outpos++ = (int)( (unsigned char)(sample) - 128); - } - } - else - { - int src=0; - int pos=0; - - while (pos++ < outsamples) - { - src = pos*speedfactor; - sample = indata[src]; - *outpos++ = (int)( (unsigned char)(sample) - 128); - } - } - } - else - Sys_Error("Width isn't 2\n"); - } - else - { - if (width == 2) - { - short sample; - short *indata = (short *)data; - short *outpos = (short *)((qbyte *)newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width); - if (speedfactor==1) //fast - { - while (samples--) - { - sample = *indata++; - *outpos++ = sample; - - sample = *indata++; - *outpos++ = sample; - } - } - else - { - int src=0; - int pos=0; - - while (pos++ < outsamples) - { - src = pos*speedfactor; - sample = indata[src*2]; - *outpos++ = sample; - - sample = indata[src*2+1]; - *outpos++ = sample; - } - } - } - else - Sys_Error("Width isn't 2\n"); + extern cvar_t snd_linearresample_stream; + short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width); + SND_ResampleStream(data, + speed, + width, + channels, + samples, + outpos, + snd_speed, + s->sfxcache->width, + s->sfxcache->numchannels, + (int)snd_linearresample_stream.value); } s->sfxcache->loopstart = s->sfxcache->length; diff --git a/engine/client/snd_mem.c b/engine/client/snd_mem.c index 4a4fcdee7..b66c70957 100644 --- a/engine/client/snd_mem.c +++ b/engine/client/snd_mem.c @@ -27,6 +27,381 @@ int cache_full_cycle; qbyte *S_Alloc (int size); +#define LINEARUPSCALE(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + outnlsamps = floor(1.0 / scale); \ + outsamps -= outnlsamps; \ + \ + while (outsamps) \ + { \ + *out = ((0xFFFF - inaccum)*in[0] + inaccum*in[1]) >> (16 + outrshift); \ + inaccum += infrac; \ + in += (inaccum >> 16); \ + inaccum &= 0xFFFF; \ + out++; \ + outsamps--; \ + } \ + while (outnlsamps) \ + { \ + *out = (*in >> outrshift) << outlshift; \ + out++; \ + outnlsamps--; \ + } \ + } + +#define LINEARUPSCALESTEREO(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + outnlsamps = floor(1.0 / scale); \ + outsamps -= outnlsamps; \ + \ + while (outsamps) \ + { \ + out[0] = ((0xFFFF - inaccum)*in[0] + inaccum*in[2]) >> (16 + outrshift); \ + out[1] = ((0xFFFF - inaccum)*in[1] + inaccum*in[3]) >> (16 + outrshift); \ + inaccum += infrac; \ + in += (inaccum >> 16) * 2; \ + inaccum &= 0xFFFF; \ + out += 2; \ + outsamps--; \ + } \ + while (outnlsamps) \ + { \ + out[0] = (in[0] >> outrshift) << outlshift; \ + out[1] = (in[1] >> outrshift) << outlshift; \ + out += 2; \ + outnlsamps--; \ + } \ + } + +#define LINEARUPSCALESTEREOTOMONO(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + outnlsamps = floor(1.0 / scale); \ + outsamps -= outnlsamps; \ + \ + while (outsamps) \ + { \ + *out = ((((0xFFFF - inaccum)*in[0] + inaccum*in[2]) >> (16 - outlshift + outrshift)) + \ + (((0xFFFF - inaccum)*in[1] + inaccum*in[3]) >> (16 - outlshift + outrshift))) >> 1; \ + inaccum += infrac; \ + in += (inaccum >> 16) * 2; \ + inaccum &= 0xFFFF; \ + out++; \ + outsamps--; \ + } \ + while (outnlsamps) \ + { \ + out[0] = (((in[0] >> outrshift) << outlshift) + ((in[1] >> outrshift) << outlshift)) >> 1; \ + out++; \ + outnlsamps--; \ + } \ + } + +#define STANDARDRESCALE(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + \ + while (outsamps) \ + { \ + *out = (*in >> outrshift) << outlshift; \ + inaccum += infrac; \ + in += (inaccum >> 16); \ + inaccum &= 0xFFFF; \ + out++; \ + outsamps--; \ + } \ + } + +#define STANDARDRESCALESTEREO(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + \ + while (outsamps) \ + { \ + out[0] = (in[0] >> outrshift) << outlshift; \ + out[1] = (in[1] >> outrshift) << outlshift; \ + inaccum += infrac; \ + in += (inaccum >> 16) * 2; \ + inaccum &= 0xFFFF; \ + out += 2; \ + outsamps--; \ + } \ + } + +#define STANDARDRESCALESTEREOTOMONO(in, inrate, insamps, out, outrate, outlshift, outrshift) \ + { \ + scale = inrate / (double)outrate; \ + infrac = floor(scale * 65536); \ + outsamps = insamps / scale; \ + inaccum = 0; \ + \ + while (outsamps) \ + { \ + out[0] = (((in[0] >> outrshift) << outlshift) + ((in[1] >> outrshift) << outlshift)) >> 1; \ + inaccum += infrac; \ + in += (inaccum >> 16) * 2; \ + inaccum &= 0xFFFF; \ + out++; \ + outsamps--; \ + } \ + } + +#define QUICKCONVERT(in, insamps, out, outlshift, outrshift) \ + { \ + while (insamps) \ + { \ + *out = (*in >> outrshift) << outlshift; \ + out++; \ + in++; \ + insamps--; \ + } \ + } + +#define QUICKCONVERTSTEREOTOMONO(in, insamps, out, outlshift, outrshift) \ + { \ + while (insamps) \ + { \ + *out = (((in[0] >> outrshift) << outlshift) + ((in[1] >> outrshift) << outlshift)) >> 1; \ + out++; \ + in += 2; \ + insamps--; \ + } \ + } + +// SND_ResampleStream: takes a sound stream and converts with given parameters. Limited to +// 8-16-bit signed conversions and mono-to-mono/stereo-to-stereo/stereo-to-mono conversions. +// Not an in-place algorithm. +void SND_ResampleStream (void *in, int inrate, int inwidth, int inchannels, int insamps, void *out, int outrate, int outwidth, int outchannels, int resampstyle) +{ + double scale; + signed char *in8 = (signed char *)in; + short *in16 = (short *)in; + signed char *out8 = (signed char *)out; + short *out16 = (short *)out; + int outsamps, outnlsamps; + int infrac, inaccum; + + if (insamps <= 0) + return; + + if (inchannels == outchannels && inwidth == outwidth && inrate == outrate) + { + memcpy(out, in, inwidth*insamps*inchannels); + return; + } + + if (inchannels == 1 && outchannels == 1) + { + if (inwidth == 1) + { + if (outwidth == 1) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALE(in8, inrate, insamps, out8, outrate, 0, 0) + else + STANDARDRESCALE(in8, inrate, insamps, out8, outrate, 0, 0) + } + else // downsample + STANDARDRESCALE(in8, inrate, insamps, out8, outrate, 0, 0) + return; + } + else + { + if (inrate == outrate) // quick convert + QUICKCONVERT(in8, insamps, out16, 8, 0) + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALE(in8, inrate, insamps, out16, outrate, 8, 0) + else + STANDARDRESCALE(in8, inrate, insamps, out16, outrate, 8, 0) + } + else // downsample + STANDARDRESCALE(in8, inrate, insamps, out16, outrate, 8, 0) + return; + } + } + else // 16-bit + { + if (outwidth == 2) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALE(in16, inrate, insamps, out16, outrate, 0, 0) + else + STANDARDRESCALE(in16, inrate, insamps, out16, outrate, 0, 0) + } + else // downsample + STANDARDRESCALE(in16, inrate, insamps, out16, outrate, 0, 0) + return; + } + else + { + if (inrate == outrate) // quick convert + QUICKCONVERT(in16, insamps, out8, 0, 8) + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALE(in16, inrate, insamps, out8, outrate, 0, 8) + else + STANDARDRESCALE(in16, inrate, insamps, out8, outrate, 0, 8) + } + else // downsample + STANDARDRESCALE(in16, inrate, insamps, out8, outrate, 0, 8) + return; + } + } + } + else if (outchannels == 2 && inchannels == 2) + { + if (inwidth == 1) + { + if (outwidth == 1) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREO(in8, inrate, insamps, out8, outrate, 0, 0) + else + STANDARDRESCALESTEREO(in8, inrate, insamps, out8, outrate, 0, 0) + } + else // downsample + STANDARDRESCALESTEREO(in8, inrate, insamps, out8, outrate, 0, 0) + } + else + { + if (inrate == outrate) // quick convert + { + insamps *= 2; + QUICKCONVERT(in8, insamps, out16, 8, 0) + } + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREO(in8, inrate, insamps, out16, outrate, 8, 0) + else + STANDARDRESCALESTEREO(in8, inrate, insamps, out16, outrate, 8, 0) + } + else // downsample + STANDARDRESCALESTEREO(in8, inrate, insamps, out16, outrate, 8, 0) + } + } + else // 16-bit + { + if (outwidth == 2) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREO(in16, inrate, insamps, out16, outrate, 0, 0) + else + STANDARDRESCALESTEREO(in16, inrate, insamps, out16, outrate, 0, 0) + } + else // downsample + STANDARDRESCALESTEREO(in16, inrate, insamps, out16, outrate, 0, 0) + } + else + { + if (inrate == outrate) // quick convert + { + insamps *= 2; + QUICKCONVERT(in16, insamps, out8, 0, 8) + } + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREO(in16, inrate, insamps, out8, outrate, 0, 8) + else + STANDARDRESCALESTEREO(in16, inrate, insamps, out8, outrate, 0, 8) + } + else // downsample + STANDARDRESCALESTEREO(in16, inrate, insamps, out8, outrate, 0, 8) + } + } + } + else if (outchannels == 1 && inchannels == 2) + { + if (inwidth == 1) + { + if (outwidth == 1) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREOTOMONO(in8, inrate, insamps, out8, outrate, 0, 0) + else + STANDARDRESCALESTEREOTOMONO(in8, inrate, insamps, out8, outrate, 0, 0) + } + else // downsample + STANDARDRESCALESTEREOTOMONO(in8, inrate, insamps, out8, outrate, 0, 0) + } + else + { + if (inrate == outrate) // quick convert + QUICKCONVERTSTEREOTOMONO(in8, insamps, out16, 8, 0) + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREOTOMONO(in8, inrate, insamps, out16, outrate, 8, 0) + else + STANDARDRESCALESTEREOTOMONO(in8, inrate, insamps, out16, outrate, 8, 0) + } + else // downsample + STANDARDRESCALESTEREOTOMONO(in8, inrate, insamps, out16, outrate, 8, 0) + } + } + else // 16-bit + { + if (outwidth == 2) + { + if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREOTOMONO(in16, inrate, insamps, out16, outrate, 0, 0) + else + STANDARDRESCALESTEREOTOMONO(in16, inrate, insamps, out16, outrate, 0, 0) + } + else // downsample + STANDARDRESCALESTEREOTOMONO(in16, inrate, insamps, out16, outrate, 0, 0) + } + else + { + if (inrate == outrate) // quick convert + QUICKCONVERTSTEREOTOMONO(in16, insamps, out8, 0, 8) + else if (inrate < outrate) // upsample + { + if (resampstyle) + LINEARUPSCALESTEREOTOMONO(in16, inrate, insamps, out8, outrate, 0, 8) + else + STANDARDRESCALESTEREOTOMONO(in16, inrate, insamps, out8, outrate, 0, 8) + } + else // downsample + STANDARDRESCALESTEREOTOMONO(in16, inrate, insamps, out8, outrate, 0, 8) + } + } + } +} + /* ================ ResampleSfx @@ -34,28 +409,21 @@ ResampleSfx */ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data) { - int incount; - int outcount; - int srcsample; - float stepscale; - int i; - int sample, fracstep; - unsigned int samplefrac; - sfxcache_t *sc; extern cvar_t snd_linearresample; - qboolean linearsampling = !!(snd_linearresample.value); - + double scale; + sfxcache_t *sc; + int insamps, outsamps; + sc = Cache_Check (&sfx->cache); if (!sc) return; - stepscale = (float)inrate / snd_speed; // this is usually 0.5, 1, or 2 - - incount = sc->length; - outcount = sc->length / stepscale; - sc->length = outcount; + insamps = sc->length; + scale = snd_speed / (double)inrate; + outsamps = insamps * scale; + sc->length = outsamps; if (sc->loopstart != -1) - sc->loopstart = sc->loopstart / stepscale; + sc->loopstart = sc->loopstart * scale; sc->speed = snd_speed; if (loadas8bit.value) @@ -63,142 +431,16 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data) else sc->width = inwidth; - if (sc->numchannels==2) - { - if (stepscale == 1 && inwidth == 1 && sc->width == 1) - { - outcount*=2; - // fast special case - for (i=0 ; idata)[i] - = (int)( (unsigned char)(data[i]) - 128); - } - else if (stepscale == 1 && inwidth == 2 && sc->width == 2) - { - outcount*=2; - // fast special case - for (i=0 ; idata)[i] = LittleShort ( ((short *)data)[i] ); - } - else - { - // general case - samplefrac = 0; - fracstep = stepscale*256; - for (i=0 ; i> 8; - linearsampling = linearsampling && ((srcsample+1) < incount); - - if (linearsampling) - { - if (inwidth == 2) - sample = ((255 - (samplefrac & 0xFF)) * - LittleShort( ((short *)data)[ srcsample<<1 ] ) + - (samplefrac & 0xFF) * - LittleShort( ((short *)data)[ (srcsample+1)<<1 ] )) >> 8; - else - sample = ((255-(samplefrac & 0xFF)) * - (int)( (unsigned char)(data[ srcsample<<1 ]) - 128 ) + - (samplefrac & 0xFF) * - (int)( (unsigned char)(data[ (srcsample+1)<<1 ]) - 128 )); - } - else - { - if (inwidth == 2) - sample = LittleShort ( ((short *)data)[(srcsample<<1)] ); - else - sample = (int)( (unsigned char)(data[(srcsample<<1)]) - 128) << 8; - } - if (sc->width == 2) - ((short *)sc->data)[i<<1] = sample; - else - ((signed char *)sc->data)[i<<1] = sample >> 8; - -// srcsample = samplefrac >> 8; -// samplefrac += fracstep; - if (linearsampling) - { - if (inwidth == 2) - sample = ((255 - (samplefrac & 0xFF)) * - LittleShort( ((short *)data)[ (srcsample<<1)+1 ] ) + - (samplefrac & 0xFF) * - LittleShort( ((short *)data)[ ((srcsample+1)<<1)+1 ] )) >> 8; - else - sample = ((255-(samplefrac & 0xFF)) * - (int)( (unsigned char)(data[ (srcsample<<1)+1 ]) - 128 ) + - (samplefrac & 0xFF) * - (int)( (unsigned char)(data[ ((srcsample+1)<<1)+1 ]) - 128 )); - } - else - { - if (inwidth == 2) - sample = LittleShort ( ((short *)data)[(srcsample<<1)+1] ); - else - sample = (int)( (unsigned char)(data[(srcsample<<1)+1]) - 128) << 8; - } - if (sc->width == 2) - ((short *)sc->data)[(i<<1)+1] = sample; - else - ((signed char *)sc->data)[(i<<1)+1] = sample >> 8; - - samplefrac += fracstep; - } - } - return; - } - -// resample / decimate to the current source rate - - if (stepscale == 1 && inwidth == 1 && sc->width == 1) - { -// fast special case - for (i=0 ; idata)[i] - = (int)( (unsigned char)(data[i]) - 128); - } - else if (stepscale == 1 && inwidth == 2 && sc->width == 2) - { -// fast special case - for (i=0 ; idata)[i] = LittleShort ( ((short *)data)[i] ); - } - else - { -// general case - samplefrac = 0; - fracstep = stepscale*256; - for (i=0 ; i> 8; - linearsampling = linearsampling && ((srcsample+1) < incount); - if (linearsampling) - { - if (inwidth == 2) - sample = ((255 - (samplefrac & 0xFF)) * - LittleShort( ((short *)data)[srcsample] ) + - (samplefrac & 0xFF) * - LittleShort( ((short *)data)[srcsample+1] )) >> 8; - else - sample = ((255-(samplefrac & 0xFF)) * - (int)( (unsigned char)(data[srcsample]) - 128 ) + - (samplefrac & 0xFF) * - (int)( (unsigned char)(data[srcsample+1]) - 128 )); - } - else - { - if (inwidth == 2) - sample = LittleShort ( ((short *)data)[srcsample] ); - else - sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8; - } - if (sc->width == 2) - ((short *)sc->data)[i] = sample; - else - ((signed char *)sc->data)[i] = sample >> 8; - samplefrac += fracstep; - } - } + SND_ResampleStream (data, + inrate, + inwidth, + sc->numchannels, + insamps, + sc->data, + sc->speed, + sc->width, + sc->numchannels, + (int)snd_linearresample.value); } //============================================================================= @@ -315,6 +557,11 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed) sc->width = 1; sc->speed = rate; + if (sc->width == 1) + COM_CharBias(data, sc->length); + else if (sc->width == 2) + COM_SwapLittleShortBlock((short *)data, sc->length); + ResampleSfx (s, sc->speed, sc->width, data); return sc; @@ -349,6 +596,11 @@ sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed) sc->width = info.width; sc->numchannels = info.numchannels; + if (sc->width == 1) + COM_CharBias(data + info.dataofs, sc->length*sc->numchannels); + else if (sc->width == 2) + COM_SwapLittleShortBlock((short *)(data + info.dataofs), sc->length*sc->numchannels); + ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); return sc; diff --git a/engine/client/sound.h b/engine/client/sound.h index 657112eeb..1c398b45d 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -139,6 +139,8 @@ channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel); // spatializes a channel void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch); +void SND_ResampleStream (void *in, int inrate, int inwidth, int inchannels, int insamps, void *out, int outrate, int outwidth, int outchannels, int resampstyle); + // restart entire sound subsystem (doesn't flush old sounds, so make sure that happens) void S_DoRestart (void); diff --git a/engine/common/common.c b/engine/common/common.c index 8a5186fc5..c9d816c7c 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -641,6 +641,35 @@ float FloatNoSwap (float f) return f; } +void COM_SwapLittleShortBlock (short *s, int size) +{ + if (size <= 0) + return; + + if (!bigendien) + return; + + while (size) + { + *s = ShortSwap(*s); + s++; + size--; + } +} + +void COM_CharBias (signed char *c, int size) +{ + if (size <= 0) + return; + + while (size) + { + *c = (*(unsigned char *)c) - 128; + c++; + size--; + } +} + /* ============================================================================== diff --git a/engine/common/common.h b/engine/common/common.h index 6fc35f54f..cdc342d71 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -112,6 +112,9 @@ extern float (*LittleFloat) (float l); short ShortSwap (short l); int LongSwap (int l); +void COM_CharBias (signed char *c, int size); +void COM_SwapLittleShortBlock (short *s, int size); + //============================================================================ struct usercmd_s; diff --git a/engine/common/fs.c b/engine/common/fs.c index 3a45b74fe..3902b28cc 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -690,7 +690,7 @@ void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, char *desc) *neatwadname = '\0'; else if (header.id[0] == 'P') { - COM_FileBase(desc, neatwadname, sizeof(neatwadname)-1); + COM_FileBase(desc, neatwadname, sizeof(neatwadname)); strcat(neatwadname, "#"); } else @@ -2298,7 +2298,7 @@ qbyte *COM_LoadFile (char *path, int usehunk) vfsfile_t *f; qbyte *buf; int len; - char base[32]; + char base[MAX_OSPATH]; flocation_t loc; FS_FLocateFile(path, FSLFRT_LENGTH, &loc);