Re-wrote the gain quantization for split-VQ excitation. Added more bits
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Mon, 8 Apr 2002 06:23:54 +0000 (06:23 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Mon, 8 Apr 2002 06:23:54 +0000 (06:23 +0000)
and quantize one at a time.

git-svn-id: http://svn.xiph.org/trunk/speex@3223 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/Makefile.am
libspeex/cb_search.c
libspeex/cb_search.h
libspeex/exc_sb_table.c [new file with mode: 0644]
libspeex/modes.c
libspeex/mpulse.c
libspeex/mpulse.h
libspeex/sb_celp.c
libspeex/sb_celp.h
libspeex/speex.c

index 810c796..d78dcdd 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.18 2002/04/02 22:58:12 jmvalin Exp $
+# $Id: Makefile.am,v 1.19 2002/04/08 06:23:54 jmvalin Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -29,7 +29,8 @@ libspeex_la_SOURCES = speex.c \
        exc_gains_wb2_table.c \
        vq.c \
        matrix.c \
-       mpulse.c
+       mpulse.c \
+       exc_sb_table.c
 
 
 include_HEADERS = speex.h \
index 7e43e41..d91b3be 100644 (file)
 #include "vq.h"
 #include "matrix.h"
 
-extern float exc_gains_wb2_table[];
+static float scal_gains4[16] = {
+   0.27713,
+   0.49282,
+   0.69570,
+   0.90786,
+   1.14235,
+   1.42798,
+   1.80756,
+   2.42801
+};
+
 /*---------------------------------------------------------------------------*\
                                                                              
  void overlap_cb_search()                                                            
@@ -128,6 +138,7 @@ int   nsf                       /* number of samples in subframe */
 }
 
 
+
 void split_cb_search(
 float target[],                        /* target vector */
 float ak[],                    /* LPCs for this subframe */
@@ -143,11 +154,12 @@ float *stack
 {
    int i,j;
    float *resp, *E, *Ee;
-   float *t, *r, *e;
+   float *t, *r, *e, *tresp;
    float *gains;
    int *ind;
-   float *shape_cb, *gain_cb;
-   int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
+   float *shape_cb;
+   int shape_cb_size, subvect_size, nb_subvect;
+   float exc_energy=0;
    split_cb_params *params;
 
    params = (split_cb_params *) par;
@@ -155,9 +167,8 @@ float *stack
    nb_subvect = params->nb_subvect;
    shape_cb_size = 1<<params->shape_bits;
    shape_cb = params->shape_cb;
-   gain_cb_size = 1<<params->gain_bits;
-   gain_cb = params->gain_cb;
    resp = PUSH(stack, shape_cb_size*subvect_size);
+   tresp = PUSH(stack, shape_cb_size*nsf);
    E = PUSH(stack, shape_cb_size);
    Ee = PUSH(stack, shape_cb_size);
    t = PUSH(stack, nsf);
@@ -165,7 +176,25 @@ float *stack
    e = PUSH(stack, nsf);
    gains = PUSH(stack, nb_subvect);
    ind = (int*)PUSH(stack, nb_subvect);
-   
+
+   syn_filt_zero(target, awk1, e, nsf, p);
+   residue_zero(e, ak, e, nsf, p);
+   residue_zero(e, awk2, e, nsf, p);
+   for (i=0;i<nsf;i++)
+      exc_energy += e[i]*e[i];
+   exc_energy=sqrt(.125*exc_energy);
+
+   /* Quantize global (average) gain */
+   {
+      float q;
+      q=log(exc_energy+.1);
+      q=floor(.5+2*(q-2));
+      if (q<0)
+         q=0;
+      if (q>15)
+         q=15;
+      exc_energy=exp(.5*q+2);
+   }
 
    for (i=0;i<nsf;i++)
       t[i]=target[i];
@@ -183,6 +212,7 @@ float *stack
          Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j];
       
    }
+
    for (i=0;i<nb_subvect;i++)
    {
       int best_index=0;
@@ -199,259 +229,32 @@ float *stack
             best_gain=corr/(.001+E[j]);
          }
       }
-      frame_bits_pack(bits,best_index,params->shape_bits);
-      if (best_gain>0)
-         frame_bits_pack(bits,0,1);
-      else
-          frame_bits_pack(bits,1,1);        
-      ind[i]=best_index;
-      gains[i]=best_gain*Ee[ind[i]];
-
-      for (j=0;j<nsf;j++)
-         e[j]=0;
-      for (j=0;j<subvect_size;j++)
-         e[subvect_size*i+j]=best_gain*shape_cb[best_index*subvect_size+j];
-      residue_zero(e, awk1, r, nsf, p);
-      syn_filt_zero(r, ak, r, nsf, p);
-      syn_filt_zero(r, awk2, r, nsf,p);
-      for (j=0;j<nsf;j++)
-         t[j]-=r[j];
-   }
-
-   {
-      int best_vq_index=0, max_index;
-      float max_gain=0, log_max, min_dist=0, *sign;
-
-      if (gain_cb) /*If no gain codebook, do not quantize (for testing/debugging) */
       {
-         sign = PUSH(stack, nb_subvect);
-         for (i=0;i<nb_subvect;i++)
+         int s=0, best_id, j;
+         float best_dist;
+         best_gain /= .01+exc_energy;
+         if (best_gain<0)
          {
-            if (gains[i]<0)
-            {
-               gains[i]=-gains[i];
-               sign[i]=-1;
-            } else {
-               sign[i]=1;
-            }
+            best_gain=-best_gain;
+            s=1;
          }
-         for (i=0;i<nb_subvect;i++)
-            if (gains[i]>max_gain)
-               max_gain=gains[i];
-         log_max=log(max_gain+1);
-         max_index = (int)(floor(.5+log_max-3));
-         if (max_index>7)
-            max_index=7;
-         if (max_index<0)
-            max_index=0;
-         max_gain=1/exp(max_index+3.0);
-         for (i=0;i<nb_subvect;i++)
-            gains[i]*=max_gain;
-         frame_bits_pack(bits,max_index,3);
-
-         /*Vector quantize gains[i]*/
-         if (nb_subvect<=5)
+         best_dist=(best_gain-scal_gains4[0])*(best_gain-scal_gains4[0]);
+         best_id=0;
+         for (j=1;j<8;j++)
          {
-         best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size);
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-         for (i=0;i<nb_subvect;i++)
-            gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001);
-         } else
-         {
-            float tmp[5];
-            int best_vq_index2;
-         best_vq_index = vq_index(gains, gain_cb, nb_subvect/2, gain_cb_size);
-         for (i=0;i<5;i++)
-            tmp[i]=gains[i]-gain_cb[best_vq_index*nb_subvect/2+i];
-         best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256);
-
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-         for (i=0;i<nb_subvect/2;i++)
-            gains[i]= sign[i]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i]]+.001);
-
-
-         best_vq_index = vq_index(gains+5, gain_cb, nb_subvect/2, gain_cb_size);
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         for (i=0;i<5;i++)
-            tmp[i]=gains[i+5]-gain_cb[best_vq_index*nb_subvect/2+i];
-         best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256);
-
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-         for (i=0;i<nb_subvect/2;i++)
-            gains[i+5]= sign[i+5]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i+5]]+.001);
-         }
-
-    
-
-         POP(stack);
-      } else {
-         printf ("exc: ");
-         for (i=0;i<nb_subvect;i++)
-            printf ("%f ", gains[i]);
-         printf ("\n");
-         for (i=0;i<nb_subvect;i++)
-            gains[i]= gains[i]/(Ee[ind[i]]+.001);
-      }
-
-      for (i=0;i<nb_subvect;i++)
-         for (j=0;j<subvect_size;j++)
-            exc[subvect_size*i+j]+=gains[i]*shape_cb[ind[i]*subvect_size+j];
-
-   }
-
-   /*TODO: Perform joint optimization of gains*/
-   
-   for (i=0;i<nsf;i++)
-      target[i]=t[i];
-
-   POP(stack);
-   POP(stack);
-   POP(stack);
-   POP(stack);
-   POP(stack);
-   POP(stack);
-   POP(stack);
-   POP(stack);
-}
-
-
-
-
-void split_cb_search_wb(
-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,
-FrameBits *bits,
-float *stack
-)
-{
-   int i,j;
-   float *resp, *E, *Ee;
-   float *t, *r, *e, *tresp;
-   float *gains;
-   int *ind;
-   float *shape_cb, *gain_cb;
-   int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
-   split_cb_params *params;
-
-   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;
-   gain_cb_size = 1<<params->gain_bits;
-   gain_cb = params->gain_cb;
-   resp = PUSH(stack, shape_cb_size*subvect_size);
-   tresp = PUSH(stack, shape_cb_size*nsf);
-   E = PUSH(stack, shape_cb_size);
-   Ee = PUSH(stack, shape_cb_size);
-   t = PUSH(stack, nsf);
-   r = PUSH(stack, nsf);
-   e = PUSH(stack, nsf);
-   gains = PUSH(stack, nb_subvect);
-   ind = (int*)PUSH(stack, nb_subvect);
-   
-
-   for (i=0;i<nsf;i++)
-      t[i]=target[i];
-   for (i=0;i<shape_cb_size;i++)
-   {
-      float *res = resp+i*subvect_size;
-      residue_zero(shape_cb+i*subvect_size, awk1, res, subvect_size, p);
-      syn_filt_zero(res, ak, res, subvect_size, p);
-      syn_filt_zero(res, awk2, res, subvect_size,p);
-      E[i]=0;
-      for(j=0;j<subvect_size;j++)
-         E[i]+=res[j]*res[j];
-      Ee[i]=0;
-      for(j=0;j<subvect_size;j++)
-         Ee[i]+=shape_cb[i*subvect_size+j]*shape_cb[i*subvect_size+j];
-      
-   }
-#if 0
-   {
-      int half,k;
-   for (half=0;half<2;half++)
-   {
-      int nb_half=nb_subvect/2;
-      int max_subvect=0;
-      float max_energy=0;
-      syn_filt_zero(t+half*nsf/2, awk1, r, nsf/2, p);
-      residue_zero(r, ak, r, nsf/2, p);
-      residue_zero(r, awk2, r, nsf/2,p);
-      for (i=0;i<nb_half;i++)
-      {
-         float energy=0;
-         for (k=0;k<subvect_size;k++)
-            energy+=r[subvect_size*i+k]*r[subvect_size*i+k];
-         if (energy>max_energy)
-         {
-            max_subvect=i;
-            max_energy=energy;
-         }
-      }
-      printf ("max_energy: %d %f\n", max_subvect, max_energy);
-      
-      for (i=0;i<nb_half;i++)
-      {
-         int nb_times=1;
-         if (i==max_subvect)
-            nb_times++;
-
-         for (k=0;k<nb_times;k++)
-         {
-         int best_index=0;
-         float g, corr, best_gain=0, score, best_score=-1;
-         for (j=0;j<shape_cb_size;j++)
-         {
-            corr=xcorr(resp+j*subvect_size,t+subvect_size*(i+half*nb_half),subvect_size);
-            score=corr*corr/(.001+E[j]);
-            g = corr/(.001+E[j]);
-            if (score>best_score)
+            float dist;
+            dist=(best_gain-scal_gains4[j])*(best_gain-scal_gains4[j]);
+            if (dist<best_dist)
             {
-               best_index=j;
-               best_score=score;
-               best_gain=corr/(.001+E[j]);
+               best_id=j;
+               best_dist=dist;
             }
          }
-         for (j=0;j<nsf;j++)
-            e[j]=0;
-         for (j=0;j<subvect_size;j++)
-            e[subvect_size*(i+half*nb_half)+j]=best_gain*shape_cb[best_index*subvect_size+j];
-         residue_zero(e, awk1, r, nsf, p);
-         syn_filt_zero(r, ak, r, nsf, p);
-         syn_filt_zero(r, awk2, r, nsf,p);
-         for (j=0;j<nsf;j++)
-            t[j]-=r[j];
-         for (j=0;j<nsf;j++)
-            exc[j]+=e[j];
-         }
-      }
-   }
-   }
-#else
-   for (i=0;i<nb_subvect;i++)
-   {
-      int best_index=0;
-      float g, corr, best_gain=0, score, best_score=-1;
-      for (j=0;j<shape_cb_size;j++)
-      {
-         corr=xcorr(resp+j*subvect_size,t+subvect_size*i,subvect_size);
-         score=corr*corr/(.001+E[j]);
-         g = corr/(.001+E[j]);
-         if (score>best_score)
-         {
-            best_index=j;
-            best_score=score;
-            best_gain=corr/(.001+E[j]);
-         }
+         best_gain=scal_gains4[best_id];
+         printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);
+         if (s)
+            best_gain=-best_gain;
+         best_gain *= exc_energy;
       }
       frame_bits_pack(bits,best_index,params->shape_bits);
       if (best_gain>0)
@@ -476,101 +279,11 @@ float *stack
         exc[j]+=e[j];*/
    }
    {
-      float A[10][10];
-      float b[10];
-      float c[10];
-      for (i=0;i<10;i++)
-         for (j=0;j<10;j++)
-            A[i][j]=xcorr(tresp+i*nsf, tresp+j*nsf, nsf);
-      for (i=0;i<10;i++)
-         b[i]=xcorr(target,tresp+i*nsf,nsf);
-      for (i=0;i<10;i++)
-         A[i][i]+=.01;
-
-
-      solve(&A[0][0],b,c, 10);
-      for (i=0;i<10;i++)
-        gains[i]*=c[i];
-      
-      for (i=0;i<10;i++)
-         gains[i]*=Ee[ind[i]];
-
-
-
-   {
-      int best_vq_index=0, max_index;
-      float max_gain=0, log_max, min_dist=0, *sign;
-
-      if (gain_cb) /*If no gain codebook, do not quantize (for testing/debugging) */
-      {
-         sign = PUSH(stack, nb_subvect);
-         for (i=0;i<nb_subvect;i++)
-         {
-            if (gains[i]<0)
-            {
-               gains[i]=-gains[i];
-               sign[i]=-1;
-            } else {
-               sign[i]=1;
-            }
-         }
-         for (i=0;i<nb_subvect;i++)
-            if (gains[i]>max_gain)
-               max_gain=gains[i];
-         log_max=log(max_gain+1);
-         max_index = (int)(floor(.5+log_max-3));
-         if (max_index>7)
-            max_index=7;
-         if (max_index<0)
-            max_index=0;
-         max_gain=1/exp(max_index+3.0);
-         for (i=0;i<nb_subvect;i++)
-            gains[i]*=max_gain;
-         frame_bits_pack(bits,max_index,3);
-
-         /*Vector quantize gains[i]*/
-         if (nb_subvect<=5)
-         {
-         best_vq_index = vq_index(gains, gain_cb, nb_subvect, gain_cb_size);
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
+         printf ("exc_gains");
          for (i=0;i<nb_subvect;i++)
-            gains[i]= sign[i]*gain_cb[best_vq_index*nb_subvect+i]/max_gain/(Ee[ind[i]]+.001);
-         } else
-         {
-            float tmp[5];
-            int best_vq_index2;
-         best_vq_index = vq_index(gains, gain_cb, nb_subvect/2, gain_cb_size);
-         for (i=0;i<5;i++)
-            tmp[i]=gains[i]-gain_cb[best_vq_index*nb_subvect/2+i];
-         best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256);
-
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-         for (i=0;i<nb_subvect/2;i++)
-            gains[i]= sign[i]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i]]+.001);
-
-
-         best_vq_index = vq_index(gains+5, gain_cb, nb_subvect/2, gain_cb_size);
-         frame_bits_pack(bits,best_vq_index,params->gain_bits);
-         for (i=0;i<5;i++)
-            tmp[i]=gains[i+5]-gain_cb[best_vq_index*nb_subvect/2+i];
-         best_vq_index2 = vq_index(tmp, exc_gains_wb2_table, nb_subvect/2, 256);
-
-         printf ("best_gains_vq_index %d %f %d\n", best_vq_index, min_dist, max_index);
-         for (i=0;i<nb_subvect/2;i++)
-            gains[i+5]= sign[i+5]*(gain_cb[best_vq_index*nb_subvect/2+i]+exc_gains_wb2_table[best_vq_index2*nb_subvect/2+i])/max_gain/(Ee[ind[i+5]]+.001);
-         }
-         
-         
-      } else {
-         
-         for (i=0;i<10;i++)
-            gains[i]/=Ee[ind[i]]+.001;
-         
-      }
-   }
-      for (i=0;i<10;i++)
+            printf (" %f", gains[i]/(.01f+exc_energy));
+         printf ("\n");
+      for (i=0;i<nb_subvect;i++)
          for (j=0;j<subvect_size;j++)
             e[subvect_size*i+j]=gains[i]*shape_cb[ind[i]*subvect_size+j];
 
@@ -583,13 +296,8 @@ float *stack
          target[j]-=r[j];
 
    }
-#endif
 
-   /*TODO: Perform joint optimization of gains*/
-   
-   /*for (i=0;i<nsf;i++)
-      target[i]=t[i];
-   */
+
    POP(stack);
    POP(stack);
    POP(stack);
@@ -617,8 +325,8 @@ float *stack
    float *sign;
    int max_gain_ind, vq_gain_ind;
    float max_gain, *Ee;
-   float *shape_cb, *gain_cb;
-   int shape_cb_size, gain_cb_size, subvect_size, nb_subvect;
+   float *shape_cb;
+   int shape_cb_size, subvect_size, nb_subvect;
    split_cb_params *params;
 
    params = (split_cb_params *) par;
@@ -626,8 +334,6 @@ float *stack
    nb_subvect = params->nb_subvect;
    shape_cb_size = 1<<params->shape_bits;
    shape_cb = params->shape_cb;
-   gain_cb_size = 1<<params->gain_bits;
-   gain_cb = params->gain_cb;
    
    ind = (int*)PUSH(stack, nb_subvect);
    gains = PUSH(stack, nb_subvect);
@@ -645,18 +351,10 @@ float *stack
       for (j=0;j<subvect_size;j++)
          Ee[i]+=shape_cb[ind[i]*subvect_size+j]*shape_cb[ind[i]*subvect_size+j];
    }
-   max_gain_ind = frame_bits_unpack_unsigned(bits, 3);
-   vq_gain_ind = frame_bits_unpack_unsigned(bits, params->gain_bits);
-   printf ("unquant gains ind: %d %d\n", max_gain_ind, vq_gain_ind);
 
-   max_gain=exp(max_gain_ind+3.0);
-   for (i=0;i<nb_subvect;i++)
-      gains[i] = sign[i]*gain_cb[vq_gain_ind*nb_subvect+i]*max_gain/Ee[i];
-   
-   printf ("unquant gains: ");
+   /*FIXME: Gain quantization changed, need to re-write that part */
    for (i=0;i<nb_subvect;i++)
-      printf ("%f ", gains[i]);
-   printf ("\n");
+      gains[i]=0;
 
    for (i=0;i<nb_subvect;i++)
       for (j=0;j<subvect_size;j++)
index 3e702ae..94e167a 100644 (file)
@@ -27,8 +27,6 @@ typedef struct split_cb_params {
    int     nb_subvect;
    float  *shape_cb;
    int     shape_bits;
-   float  *gain_cb;
-   int     gain_bits;
 } split_cb_params;
 
 float overlap_cb_search(
diff --git a/libspeex/exc_sb_table.c b/libspeex/exc_sb_table.c
new file mode 100644 (file)
index 0000000..f332203
--- /dev/null
@@ -0,0 +1,128 @@
+float exc_sb_table[128][5]={{-0.102624,-0.054111,-0.150332,0.925474,-0.073627},
+{0.0334537,0.427829,0.534788,-0.188438,0.604833},
+{0.139761,0.666278,0.0654791,0.629374,-0.0485821},
+{0.381103,-0.348657,-0.223198,0.754575,-0.162999},
+{0.139871,-0.65616,0.567975,0.365822,0.0199881},
+{0.238787,-0.663805,0.412313,-0.011008,0.504689},
+{-0.255037,-0.268362,0.337979,0.00543153,0.800096},
+{0.0157631,0.0546008,-0.587497,0.43831,0.602686},
+{0.266576,0.454332,-0.287143,0.543867,0.4675},
+{0.539929,-0.211438,0.544636,-0.19762,0.497794},
+{0.790626,0.281386,-0.434619,0.0150189,0.0396688},
+{0.537489,-0.697916,0.358457,0.137981,0.0744294},
+{-0.171602,0.661162,0.530261,-0.141799,-0.34708},
+{0.550564,-0.357929,0.47943,-0.486588,0.234207},
+{-0.522763,0.70251,-0.180435,0.0110766,0.34005},
+{0.290646,-0.486299,-0.0267554,0.0195369,0.765342},
+{-0.510804,0.543264,-0.0113427,0.559072,-0.214979},
+{-0.054281,0.296506,0.227583,-0.663565,0.585474},
+{0.281311,0.410409,-0.589923,0.514236,-0.24451},
+{0.352187,-0.681431,0.0409394,0.529577,0.180429},
+{0.335686,0.152943,0.340562,0.350725,-0.716269},
+{-0.184544,-0.493059,0.709312,0.0789398,0.333809},
+{0.36807,0.398848,0.439442,0.469874,0.426293},
+{-0.074492,-0.067026,-0.220689,0.0949041,0.911539},
+{-0.0244626,0.599877,-0.664436,0.337101,0.102803},
+{0.507241,0.299874,0.67683,-0.183245,0.1731},
+{-0.158717,0.687196,0.0106936,-0.49428,0.40757},
+{0.18848,-0.206213,0.859075,-0.0790016,-0.271342},
+{-0.481602,0.268191,0.761241,-0.0182754,-0.102577},
+{0.654972,-0.254684,-0.0536777,-0.326449,0.566277},
+{-0.311018,0.468055,-0.518803,0.260996,0.508674},
+{0.409175,-0.0381644,-0.507158,-0.00951909,0.694244},
+{-0.246701,0.0131884,0.376172,0.718583,-0.416487},
+{-0.483561,0.409034,0.162806,-0.293085,0.631156},
+{0.158998,0.813405,-0.0109502,0.0180112,-0.445918},
+{0.705327,-0.410767,-0.241706,0.433087,-0.00413281},
+{0.600455,-0.479235,0.23816,0.379886,-0.3432},
+{0.301259,-0.582477,0.700397,-0.0832768,0.0474716},
+{-0.281273,-0.426036,0.296623,0.708078,0.198903},
+{0.405234,0.466206,-0.612542,-0.124835,0.369165},
+{-0.211322,0.835041,-0.341256,0.212979,-0.112143},
+{0.00691859,0.220931,0.802972,-0.420141,-0.163715},
+{0.665906,0.121232,-0.357705,-0.342484,0.451004},
+{0.659969,-0.509186,-0.178865,0.147746,0.408789},
+{-0.52733,0.627687,0.394084,-0.203386,0.184659},
+{0.561308,-0.582705,0.43265,-0.259265,0.219455},
+{-0.478271,0.78833,0.1123,0.166179,-0.128496},
+{0.257733,0.0106463,0.364816,-0.0231152,0.831136},
+{-0.206288,0.304049,-0.176448,0.781093,-0.380172},
+{-0.282692,0.0171014,0.501923,-0.470113,0.608837},
+{0.640325,0.422174,-0.139084,0.14123,-0.503401},
+{0.278649,-0.375512,-0.352527,0.432341,0.606905},
+{-0.259996,-0.24862,0.754151,0.402793,-0.161873},
+{0.176409,-0.37323,0.272941,-0.332164,0.760739},
+{0.219157,0.591943,0.619522,0.281972,-0.111015},
+{0.355112,0.0542548,0.0346132,-0.572545,0.682399},
+{0.302553,-0.0692851,-0.581226,0.676379,0.140197},
+{0.158078,0.634064,0.347225,-0.569978,-0.118974},
+{0.233516,0.790668,-0.266387,-0.37779,0.0894651},
+{0.88696,0.0427845,0.0771191,-0.275171,-0.177864},
+{-0.20828,0.401446,0.661027,0.416781,0.244633},
+{0.444848,-0.0251255,0.339661,-0.659061,0.42588},
+{-0.392048,0.144615,-0.28817,0.665781,0.441333},
+{0.664287,0.0737455,-0.54894,0.376551,-0.144804},
+{-0.564502,0.128396,0.0865737,0.728833,0.120127},
+{-0.57034,0.0979681,0.585372,-0.0564536,0.460319},
+{-0.168581,0.587204,0.220691,0.365764,-0.58274},
+{0.559779,-0.0715092,-0.152879,0.567635,-0.49618},
+{0.114242,-0.456576,0.288872,0.736407,-0.231899},
+{0.00837993,-0.595792,0.218303,0.425367,0.55763},
+{-0.331547,-0.329078,-0.0551475,0.490597,0.661246},
+{0.0816829,0.304182,-0.544833,-0.0409868,0.719706},
+{0.344068,0.274524,-0.736783,0.315036,0.275653},
+{0.228404,-0.315749,0.768149,-0.422216,0.106815},
+{0.662165,0.486676,-0.276654,-0.386017,0.0209953},
+{0.80392,-0.513347,0.138384,0.0246297,-0.0146162},
+{0.301751,0.449556,0.488575,-0.163447,-0.571901},
+{0.781474,-0.371342,0.196756,-0.318678,0.22194},
+{-0.726348,0.441955,0.208678,0.257971,0.249602},
+{0.589172,-0.58137,0.177834,-0.0952224,0.457552},
+{-0.457955,0.582895,-0.357162,0.486044,0.0770756},
+{0.0950343,-0.109581,0.345219,-0.587601,0.677624},
+{0.19224,0.115768,-0.408221,0.771759,-0.332153},
+{0.517119,-0.256665,0.185316,0.643863,0.309937},
+{0.540099,0.105316,0.53074,0.490803,-0.210116},
+{0.249416,-0.140204,0.725332,0.3115,0.40436},
+{-0.151338,0.655717,0.0959581,0.334807,0.543585},
+{-0.11283,0.0734222,0.0532614,-0.370352,0.872759},
+{-0.125588,0.314843,-0.574553,0.687819,0.0452927},
+{0.538183,0.031037,0.541285,-0.550722,-0.120951},
+{0.153766,0.427132,-0.291862,-0.49462,0.613839},
+{0.652598,-0.0458756,0.463965,-0.0682286,-0.493205},
+{-0.531497,0.318335,0.53472,0.409559,-0.237859},
+{0.48061,-0.422219,0.294698,-0.43837,0.517025},
+{-0.103654,0.744761,-0.474463,-0.0720102,0.340483},
+{0.628206,-0.13234,-0.545444,0.258424,0.366585},
+{0.148394,-0.0425618,0.0865729,0.759242,-0.544229},
+{-0.260555,0.434974,-0.259427,-0.205655,0.740156},
+{0.60187,0.540709,0.113835,-0.315797,-0.351679},
+{0.849773,-0.142091,-0.0420795,0.211852,-0.34112},
+{0.277191,-0.376379,0.613516,0.320655,-0.451303},
+{0.636778,-0.429747,0.529245,-0.187377,-0.141152},
+{-0.580468,-0.11628,0.481246,0.428717,0.340724},
+{0.402818,0.52967,-0.0272272,-0.0541325,0.655869},
+{0.324038,0.710271,-0.503013,0.131347,-0.125574},
+{-0.220883,-0.103133,0.882013,-0.207169,0.146864},
+{0.766691,0.0705879,0.0825369,-0.502545,0.228221},
+{0.895274,-0.197354,-0.234603,-0.0232927,0.131917},
+{-0.257596,0.412843,0.566726,-0.544417,0.226161},
+{0.296013,-0.541693,0.559311,-0.348357,0.375752},
+{-0.255127,0.882802,0.0156524,-0.25512,0.0153832},
+{0.668598,0.0427881,-0.000316741,0.194706,0.627481},
+{-0.150822,0.60525,-0.383042,0.535514,-0.329319},
+{0.0835202,0.0230119,0.619825,-0.662472,0.304508},
+{0.228531,0.43578,-0.163453,0.526958,-0.600919},
+{-0.024975,0.0622987,0.21989,0.57448,0.702719},
+{-0.0771633,0.170254,0.718226,0.226328,-0.532113},
+{-0.031851,-0.316799,0.649984,-0.375654,0.513181},
+{0.720653,0.52339,0.203987,0.167927,0.0998602},
+{0.22968,-0.101649,-0.158635,-0.324444,0.853797},
+{0.0138676,-0.311507,-0.253608,0.790742,0.326826},
+{0.404968,0.458736,0.124864,-0.662365,0.25065},
+{0.247051,0.851768,0.234943,-0.0360821,0.174313},
+{0.820181,-0.142236,0.401901,0.092983,0.171547},
+{-0.0234138,0.102285,0.470282,0.792313,0.112344},
+{0.276176,-0.323481,0.500884,-0.559456,0.4644},
+{-0.535225,0.156369,-0.0102809,0.197816,0.733569},
+{0.609358,0.217827,-0.0926352,0.661177,0.0951336}};
index fa0cc38..e6cb418 100644 (file)
@@ -32,6 +32,7 @@ extern float exc_gains_table[];
 extern float exc_table[];
 extern float exc_wb_table[];
 extern float exc_gains_wb_table[];
+extern float exc_sb_table[];
 ltp_params ltp_params_nb = {
    gain_cdbk_nb,
    7,
@@ -49,8 +50,13 @@ split_cb_params split_cb_nb = {
    5,               /*nb_subvect*/
    exc_table,       /*shape_cb*/
    7,               /*shape_bits*/
-   exc_gains_table, /*gain_cb*/
-   8                /*gain_bits*/
+};
+
+split_cb_params split_cb_sb = {
+   5,               /*subvect_size*/
+   8,              /*nb_subvect*/
+   exc_sb_table,    /*shape_cb*/
+   7,               /*shape_bits*/
 };
 
 split_cb_params split_cb_wb = {
@@ -58,8 +64,6 @@ split_cb_params split_cb_wb = {
    10,              /*nb_subvect*/
    exc_wb_table,    /*shape_cb*/
    7,               /*shape_bits*/
-   exc_gains_wb_table, /*gain_cb*/
-   8                /*gain_bits*/
 };
 
 mpulse_params mpulse_nb = {
@@ -160,7 +164,7 @@ SpeexMode wb_mode = {
    pitch_unquant_3tap,
    &ltp_params_wb,
    /*Innovation quantization*/
-   split_cb_search_wb,
+   split_cb_search,
    split_cb_unquant,
    &split_cb_wb
 };
@@ -202,7 +206,7 @@ SpeexMode mp_sb_mode = {
    17,     /*pitchStart*/
    144,    /*pitchEnd*/
    0.9,    /*gamma1*/
-   0.4,    /*gamma2*/
+   0.6,    /*gamma2*/
    .002,   /*lag_factor*/
    1.0001, /*lpc_floor*/
    0.0,    /*preemph*/
@@ -214,7 +218,13 @@ SpeexMode mp_sb_mode = {
    pitch_unquant_3tap,
    &ltp_params_nb,
    /*Innovation quantization*/
+#if 1
+   split_cb_search,
+   split_cb_unquant,
+   &split_cb_sb
+#else
    mpulse_search,
    mpulse_unquant,
    &mpulse_sb
+#endif
 };
index 80ba16e..689e364 100644 (file)
@@ -26,7 +26,7 @@
 #include "filters.h"
 #include <math.h>
 
-#define MAX_PULSE 30
+#define MAX_PULSE 60
 #define MAX_POS  100
 
 int porder(int *p, int *s, int *o, int len)
@@ -216,7 +216,7 @@ float *stack
    int i,j, nb_pulse;
    float *resp, *resp2, *energy, *t, *e, *pulses;
    float te=0,ee=0;
-   float g;
+   float g, gain_coef;
    int nb_tracks, track_ind_bits;
    int *tracks, *signs, *tr, *nb;
    mpulse_params *params;
@@ -227,6 +227,7 @@ float *stack
    nb_tracks=params->nb_tracks;
    pulses_per_track=nb_pulse/nb_tracks;
    track_ind_bits=params->track_ind_bits;
+   gain_coef=params->gain_coef;
 
    tracks = (int*)PUSH(stack,nb_pulse);
    signs = (int*)PUSH(stack,nb_pulse);
@@ -251,7 +252,7 @@ float *stack
       ee+=e[i]*e[i];
    }
    /*Compute global gain (coef found from linear regression and tweaking)*/
-   g=2.2/sqrt(nb_pulse)*exp(0.18163*log(te+1)+0.17293*log(ee+1));
+   g=gain_coef/sqrt(nb_pulse)*exp(0.18163*log(te+1)+0.17293*log(ee+1));
    
    e[0]=1;
    for (i=1;i<nsf;i++)
@@ -291,37 +292,43 @@ float *stack
          float dist;
          float *base=t+j;
          /*Fill any track until it's full*/
-         /*if (nb[j%nb_tracks]==pulses_per_track)
-              continue;*/
+         if (nb[j%nb_tracks]==pulses_per_track)
+              continue;
          /*Constrain search in alternating tracks*/
          /*FIXME: Should get rid of this, it's *really* slow*/
-         if ((i%nb_tracks) != (j%nb_tracks))
-           continue;
+         /*if ((i%nb_tracks) != (j%nb_tracks))
+           continue;*/
          /*Try for positive sign*/
-         dist=energy[j];
-         for (k=0;k<nsf-j;k++)
-         {
-            float tmp=(base[k]-resp2[k]);
-            dist+=tmp*tmp;
-         }
-         if (dist<best_score || j==0)
+         if (pulses[j]>=0)
          {
-            best_score=dist;
-            best_gain=g;
-            best_ind=j;
+            dist=energy[j];
+            for (k=0;k<nsf-j;k++)
+            {
+               float tmp=(base[k]-resp2[k]);
+               dist+=tmp*tmp;
+            }
+            if (dist<best_score || j==0)
+            {
+               best_score=dist;
+               best_gain=g;
+               best_ind=j;
+            }
          }
          /*Try again for negative sign*/
-         dist=energy[j];
-         for (k=0;k<nsf-j;k++)
+         if (pulses[j]<=0)
          {
-            float tmp=(base[k]+resp2[k]);
-            dist+=tmp*tmp;
-         }
-            if (dist<best_score || j==0)
-         {
-            best_score=dist;
-            best_gain=-g;
-            best_ind=j;
+            dist=energy[j];
+            for (k=0;k<nsf-j;k++)
+            {
+               float tmp=(base[k]+resp2[k]);
+               dist+=tmp*tmp;
+            }
+            if (dist<best_score)
+            {
+               best_score=dist;
+               best_gain=-g;
+               best_ind=j;
+            }
          }
       }
 #ifdef DEBUG
@@ -352,6 +359,7 @@ float *stack
       syn_filt_zero(resp, awk2, resp, nsf, p);
 
       f=((.1+(xcorr(resp,target,nsf)))/(.1+xcorr(resp,resp,nsf)));
+      printf ("gain correction %f\n", f);
       /*for (i=0;i<nsf;i++)
         e[i]*=f;*/
       g *= f;
index 881e705..9075350 100644 (file)
@@ -27,7 +27,7 @@
 typedef struct mpulse_params {
    int     nb_pulse;
    int     nb_tracks;
-   int     gain_coef;
+   float     gain_coef;
    int     track_ind_bits;
 } mpulse_params;
 
index 629241d..4b00a89 100644 (file)
@@ -182,6 +182,7 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode)
    st->buf=calloc(st->windowSize, sizeof(float));
    st->excBuf=calloc(2*st->frame_size, sizeof(float));
    st->exc=st->excBuf+st->frame_size;
+   st->exc_alias=calloc(st->frame_size, sizeof(float));
 
    st->res=calloc(st->frame_size, sizeof(float));
    st->sw=calloc(st->frame_size, sizeof(float));
@@ -190,6 +191,10 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode)
    for (i=0;i<st->windowSize;i++)
       st->window[i]=.5*(1-cos(2*M_PI*i/st->windowSize));
 
+   st->exc_window=calloc(st->frame_size, sizeof(float));
+   for (i=0;i<st->frame_size;i++)
+      st->exc_window[i]=.5*(1-cos(2*M_PI*i/st->frame_size));
+
    st->lagWindow = malloc((st->lpcSize+1)*sizeof(float));
    for (i=0;i<st->lpcSize+1;i++)
       st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i));
@@ -209,7 +214,9 @@ void sb_encoder_init(SBEncState *st, SpeexMode *mode)
    st->interp_qlpc = malloc((st->lpcSize+1)*sizeof(float));
 
    st->mem_sp = calloc(st->lpcSize, sizeof(float));
+   st->mem_sp2 = calloc(st->lpcSize, sizeof(float));
    st->mem_sw = calloc(st->lpcSize, sizeof(float));
+   st->mem_exc = calloc(st->lpcSize, sizeof(float));
 
 }
 
@@ -306,6 +313,30 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
       exit(1);
    }
 
+   {
+      for (i=0;i<st->frame_size;i++)
+         st->buf[i] = st->st_low.exc[i] * st->exc_window[i];
+      
+      /* Compute auto-correlation */
+      autocorr(st->buf, st->autocorr, st->lpcSize+1, st->frame_size);
+      
+      st->autocorr[0] += 1;        /* prevents NANs */
+      st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */
+      /* Lag windowing: equivalent to filtering in the power-spectrum domain */
+      for (i=0;i<st->lpcSize+1;i++)
+         st->autocorr[i] *= st->lagWindow[i];
+      
+      /* Levinson-Durbin */
+      wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize);
+      st->lpc[0]=1;
+      printf ("exc_lpc: ");
+      for(i=0;i<=st->lpcSize;i++)
+         printf ("%f ", st->lpc[i]);
+      printf ("\n");
+      residue_mem(st->st_low.exc, st->lpc, st->exc_alias, st->frame_size, st->lpcSize, st->mem_exc);
+   }
+
+
    /* x-domain to angle domain*/
    for (i=0;i<st->lpcSize;i++)
       st->lsp[i] = acos(st->lsp[i]);
@@ -353,20 +384,32 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
 
       bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
       bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
-#if 1 /* 1 for spectral folding excitation, 0 for stochastic */
+#if 0 /* 1 for spectral folding excitation, 0 for stochastic */
       for (i=0;i<st->lpcSize;i++)
          mem[i]=st->mem_sp[i];
       residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp);
       {
          float el=0,eh=0,g;
+         printf ("exca");
+         for (i=0;i<st->subframeSize;i++)
+            printf (" %f", exc[i]);
+         printf ("\n");
          for (i=0;i<st->subframeSize;i++)
             eh+=sqr(exc[i]);
+         /*for (i=0;i<st->subframeSize;i++)
+            el+=sqr(st->exc_alias[offset+i]);*/
          for (i=0;i<st->subframeSize;i++)
-            el+=sqr(st->st_low.exc[offset+i]);
+           el+=sqr(st->st_low.exc[offset+i]);
          g=eh/(.01+el);
          g=sqrt(g);
          for (i=0;i<st->subframeSize;i++)
-            exc[i]=g*st->st_low.exc[offset+i];
+           exc[i]=g*st->st_low.exc[offset+i];
+         /*for (i=0;i<st->subframeSize;i++)
+           exc[i]=g*st->exc_alias[offset+i];*/
+         printf ("excb");
+         for (i=0;i<st->subframeSize;i++)
+            printf (" %f", exc[i]);
+         printf ("\n");
       }
       syn_filt_mem(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, mem);
 
@@ -401,13 +444,31 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
          int ind;
          float gain;
 #if 0
+         
+         float el=0,eh=0,g;
+         residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
+         
+         for (i=0;i<st->subframeSize;i++)
+            eh+=sqr(exc[i]);
          overlap_cb_search(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
                            &stoc[0], 512, &gain, &ind, st->lpcSize,
                            st->subframeSize);
          for (i=0;i<st->subframeSize;i++)
             exc[i]=gain*stoc[ind+i];
+         for (i=0;i<st->subframeSize;i++)
+            el+=sqr(exc[i]);
+         g=sqrt(eh/(el+.001));
+         for (i=0;i<st->subframeSize;i++)
+            exc[i]*=g;
+         
 #else
          int k,N=2;
+         float el=0,eh=0,g;
+         residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
+         
+         for (i=0;i<st->subframeSize;i++)
+            eh+=sqr(exc[i]);
+
          for (i=0;i<st->subframeSize;i++)
             exc[i]=0;
          for (k=0;k<N;k++)
@@ -428,6 +489,11 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
          for (i=0;i<st->subframeSize/N;i++)
             exc[of+i]+=gain*stoc[ind+i];
          }
+         for (i=0;i<st->subframeSize;i++)
+            el+=sqr(exc[i]);
+         g=sqrt(eh/(el+.001));
+         for (i=0;i<st->subframeSize;i++)
+            exc[i]*=g;
 
 #endif
       }
index ac3fe43..7068c3e 100644 (file)
@@ -47,11 +47,13 @@ typedef struct SBEncState {
 
    float *excBuf;
    float *exc;
+   float *exc_alias;
    float *buf;
    float *res;
    float *sw;
    float *target;
    float *window;
+   float *exc_window;
    float *lagWindow;
    float *autocorr;
    float *rc;
@@ -68,7 +70,9 @@ typedef struct SBEncState {
    float *bw_lpc2;
 
    float *mem_sp;
+   float *mem_sp2;
    float *mem_sw;
+   float *mem_exc;
 } SBEncState;
 
 
index 491793b..6b2a841 100644 (file)
@@ -354,16 +354,19 @@ void encode(EncState *st, float *in, FrameBits *bits)
       syn_filt_zero(target, st->bw_lpc1, res, st->subframeSize, st->lpcSize);
       residue_zero(res, st->interp_qlpc, st->buf2, st->subframeSize, st->lpcSize);
       residue_zero(st->buf2, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize);
-      if (1||(snr>9 && (rand()%10==0)))
+      if (1||(snr>9 && (rand()%6==0)))
       {
+         float ener=0;
          printf ("exc ");
          for (i=0;i<st->subframeSize;i++)
          {
-            if (0&&i && i%8==0)
+            ener+=st->buf2[i]*st->buf2[i];
+            if (i && i%5==0)
                printf ("\nexc ");
             printf ("%f ", st->buf2[i]);
          }
          printf ("\n");
+      printf ("innovation_energy = %f\n", ener);
       }
       for (i=0;i<st->subframeSize;i++)
          exc[i]+=st->buf2[i];