[xiph-commits] r12344 - trunk/speex/libspeex
jm at svn.xiph.org
jm at svn.xiph.org
Thu Jan 18 03:57:05 PST 2007
Author: jm
Date: 2007-01-18 03:57:03 -0800 (Thu, 18 Jan 2007)
New Revision: 12344
Modified:
trunk/speex/libspeex/resample.c
Log:
So doing a lookup is 100x faster than computing sin(x)/x * cos(x/N)... how
surprising! Still need to handle the case where the denominator is too large
to pre-compute everything.
Modified: trunk/speex/libspeex/resample.c
===================================================================
--- trunk/speex/libspeex/resample.c 2007-01-18 10:38:06 UTC (rev 12343)
+++ trunk/speex/libspeex/resample.c 2007-01-18 11:57:03 UTC (rev 12344)
@@ -46,8 +46,19 @@
int samp_frac_num;
int filt_len;
float *mem;
+ float *sinc_table;
} SpeexResamplerState;
+static float sinc(float x, int N)
+{
+ //fprintf (stderr, "%f ", x);
+ if (fabs(x)<1e-6)
+ return 1;
+ else if (fabs(x) > .5f*N)
+ return 0;
+ /*FIXME: Can it really be any slower than this? */
+ return sin(M_PI*x)/(M_PI*x) * (.5+.5*cos(2*x*M_PI/N));
+}
SpeexResamplerState *speex_resampler_init(int in_rate, int out_rate, int in_rate_den, int out_rate_den)
{
@@ -68,9 +79,23 @@
}
st->last_sample = 0;
st->filt_len = FILTER_SIZE;
- st->mem = speex_alloc((st->filt_len-1) * sizeof(float));
+ st->mem = (float*)speex_alloc((st->filt_len-1) * sizeof(float));
for (i=0;i<st->filt_len-1;i++)
st->mem[i] = 0;
+ if (1)
+ {
+ st->sinc_table = (float *)speex_alloc(st->filt_len*st->den_rate*sizeof(float));
+ 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((j-st->filt_len/2+1)-((float)i)/st->den_rate, st->filt_len);
+ }
+ }
+ } else {
+ st->sinc_table = NULL;
+ }
return st;
}
@@ -80,16 +105,6 @@
speex_free(st);
}
-static float sinc(float x, int N)
-{
- //fprintf (stderr, "%f ", x);
- if (fabs(x)<1e-6)
- return 1;
- else if (fabs(x) > .5f*N)
- return 0;
- /*FIXME: Can it really be any slower than this? */
- return sin(M_PI*x)/(M_PI*x) * (.5+.5*cos(2*x*M_PI/N));
-}
int speex_resample_float(SpeexResamplerState *st, const float *in, int len, float *out)
{
@@ -101,15 +116,28 @@
int j;
float sum=0;
/* Do the memory part */
- for (j=0;st->last_sample-N+1+j < 0;j++)
+ if (st->sinc_table)
{
- sum += st->mem[st->last_sample+j]*sinc((j-N/2+1)-((float)st->samp_frac_num)/st->den_rate, N);
+ for (j=0;st->last_sample-N+1+j < 0;j++)
+ {
+ sum += st->mem[st->last_sample+j]*st->sinc_table[st->samp_frac_num*st->filt_len+j];
+ }
+ /* Do the new part */
+ for (;j<N;j++)
+ {
+ sum += in[st->last_sample-N+1+j]*st->sinc_table[st->samp_frac_num*st->filt_len+j];
+ }
+ } else {
+ for (j=0;st->last_sample-N+1+j < 0;j++)
+ {
+ sum += st->mem[st->last_sample+j]*sinc((j-N/2+1)-((float)st->samp_frac_num)/st->den_rate, N);
+ }
+ /* Do the new part */
+ for (;j<N;j++)
+ {
+ sum += in[st->last_sample-N+1+j]*sinc((j-N/2+1)-((float)st->samp_frac_num)/st->den_rate, N);
+ }
}
- /* Do the new part */
- for (;j<N;j++)
- {
- sum += in[st->last_sample-N+1+j]*sinc((j-N/2+1)-((float)st->samp_frac_num)/st->den_rate, N);
- }
out[out_sample++] = sum;
st->last_sample += st->num_rate/st->den_rate;
@@ -155,7 +183,7 @@
out_num = speex_resample_float(st, fin, NN, fout);
//fprintf (stderr, "%d\n", out_num);
for (i=0;i<2*NN;i++)
- out[i]=fout[i];
+ out[i]=floor(.5+fout[i]);
fwrite(out, sizeof(short), out_num, stdout);
}
speex_resampler_destroy(st);
More information about the commits
mailing list