split the filter update part.
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 31 Jan 2007 06:34:21 +0000 (06:34 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Wed, 31 Jan 2007 06:34:21 +0000 (06:34 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@12402 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/resample.c

index c41cfbd..06f889c 100644 (file)
@@ -33,6 +33,7 @@
 /*
    The design goals of this code are:
       - Very fast algorithm
+      - SIMD-friendly algorithm
       - Low memory requirement
       - Good *perceptual* quality (and not best SNR)
 
@@ -94,6 +95,7 @@ struct SpeexResamplerState_ {
    int    filt_len;
    int    int_advance;
    int    frac_advance;
+   float  cutoff;
    
    spx_word16_t *mem;
    spx_word16_t *sinc_table;
@@ -131,6 +133,8 @@ static spx_word16_t sinc(float cutoff, float x, int N)
 }
 #endif
 
+/*SpeexResamplerState *speex_resampler_init(int nb_channels, int ratio_num, int ratio_den, int in_rate, int out_rate, int quality)*/
+
 SpeexResamplerState *speex_resampler_init(int nb_channels, int in_rate, int out_rate, int in_rate_den, int out_rate_den)
 {
    int i;
@@ -140,6 +144,7 @@ SpeexResamplerState *speex_resampler_init(int nb_channels, int in_rate, int out_
    st->num_rate = 0;
    st->den_rate = 0;
    
+   st->cutoff = 1.f;
    st->nb_channels = nb_channels;
    st->last_sample = 0;
    st->filt_len = FILTER_SIZE;
@@ -305,37 +310,9 @@ void speex_resampler_process_interleaved_float(SpeexResamplerState *st, const fl
    st->out_stride = ostride_save;
 }
 
-void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate, int in_rate_den, int out_rate_den)
+static void update_filter(SpeexResamplerState *st)
 {
-   float cutoff;
-   int i, fact;
-   if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == in_rate && st->den_rate == out_rate)
-      return;
-   
-   st->in_rate = in_rate;
-   st->out_rate = out_rate;
-   st->num_rate = in_rate;
-   st->den_rate = out_rate;
-   /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
-   for (fact=2;fact<=sqrt(IMAX(in_rate, out_rate));fact++)
-   {
-      while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
-      {
-         st->num_rate /= fact;
-         st->den_rate /= fact;
-      }
-   }
-   
-   /* FIXME: Is there a danger of overflow? */
-   if (in_rate*out_rate_den > out_rate*in_rate_den)
-   {
-      /* down-sampling */
-      cutoff = .92f * out_rate*in_rate_den / (in_rate*out_rate_den);
-   } else {
-      /* up-sampling */
-      cutoff = .97f;
-   }
-   
+   int i;
    /* Choose the resampling type that requires the least amount of memory */
    if (st->den_rate <= OVERSAMPLE)
    {
@@ -351,7 +328,7 @@ void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate,
          int j;
          for (j=0;j<st->filt_len;j++)
          {
-            st->sinc_table[i*st->filt_len+j] = sinc(cutoff,((j-st->filt_len/2+1)-((float)i)/st->den_rate), st->filt_len);
+            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;
@@ -365,7 +342,7 @@ void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate,
          st->sinc_table_length = st->filt_len*OVERSAMPLE+8;
       }
       for (i=-4;i<OVERSAMPLE*st->filt_len+4;i++)
-         st->sinc_table[i+4] = sinc(cutoff,(i/(float)OVERSAMPLE - st->filt_len/2), st->filt_len);
+         st->sinc_table[i+4] = sinc(st->cutoff,(i/(float)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);*/
    }
@@ -374,6 +351,39 @@ void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate,
 
 }
 
+void speex_resample_set_rate(SpeexResamplerState *st, int in_rate, int out_rate, int in_rate_den, int out_rate_den)
+{
+   int fact;
+   if (st->in_rate == in_rate && st->out_rate == out_rate && st->num_rate == in_rate && st->den_rate == out_rate)
+      return;
+   
+   st->in_rate = in_rate;
+   st->out_rate = out_rate;
+   st->num_rate = in_rate;
+   st->den_rate = out_rate;
+   /* FIXME: This is terribly inefficient, but who cares (at least for now)? */
+   for (fact=2;fact<=sqrt(IMAX(in_rate, out_rate));fact++)
+   {
+      while ((st->num_rate % fact == 0) && (st->den_rate % fact == 0))
+      {
+         st->num_rate /= fact;
+         st->den_rate /= fact;
+      }
+   }
+   
+   /* FIXME: Is there a danger of overflow? */
+   if (in_rate*out_rate_den > out_rate*in_rate_den)
+   {
+      /* down-sampling */
+      st->cutoff = .92f * out_rate*in_rate_den / (in_rate*out_rate_den);
+   } else {
+      /* up-sampling */
+      st->cutoff = .97f;
+   }
+   update_filter(st);
+}
+
+
 void speex_resample_set_input_stride(SpeexResamplerState *st, int stride)
 {
    st->in_stride = stride;