add simple linear resampling implementation to be used when libsamplerate
is not available git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@1282 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
de56acd493
commit
a8f9e84598
67
rdpsnd_dsp.c
67
rdpsnd_dsp.c
@ -132,11 +132,6 @@ rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16
|
|||||||
int err;
|
int err;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_LIBSAMPLERATE
|
|
||||||
if (device_srate != 44100 && device_srate != 22050)
|
|
||||||
return False;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (device_bitspersample != 16 && device_bitspersample != 8)
|
if (device_bitspersample != 16 && device_bitspersample != 8)
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
@ -170,10 +165,6 @@ rdpsnd_dsp_resample_supported(WAVEFORMATEX * format)
|
|||||||
return False;
|
return False;
|
||||||
if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
|
if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
|
||||||
return False;
|
return False;
|
||||||
#ifndef HAVE_LIBSAMPLERATE
|
|
||||||
if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))
|
|
||||||
return False;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
@ -185,11 +176,11 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
|||||||
#ifdef HAVE_LIBSAMPLERATE
|
#ifdef HAVE_LIBSAMPLERATE
|
||||||
SRC_DATA resample_data;
|
SRC_DATA resample_data;
|
||||||
float *infloat, *outfloat;
|
float *infloat, *outfloat;
|
||||||
int innum, outnum;
|
|
||||||
int err;
|
int err;
|
||||||
#else
|
#else
|
||||||
int offset;
|
int ratio1k = (resample_to_srate * 1000) / format->nSamplesPerSec;
|
||||||
#endif
|
#endif
|
||||||
|
int innum, outnum;
|
||||||
static BOOL warned = False;
|
static BOOL warned = False;
|
||||||
unsigned char *tmpdata = NULL;
|
unsigned char *tmpdata = NULL;
|
||||||
int samplewidth = format->wBitsPerSample / 8;
|
int samplewidth = format->wBitsPerSample / 8;
|
||||||
@ -232,6 +223,8 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
|||||||
warned = True;
|
warned = True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
innum = size / samplewidth;
|
||||||
|
|
||||||
/* Do the resampling */
|
/* Do the resampling */
|
||||||
#ifdef HAVE_LIBSAMPLERATE
|
#ifdef HAVE_LIBSAMPLERATE
|
||||||
if (src_converter == NULL)
|
if (src_converter == NULL)
|
||||||
@ -240,7 +233,6 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
innum = size / samplewidth;
|
|
||||||
outnum = ((float) innum * ((float) resample_to_srate / (float) format->nSamplesPerSec)) + 1;
|
outnum = ((float) innum * ((float) resample_to_srate / (float) format->nSamplesPerSec)) + 1;
|
||||||
|
|
||||||
infloat = xmalloc(sizeof(float) * innum);
|
infloat = xmalloc(sizeof(float) * innum);
|
||||||
@ -263,42 +255,45 @@ rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
|
|||||||
|
|
||||||
outsize = resample_data.output_frames_gen * resample_to_channels * samplewidth;
|
outsize = resample_data.output_frames_gen * resample_to_channels * samplewidth;
|
||||||
*out = xmalloc(outsize);
|
*out = xmalloc(outsize);
|
||||||
src_float_to_short_array(outfloat, (short *) *out, resample_data.output_frames_gen * resample_to_channels);
|
src_float_to_short_array(outfloat, (short *) *out,
|
||||||
|
resample_data.output_frames_gen * resample_to_channels);
|
||||||
xfree(outfloat);
|
xfree(outfloat);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
if (format->nSamplesPerSec != 22050)
|
/* Michaels simple linear resampler */
|
||||||
|
if (resample_to_srate < format->nSamplesPerSec)
|
||||||
{
|
{
|
||||||
if (!warned)
|
warning("downsampling currently not supported!\n");
|
||||||
{
|
|
||||||
warning("unsupported source samplerate (%u), not resampling!\n",
|
|
||||||
format->nSamplesPerSec);
|
|
||||||
warned = True;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
outsize = size * 2;
|
outnum = (innum * ratio1k) / 1000;
|
||||||
|
|
||||||
|
outsize = outnum * samplewidth;
|
||||||
*out = xmalloc(outsize);
|
*out = xmalloc(outsize);
|
||||||
|
bzero(*out, outsize);
|
||||||
|
|
||||||
/* Resample from 22050 to 44100 */
|
for (i = 0; i < outsize / (resample_to_channels * samplewidth); i++)
|
||||||
for (i = 0; i < (size / samplewidth); i++)
|
|
||||||
{
|
{
|
||||||
/* On a stereo-channel we must make sure that left and right
|
int source = ((i + ratio1k / 1000 - 1) * 1000) / ratio1k;
|
||||||
does not get mixed up, so we need to expand the sample-
|
|
||||||
data with channels in mind: 1234 -> 12123434
|
if (source * resample_to_channels + samplewidth > size)
|
||||||
If we have a mono-channel, we can expand the data by simply
|
break;
|
||||||
doubling the sample-data: 1234 -> 11223344 */
|
|
||||||
if (resample_to_channels == 2)
|
if (resample_to_channels == 2)
|
||||||
offset = ((i * 2) - (i & 1)) * samplewidth;
|
{
|
||||||
else
|
memcpy(*out + (i * resample_to_channels * samplewidth),
|
||||||
offset = (i * 2) * samplewidth;
|
in + (source * resample_to_channels * samplewidth), samplewidth);
|
||||||
|
memcpy(*out + (i * resample_to_channels * samplewidth) + samplewidth,
|
||||||
memcpy(*out + offset, in + (i * samplewidth), samplewidth);
|
in + (source * resample_to_channels * samplewidth) + samplewidth,
|
||||||
memcpy(*out + (resample_to_channels * samplewidth + offset),
|
samplewidth);
|
||||||
in + (i * samplewidth), samplewidth);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(*out + (i * samplewidth), in + (source * samplewidth), samplewidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outsize = i * resample_to_channels * samplewidth;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (tmpdata != NULL)
|
if (tmpdata != NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user