mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 22:51:57 +00:00
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);
|
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;
|
||||||
|
|
|
@ -395,6 +395,20 @@ 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;
|
||||||
|
|
|
@ -84,6 +84,7 @@ cvar_t snd_playersoundvolume = SCVAR("snd_localvolume", "1"); //sugested by crun
|
||||||
|
|
||||||
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 sample;
|
|
||||||
short *indata = (short *)data;
|
|
||||||
short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
|
short *outpos = (short *)(newcache->data + spare * (s->sfxcache->numchannels) * s->sfxcache->width);
|
||||||
if (speedfactor==1) //fast
|
SND_ResampleStream(data,
|
||||||
{
|
speed,
|
||||||
while (samples--)
|
width,
|
||||||
{
|
channels,
|
||||||
sample = *indata++;
|
samples,
|
||||||
*outpos++ = sample;
|
outpos,
|
||||||
}
|
snd_speed,
|
||||||
}
|
s->sfxcache->width,
|
||||||
else
|
s->sfxcache->numchannels,
|
||||||
{
|
(int)snd_linearresample_stream.value);
|
||||||
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue