engine: soundlib: implement linear interpolation in Sound_ResampleInternal
* split resampling into three functions * added resampling using SDL_AudioCVT, it's slow, so isn't enabled by default
This commit is contained in:
parent
e19aa001b2
commit
55fcbc8880
1 changed files with 352 additions and 104 deletions
|
@ -14,6 +14,9 @@ GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "soundlib.h"
|
#include "soundlib.h"
|
||||||
|
#if XASH_SDL
|
||||||
|
#include <SDL_audio.h>
|
||||||
|
#endif // XASH_SDL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============================================================================
|
=============================================================================
|
||||||
|
@ -130,6 +133,309 @@ uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
|
||||||
return msecs;
|
return msecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static qboolean Sound_ConvertNoResample( wavdata_t *sc, int inwidth, int outwidth, int outcount )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if( inwidth == 1 && outwidth == 2 ) // S8 to S16
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount * sc->channels; i++ )
|
||||||
|
((int16_t*)sound.tempbuffer)[i] = ((int8_t *)sc->buffer)[i] * 256;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inwidth == 2 && outwidth == 1 ) // S16 to S8
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount * sc->channels; i++ )
|
||||||
|
((int8_t*)sound.tempbuffer)[i] = ((int16_t *)sc->buffer)[i] / 256;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean Sound_ConvertDownsample( wavdata_t *sc, int inwidth, int outwidth, int outcount, double stepscale )
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
double j;
|
||||||
|
|
||||||
|
if( inwidth == 1 && outwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *data = (int8_t *)sc->buffer;
|
||||||
|
|
||||||
|
if( outwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0];
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( outwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0] * 256;
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1] * 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j] * 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *data = (int16_t *)sc->buffer;
|
||||||
|
|
||||||
|
if( outwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0] / 256;
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1] / 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j] / 256;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( outwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0];
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qboolean Sound_ConvertUpsample( wavdata_t *sc, int inwidth, int outwidth, int outcount, double stepscale )
|
||||||
|
{
|
||||||
|
const int incount = ( outcount * stepscale ) - 1;
|
||||||
|
size_t i;
|
||||||
|
double j;
|
||||||
|
double frac;
|
||||||
|
|
||||||
|
if( inwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *data = (int8_t *)sc->buffer;
|
||||||
|
|
||||||
|
if( outwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0];
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1];
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = j - (int)j;
|
||||||
|
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||||
|
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j];
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = j - (int)j;
|
||||||
|
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( outwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0] * 256;
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1] * 256;
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = ( j - (int)j ) * 256;
|
||||||
|
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||||
|
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j] * 256;
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = ( j - (int)j ) * 256;
|
||||||
|
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *data = (int16_t *)sc->buffer;
|
||||||
|
|
||||||
|
if( outwidth == 1 )
|
||||||
|
{
|
||||||
|
int8_t *outdata = (int8_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0] / 256;
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1] / 256;
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = ( j - (int)j ) / 256;
|
||||||
|
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||||
|
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j] / 256;
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = ( j - (int)j ) / 256;
|
||||||
|
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( outwidth == 2 )
|
||||||
|
{
|
||||||
|
int16_t *outdata = (int16_t *)sound.tempbuffer;
|
||||||
|
|
||||||
|
if( sc->channels == 2 )
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i*2+0] = data[((int)j)*2+0];
|
||||||
|
outdata[i*2+1] = data[((int)j)*2+1];
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = j - (int)j;
|
||||||
|
outdata[i*2+0] += (data[((int)j+1)*2+0] - data[((int)j)*2+0]) * frac;
|
||||||
|
outdata[i*2+1] += (data[((int)j+1)*2+1] - data[((int)j)*2+1]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( i = 0; i < outcount; i++ )
|
||||||
|
{
|
||||||
|
j = stepscale * i;
|
||||||
|
outdata[i] = data[(int)j];
|
||||||
|
if( j != (int)j && j < incount )
|
||||||
|
{
|
||||||
|
frac = j - (int)j;
|
||||||
|
outdata[i] += (data[(int)j+1] - data[(int)j]) * frac;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sound_ResampleInternal
|
Sound_ResampleInternal
|
||||||
|
@ -139,125 +445,70 @@ We need convert sound to signed even if nothing to resample
|
||||||
*/
|
*/
|
||||||
static qboolean Sound_ResampleInternal( wavdata_t *sc, int inrate, int inwidth, int outrate, int outwidth )
|
static qboolean Sound_ResampleInternal( wavdata_t *sc, int inrate, int inwidth, int outrate, int outwidth )
|
||||||
{
|
{
|
||||||
double stepscale, j;
|
const size_t oldsize = sc->size;
|
||||||
int outcount;
|
|
||||||
int i;
|
|
||||||
qboolean handled = false;
|
qboolean handled = false;
|
||||||
|
double stepscale;
|
||||||
|
double t1, t2;
|
||||||
|
int outcount;
|
||||||
|
|
||||||
if( inrate == outrate && inwidth == outwidth )
|
if( inrate == outrate && inwidth == outwidth )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
t1 = Sys_DoubleTime();
|
||||||
|
|
||||||
stepscale = (double)inrate / outrate; // this is usually 0.5, 1, or 2
|
stepscale = (double)inrate / outrate; // this is usually 0.5, 1, or 2
|
||||||
outcount = sc->samples / stepscale;
|
outcount = sc->samples / stepscale;
|
||||||
sc->size = outcount * outwidth * sc->channels;
|
sc->size = outcount * outwidth * sc->channels;
|
||||||
|
|
||||||
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, sc->size );
|
|
||||||
|
|
||||||
sc->samples = outcount;
|
sc->samples = outcount;
|
||||||
if( FBitSet( sc->flags, SOUND_LOOPED ))
|
if( FBitSet( sc->flags, SOUND_LOOPED ))
|
||||||
sc->loopStart = sc->loopStart / stepscale;
|
sc->loopStart = sc->loopStart / stepscale;
|
||||||
|
|
||||||
if( inrate == outrate )
|
#if 0 && XASH_SDL // slow but somewhat accurate
|
||||||
{
|
{
|
||||||
if( inwidth == 1 && outwidth == 2 ) // S8 to S16
|
const SDL_AudioFormat infmt = inwidth == 1 ? AUDIO_S8 : AUDIO_S16;
|
||||||
{
|
const SDL_AudioFormat outfmt = outwidth == 1 ? AUDIO_S8 : AUDIO_S16;
|
||||||
for( i = 0; i < outcount * sc->channels; i++ )
|
SDL_AudioCVT cvt;
|
||||||
((int16_t*)sound.tempbuffer)[i] = ((int8_t *)sc->buffer)[i] * 256;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
else if( inwidth == 2 && outwidth == 1 ) // S16 to S8
|
|
||||||
{
|
|
||||||
for( i = 0; i < outcount * sc->channels; i++ )
|
|
||||||
((int8_t*)sound.tempbuffer)[i] = ((int16_t *)sc->buffer)[i] / 256;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // resample case
|
|
||||||
{
|
|
||||||
if( inwidth == 1 )
|
|
||||||
{
|
|
||||||
int8_t *data = (int8_t *)sc->buffer;
|
|
||||||
|
|
||||||
if( outwidth == 1 )
|
// SDL_AudioCVT does conversion in place, original buffer is used for it
|
||||||
{
|
if( SDL_BuildAudioCVT( &cvt, infmt, sc->channels, inrate, outfmt, sc->channels, outrate ) > 0 && cvt.needed )
|
||||||
if( sc->channels == 2 )
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
{
|
|
||||||
((int8_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0];
|
|
||||||
((int8_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
((int8_t*)sound.tempbuffer)[i] = data[(int)j];
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
else if( outwidth == 2 )
|
|
||||||
{
|
|
||||||
if( sc->channels == 2 )
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
{
|
|
||||||
((int16_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0] * 256;
|
|
||||||
((int16_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1] * 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
((int16_t*)sound.tempbuffer)[i] = data[(int)j] * 256;
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( inwidth == 2 )
|
|
||||||
{
|
{
|
||||||
int16_t *data = (int16_t *)sc->buffer;
|
sc->buffer = (byte *)Mem_Realloc( host.soundpool, sc->buffer, oldsize * cvt.len_mult );
|
||||||
|
cvt.len = oldsize;
|
||||||
|
cvt.buf = sc->buffer;
|
||||||
|
|
||||||
if( outwidth == 1 )
|
if( !SDL_ConvertAudio( &cvt ))
|
||||||
{
|
{
|
||||||
if( sc->channels == 2 )
|
t2 = Sys_DoubleTime();
|
||||||
{
|
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs through SDL)\n", inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
sc->rate = outrate;
|
||||||
{
|
sc->width = outwidth;
|
||||||
((int8_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0] / 256;
|
return false; // HACKHACK: return false so Sound_Process won't reallocate buffer
|
||||||
((int8_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1] / 256;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
((int8_t*)sound.tempbuffer)[i] = data[(int)j] / 256;
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
else if( outwidth == 2 )
|
|
||||||
{
|
|
||||||
if( sc->channels == 2 )
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
{
|
|
||||||
((int16_t*)sound.tempbuffer)[i*2+0] = data[((int)j)*2+0];
|
|
||||||
((int16_t*)sound.tempbuffer)[i*2+1] = data[((int)j)*2+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for( i = 0, j = 0; i < outcount; i++, j += stepscale )
|
|
||||||
((int16_t*)sound.tempbuffer)[i] = data[(int)j];
|
|
||||||
}
|
|
||||||
handled = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sound.tempbuffer = (byte *)Mem_Realloc( host.soundpool, sound.tempbuffer, sc->size );
|
||||||
|
|
||||||
|
if( inrate == outrate ) // no resampling, just copy data
|
||||||
|
handled = Sound_ConvertNoResample( sc, inwidth, outwidth, outcount );
|
||||||
|
else if( inrate > outrate ) // fast case, usually downsample but is also ok for upsampling
|
||||||
|
handled = Sound_ConvertDownsample( sc, inwidth, outwidth, outcount, stepscale );
|
||||||
|
else // upsample case, w/ interpolation
|
||||||
|
handled = Sound_ConvertUpsample( sc, inwidth, outwidth, outcount, stepscale );
|
||||||
|
|
||||||
|
t2 = Sys_DoubleTime();
|
||||||
|
|
||||||
if( handled )
|
if( handled )
|
||||||
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz]\n", inwidth * 8, inrate, outwidth * 8, outrate );
|
{
|
||||||
|
if( t2 - t1 > 0.01f ) // critical, report to mod developer
|
||||||
|
Con_Printf( S_WARN "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs)\n", inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||||
|
else
|
||||||
|
Con_Reportf( "Sound_Resample: from [%d bit %d Hz] to [%d bit %d Hz] (took %.3fs)\n", inwidth * 8, inrate, outwidth * 8, outrate, t2 - t1 );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Con_Reportf( S_ERROR "Sound_Resample: unsupported from [%d bit %d Hz] to [%d bit %d Hz]\n", inwidth * 8, inrate, outwidth * 8, outrate );
|
Con_Printf( S_ERROR "Sound_Resample: unsupported from [%d bit %d Hz] to [%d bit %d Hz]\n", inwidth * 8, inrate, outwidth * 8, outrate );
|
||||||
|
|
||||||
sc->rate = outrate;
|
sc->rate = outrate;
|
||||||
sc->width = outwidth;
|
sc->width = outwidth;
|
||||||
|
@ -274,23 +525,20 @@ qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags )
|
||||||
if( !snd || !snd->buffer )
|
if( !snd || !snd->buffer )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(( flags & SOUND_RESAMPLE ) && ( width > 0 || rate > 0 ))
|
if( FBitSet( flags, SOUND_RESAMPLE ) && ( width > 0 || rate > 0 ))
|
||||||
{
|
{
|
||||||
if( Sound_ResampleInternal( snd, snd->rate, snd->width, rate, width ))
|
result = Sound_ResampleInternal( snd, snd->rate, snd->width, rate, width );
|
||||||
|
|
||||||
|
if( result )
|
||||||
{
|
{
|
||||||
Mem_Free( snd->buffer ); // free original image buffer
|
Mem_Free( snd->buffer ); // free original image buffer
|
||||||
snd->buffer = Sound_Copy( snd->size ); // unzone buffer (don't touch image.tempbuffer)
|
snd->buffer = Sound_Copy( snd->size ); // unzone buffer (don't touch sound.tempbuffer)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not resampled
|
|
||||||
result = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*wav = snd;
|
*wav = snd;
|
||||||
|
|
||||||
return false;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean Sound_SupportedFileFormat( const char *fileext )
|
qboolean Sound_SupportedFileFormat( const char *fileext )
|
||||||
|
|
Loading…
Add table
Reference in a new issue