[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