[xiph-cvs] cvs commit: speex/libspeex filters.c sb_celp.c sb_celp.h

Jean-Marc Valin jm at xiph.org
Fri Oct 25 19:58:37 PDT 2002



jm          02/10/25 22:58:36

  Modified:    libspeex filters.c sb_celp.c sb_celp.h
  Log:
  QMF optimizations by segher

Revision  Changes    Path
1.26      +52 -23    speex/libspeex/filters.c

Index: filters.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/filters.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -r1.25 -r1.26
--- filters.c	25 Oct 2002 04:11:15 -0000	1.25
+++ filters.c	26 Oct 2002 02:58:36 -0000	1.26
@@ -73,6 +73,7 @@
    }
 }
 
+
 void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem)
 {
    int i,j;
@@ -163,31 +164,59 @@
      mem[i]=xx[N-i-1];
 }
 
-void fir_decim_mem(float *xx, float *aa, float *y, int N, int M, float *mem)
-{
-   int i,j,M2;
-   float a[MAX_FILTER];
-   float x[MAX_SIGNAL];
-   M2=M>>1;
-   for (i=0;i<M;i++)
-      a[M-i-1]=aa[i];
-   for (i=0;i<M-1;i++)
-      x[i]=mem[M-i-2];
-   for (i=0;i<N;i++)
-      x[i+M-1]=xx[i];
-   for (i=0;i<N;i++)
-   {
-      y[i]=0;
-      for (j=1;j<M;j+=2)
-         y[i]+=a[j]*x[i+j];
-      i++;
-      y[i]=0;
-      for (j=0;j<M;j+=2)
-         y[i]+=a[j]*x[i+j];
+
+void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem)
+   /* assumptions:
+      all odd x[i] are zero -- well, actually they are left out of the array now
+      N and M are multiples of 4 */
+{
+   int i, j;
+   float xx[N+M-1];
+
+   for (i = 0; i < N/2; i++)
+      xx[2*i] = x[N/2-1-i];
+   for (i = 0; i < M - 1; i += 2)
+      xx[N+i] = mem[i+1];
+
+   for (i = 0; i < N; i += 4) {
+      float y0, y1, y2, y3;
+      float x0;
+
+      y0 = y1 = y2 = y3 = 0.f;
+      x0 = xx[N-4-i];
+
+      for (j = 0; j < M; j += 4) {
+         float x1;
+         float a0, a1;
+
+         a0 = a[j];
+         a1 = a[j+1];
+         x1 = xx[N-2+j-i];
+
+         y0 += a0 * x1;
+         y1 += a1 * x1;
+         y2 += a0 * x0;
+         y3 += a1 * x0;
+
+         a0 = a[j+2];
+         a1 = a[j+3];
+         x0 = xx[N+j-i];
+
+         y0 += a0 * x0;
+         y1 += a1 * x0;
+         y2 += a0 * x1;
+         y3 += a1 * x1;
+      }
+      y[i] = y0;
+      y[i+1] = y1;
+      y[i+2] = y2;
+      y[i+3] = y3;
    }
-   for (i=0;i<M-1;i++)
-     mem[i]=xx[N-i-1];
+
+   for (i = 0; i < M - 1; i += 2)
+      mem[i+1] = xx[i];
 }
+
 
 void comb_filter(
 float *exc,          /*decoded excitation*/

<p><p>1.80      +18 -72    speex/libspeex/sb_celp.c

Index: sb_celp.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/sb_celp.c,v
retrieving revision 1.79
retrieving revision 1.80
diff -u -r1.79 -r1.80
--- sb_celp.c	23 Oct 2002 19:06:19 -0000	1.79
+++ sb_celp.c	26 Oct 2002 02:58:36 -0000	1.80
@@ -158,8 +158,6 @@
    st->first=1;
    st->stack = speex_alloc(10000*sizeof(float));
 
-   st->x0=speex_alloc(st->full_frame_size*sizeof(float));
-   st->x1=speex_alloc(st->full_frame_size*sizeof(float));
    st->x0d=speex_alloc(st->frame_size*sizeof(float));
    st->x1d=speex_alloc(st->frame_size*sizeof(float));
    st->high=speex_alloc(st->full_frame_size*sizeof(float));
@@ -222,9 +220,7 @@
    SBEncState *st=state;
 
    nb_encoder_destroy(st->st_low);
-   speex_free(st->x0);
    speex_free(st->x0d);
-   speex_free(st->x1);
    speex_free(st->x1d);
    speex_free(st->high);
    speex_free(st->y0);
@@ -276,19 +272,8 @@
    stack=st->stack;
 
    /* Compute the two sub-bands by filtering with h0 and h1*/
-#if 0
-   fir_mem(in, h0, st->x0, st->full_frame_size, QMF_ORDER, st->h0_mem);
-   fir_mem(in, h1, st->x1, st->full_frame_size, QMF_ORDER, st->h1_mem);
-   
-   /* Down-sample x0 and x1 */
-   for (i=0;i<st->frame_size;i++)
-      st->x1d[i]=st->x1[i<<1];
-
-   for (i=0;i<st->frame_size;i++)
-      st->x0d[i]=st->x0[i<<1];
-#else
    qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem);
-#endif
+
    /* Encode the narrowband part*/
    nb_encode(st->st_low, st->x0d, bits);
 
@@ -355,17 +340,11 @@
       iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp);
 
 #ifndef RELEASE
-      /* Up-sample coded low-band and high-band*/
-      for (i=0;i<st->frame_size;i++)
-      {
-         st->x0[(i<<1)]=st->x0d[i];
-         st->x1[(i<<1)]=st->high[i];
-         st->x0[(i<<1)+1]=0;
-         st->x1[(i<<1)+1]=0;
-      }
+
       /* Reconstruct the original */
-      fir_decim_mem(st->x0, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
-      fir_decim_mem(st->x1, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+      fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
+      fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+
       for (i=0;i<st->full_frame_size;i++)
          in[i]=2*(st->y0[i]-st->y1[i]);
 #endif
@@ -627,17 +606,11 @@
 
 
 #ifndef RELEASE
-   /* Up-sample coded low-band and high-band*/
-   for (i=0;i<st->frame_size;i++)
-   {
-      st->x0[(i<<1)]=st->x0d[i];
-      st->x1[(i<<1)]=st->high[i];
-      st->x0[(i<<1)+1]=0;
-      st->x1[(i<<1)+1]=0;
-   }
+
    /* Reconstruct the original */
-   fir_decim_mem(st->x0, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
-   fir_decim_mem(st->x1, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+
    for (i=0;i<st->full_frame_size;i++)
       in[i]=2*(st->y0[i]-st->y1[i]);
 #endif
@@ -674,8 +647,6 @@
    st->first=1;
    st->stack = speex_alloc(10000*sizeof(float));
 
-   st->x0=speex_alloc(st->full_frame_size*sizeof(float));
-   st->x1=speex_alloc(st->full_frame_size*sizeof(float));
    st->x0d=speex_alloc(st->frame_size*sizeof(float));
    st->x1d=speex_alloc(st->frame_size*sizeof(float));
    st->high=speex_alloc(st->full_frame_size*sizeof(float));
@@ -703,9 +674,7 @@
    SBDecState *st;
    st = state;
    nb_decoder_destroy(st->st_low);
-   speex_free(st->x0);
    speex_free(st->x0d);
-   speex_free(st->x1);
    speex_free(st->x1d);
    speex_free(st->high);
    speex_free(st->y0);
@@ -739,17 +708,10 @@
    /* Final signal synthesis from excitation */
    iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp);
    
-   /* Up-sample coded low-band and high-band*/
-   for (i=0;i<st->frame_size;i++)
-   {
-      st->x0[(i<<1)]=st->x0d[i];
-      st->x1[(i<<1)]=st->high[i];
-      st->x0[(i<<1)+1]=0;
-      st->x1[(i<<1)+1]=0;
-   }
    /* Reconstruct the original */
-   fir_decim_mem(st->x0, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
-   fir_decim_mem(st->x1, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+
    for (i=0;i<st->full_frame_size;i++)
       out[i]=2*(st->y0[i]-st->y1[i]);
    
@@ -809,17 +771,9 @@
       /* Final signal synthesis from excitation */
       iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp);
 
-      /* Up-sample coded low-band and high-band*/
-      for (i=0;i<st->frame_size;i++)
-      {
-         st->x0[(i<<1)]=st->x0d[i];
-         st->x1[(i<<1)]=st->high[i];
-         st->x0[(i<<1)+1]=0;
-         st->x1[(i<<1)+1]=0;
-      }
-      /* Reconstruct the original */
-      fir_decim_mem(st->x0, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
-      fir_decim_mem(st->x1, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+      fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
+      fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+
       for (i=0;i<st->full_frame_size;i++)
          out[i]=2*(st->y0[i]-st->y1[i]);
 
@@ -928,17 +882,9 @@
 
    }
 
-   /* Up-sample coded low-band and high-band*/
-   for (i=0;i<st->frame_size;i++)
-   {
-      st->x0[(i<<1)]=st->x0d[i];
-      st->x1[(i<<1)]=st->high[i];
-      st->x0[(i<<1)+1]=0;
-      st->x1[(i<<1)+1]=0;
-   }
-   /* Reconstruct the original */
-   fir_decim_mem(st->x0, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
-   fir_decim_mem(st->x1, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem);
+
    for (i=0;i<st->full_frame_size;i++)
       out[i]=2*(st->y0[i]-st->y1[i]);
 

<p><p>1.27      +2 -2      speex/libspeex/sb_celp.h

Index: sb_celp.h
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/sb_celp.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- sb_celp.h	11 Oct 2002 03:39:34 -0000	1.26
+++ sb_celp.h	26 Oct 2002 02:58:36 -0000	1.27
@@ -58,7 +58,7 @@
    float  gamma2;              /**< Perceptual weighting coef 2 */
 
    float *stack;               /**< Temporary allocation stack */
-   float *x0, *x0d, *x1, *x1d; /**< QMF filter signals*/
+   float *x0d, *x1d; /**< QMF filter signals*/
    float *high;                /**< High-band signal (buffer) */
    float *y0, *y1;             /**< QMF synthesis signals */
    float *h0_mem, *h1_mem, *g0_mem, *g1_mem; /**< QMF memories */
@@ -108,7 +108,7 @@
    int    first;
 
    float *stack;
-   float *x0, *x0d, *x1, *x1d;
+   float *x0d, *x1d;
    float *high;
    float *y0, *y1;
    float *h0_mem, *h1_mem, *g0_mem, *g1_mem;

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list