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:
parent
a10f1f22a6
commit
b67a5991dc
8 changed files with 510 additions and 284 deletions
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ; i<outcount ; i++)
|
||||
((signed char *)sc->data)[i]
|
||||
= (int)( (unsigned char)(data[i]) - 128);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue