[xiph-commits] r12411 - in trunk/speex: include/speex libspeex
jm at svn.xiph.org
jm at svn.xiph.org
Thu Feb 1 06:02:45 PST 2007
Author: jm
Date: 2007-02-01 06:02:40 -0800 (Thu, 01 Feb 2007)
New Revision: 12411
Modified:
trunk/speex/include/speex/speex_resampler.h
trunk/speex/libspeex/resample.c
trunk/speex/libspeex/testresample.c
Log:
Changed the resampler API again. Introducing a quality setting.
Modified: trunk/speex/include/speex/speex_resampler.h
===================================================================
--- trunk/speex/include/speex/speex_resampler.h 2007-02-01 06:44:20 UTC (rev 12410)
+++ trunk/speex/include/speex/speex_resampler.h 2007-02-01 14:02:40 UTC (rev 12411)
@@ -66,7 +66,7 @@
typedef struct SpeexResamplerState_ SpeexResamplerState;
//typedef SpeexResamplerState;
-SpeexResamplerState *speex_resampler_init(int nb_channels, int in_rate, int out_rate, int in_rate_den, int out_rate_den);
+SpeexResamplerState *speex_resampler_init(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality);
void speex_resampler_destroy(SpeexResamplerState *st);
@@ -76,8 +76,10 @@
void speex_resampler_process_interleaved_float(SpeexResamplerState *st, const float *in, int *in_len, float *out, int *out_len);
-void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate, int in_rate_den, int out_rate_den);
+void speex_resample_set_rate(SpeexResamplerState *st, int ratio_num, int ratio_den, int in_rate, int out_rate);
+void speex_resample_set_quality(SpeexResamplerState *st, int quality);
+
void speex_resample_set_input_stride(SpeexResamplerState *st, int stride);
void speex_resample_set_output_stride(SpeexResamplerState *st, int stride);
Modified: trunk/speex/libspeex/resample.c
===================================================================
--- trunk/speex/libspeex/resample.c 2007-02-01 06:44:20 UTC (rev 12410)
+++ trunk/speex/libspeex/resample.c 2007-02-01 14:02:40 UTC (rev 12411)
@@ -89,6 +89,7 @@
int num_rate;
int den_rate;
+ int quality;
int nb_channels;
int last_sample;
int samp_frac_num;
@@ -97,7 +98,9 @@
int frac_advance;
float cutoff;
int oversample;
+ int initialised;
+
spx_word16_t *mem;
spx_word16_t *sinc_table;
int sinc_table_length;
@@ -134,31 +137,86 @@
}
#endif
-/*SpeexResamplerState *speex_resampler_init(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality)*/
+static void update_filter(SpeexResamplerState *st)
+{
+ int i;
+
+ st->oversample = OVERSAMPLE;
-SpeexResamplerState *speex_resampler_init(int nb_channels, int in_rate, int out_rate, int in_rate_den, int out_rate_den)
+ st->filt_len = 8 + 12*st->quality;
+
+ /* Choose the resampling type that requires the least amount of memory */
+ if (st->den_rate <= st->oversample)
+ {
+ if (!st->sinc_table)
+ st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));
+ else if (st->sinc_table_length < st->filt_len*st->den_rate)
+ {
+ st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));
+ st->sinc_table_length = st->filt_len*st->den_rate;
+ }
+ for (i=0;i<st->den_rate;i++)
+ {
+ int j;
+ for (j=0;j<st->filt_len;j++)
+ {
+ st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len);
+ }
+ }
+ st->type = SPEEX_RESAMPLER_DIRECT;
+ /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
+ } else {
+ if (!st->sinc_table)
+ st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
+ else if (st->sinc_table_length < st->filt_len*st->oversample+8)
+ {
+ st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
+ st->sinc_table_length = st->filt_len*st->oversample+8;
+ }
+ for (i=-4;i<st->oversample*st->filt_len+4;i++)
+ st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len);
+ st->type = SPEEX_RESAMPLER_INTERPOLATE;
+ /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
+ }
+ st->int_advance = st->num_rate/st->den_rate;
+ st->frac_advance = st->num_rate%st->den_rate;
+
+ if (!st->mem)
+ st->mem = (spx_word16_t*)speex_alloc(st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
+ else
+ st->mem = (spx_word16_t*)speex_realloc(st->mem, st->nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
+ for (i=0;i<st->nb_channels*(st->filt_len-1);i++)
+ st->mem[i] = 0;
+
+}
+
+
+SpeexResamplerState *speex_resampler_init(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality)
{
- int i;
SpeexResamplerState *st = (SpeexResamplerState *)speex_alloc(sizeof(SpeexResamplerState));
+ st->initialised = 0;
st->in_rate = 0;
st->out_rate = 0;
st->num_rate = 0;
st->den_rate = 0;
+ st->quality = -1;
+ st->sinc_table_length = 0;
+ st->mem = 0;
st->cutoff = 1.f;
st->nb_channels = nb_channels;
st->last_sample = 0;
- st->filt_len = FILTER_SIZE;
- st->oversample = OVERSAMPLE;
- st->mem = (spx_word16_t*)speex_alloc(nb_channels*(st->filt_len-1) * sizeof(spx_word16_t));
- for (i=0;i<nb_channels*(st->filt_len-1);i++)
- st->mem[i] = 0;
- st->sinc_table_length = 0;
- speex_resample_set_rate(st, in_rate, out_rate, in_rate_den, out_rate_den);
-
st->in_stride = 1;
st->out_stride = 1;
+
+ speex_resample_set_quality(st, quality);
+ speex_resample_set_rate(st, ratio_num, ratio_den, in_rate, out_rate);
+
+
+ update_filter(st);
+
+ st->initialised = 1;
return st;
}
@@ -312,57 +370,17 @@
st->out_stride = ostride_save;
}
-static void update_filter(SpeexResamplerState *st)
-{
- int i;
- /* Choose the resampling type that requires the least amount of memory */
- if (st->den_rate <= st->oversample)
- {
- if (!st->sinc_table)
- st->sinc_table = (spx_word16_t *)speex_alloc(st->filt_len*st->den_rate*sizeof(spx_word16_t));
- else if (st->sinc_table_length < st->filt_len*st->den_rate)
- {
- st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,st->filt_len*st->den_rate*sizeof(spx_word16_t));
- st->sinc_table_length = st->filt_len*st->den_rate;
- }
- for (i=0;i<st->den_rate;i++)
- {
- int j;
- for (j=0;j<st->filt_len;j++)
- {
- st->sinc_table[i*st->filt_len+j] = sinc(st->cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len);
- }
- }
- st->type = SPEEX_RESAMPLER_DIRECT;
- /*fprintf (stderr, "resampler uses direct sinc table and normalised cutoff %f\n", cutoff);*/
- } else {
- if (!st->sinc_table)
- st->sinc_table = (spx_word16_t *)speex_alloc((st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
- else if (st->sinc_table_length < st->filt_len*st->oversample+8)
- {
- st->sinc_table = (spx_word16_t *)speex_realloc(st->sinc_table,(st->filt_len*st->oversample+8)*sizeof(spx_word16_t));
- st->sinc_table_length = st->filt_len*st->oversample+8;
- }
- for (i=-4;i<st->oversample*st->filt_len+4;i++)
- st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)st->oversample - st->filt_len/2), st->filt_len);
- st->type = SPEEX_RESAMPLER_INTERPOLATE;
- /*fprintf (stderr, "resampler uses interpolated sinc table and normalised cutoff %f\n", cutoff);*/
- }
- st->int_advance = st->num_rate/st->den_rate;
- st->frac_advance = st->num_rate%st->den_rate;
-}
-
-void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate, int in_rate_den, int out_rate_den)
+void speex_resample_set_rate(SpeexResamplerState *st, int ratio_num, int ratio_den, int in_rate, int out_rate)
{
int fact;
- if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == in_rate && st->den_rate == out_rate)
+ if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == ratio_num && st->den_rate == ratio_den)
return;
st->in_rate = in_rate;
st->out_rate = out_rate;
- st->num_rate = in_rate;
- st->den_rate = out_rate;
+ st->num_rate = ratio_num;
+ st->den_rate = ratio_den;
/* FIXME: This is terribly inefficient, but who cares (at least for now)? */
for (fact=2;fact<=sqrt(IMAX(in_rate, out_rate));fact++)
{
@@ -373,18 +391,27 @@
}
}
- /* FIXME: Is there a danger of overflow? */
- if (in_rate*out_rate_den > out_rate*in_rate_den)
+ if (ratio_num > ratio_den)
{
/* down-sampling */
- st->cutoff = .92f * out_rate*in_rate_den / (in_rate*out_rate_den);
+ st->cutoff = .92f * ratio_den / ratio_num;
} else {
/* up-sampling */
st->cutoff = .97f;
}
- update_filter(st);
+
+ if (st->initialised)
+ update_filter(st);
}
+void speex_resample_set_quality(SpeexResamplerState *st, int quality)
+{
+ if (st->quality == quality)
+ return;
+ st->quality = quality;
+ if (st->initialised)
+ update_filter(st);
+}
void speex_resample_set_input_stride(SpeexResamplerState *st, int stride)
{
Modified: trunk/speex/libspeex/testresample.c
===================================================================
--- trunk/speex/libspeex/testresample.c 2007-02-01 06:44:20 UTC (rev 12410)
+++ trunk/speex/libspeex/testresample.c 2007-02-01 14:02:40 UTC (rev 12411)
@@ -47,8 +47,8 @@
short *in;
short *out;
float *fin, *fout;
- SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 1, 1);
- speex_resample_set_rate(st, 8000, 16000, 1, 1);
+ SpeexResamplerState *st = speex_resampler_init(1, 8000, 12000, 8000, 12000, 10);
+ speex_resample_set_rate(st, 8000, 15999, 8000, 15999);
speex_resample_skip_zeros(st);
in = malloc(NN*sizeof(short));
@@ -63,7 +63,7 @@
if (feof(stdin))
break;
for (i=0;i<NN;i++)
- fin[i]=in[i];
+ fin[i]=3.f*in[i];
in_len = NN;
out_len = 2*NN;
speex_resampler_process_float(st, 0, fin, &in_len, fout, &out_len);
More information about the commits
mailing list