1
0
Fork 0
forked from fte/fteqw

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
This commit is contained in:
TimeServ 2006-06-04 01:43:52 +00:00
parent a10f1f22a6
commit b67a5991dc
8 changed files with 510 additions and 284 deletions

View file

@ -361,6 +361,11 @@ qbyte *CIN_ReadNextFrame (void)
VFS_READ (cin.cinematic_file, samples, count*cin.s_width*cin.s_channels); 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); S_RawAudio (0, samples, cin.s_rate, count, cin.s_channels, cin.s_width);
in.data = compressed; in.data = compressed;

View file

@ -395,44 +395,58 @@ void Con_Selectioncolour_Callback(struct cvar_s *var, char *oldvalue)
SCR_StringToRGB(var->string, sccolor, 1); 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) void Key_ConsoleDrawSelectionBox(void)
{ {
extern cvar_t vid_conwidth, vid_conheight; extern cvar_t vid_conwidth, vid_conheight;
extern int mousecursor_x, mousecursor_y; extern int mousecursor_x, mousecursor_y;
int xpos, ypos, temp; int xpos, ypos, temp;
int xpos2, ypos2; int xpos2, ypos2;
if (!con_mousedown[2]) if (!con_mousedown[2])
return; return;
xpos2 = con_mousedown[0]; xpos2 = con_mousedown[0];
ypos2 = con_mousedown[1]; ypos2 = con_mousedown[1];
xpos = (int)((mousecursor_x*vid_conwidth.value)/(vid.width*8)); xpos = (int)((mousecursor_x*vid_conwidth.value)/(vid.width*8));
ypos = (int)((mousecursor_y*vid_conheight.value)/(vid.height*8)); ypos = (int)((mousecursor_y*vid_conheight.value)/(vid.height*8));
if (xpos2 < 1) if (xpos2 < 1)
xpos2 = 1; xpos2 = 1;
if (xpos < 1) if (xpos < 1)
xpos = 1; xpos = 1;
if (xpos2 > con_current->linewidth) if (xpos2 > con_current->linewidth)
xpos2 = con_current->linewidth; xpos2 = con_current->linewidth;
if (xpos > con_current->linewidth) if (xpos > con_current->linewidth)
xpos = con_current->linewidth; xpos = con_current->linewidth;
if (xpos2 > xpos) if (xpos2 > xpos)
{ {
temp = xpos; temp = xpos;
xpos = xpos2; xpos = xpos2;
xpos2 = temp; xpos2 = temp;
} }
xpos++; xpos++;
if (ypos2 > ypos) if (ypos2 > ypos)
{ {
temp = ypos; temp = ypos;
ypos = ypos2; ypos = ypos2;
ypos2 = temp; ypos2 = temp;
} }
ypos++; ypos++;
Draw_FillRGB(xpos2*8, ypos2*8, (xpos - xpos2)*8, (ypos - ypos2)*8, sccolor[0], sccolor[1], sccolor[2]); Draw_FillRGB(xpos2*8, ypos2*8, (xpos - xpos2)*8, (ypos - ypos2)*8, sccolor[0], sccolor[1], sccolor[2]);
} }

View file

@ -80,10 +80,11 @@ cvar_t snd_eax = SCVAR("snd_eax", "0");
cvar_t snd_speakers = SCVAR("snd_numspeakers", "2"); cvar_t snd_speakers = SCVAR("snd_numspeakers", "2");
cvar_t snd_buffersize = SCVAR("snd_buffersize", "0"); cvar_t snd_buffersize = SCVAR("snd_buffersize", "0");
cvar_t snd_samplebits = SCVARF("snd_samplebits", "16", CVAR_ARCHIVE); 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_capture = SCVAR("snd_capture", "0");
cvar_t snd_linearresample = SCVAR("snd_linearresample", "1"); 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"); 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_usemultipledevices, "Sound controls");
Cvar_Register(&snd_linearresample, "Sound controls"); Cvar_Register(&snd_linearresample, "Sound controls");
Cvar_Register(&snd_linearresample_stream, "Sound controls");
if (COM_CheckParm("-nosound")) if (COM_CheckParm("-nosound"))
{ {
@ -1560,7 +1562,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
int oldlength; int oldlength;
int spare; int spare;
int outsamples; int outsamples;
float speedfactor; double speedfactor;
sfxcache_t *newcache; sfxcache_t *newcache;
streaming_t *s, *free=NULL; streaming_t *s, *free=NULL;
for (s = s_streamers, i = 0; i < MAX_RAW_SOURCES; i++, s++) 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; newcache->length = spare + outsamples;
// move this whole operation to a seperate function?
if (channels == 1)
{ {
if (width == 2) extern cvar_t snd_linearresample_stream;
{ short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
short sample; SND_ResampleStream(data,
short *indata = (short *)data; speed,
short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width); width,
if (speedfactor==1) //fast channels,
{ samples,
while (samples--) outpos,
{ snd_speed,
sample = *indata++; s->sfxcache->width,
*outpos++ = sample; s->sfxcache->numchannels,
} (int)snd_linearresample_stream.value);
}
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");
} }
s->sfxcache->loopstart = s->sfxcache->length; s->sfxcache->loopstart = s->sfxcache->length;

View file

@ -27,6 +27,381 @@ int cache_full_cycle;
qbyte *S_Alloc (int size); 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 ResampleSfx
@ -34,28 +409,21 @@ ResampleSfx
*/ */
void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data) 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; extern cvar_t snd_linearresample;
qboolean linearsampling = !!(snd_linearresample.value); double scale;
sfxcache_t *sc;
int insamps, outsamps;
sc = Cache_Check (&sfx->cache); sc = Cache_Check (&sfx->cache);
if (!sc) if (!sc)
return; return;
stepscale = (float)inrate / snd_speed; // this is usually 0.5, 1, or 2 insamps = sc->length;
scale = snd_speed / (double)inrate;
incount = sc->length; outsamps = insamps * scale;
outcount = sc->length / stepscale; sc->length = outsamps;
sc->length = outcount;
if (sc->loopstart != -1) if (sc->loopstart != -1)
sc->loopstart = sc->loopstart / stepscale; sc->loopstart = sc->loopstart * scale;
sc->speed = snd_speed; sc->speed = snd_speed;
if (loadas8bit.value) if (loadas8bit.value)
@ -63,142 +431,16 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
else else
sc->width = inwidth; sc->width = inwidth;
if (sc->numchannels==2) SND_ResampleStream (data,
{ inrate,
if (stepscale == 1 && inwidth == 1 && sc->width == 1) inwidth,
{ sc->numchannels,
outcount*=2; insamps,
// fast special case sc->data,
for (i=0 ; i<outcount ; i++) sc->speed,
((signed char *)sc->data)[i] sc->width,
= (int)( (unsigned char)(data[i]) - 128); sc->numchannels,
} (int)snd_linearresample.value);
else if (stepscale == 1 && inwidth == 2 && sc->width == 2)
{
outcount*=2;
// fast special case
for (i=0 ; i<outcount ; i++)
((short *)sc->data)[i] = LittleShort ( ((short *)data)[i] );
}
else
{
// general case
samplefrac = 0;
fracstep = stepscale*256;
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 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 ; i<outcount ; i++)
((signed char *)sc->data)[i]
= (int)( (unsigned char)(data[i]) - 128);
}
else if (stepscale == 1 && inwidth == 2 && sc->width == 2)
{
// fast special case
for (i=0 ; i<outcount ; i++)
((short *)sc->data)[i] = LittleShort ( ((short *)data)[i] );
}
else
{
// general case
samplefrac = 0;
fracstep = stepscale*256;
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 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;
}
}
} }
//============================================================================= //=============================================================================
@ -315,6 +557,11 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
sc->width = 1; sc->width = 1;
sc->speed = rate; 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); ResampleSfx (s, sc->speed, sc->width, data);
return sc; return sc;
@ -349,6 +596,11 @@ sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
sc->width = info.width; sc->width = info.width;
sc->numchannels = info.numchannels; 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); ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);
return sc; return sc;

View file

@ -139,6 +139,8 @@ channel_t *SND_PickChannel(soundcardinfo_t *sc, int entnum, int entchannel);
// spatializes a channel // spatializes a channel
void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch); 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) // restart entire sound subsystem (doesn't flush old sounds, so make sure that happens)
void S_DoRestart (void); void S_DoRestart (void);

View file

@ -641,6 +641,35 @@ float FloatNoSwap (float f)
return 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--;
}
}
/* /*
============================================================================== ==============================================================================

View file

@ -112,6 +112,9 @@ extern float (*LittleFloat) (float l);
short ShortSwap (short l); short ShortSwap (short l);
int LongSwap (int l); int LongSwap (int l);
void COM_CharBias (signed char *c, int size);
void COM_SwapLittleShortBlock (short *s, int size);
//============================================================================ //============================================================================
struct usercmd_s; struct usercmd_s;

View file

@ -690,7 +690,7 @@ void *FSPAK_LoadDoomWadFile (vfsfile_t *packhandle, char *desc)
*neatwadname = '\0'; *neatwadname = '\0';
else if (header.id[0] == 'P') else if (header.id[0] == 'P')
{ {
COM_FileBase(desc, neatwadname, sizeof(neatwadname)-1); COM_FileBase(desc, neatwadname, sizeof(neatwadname));
strcat(neatwadname, "#"); strcat(neatwadname, "#");
} }
else else
@ -2298,7 +2298,7 @@ qbyte *COM_LoadFile (char *path, int usehunk)
vfsfile_t *f; vfsfile_t *f;
qbyte *buf; qbyte *buf;
int len; int len;
char base[32]; char base[MAX_OSPATH];
flocation_t loc; flocation_t loc;
FS_FLocateFile(path, FSLFRT_LENGTH, &loc); FS_FLocateFile(path, FSLFRT_LENGTH, &loc);