Decoder back in sync with the encoder
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Mon, 29 Apr 2002 09:59:11 +0000 (09:59 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Mon, 29 Apr 2002 09:59:11 +0000 (09:59 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@3261 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/cb_search.c
libspeex/cb_search.h
libspeex/ltp.c
libspeex/ltp.h
libspeex/sb_celp.c
libspeex/testenc_sb.c

index 1b89ec1..e46c4e1 100644 (file)
@@ -454,7 +454,7 @@ float *stack
    float *resp, *E, q;
    float *t, *r, *e;
    float *gains;
-   int *ind;
+   int *ind, *gain_ind;
    float *shape_cb;
    int shape_cb_size, subvect_size, nb_subvect;
    float exc_energy=0;
@@ -472,6 +472,7 @@ float *stack
    e = PUSH(stack, nsf);
    gains = PUSH(stack, nb_subvect);
    ind = (int*)PUSH(stack, nb_subvect);
+   gain_ind = (int*)PUSH(stack, nb_subvect);
 
    /* Compute energy of the "real excitation" */
    syn_filt_zero(target, awk1, e, nsf, p);
@@ -526,7 +527,7 @@ float *stack
 
    for (i=0;i<nb_subvect;i++)
    {
-      int best_index[2]={0,0}, k, m;
+      int best_index[2]={0,0}, k, m, best_gain_ind[2]={0,0};
       float g, corr, best_gain[2]={0,0}, score, best_score[2]={-1,-1};
       /* Find best codeword for current sub-vector */
       for (j=0;j<shape_cb_size;j++)
@@ -563,6 +564,7 @@ float *stack
          /* Find gain index (it's a scalar but we use the VQ code anyway)*/
          best_id = vq_index(&best_gain[k], scal_gains4, 1, 8);
 
+         best_gain_ind[k]=best_id;
          best_gain[k]=scal_gains4[best_id];
          /*printf ("gain_quant: %f %d %f\n", best_gain, best_id, scal_gains4[best_id]);*/
          if (s)
@@ -635,7 +637,7 @@ float *stack
             best_index[0]=best_index[1];
             best_score[0]=best_score[1];
             best_gain[0]=best_gain[1];
-
+            best_gain_ind[0]=best_gain_ind[1];
          }
          POP(stack);
       }
@@ -644,6 +646,7 @@ float *stack
       
 
       ind[i]=best_index[0];
+      gain_ind[i]=best_gain_ind[0];
       gains[i]=best_gain[0];
       /* Update target for next subvector */
       for (j=0;j<subvect_size;j++)
@@ -653,7 +656,17 @@ float *stack
             t[k] -= g*r[m];
       }
    }
-   
+   for (i=0;i<nb_subvect;i++)
+   {
+      frame_bits_pack(bits, ind[i], params->shape_bits);
+      if (gains[i]<0)
+         frame_bits_pack(bits, 1, 1);
+      else
+         frame_bits_pack(bits, 0, 1);
+      frame_bits_pack(bits, gain_ind[i], 3);
+      printf ("encode split: %d %d %f\n", i, ind[i], gains[i]);
+
+   }
    /* Put everything back together */
    for (i=0;i<nb_subvect;i++)
       for (j=0;j<subvect_size;j++)
@@ -679,6 +692,7 @@ float *stack
    POP(stack);
    POP(stack);
    POP(stack);
+   POP(stack);
 }
 
 
@@ -732,7 +746,7 @@ float *stack
       gains[i] *= sign[i];
       gains[i] *= exc_energy;
 
-
+      printf ("decode split: %d %d %f\n", i, ind[i], gains[i]);
    }
 
    /* Compute decoded excitation */
@@ -744,3 +758,43 @@ float *stack
    POP(stack);
    POP(stack);
 }
+
+
+
+void split_cb_nogain_unquant(
+float *exc,
+void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+float gain,
+FrameBits *bits,
+float *stack
+)
+{
+   int i,j;
+   int *ind;
+   float *shape_cb;
+   int shape_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;
+   
+   ind = (int*)PUSH(stack, nb_subvect);
+
+   /* Decode codewords and gains */
+   for (i=0;i<nb_subvect;i++)
+   {
+      int gain_id;
+      ind[i] = frame_bits_unpack_unsigned(bits, params->shape_bits);
+   }
+
+   /* Compute decoded excitation */
+   for (i=0;i<nb_subvect;i++)
+      for (j=0;j<subvect_size;j++)
+         exc[subvect_size*i+j]+=gain*shape_cb[ind[i]*subvect_size+j];
+
+   POP(stack);
+}
index 244ff36..f4f4530 100644 (file)
@@ -92,4 +92,13 @@ FrameBits *bits,
 float *stack
 );
 
+void split_cb_nogain_unquant(
+float *exc,
+void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+float gain,
+FrameBits *bits,
+float *stack
+);
+
 #endif
index 7d565c2..24a420d 100644 (file)
@@ -328,7 +328,6 @@ float *stack
 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
 float pitch_gain_search_3tap(
 float target[],                 /* Target vector */
-float *sw,
 float ak[],                     /* LPCs for this subframe */
 float awk1[],                   /* Weighted LPCs #1 for this subframe */
 float awk2[],                   /* Weighted LPCs #2 for this subframe */
@@ -468,21 +467,28 @@ float *exc2
 )
 {
    int i,j;
-   int cdbk_index, pitch, ol_pitch;
+   int cdbk_index, pitch, ol_pitch, best_gain_index=0;
    float *best_exc;
    int best_pitch=0;
    float err, best_err=-1;
-   int N=0;
+   int N=2;
+   ltp_params *params;
+   params = (ltp_params*) par;
 
    best_exc=PUSH(stack,nsf);
 
    open_loop_pitch(sw, start, nsf, nsf, &ol_pitch);
 
+   if (ol_pitch-N<start)
+      ol_pitch=start+N;
+   if (ol_pitch+N>end)
+      ol_pitch=end-N;
+
    for (pitch=ol_pitch-N; pitch<=ol_pitch+N; pitch++)
    {
       for (j=0;j<nsf;j++)
          exc[j]=0;
-      err=pitch_gain_search_3tap(target, sw, ak, awk1, awk2, exc, par, pitch, p, nsf,
+      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
                              bits, stack, exc2, &cdbk_index);
       if (err<best_err || best_err<0)
       {
@@ -490,6 +496,7 @@ float *exc2
             best_exc[j]=exc[j];
          best_err=err;
          best_pitch=pitch;
+         best_gain_index=cdbk_index;
       }
    }
 
@@ -500,7 +507,7 @@ float *exc2
    {
       for (j=0;j<nsf;j++)
          exc[j]=0;
-      err=pitch_gain_search_3tap(target, sw, ak, awk1, awk2, exc, par, pitch, p, nsf,
+      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
                              bits, stack, exc2, &cdbk_index);
       if (err<best_err || best_err<0)
       {
@@ -508,11 +515,13 @@ float *exc2
             best_exc[j]=exc[j];
          best_err=err;
          best_pitch=pitch;
+         best_gain_index=cdbk_index;
       }
    }
 
-
-
+   frame_bits_pack(bits, best_pitch-start, params->pitch_bits);
+   frame_bits_pack(bits, best_gain_index, params->gain_bits);
+   printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);
    for (i=0;i<nsf;i++)
       exc[i]=best_exc[i];
 
@@ -543,6 +552,7 @@ float *stack
    pitch = frame_bits_unpack_unsigned(bits, params->pitch_bits);
    pitch += start;
    gain_index = frame_bits_unpack_unsigned(bits, params->gain_bits);
+   printf ("decode pitch: %d %d\n", pitch, gain_index);
    gain[0] = gain_cdbk[gain_index*12];
    gain[1] = gain_cdbk[gain_index*12+1];
    gain[2] = gain_cdbk[gain_index*12+2];
@@ -555,4 +565,30 @@ float *stack
    {
       exc[i]=gain[0]*exc[i-pitch+1] + gain[1]*exc[i-pitch] + gain[2]*exc[i-pitch-1];
    }
+
+   {
+      float *e[3];
+      float *tmp2;
+      tmp2=PUSH(stack, 3*nsf);
+      e[0]=tmp2;
+      e[1]=tmp2+nsf;
+      e[2]=tmp2+2*nsf;
+      
+      for (i=0;i<3;i++)
+      {
+         int j;
+         int pp=pitch+1-i;
+         for (j=0;j<nsf;j++)
+         {
+            if (j-pp<0)
+               e[i][j]=exc[j-pp];
+            else
+               e[i][j]=exc[j-pp-pitch];
+         }
+      }
+      for (i=0;i<nsf;i++)
+         exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
+      
+      POP(stack);
+   }
 }
index 55d9a33..9638aac 100644 (file)
@@ -93,3 +93,19 @@ int   nsf,                      /* Number of samples in subframe */
 FrameBits *bits,
 float *stack
 );
+
+float pitch_gain_search_3tap(
+float target[],                 /* Target vector */
+float ak[],                     /* LPCs for this subframe */
+float awk1[],                   /* Weighted LPCs #1 for this subframe */
+float awk2[],                   /* Weighted LPCs #2 for this subframe */
+float exc[],                    /* Excitation */
+void *par,
+int   pitch,                    /* Pitch value */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+FrameBits *bits,
+float *stack,
+float *exc2,
+int  *cdbk_index
+);
index 15ed4d6..05c78a7 100644 (file)
@@ -30,6 +30,7 @@
 #include "quant_lsp.h"
 #include "vq.h"
 #include <string.h>
+#include "ltp.h"
 
 #ifndef M_PI
 #define M_PI           3.14159265358979323846  /* pi */
@@ -364,9 +365,9 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
    /*printf ("high_lsp:");
    for (i=0;i<st->lpcSize;i++)
       printf (" %f", st->lsp[i]);
-      printf ("\n");
-   for (i=0;i<st->lpcSize;i++)
-   st->qlsp[i]=st->lsp[i];*/
+      printf ("\n");*/
+   /*for (i=0;i<st->lpcSize;i++)
+     st->qlsp[i]=st->lsp[i];*/
    
 
    if (st->first)
@@ -411,7 +412,7 @@ 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);
 
-      /* Compute mid-band (4000 for wideband) response of low-band and high-band
+      /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
          filters */
       rl=rh=0;
       tmp=1;
@@ -421,10 +422,10 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
          tmp = -tmp;
       }
       rl = st->st_low.pi_gain[sub];
-      rl=1/(fabs(rl)+.001);
-      rh=1/(fabs(rh)+.001);
+      rl=1/(fabs(rl)+.01);
+      rh=1/(fabs(rh)+.01);
       /* Compute ratio, will help predict the gain */
-      filter_ratio=fabs(.001+rh)/(.001+fabs(rl));
+      filter_ratio=fabs(.01+rh)/(.01+fabs(rl));
 
       
       if (0) {/* 1 for spectral folding excitation, 0 for stochastic */
@@ -434,7 +435,13 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
             mem[i]=st->mem_sp[i];
          /* Compute "real excitation" */
          residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp);
-         
+         printf ("high_exc:");
+         for (i=0;i<st->subframeSize;i++)
+            printf (" %f", exc[i]);
+         printf ("\nlow_exc:");
+         for (i=0;i<st->subframeSize;i++)
+            printf (" %f", st->st_low.exc[offset+i]);
+         printf ("\n");
 #if 1
          /* Compute energy of low-band and high-band excitation */
          for (i=0;i<st->subframeSize;i++)
@@ -459,149 +466,17 @@ void sb_encode(SBEncState *st, float *in, FrameBits *bits)
          /* High-band excitation using the low-band excitation and a gain */
          for (i=0;i<st->subframeSize;i++)
             exc[i]=g*st->st_low.exc[offset+i];
-         
+
          /* FIXME: Should encode the gain here */
 #endif
          /* Update the input signal using the non-coded memory */
          syn_filt_mem(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, mem);
-      } else if (0) {/* Stochastic split-VQ excitation */
-         int k,N=4;
-         float el=0,eh=0,eb=0,g;
-         int *index;
-         float *gains;
-         gains = PUSH(st->stack, N);
-         index = (int*) PUSH(st->stack, N);
-         
-         /* Reset excitation */
-         for (i=0;i<st->subframeSize;i++)
-            exc[i]=0;
-         
-         /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sp[i];
-         syn_filt_mem(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem);
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sp[i];
-         residue_mem(exc, st->bw_lpc1, res, st->subframeSize, st->lpcSize, mem);
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sw[i];
-         syn_filt_mem(res, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem);
-         
-         /* Compute weighted signal */
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sp[i];
-         residue_mem(sp, st->bw_lpc1, sw, st->subframeSize, st->lpcSize, mem);
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sw[i];
-         syn_filt_mem(sw, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem);
-         
-         /* Compute target signal */
-         for (i=0;i<st->subframeSize;i++)
-            target[i]=sw[i]-res[i];
-         
-         
-         /* Compute "real excitation" */
-         residue_mem(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
-         /* Energy of "real excitation" */
-         for (i=0;i<st->subframeSize;i++)
-            eh+=sqr(exc[i]);
-
-         for (i=0;i<st->subframeSize;i++)
-            exc[i]=0;
-         /*
-st->st_low.ltp_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                    exc, st->st_low.ltp_params, st->st_low.min_pitch, st->st_low.max_pitch, 
-                    st->lpcSize, st->subframeSize, bits, st->stack, exc);
-         */
-         /* For all sub-vectors, find best gain and codeword/shape */
-         for (k=0;k<N;k++)
-         {
-            int of=k*st->subframeSize/N;
-            overlap_cb_search(target+of, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                              &stoc[0], 64, &gains[k], &index[k], st->lpcSize,
-                              st->subframeSize/N, st->stack);
-            
-            frame_bits_pack(bits,index[k],6);
-            
-            /* Compute response */
-            for (i=0;i<st->subframeSize;i++)
-               res[i]=0;
-            for (i=0;i<st->subframeSize/N;i++)
-               res[of+i]=gains[k]*stoc[index[k]+i];
-            residue_zero(res, st->bw_lpc1, res, st->subframeSize, st->lpcSize);
-            syn_filt_zero(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize);
-            syn_filt_zero(res, st->bw_lpc2, res, st->subframeSize, st->lpcSize);
-            /* Update target */
-            for (i=0;i<st->subframeSize;i++)
-               target[i]-=res[i];
-
-            /* Update excitation */
-            for (i=0;i<st->subframeSize/N;i++)
-               exc[of+i]+=gains[k]*stoc[index[k]+i];
-         }
-         /* Compute energy of best excitation found */
-         for (i=0;i<st->subframeSize;i++)
-            eb+=sqr(exc[i]);
-
-         /* Compute adjustment gain for the new excitation to have the same energy 
-            as the "real" one */
-         g=sqrt(eh/(eb+.001));
-
-         /* Compute low-band excitation energy*/
-         for (i=0;i<st->subframeSize;i++)
-            el+=sqr(st->st_low.exc[offset+i]);
-         
-         /* Quantize all gains */
-         for (k=0;k<N;k++)
-         {
-            int sign=0;
-            float quant;
-            int best_ind;
-            int of=k*st->subframeSize/N;
-            gains[k]*=g;
-
-            /* Get sign separately */
-            if (gains[k]<0)
-            {
-               sign=1;
-               gains[k] = -gains[k];
-            }
-            /* Use prediction with low-band energy and filter pi-response ratio and 
-               then convert to the log domain */
-            quant = log((1+gains[k])*filter_ratio/(1+sqrt(el/st->subframeSize)));
-            
-            /* Quantize the gain */
-            best_ind = vq_index(&quant, quant_high_gain2, 1, 8);
-            quant=quant_high_gain2[best_ind];
-
-            frame_bits_pack(bits,sign,1);
-            frame_bits_pack(bits,best_ind,3);
-
-            gains[k]=exp(quant)*(1+sqrt(el/st->subframeSize))/filter_ratio;
-            if (sign)
-               gains[k] = -gains[k];
-
-            /* FIXME: Should we use the "adjusted excitation" in the encoder? */
-            for (i=0;i<st->subframeSize/N;i++)
-              exc[of+i]=gains[k]*stoc[index[k]+i];
-
-         }
-         POP(st->stack);
-         POP(st->stack);
-
-
-         /*Keep the previous memory*/
-         for (i=0;i<st->lpcSize;i++)
-            mem[i]=st->mem_sp[i];
-         /* Final signal synthesis from excitation */
-         syn_filt_mem(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
-         
-         /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
-         residue_mem(sp, st->bw_lpc1, sw, st->subframeSize, st->lpcSize, mem);
-         syn_filt_mem(sw, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);
       } else {
          float el=0;
          float gc;
+         float *innov;
+
+         innov = PUSH(st->stack, st->subframeSize);
 
          for (i=0;i<st->subframeSize;i++)
             el+=sqr(st->st_low.exc[offset+i]);
@@ -633,20 +508,27 @@ st->st_low.ltp_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
          
          /* Compute target signal */
          for (i=0;i<st->subframeSize;i++)
-            target[i]=gc*(sw[i]-res[i]);
+            target[i]=sw[i]-res[i];
+
+         for (i=0;i<st->subframeSize;i++)
+           exc[i]=0;
+
+
+         for (i=0;i<st->subframeSize;i++)
+            target[i]*=gc;
          
          /* Reset excitation */
          for (i=0;i<st->subframeSize;i++)
-            exc[i]=0;
+            innov[i]=0;
 
          print_vec(target, st->subframeSize, "\ntarget");
          split_cb_search_nogain(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
                                 &split_cb_high, st->lpcSize, st->subframeSize, 
-                                exc, bits, st->stack);
+                                innov, bits, st->stack);
          print_vec(target, st->subframeSize, "after");
 
          for (i=0;i<st->subframeSize;i++)
-            exc[i] *= 1/gc;
+            exc[i] += innov[i]/gc;
 #if 1
          /*Keep the previous memory*/
          for (i=0;i<st->lpcSize;i++)
@@ -658,6 +540,7 @@ st->st_low.ltp_quant(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
          residue_mem(sp, st->bw_lpc1, sw, st->subframeSize, st->lpcSize, mem);
          syn_filt_mem(sw, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);
 #endif
+         POP(st->stack);
       }
       
       POP(st->stack);
@@ -777,7 +660,7 @@ void sb_decode(SBDecState *st, FrameBits *bits, float *out)
    
    for (sub=0;sub<st->nbSubframes;sub++)
    {
-      float *exc, *sp, tmp, filter_ratio;
+      float *exc, *sp, tmp, filter_ratio, gain, el=0;
       int offset;
       
       offset = st->subframeSize*sub;
@@ -805,45 +688,19 @@ void sb_decode(SBDecState *st, FrameBits *bits, float *out)
             tmp = -tmp;
          }
          rl = st->st_low.pi_gain[sub];
-         rl=1/(fabs(rl)+.001);
-         rh=1/(fabs(rh)+.001);
-         filter_ratio=fabs(.001+rh)/(.001+fabs(rl));
+         rl=1/(fabs(rl)+.01);
+         rh=1/(fabs(rh)+.01);
+         filter_ratio=fabs(.01+rh)/(.01+fabs(rl));
       }
 
-      {
-         int k,N=4,el=0;
-         int *index;
-         float *gains;
-         int of;
-         gains = PUSH(st->stack, N);
-         index = (int*) PUSH(st->stack, N);
-
-         for (i=0;i<st->subframeSize;i++)
-           el+=sqr(st->st_low.exc[offset+i]);
-         
-         for (k=0;k<N;k++)
-            index[k] = frame_bits_unpack_unsigned(bits,6);
-
-         for (k=0;k<N;k++)
-         {
-            int sign, gain_ind;
-            sign = frame_bits_unpack_unsigned(bits,1);
-            gain_ind = frame_bits_unpack_unsigned(bits,3);
-            gains[k]=exp(quant_high_gain2[gain_ind])*(1+sqrt(el/st->subframeSize))/filter_ratio;
-            if (sign)
-               gains[k] =- gains[k];
-         }
-
-         for (k=0;k<N;k++)
-         {
-            of=k*st->subframeSize/N;
-            for (i=0;i<st->subframeSize/N;i++)
-               exc[of+i]=gains[k]*stoc[index[k]+i];
-         }
-
-         POP(st->stack);
-         POP(st->stack);
-      }
+      for (i=0;i<st->subframeSize;i++)
+         el+=sqr(st->st_low.exc[offset+i]);
+      gain=(1+sqrt(el/st->subframeSize))/filter_ratio;
+      
+      for (i=0;i<st->subframeSize;i++)
+         exc[i]=0;
+      split_cb_nogain_unquant(exc, &split_cb_high, st->subframeSize, gain, 
+                              bits, st->stack);
 
       syn_filt_mem(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
 
index 37adc9a..00887b5 100644 (file)
@@ -59,7 +59,7 @@ int main(int argc, char **argv)
 
       frame_bits_rewind(&bits);
       
-      /*sb_decode(&dec, &bits, input);*/
+      sb_decode(&dec, &bits, input);
 
       frame_bits_reset(&bits);
       for (i=0;i<FRAME_SIZE;i++)