added snd_linearresample for better quality resampling, defaults to 1

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2253 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
TimeServ 2006-05-08 06:44:47 +00:00
parent 6197004228
commit de74e43c4a
2 changed files with 69 additions and 15 deletions

View File

@ -81,6 +81,7 @@ cvar_t snd_speakers = SCVAR("snd_numspeakers", "2");
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_usemultipledevices = SCVAR("snd_multipledevices", "0"); cvar_t snd_usemultipledevices = SCVAR("snd_multipledevices", "0");
@ -556,6 +557,8 @@ void S_Init (void)
Cvar_Register(&snd_playersoundvolume, "Sound controls"); Cvar_Register(&snd_playersoundvolume, "Sound controls");
Cvar_Register(&snd_usemultipledevices, "Sound controls"); Cvar_Register(&snd_usemultipledevices, "Sound controls");
Cvar_Register(&snd_linearresample, "Sound controls");
if (COM_CheckParm("-nosound")) if (COM_CheckParm("-nosound"))
{ {
Cvar_ForceSet(&nosound, "1"); Cvar_ForceSet(&nosound, "1");

View File

@ -34,6 +34,7 @@ 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 outcount;
int srcsample; int srcsample;
float stepscale; float stepscale;
@ -41,6 +42,8 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
int sample, fracstep; int sample, fracstep;
unsigned int samplefrac; unsigned int samplefrac;
sfxcache_t *sc; sfxcache_t *sc;
extern cvar_t snd_linearresample;
qboolean linearsampling = !!(snd_linearresample.value);
sc = Cache_Check (&sfx->cache); sc = Cache_Check (&sfx->cache);
if (!sc) if (!sc)
@ -48,6 +51,7 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
stepscale = (float)inrate / snd_speed; // this is usually 0.5, 1, or 2 stepscale = (float)inrate / snd_speed; // this is usually 0.5, 1, or 2
incount = sc->length;
outcount = sc->length / stepscale; outcount = sc->length / stepscale;
sc->length = outcount; sc->length = outcount;
if (sc->loopstart != -1) if (sc->loopstart != -1)
@ -84,12 +88,28 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
for (i=0 ; i<outcount ; i++) for (i=0 ; i<outcount ; i++)
{ {
srcsample = samplefrac >> 8; srcsample = samplefrac >> 8;
samplefrac += fracstep; 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) if (inwidth == 2)
sample = LittleShort ( ((short *)data)[(srcsample<<1)] ); sample = LittleShort ( ((short *)data)[(srcsample<<1)] );
else else
sample = (int)( (unsigned char)(data[(srcsample<<1)]) - 128) << 8; sample = (int)( (unsigned char)(data[(srcsample<<1)]) - 128) << 8;
}
if (sc->width == 2) if (sc->width == 2)
((short *)sc->data)[i<<1] = sample; ((short *)sc->data)[i<<1] = sample;
else else
@ -97,14 +117,32 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
// srcsample = samplefrac >> 8; // srcsample = samplefrac >> 8;
// samplefrac += fracstep; // 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) if (inwidth == 2)
sample = LittleShort ( ((short *)data)[(srcsample<<1)+1] ); sample = LittleShort ( ((short *)data)[(srcsample<<1)+1] );
else else
sample = (int)( (unsigned char)(data[(srcsample<<1)+1]) - 128) << 8; sample = (int)( (unsigned char)(data[(srcsample<<1)+1]) - 128) << 8;
}
if (sc->width == 2) if (sc->width == 2)
((short *)sc->data)[(i<<1)+1] = sample; ((short *)sc->data)[(i<<1)+1] = sample;
else else
((signed char *)sc->data)[(i<<1)+1] = sample >> 8; ((signed char *)sc->data)[(i<<1)+1] = sample >> 8;
samplefrac += fracstep;
} }
} }
return; return;
@ -133,21 +171,37 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
for (i=0 ; i<outcount ; i++) for (i=0 ; i<outcount ; i++)
{ {
srcsample = samplefrac >> 8; srcsample = samplefrac >> 8;
samplefrac += fracstep; 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) if (inwidth == 2)
sample = LittleShort ( ((short *)data)[srcsample] ); sample = LittleShort ( ((short *)data)[srcsample] );
else else
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8; sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
}
if (sc->width == 2) if (sc->width == 2)
((short *)sc->data)[i] = sample; ((short *)sc->data)[i] = sample;
else else
((signed char *)sc->data)[i] = sample >> 8; ((signed char *)sc->data)[i] = sample >> 8;
samplefrac += fracstep;
} }
} }
} }
//============================================================================= //=============================================================================
#ifdef DOOMWADS
// needs fine tuning.. educated guesses // needs fine tuning.. educated guesses
#define DSPK_RATE 128 #define DSPK_RATE 128
#define DSPK_FREQ 31 #define DSPK_FREQ 31
@ -264,7 +318,6 @@ sfxcache_t *S_LoadDoomSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
return sc; return sc;
} }
#endif
sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed) sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
{ {
@ -307,10 +360,8 @@ S_LoadSound_t AudioInputPlugins[10] =
S_LoadOVSound, S_LoadOVSound,
#endif #endif
S_LoadWavSound, S_LoadWavSound,
#ifdef DOOMWADS
S_LoadDoomSound, S_LoadDoomSound,
S_LoadDoomSpeakerSound, S_LoadDoomSpeakerSound,
#endif
}; };
qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc) qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc)