summaryrefslogtreecommitdiff
path: root/codecs/speex/resample.c
diff options
context:
space:
mode:
Diffstat (limited to 'codecs/speex/resample.c')
-rw-r--r--codecs/speex/resample.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/codecs/speex/resample.c b/codecs/speex/resample.c
index 2b0395180..0797352ad 100644
--- a/codecs/speex/resample.c
+++ b/codecs/speex/resample.c
@@ -1,6 +1,6 @@
/* Copyright (C) 2007-2008 Jean-Marc Valin
Copyright (C) 2008 Thorvald Natvig
-
+
File: resample.c
Arbitrary resampling code
@@ -38,22 +38,22 @@
- Low memory requirement
- Good *perceptual* quality (and not best SNR)
- Warning: This resampler is relatively new. Although I think I got rid of
+ Warning: This resampler is relatively new. Although I think I got rid of
all the major bugs and I don't expect the API to change anymore, there
may be something I've missed. So use with caution.
This algorithm is based on this original resampling algorithm:
Smith, Julius O. Digital Audio Resampling Home Page
- Center for Computer Research in Music and Acoustics (CCRMA),
+ Center for Computer Research in Music and Acoustics (CCRMA),
Stanford University, 2007.
Web published at http://www-ccrma.stanford.edu/~jos/resample/.
- There is one main difference, though. This resampler uses cubic
+ There is one main difference, though. This resampler uses cubic
interpolation instead of linear interpolation in the above paper. This
makes the table much smaller and makes it possible to compute that table
- on a per-stream basis. In turn, being able to tweak the table for each
- stream makes it possible to both reduce complexity on simple ratios
- (e.g. 2/3), and get rid of the rounding operations in the inner loop.
+ on a per-stream basis. In turn, being able to tweak the table for each
+ stream makes it possible to both reduce complexity on simple ratios
+ (e.g. 2/3), and get rid of the rounding operations in the inner loop.
The latter both reduces CPU time and makes the algorithm more SIMD-friendly.
*/
@@ -106,7 +106,7 @@ struct SpeexResamplerState_ {
spx_uint32_t out_rate;
spx_uint32_t num_rate;
spx_uint32_t den_rate;
-
+
int quality;
spx_uint32_t nb_channels;
spx_uint32_t filt_len;
@@ -118,17 +118,17 @@ struct SpeexResamplerState_ {
spx_uint32_t oversample;
int initialised;
int started;
-
+
/* These are per-channel */
spx_int32_t *last_sample;
spx_uint32_t *samp_frac_num;
spx_uint32_t *magic_samples;
-
+
spx_word16_t *mem;
spx_word16_t *sinc_table;
spx_uint32_t sinc_table_length;
resampler_basic_func resampler_ptr;
-
+
int in_stride;
int out_stride;
} ;
@@ -170,7 +170,7 @@ static double kaiser8_table[36] = {
0.32108304, 0.27619388, 0.23465776, 0.19672670, 0.16255380, 0.13219758,
0.10562887, 0.08273982, 0.06335451, 0.04724088, 0.03412321, 0.02369490,
0.01563093, 0.00959968, 0.00527363, 0.00233883, 0.00050000, 0.00000000};
-
+
static double kaiser6_table[36] = {
0.99733006, 1.00000000, 0.99733006, 0.98935595, 0.97618418, 0.95799003,
0.93501423, 0.90755855, 0.87598009, 0.84068475, 0.80211977, 0.76076565,
@@ -183,7 +183,7 @@ struct FuncDef {
double *table;
int oversample;
};
-
+
static struct FuncDef _KAISER12 = {kaiser12_table, 64};
#define KAISER12 (&_KAISER12)
/*static struct FuncDef _KAISER12 = {kaiser12_table, 32};
@@ -205,7 +205,7 @@ struct QualityMapping {
/* This table maps conversion quality to internal parameters. There are two
- reasons that explain why the up-sampling bandwidth is larger than the
+ reasons that explain why the up-sampling bandwidth is larger than the
down-sampling bandwidth:
1) When up-sampling, we can assume that the spectrum is already attenuated
close to the Nyquist rate (from an A/D or a previous resampling filter)
@@ -231,7 +231,7 @@ static double compute_func(float x, struct FuncDef *func)
{
float y, frac;
double interp[4];
- int ind;
+ int ind;
y = x*func->oversample;
ind = (int)floor(y);
frac = (y-ind);
@@ -242,7 +242,7 @@ static double compute_func(float x, struct FuncDef *func)
interp[0] = -0.3333333333*frac + 0.5*(frac*frac) - 0.1666666667*(frac*frac*frac);
/* Just to make sure we don't have rounding problems */
interp[1] = 1.f-interp[3]-interp[2]-interp[0];
-
+
/*sum = frac*accum[1] + (1-frac)*accum[2];*/
return interp[0]*func->table[ind] + interp[1]*func->table[ind+1] + interp[2]*func->table[ind+2] + interp[3]*func->table[ind+3];
}
@@ -461,7 +461,7 @@ static int resampler_basic_interpolate_single(SpeexResamplerState *st, spx_uint3
cubic_coef(frac, interp);
sum = interpolate_product_single(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
#endif
-
+
out[out_stride * out_sample++] = PSHR32(sum,15);
last_sample += int_advance;
samp_frac_num += frac_advance;
@@ -523,7 +523,7 @@ static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint3
cubic_coef(frac, interp);
sum = interpolate_product_double(iptr, st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample, interp);
#endif
-
+
out[out_stride * out_sample++] = PSHR32(sum,15);
last_sample += int_advance;
samp_frac_num += frac_advance;
@@ -543,11 +543,11 @@ static int resampler_basic_interpolate_double(SpeexResamplerState *st, spx_uint3
static void update_filter(SpeexResamplerState *st)
{
spx_uint32_t old_length;
-
+
old_length = st->filt_len;
st->oversample = quality_map[st->quality].oversample;
st->filt_len = quality_map[st->quality].base_length;
-
+
if (st->num_rate > st->den_rate)
{
/* down-sampling */
@@ -570,7 +570,7 @@ static void update_filter(SpeexResamplerState *st)
/* up-sampling */
st->cutoff = quality_map[st->quality].upsample_bandwidth;
}
-
+
/* Choose the resampling type that requires the least amount of memory */
if (st->den_rate <= st->oversample)
{
@@ -623,7 +623,7 @@ static void update_filter(SpeexResamplerState *st)
st->int_advance = st->num_rate/st->den_rate;
st->frac_advance = st->num_rate%st->den_rate;
-
+
/* Here's the place where we update the filter memory to take into account
the change in filter length. It's probably the messiest part of the code
due to handling of lots of corner cases. */
@@ -661,7 +661,7 @@ static void update_filter(SpeexResamplerState *st)
/*if (st->magic_samples[i])*/
{
/* Try and remove the magic samples as if nothing had happened */
-
+
/* FIXME: This is wrong but for now we need it to avoid going over the array bounds */
olen = old_length + 2*st->magic_samples[i];
for (j=old_length-2+st->magic_samples[i];j>=0;j--)
@@ -736,18 +736,18 @@ static void update_filter(SpeexResamplerState *st)
st->filt_len = 0;
st->mem = 0;
st->resampler_ptr = 0;
-
+
st->cutoff = 1.f;
st->nb_channels = nb_channels;
st->in_stride = 1;
st->out_stride = 1;
-
+
#ifdef FIXED_POINT
st->buffer_size = 160;
#else
st->buffer_size = 160;
#endif
-
+
/* Per channel data */
st->last_sample = (spx_int32_t*)speex_alloc(nb_channels*sizeof(int));
st->magic_samples = (spx_uint32_t*)speex_alloc(nb_channels*sizeof(int));
@@ -762,9 +762,9 @@ static void update_filter(SpeexResamplerState *st)
speex_resampler_set_quality(st, quality);
speex_resampler_set_rate_frac(st, ratio_num, ratio_den, in_rate, out_rate);
-
+
update_filter(st);
-
+
st->initialised = 1;
if (err)
*err = RESAMPLER_ERR_SUCCESS;
@@ -789,17 +789,17 @@ static int speex_resampler_process_native(SpeexResamplerState *st, spx_uint32_t
int out_sample = 0;
spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
spx_uint32_t ilen;
-
+
st->started = 1;
-
+
/* Call the right resampler through the function ptr */
out_sample = st->resampler_ptr(st, channel_index, mem, in_len, out, out_len);
-
+
if (st->last_sample[channel_index] < (spx_int32_t)*in_len)
*in_len = st->last_sample[channel_index];
*out_len = out_sample;
st->last_sample[channel_index] -= *in_len;
-
+
ilen = *in_len;
for(j=0;j<N-1;++j)
@@ -812,11 +812,11 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
spx_uint32_t tmp_in_len = st->magic_samples[channel_index];
spx_word16_t *mem = st->mem + channel_index * st->mem_alloc_size;
const int N = st->filt_len;
-
+
speex_resampler_process_native(st, channel_index, &tmp_in_len, *out, &out_len);
st->magic_samples[channel_index] -= tmp_in_len;
-
+
/* If we couldn't process all "magic" input samples, save the rest for next time */
if (st->magic_samples[channel_index])
{
@@ -842,13 +842,13 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
const spx_uint32_t xlen = st->mem_alloc_size - filt_offs;
const int istride = st->in_stride;
- if (st->magic_samples[channel_index])
+ if (st->magic_samples[channel_index])
olen -= speex_resampler_magic(st, channel_index, &out, olen);
if (! st->magic_samples[channel_index]) {
while (ilen && olen) {
spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
spx_uint32_t ochunk = olen;
-
+
if (in) {
for(j=0;j<ichunk;++j)
x[j+filt_offs]=in[j*istride];
@@ -892,7 +892,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
#endif
st->out_stride = 1;
-
+
while (ilen && olen) {
spx_word16_t *y = ystack;
spx_uint32_t ichunk = (ilen > xlen) ? xlen : ilen;
@@ -929,7 +929,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
#else
out[j*ostride_save] = WORD2INT(ystack[j]);
#endif
-
+
ilen -= ichunk;
olen -= ochunk;
out += (ochunk+omagic) * ostride_save;
@@ -963,7 +963,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
st->out_stride = ostride_save;
return RESAMPLER_ERR_SUCCESS;
}
-
+
int speex_resampler_process_interleaved_int(SpeexResamplerState *st, const spx_int16_t *in, spx_uint32_t *in_len, spx_int16_t *out, spx_uint32_t *out_len)
{
spx_uint32_t i;
@@ -1003,7 +1003,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
spx_uint32_t i;
if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
return RESAMPLER_ERR_SUCCESS;
-
+
old_den = st->den_rate;
st->in_rate = in_rate;
st->out_rate = out_rate;
@@ -1018,7 +1018,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
st->den_rate /= fact;
}
}
-
+
if (old_den > 0)
{
for (i=0;i<st->nb_channels;i++)
@@ -1029,7 +1029,7 @@ static int speex_resampler_magic(SpeexResamplerState *st, spx_uint32_t channel_i
st->samp_frac_num[i] = st->den_rate-1;
}
}
-
+
if (st->initialised)
update_filter(st);
return RESAMPLER_ERR_SUCCESS;