[xiph-cvs] cvs commit: speex/libspeex cb_search.c vq.c vq.h

Jean-Marc Valin jm at xiph.org
Tue Oct 22 22:18:29 PDT 2002



jm          02/10/23 01:18:29

  Modified:    libspeex cb_search.c vq.c vq.h
  Log:
  Re-wrote the signed search to be like the unsigned one (should make them
  use the same code now)

Revision  Changes    Path
1.70      +297 -1    speex/libspeex/cb_search.c

Index: cb_search.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/cb_search.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- cb_search.c	23 Oct 2002 00:53:19 -0000	1.69
+++ cb_search.c	23 Oct 2002 05:18:29 -0000	1.70
@@ -326,6 +326,302 @@
 
 
 
+#if 1
+void split_cb_search_shape_sign(
+float target[],			/* target vector */
+float ak[],			/* LPCs for this subframe */
+float awk1[],			/* Weighted LPCs for this subframe */
+float awk2[],			/* Weighted LPCs for this subframe */
+void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+float *exc,
+SpeexBits *bits,
+float *stack,
+int   complexity
+)
+{
+   int i,j,k,m,n,q;
+   float *resp;
+   float *t, *r, *e, *E;
+   /*FIXME: Should make this dynamic*/
+   float *tmp, *_ot[20], *_nt[20];
+   float *ndist, *odist;
+   int *itmp, *_nind[20], *_oind[20];
+   float **ot, **nt;
+   int **nind, **oind;
+   int *ind;
+   float *shape_cb;
+   int shape_cb_size, subvect_size, nb_subvect;
+   split_cb_params *params;
+   int N=2;
+   int *best_index;
+   float *best_dist;
+
+   ot=_ot;
+   nt=_nt;
+   oind=_oind;
+   nind=_nind;
+   N=complexity;
+   if (N<1)
+      N=1;
+   if (N>10)
+      N=10;
+
+   params = (split_cb_params *) par;
+   subvect_size = params->subvect_size;
+   nb_subvect = params->nb_subvect;
+   shape_cb_size = 1<<params->shape_bits;
+   shape_cb = params->shape_cb;
+   resp = PUSH(stack, shape_cb_size*subvect_size);
+   t = PUSH(stack, nsf);
+   r = PUSH(stack, nsf);
+   e = PUSH(stack, nsf);
+   E = PUSH(stack, shape_cb_size);
+   /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+   ind = (int*)PUSH(stack, nb_subvect);
+
+   tmp = PUSH(stack, 2*N*nsf);
+   for (i=0;i<N;i++)
+   {
+      ot[i]=tmp;
+      tmp += nsf;
+      nt[i]=tmp;
+      tmp += nsf;
+   }
+
+   /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+   best_index = (int*)PUSH(stack, N);
+   best_dist = PUSH(stack, N);
+   ndist = PUSH(stack, N);
+   odist = PUSH(stack, N);
+   
+   /*FIXME: This breaks if sizeof(int) != sizeof(float) */
+   itmp = (int*)PUSH(stack, 2*N*nb_subvect);
+   for (i=0;i<N;i++)
+   {
+      nind[i]=itmp;
+      itmp+=nb_subvect;
+      oind[i]=itmp;
+      itmp+=nb_subvect;
+      for (j=0;j<nb_subvect;j++)
+         nind[i][j]=oind[i][j]=-1;
+   }
+
+   for (j=0;j<N;j++)
+      for (i=0;i<nsf;i++)
+         ot[j][i]=target[i];
+
+   for (i=0;i<nsf;i++)
+      t[i]=target[i];
+
+   e[0]=1;
+   for (i=1;i<nsf;i++)
+      e[i]=0;
+   syn_percep_zero(e, ak, awk1, awk2, r, nsf,p, stack);
+
+   /* Pre-compute codewords response and energy */
+   for (i=0;i<shape_cb_size;i++)
+   {
+      float *res;
+      float *shape;
+      int k;
+      res = resp+i*subvect_size;
+      shape = shape_cb+i*subvect_size;
+      /* Compute codeword response */
+      k=0;
+#if 0
+      for(j=0;j<subvect_size;j++)
+         res[j]=0;
+      for(j=0;j<subvect_size;j++)
+      {
+#if 1
+         float s=shape[j];
+         float *rr;
+         int lim=subvect_size-j;
+         float *ress=res+j;
+         rr=r;
+         while(lim--)
+            *ress+++=s* *rr++;
+#else
+         for (k=j;k<subvect_size;k++)
+           res[k]+=shape_cb[i*subvect_size+j]*r[k-j];
+#endif
+      }
+#else
+      for(j=0;j<subvect_size;j++)
+      {
+         res[j]=0;
+         for (k=0;k<=j;k++)
+            res[j] += shape[k]*r[j-k];
+      }
+#endif
+      E[i]=0;
+      for(j=0;j<subvect_size;j++)
+         E[i]+=res[j]*res[j];
+   }
+
+   for (j=0;j<N;j++)
+      odist[j]=0;
+   /*For all subvectors*/
+   for (i=0;i<nb_subvect;i++)
+   {
+      /*"erase" nbest list*/
+      for (j=0;j<N;j++)
+         ndist[j]=-1;
+
+      /*For all n-bests of previous subvector*/
+      for (j=0;j<N;j++)
+      {
+         float *x=ot[j]+subvect_size*i;
+         /*Find new n-best based on previous n-best j*/
+         vq_nbest_sign(x, resp, subvect_size, shape_cb_size, E, N, best_index, best_dist);
+
+         /*For all new n-bests*/
+         for (k=0;k<N;k++)
+         {
+            float *ct;
+            float err=0;
+            ct = ot[j];
+            /*update target*/
+
+            /*previous target*/
+            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+               t[m]=ct[m];
+
+            /* New code: update only enough of the target to calculate error*/
+            {
+               int rind;
+               float *res;
+               float sign=1;
+               rind = best_index[k];
+               if (rind>shape_cb_size)
+               {
+                  sign=-1;
+                  rind-=shape_cb_size;
+               }
+               res = resp+rind*subvect_size;
+               if (sign>0)
+                  for (m=0;m<subvect_size;m++)
+                     t[subvect_size*i+m] -= res[m];
+               else
+                  for (m=0;m<subvect_size;m++)
+                     t[subvect_size*i+m] += res[m];
+            }
+            
+            /*compute error (distance)*/
+            err=odist[j];
+            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+               err += t[m]*t[m];
+            /*update n-best list*/
+            if (err<ndist[N-1] || ndist[N-1]<-.5)
+            {
+
+               /*previous target (we don't care what happened before*/
+               for (m=(i+1)*subvect_size;m<nsf;m++)
+                  t[m]=ct[m];
+               /* New code: update the rest of the target only if it's worth it */
+               for (m=0;m<subvect_size;m++)
+               {
+                  float g;
+                  int rind;
+                  float sign=1;
+                  rind = best_index[k];
+                  if (rind>shape_cb_size)
+                  {
+                     sign=-1;
+                     rind-=shape_cb_size;
+                  }
+
+                  g=sign*shape_cb[rind*subvect_size+m];
+                  q=subvect_size-m;
+                  for (n=subvect_size*(i+1);n<nsf;n++,q++)
+                     t[n] -= g*r[q];
+               }
+
+
+               for (m=0;m<N;m++)
+               {
+                  if (err < ndist[m] || ndist[m]<-.5)
+                  {
+                     for (n=N-1;n>m;n--)
+                     {
+                        for (q=0;q<nsf;q++)
+                           nt[n][q]=nt[n-1][q];
+                        for (q=0;q<nb_subvect;q++)
+                           nind[n][q]=nind[n-1][q];
+                        ndist[n]=ndist[n-1];
+                     }
+                     for (q=0;q<nsf;q++)
+                        nt[m][q]=t[q];
+                     for (q=0;q<nb_subvect;q++)
+                        nind[m][q]=oind[j][q];
+                     nind[m][i]=best_index[k];
+                     ndist[m]=err;
+                     break;
+                  }
+               }
+            }
+         }
+         if (i==0)
+           break;
+      }
+
+      /*update old-new data*/
+#if 1
+      /* just swap pointers instead of a long copy */
+      {
+         float **tmp;
+         tmp=ot;
+         ot=nt;
+         nt=tmp;
+      }
+#else
+      for (j=0;j<N;j++)
+         for (m=0;m<nsf;m++)
+            ot[j][m]=nt[j][m];
+#endif
+      for (j=0;j<N;j++)
+         for (m=0;m<nb_subvect;m++)
+            oind[j][m]=nind[j][m];
+      for (j=0;j<N;j++)
+         odist[j]=ndist[j];
+   }
+
+   /*save indices*/
+   for (i=0;i<nb_subvect;i++)
+   {
+      ind[i]=nind[0][i];
+      speex_bits_pack(bits,ind[i],params->shape_bits+1);
+   }
+   
+   /* Put everything back together */
+   for (i=0;i<nb_subvect;i++)
+   {
+      int rind;
+      float sign=1;
+      rind = ind[i];
+      if (rind>shape_cb_size)
+      {
+         sign=-1;
+         rind-=shape_cb_size;
+      }
+
+      for (j=0;j<subvect_size;j++)
+         e[subvect_size*i+j]=sign*shape_cb[rind*subvect_size+j];
+   }   
+   /* Update excitation */
+   for (j=0;j<nsf;j++)
+      exc[j]+=e[j];
+   
+   /* Update target */
+   syn_percep_zero(e, ak, awk1, awk2, r, nsf,p, stack);
+   for (j=0;j<nsf;j++)
+      target[j]-=r[j];
+
+}
+
+#else
 
 void split_cb_search_shape_sign(
 float target[],			/* target vector */
@@ -542,7 +838,7 @@
 
    
 }
-
+#endif
 
 void split_cb_nogain_unquant(
 float *exc,

<p><p>1.7       +40 -0     speex/libspeex/vq.c

Index: vq.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/vq.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vq.c	11 Oct 2002 03:39:34 -0000	1.6
+++ vq.c	23 Oct 2002 05:18:29 -0000	1.7
@@ -86,3 +86,43 @@
    }
 }
 
+/*Finds the indices of the n-best entries in a codebook with sign*/
+void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist)
+{
+   int i,j,k, sign;
+   for (i=0;i<entries;i++)
+   {
+      float dist=0;
+      for (j=0;j<len;j++)
+         dist -= in[j]**codebook++;
+      if (dist>0)
+      {
+         sign=1;
+         dist=-dist;
+      } else
+      {
+         sign=0;
+      }
+      dist += .5*E[i];
+      if (i<N || dist<best_dist[N-1])
+      {
+
+         for (j=0;j<N;j++)
+         {
+            if (j >= i || dist < best_dist[j])
+            {
+               for (k=N-1;k>j;k--)
+               {
+                  best_dist[k]=best_dist[k-1];
+                  nbest[k] = nbest[k-1];
+               }
+               best_dist[j]=dist;
+               nbest[j]=i;
+               if (sign)
+                  nbest[j]+=entries;
+               break;
+            }
+         }
+      }
+   }
+}

<p><p>1.7       +1 -0      speex/libspeex/vq.h

Index: vq.h
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/vq.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- vq.h	11 Oct 2002 03:39:34 -0000	1.6
+++ vq.h	23 Oct 2002 05:18:29 -0000	1.7
@@ -37,5 +37,6 @@
 
 void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
 
+void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist);
 
 #endif

<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