The code is getting horribly messy, but there's too much stuff that needs
authorjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 7 Mar 2002 21:55:22 +0000 (21:55 +0000)
committerjmvalin <jmvalin@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 7 Mar 2002 21:55:22 +0000 (21:55 +0000)
to be added:
- Fractional pitch
- SNR measurements
- Split-codebook search for excitation
- ...

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

libspeex/Makefile.am
libspeex/cb_search.c
libspeex/cb_search.h
libspeex/filters.c
libspeex/filters.h
libspeex/ltp.c
libspeex/ltp.h
libspeex/speex.c
libspeex/speex.h

index b1b7793..d992d66 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in. -*-Makefile-*-
 
-# $Id: Makefile.am,v 1.7 2002/03/01 15:40:57 jmvalin Exp $
+# $Id: Makefile.am,v 1.8 2002/03/07 21:55:22 jmvalin Exp $
 
 # Disable automatic dependency tracking if using other tools than gcc and gmake
 #AUTOMAKE_OPTIONS = no-dependencies
@@ -19,7 +19,8 @@ libspeex_la_SOURCES = speex.c \
        stoc.c \
        filters.c \
        bits.c \
-       modes.c
+       modes.c \
+       exc_table.c
 
 include_HEADERS = speex.h \
        bits.h \
index b213a83..346dc64 100644 (file)
@@ -46,7 +46,7 @@
                                                                              
 \*---------------------------------------------------------------------------*/
 
-void overlap_cb_search(
+float overlap_cb_search(
 float target[],                        /* target vector */
 float ak[],                    /* LPCs for this subframe */
 float awk1[],                  /* Weighted LPCs for this subframe */
@@ -120,6 +120,73 @@ int   nsf                       /* number of samples in subframe */
   free(resp);
   free(h);
   free(impulse);
+  return bscore;
+}
+
+
 
+
+
+float split_cb_search(
+float target[],                        /* target vector */
+float ak[],                    /* LPCs for this subframe */
+float awk1[],                  /* Weighted LPCs for this subframe */
+float awk2[],                  /* Weighted LPCs for this subframe */
+float codebook[][8],           /* overlapping codebook */
+int   entries,                 /* number of entries to search */
+float *gain,                   /* gain of optimum entries */
+int   *index,                  /* index of optimum entries */
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+float *exc
+)
+{
+   int i,j;
+   float resp[64][8], E[64];
+   float t[40], r[40], e[40];
+   for (i=0;i<40;i++)
+      t[i]=target[i];
+   for (i=0;i<64;i++)
+   {
+      residue_zero(codebook[i], awk1, resp[i], 8, p);
+      syn_filt_zero(resp[i], ak, resp[i], 8, p);
+      syn_filt_zero(resp[i], awk2, resp[i], 8,p);
+      E[i]=0;
+      for(j=0;j<8;j++)
+         E[i]+=resp[i][j]*resp[i][j];
+   }
+   for (i=0;i<5;i++)
+   {
+      int best_index;
+      float corr, best_gain, score, best_score=-1;
+      for (j=0;j<64;j++)
+      {
+         corr=xcorr(resp[j],t+8*i,8);
+         score=corr*corr/(.001+E[j]);
+         if (score>best_score)
+         {
+            best_index=j;
+            best_score=score;
+            best_gain=corr/(.001+E[j]);
+         }
+      }
+      printf ("search: %d %f %f\n", best_index, best_gain, best_score);
+      for (j=0;j<40;j++)
+         e[j]=0;
+      for (j=0;j<8;j++)
+         e[8*i+j]=best_gain*codebook[best_index][j];
+      residue_zero(e, awk1, r, 40, p);
+      syn_filt_zero(r, ak, r, 40, p);
+      syn_filt_zero(r, awk2, r, 40,p);
+      for (j=0;j<40;j++)
+         t[j]-=r[j];
+
+      for (j=0;j<40;j++)
+         exc[j]+=e[j];
+   }
+
+
+   for (i=0;i<40;i++)
+      target[i]=t[i];
 }
 
index dd3f08f..0f7136c 100644 (file)
@@ -20,7 +20,7 @@
 #ifndef CB_SEARCH_H
 #define CB_SEARCH_H
 
-void overlap_cb_search(
+float overlap_cb_search(
 float target[],                        /* target vector */
 float ak[],                    /* LPCs for this subframe */
 float awk1[],                  /* Weighted LPCs for this subframe */
@@ -33,4 +33,19 @@ int   p,                        /* number of LPC coeffs */
 int   nsf                       /* number of samples in subframe */
 );
 
+
+float split_cb_search(
+float target[],                        /* target vector */
+float ak[],                    /* LPCs for this subframe */
+float awk1[],                  /* Weighted LPCs for this subframe */
+float awk2[],                  /* Weighted LPCs for this subframe */
+float codebook[][8],           /* overlapping codebook */
+int   entries,                 /* number of entries to search */
+float *gain,                   /* gain of optimum entries */
+int   *index,                  /* index of optimum entries */
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+float *exc
+);
+
 #endif
index fbe8790..325b450 100644 (file)
 
 #define min(a,b) ((a) < (b) ? (a) : (b))
 
+void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order)
+{
+   int i;
+   float tmp=1;
+   for (i=0;i<order+1;i++)
+   {
+      lpc_out[i] = tmp * lpc_in[i];
+      tmp *= gamma;
+   }
+}
+
 void syn_filt(float *x, float *a, float *y, int N, int ord)
 {
    int i,j;
index 14337b8..81515b9 100644 (file)
@@ -20,6 +20,9 @@
 #ifndef FILTERS_H
 #define FILTERS_H
 
+/* Apply bandwidth expansion on LPC coef */
+void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order);
+
 /* Synthesis filter using the past of y[n] (negative indices) as memory */
 void syn_filt(float *x, float *a, float *y, int N, int ord);
 
index 9bcefec..4879335 100644 (file)
 
 #define abs(x) ((x)<0 ? -(x) : (x))
 
+void open_loop_pitch(float *sw, int start, int end, int len, int *pitch, int *vuv)
+{
+   int i;
+   float e0, corr, energy, best_gain, pred_gain, best_corr, best_energy;
+   float score, best_score=-1;
+   e0=xcorr(sw, sw, len);
+   energy=xcorr(sw-start, sw-start, len);
+   for (i=start;i<=end;i++)
+   {
+      corr=xcorr(sw, sw-i, len);
+      score=corr*corr/(energy+1);
+      if (score>best_score)
+      {
+         if ((abs(i-2**pitch)>4 && abs(i-3**pitch)>6) || score>1.2*best_score)
+         {
+         best_score=score;
+         best_gain=corr/(energy+1);
+         best_corr=corr;
+         best_energy=energy;
+         *pitch=i;
+         }
+      }
+
+      /* Update energy for next pitch*/
+      energy+=sw[-i-1]*sw[-i-1] - sw[-i+len]*sw[-i+len];
+   }
+   pred_gain=e0/(1+fabs(e0+best_gain*best_gain*best_energy-2*best_gain*best_corr));
+   printf ("pred = %f\n", pred_gain);
+   *vuv=1;
+}
+
+void closed_loop_fractional_pitch(
+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[],                    /* Overlapping codebook */
+float *filt,                    /* Over-sampling filter */
+int   filt_side,                /* Over-sampling factor */
+int   fact,                     /* Over-sampling factor */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+float *gain,                    /* 3-tab gains of optimum entry */
+int   *pitch,                   /* Index of optimum entry */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+float *stack
+)
+{
+   int i, j, size, filt_size, base, frac, best_cor;
+   float *oexc_mem, *oexc, *exc_ptr, *fexc, *f, frac_pitch, best_score=-1, best_gain;
+   float sc;
+   float corr[3];
+   float A[3][3];
+#if 1
+   sc = overlap_cb_search(target, ak, awk1, awk2,
+                     &exc[-end], end-start+1, gain, pitch, p,
+                     nsf);
+                     *pitch=end-*pitch;
+   printf ("ol score: %d %f\n", *pitch, sc);
+#endif
+   base=*pitch;
+   exc_ptr=exc-*pitch;
+   size = fact*nsf + filt_side*2 + 16*fact;
+   filt_size = 2*filt_side+1;
+   oexc_mem = PUSH(stack, size);
+   oexc=oexc_mem+filt_side;
+   fexc = PUSH(stack, size/fact);
+   f=filt+filt_side;
 
+   for(i=0;i<size;i++)
+      oexc_mem[i]=0;
+   for (i=-8;i<nsf+8;i++)
+   {
+      for (j=-filt_side;j<=filt_side;j++)
+         oexc[fact*(i+8)+j] += fact*exc_ptr[i]*f[j];
+   }
+
+   /*for (i=0;i<size;i++)
+     printf ("%f ", oexc_mem[i]);
+   printf ("eee\n");
+   */
+   for (j=0;j<fact;j++)
+   {
+      int correction;
+      float score;
+      for (i=0;i<size/fact;i++)
+         fexc[i]=oexc[fact*i+j];
+      score=overlap_cb_search(target, ak, awk1, awk2,
+                        fexc, 16, gain, &correction, p,
+                        nsf);
+      if (score>best_score)
+      {
+         best_cor = correction;
+         *pitch = base+8-correction;
+         frac = j;
+         best_gain=*gain;
+         frac_pitch = *pitch-(j/(float)fact);
+         best_score=score;
+      }
+      printf ("corr: %d %d %f\n", correction, *pitch, score);
+   }
+   /*for (i=0;i<nsf;i++)
+     printf ("%f ", oexc[4*(i+8)]);
+   printf ("aaa\n");
+   for (i=0;i<nsf;i++)
+     printf ("%f ", exc[i-base]);
+     printf ("bbb\n");*/
+
+   /*if (best_gain>1.2)
+      best_gain=1.2;
+   if (best_gain<-.2)
+   best_gain=-.2;*/
+   for (i=0;i<nsf;i++)
+     exc[i]=best_gain*oexc[fact*(best_cor+i)+frac];
+   
+   {
+      float *x[3];
+      x[0] = PUSH(stack, nsf);
+      x[1] = PUSH(stack, nsf);
+      x[2] = PUSH(stack, nsf);
+      
+      for (j=0;j<3;j++)
+         for (i=0;i<nsf;i++)
+            x[j][i]=oexc[fact*(best_cor+i)+frac+fact*(j-1)];
+
+
+   for (i=0;i<3;i++)
+   {
+      residue_zero(x[i],awk1,x[i],nsf,p);
+      syn_filt_zero(x[i],ak,x[i],nsf,p);
+      syn_filt_zero(x[i],awk2,x[i],nsf,p);
+   }
+
+   for (i=0;i<3;i++)
+      corr[i]=xcorr(x[i],target,nsf);
+   
+   for (i=0;i<3;i++)
+      for (j=0;j<=i;j++)
+         A[i][j]=A[j][i]=xcorr(x[i],x[j],nsf);
+   /*for (i=0;i<3;i++)
+   {
+      for (j=0;j<3;j++)
+         printf ("%f ", A[i][j]);
+      printf ("\n");
+      }*/
+   A[0][0]+=1;
+   A[1][1]+=1;
+   A[2][2]+=1;
+   {
+      float tmp=A[1][0]/A[0][0];
+      for (i=0;i<3;i++)
+         A[1][i] -= tmp*A[0][i];
+      corr[1] -= tmp*corr[0];
+
+      tmp=A[2][0]/A[0][0];
+      for (i=0;i<3;i++)
+         A[2][i] -= tmp*A[0][i];
+      corr[2] -= tmp*corr[0];
+      
+      tmp=A[2][1]/A[1][1];
+      A[2][2] -= tmp*A[1][2];
+      corr[2] -= tmp*corr[1];
+
+      corr[2] /= A[2][2];
+      corr[1] = (corr[1] - A[1][2]*corr[2])/A[1][1];
+      corr[0] = (corr[0] - A[0][2]*corr[2] - A[0][1]*corr[1])/A[0][0];
+      /*printf ("\n%f %f %f\n", best_corr[0], best_corr[1], best_corr[2]);*/
+
+   }
+   /* Put gains in right order */
+   /*gain[0]=corr[2];gain[1]=corr[1];gain[2]=corr[0];*/
+   gain[0]=corr[0];gain[1]=corr[1];gain[2]=corr[2];
+
+   for (i=0;i<nsf;i++)
+      exc[i]=gain[0]*oexc[fact*(best_cor+i)+frac-fact] + 
+             gain[1]*oexc[fact*(best_cor+i)+frac] + 
+             gain[2]*oexc[fact*(best_cor+i)+frac+fact];
+   
+   /*for (i=0;i<nsf;i++)
+     exc[i]=best_gain*x[1][i];*/
+   /*for (i=0;i<nsf;i++)
+     exc[i]=best_gain*oexc[fact*(best_cor+i)+frac];*/
+   printf ("frac gains: %f %f %f\n", gain[0], gain[1], gain[2]);
+
+      POP(stack);
+      POP(stack);
+      POP(stack);
+   }
+   printf ("frac pitch = %f %f\n", frac_pitch, best_score);
+   POP(stack);
+   POP(stack);
+
+}
 
 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
 float pitch_search_3tap_unquant(
index 8681134..566b5ce 100644 (file)
 
 extern float gain_cdbk_nb[];
 
+/* Finds open-loop pitch */
+void open_loop_pitch(float *sw, int start, int end, int len, int *pitch, int *vuv);
+
+void closed_loop_fractional_pitch(
+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[],                    /* Overlapping codebook */
+float *filt,                    /* Over-sampling filter */
+int   filt_side,                /* Over-sampling factor */
+int   fact,                     /* Over-sampling factor */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+float *gain,                    /* 3-tab gains of optimum entry */
+int   *pitch,                   /* Index of optimum entry */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+float *stack
+);
 
 /** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
 float pitch_search_3tap(
index 80dc369..e381069 100644 (file)
@@ -30,7 +30,7 @@
 #include "stack_alloc.h"
 
 extern float stoc[];
-
+extern float exc_table[][8];
 #ifndef M_PI
 #define M_PI           3.14159265358979323846  /* pi */
 #endif
@@ -41,6 +41,7 @@ extern float stoc[];
 void encoder_init(EncState *st, SpeexMode *mode)
 {
    int i;
+   float tmp;
    /* Codec parameters, should eventually have several "modes"*/
    st->frameSize = mode->frameSize;
    st->windowSize = mode->windowSize;
@@ -50,16 +51,39 @@ void encoder_init(EncState *st, SpeexMode *mode)
    st->bufSize = mode->bufSize;
    st->gamma1=mode->gamma1;
    st->gamma2=mode->gamma2;
-
-
-   st->inBuf = malloc(st->bufSize*sizeof(float));
+   st->min_pitch=mode->pitchStart;
+   st->max_pitch=mode->pitchEnd;
+
+   /* Over-sampling filter (fractional pitch)*/
+   st->os_fact=4;
+   st->os_filt_ord2=4*st->os_fact;
+   st->os_filt = malloc((1+2*st->os_filt_ord2)*sizeof(float));
+   st->os_filt[st->os_filt_ord2] = 1;
+   for (i=1;i<=st->os_filt_ord2;i++)
+   {
+      float x=M_PI*i/st->os_fact;
+      st->os_filt[st->os_filt_ord2-i] = st->os_filt[st->os_filt_ord2+i]=sin(x)/x*(.5+.5*cos(M_PI*i/st->os_filt_ord2));
+   }
+   /* Normalizing the over-sampling filter */
+   tmp=0;
+   for (i=0;i<2*st->os_filt_ord2+1;i++)
+      tmp += st->os_filt[i];
+   tmp=1/tmp;
+   for (i=0;i<2*st->os_filt_ord2+1;i++)
+      st->os_filt[i] *= tmp;
+
+   /*for (i=0;i<2*st->os_filt_ord2+1;i++)
+      printf ("%f ", st->os_filt[i]);
+      printf ("\n");*/
+
+   /* Allocating input buffer */
+   st->inBuf = calloc(st->bufSize,sizeof(float));
    st->frame = st->inBuf + st->bufSize - st->windowSize;
-   st->excBuf = malloc(st->bufSize*sizeof(float));
+   /* Allocating excitation buffer */
+   st->excBuf = calloc(st->bufSize,sizeof(float));
    st->exc = st->excBuf + st->bufSize - st->windowSize;
-   for (i=0;i<st->bufSize;i++)
-      st->inBuf[i]=0;
-   for (i=0;i<st->bufSize;i++)
-      st->excBuf[i]=0;
+   st->swBuf = calloc(st->bufSize,sizeof(float));
+   st->sw = st->swBuf + st->bufSize - st->windowSize;
 
    /* Hanning window */
    st->window = malloc(st->windowSize*sizeof(float));
@@ -73,7 +97,7 @@ void encoder_init(EncState *st, SpeexMode *mode)
 
    st->autocorr = malloc((st->lpcSize+1)*sizeof(float));
 
-   st->stack = calloc(2000, sizeof(float));
+   st->stack = calloc(10000, sizeof(float));
 
    st->buf2 = malloc(st->windowSize*sizeof(float));
 
@@ -102,6 +126,7 @@ void encoder_destroy(EncState *st)
    /* Free all allocated memory */
    free(st->inBuf);
    free(st->excBuf);
+   free(st->swBuf);
    
    free(st->stack);
 
@@ -138,6 +163,7 @@ void encode(EncState *st, float *in, FrameBits *bits)
    for (i=0;i<st->frameSize;i++)
       st->inBuf[st->bufSize-st->frameSize+i] = in[i];
    memmove(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
+   memmove(st->swBuf, st->swBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float));
 
    /* Window for analysis */
    for (i=0;i<st->windowSize;i++)
@@ -177,6 +203,28 @@ void encode(EncState *st, float *in, FrameBits *bits)
       lsp_unquant_nb(st->qlsp,10,id);
    }
 
+   /*Find open-loop pitch for the whole frame*/
+   {
+      float *mem = PUSH(st->stack, st->lpcSize);
+      
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_lsp[i] = .5*st->old_lsp[i] + .5*st->lsp[i];
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_lsp[i] = cos(st->interp_lsp[i]);
+      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,st->stack);
+      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+      bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sp[i];
+      residue_mem(st->frame, st->bw_lpc1, st->sw, st->frameSize, st->lpcSize, mem);
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sw[i];
+         syn_filt_mem(st->sw, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, mem);
+      open_loop_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, &st->ol_pitch, &st->ol_voiced);
+      printf ("Open-loop pitch = %d\n", st->ol_pitch);
+      POP(st->stack);
+   }
+
    /* Loop on sub-frames */
    for (sub=0;sub<st->nbSubframes;sub++)
    {
@@ -187,10 +235,12 @@ void encode(EncState *st, float *in, FrameBits *bits)
       
       /* Offset relative to start of frame */
       offset = st->subframeSize*sub;
+      /* Original signal */
       sp=st->frame+offset;
+      /* Excitation */
       exc=st->exc+offset;
       /* Weighted signal */
-      sw = PUSH(st->stack, st->subframeSize);
+      sw=st->sw+offset;
       /* Filter response */
       res = PUSH(st->stack, st->subframeSize);
       /* Target signal */
@@ -214,18 +264,8 @@ void encode(EncState *st, float *in, FrameBits *bits)
       lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, st->stack);
 
       /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */
-      tmp=1;
-      for (i=0;i<st->lpcSize+1;i++)
-      {
-         st->bw_lpc1[i] = tmp * st->interp_lpc[i];
-         tmp *= st->gamma1;
-      }
-      tmp=1;
-      for (i=0;i<st->lpcSize+1;i++)
-      {
-         st->bw_lpc2[i] = tmp * st->interp_lpc[i];
-         tmp *= st->gamma2;
-      }
+      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+      bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
       
       /* Reset excitation */
       for (i=0;i<st->subframeSize;i++)
@@ -262,27 +302,39 @@ void encode(EncState *st, float *in, FrameBits *bits)
 #if 1 /*If set to 0, we compute the excitation directly from the target, i.e. we're cheating */
 
       /* Perform adaptive codebook search (3-tap pitch predictor) */
-      pitch_search_3tap(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+      pitch = st->ol_pitch;
+      closed_loop_fractional_pitch(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                                   exc, st->os_filt, st->os_filt_ord2, st->os_fact, 20, 147, 
+                                   &gain[0], &pitch, st->lpcSize,
+                                   st->subframeSize, st->stack);
+      /*pitch_search_3tap(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
                         exc, 20, 147, &gain[0], &pitch, &pitch_gain_index, st->lpcSize,
                         st->subframeSize);
       for (i=0;i<st->subframeSize;i++)
         exc[i]=gain[0]*exc[i-pitch]+gain[1]*exc[i-pitch-1]+gain[2]*exc[i-pitch-2];
       printf ("3-tap pitch = %d, gains = [%f %f %f]\n",pitch, gain[0], gain[1], gain[2]);
-
+      */
       /* Update target for adaptive codebook contribution */
       residue_zero(exc, 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);
       for (i=0;i<st->subframeSize;i++)
         target[i]-=res[i];
-      {
+
+      enoise=0;
+      for (i=0;i<st->subframeSize;i++)
+         enoise += target[i]*target[i];
+      snr = 10*log10((esig+1)/(enoise+1));
+      printf ("pitch SNR = %f\n", snr);
+#if 0
+      for(j=0;j<1;j++){
          /*float stoc2[1080];*/
          float *stoc2 = PUSH(st->stack,1080);
          for (i=0;i<1080;i++)
          {
             stoc2[i]=stoc[i];
             if (i-(pitch-1)>=0)
-               stoc2[i] += .8*stoc[i-(pitch-1)];
+               stoc2[i] += .0*stoc[i-(pitch-1)];
          }
          POP(st->stack);
       /* Perform stochastic codebook search */
@@ -292,7 +344,7 @@ void encode(EncState *st, float *in, FrameBits *bits)
       printf ("gain = %f index = %d energy = %f\n",gain[0], pitch, esig);
       for (i=0;i<st->subframeSize;i++)
          exc[i]+=gain[0]*stoc2[i+pitch];
-
+      
       /* Update target for adaptive codebook contribution (Useless for now)*/
       residue_zero(stoc2+pitch, st->bw_lpc1, res, st->subframeSize, st->lpcSize);
       syn_filt_zero(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize);
@@ -300,8 +352,13 @@ void encode(EncState *st, float *in, FrameBits *bits)
       for (i=0;i<st->subframeSize;i++)
          target[i]-=gain[0]*res[i];
       }
-
+#else
+      split_cb_search(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                        exc_table, 64, &gain[0], &pitch, st->lpcSize,
+                        st->subframeSize, exc);
+#endif
       /* Compute weighted noise energy, SNR */
+      enoise=0;
       for (i=0;i<st->subframeSize;i++)
          enoise += target[i]*target[i];
       snr = 10*log10((esig+1)/(enoise+1));
@@ -309,17 +366,23 @@ void encode(EncState *st, float *in, FrameBits *bits)
 
 #else
 
-#if 0 /* Code to calculate the exact excitation after pitch prediction  */
+#if 1 /* Code to calculate the exact excitation after pitch prediction  */
       for (i=0;i<st->subframeSize;i++)
          st->buf2[i]=target[i];
-
+#if 0
       pitch_search_3tap(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
-                        exc, 20, 147, &gain[0], &pitch, &pitch_gain_index, st->lpcSize,
+                                exc, 20, 147, &gain[0], &pitch, &pitch_gain_index, st->lpcSize,
                         st->subframeSize);
       for (i=0;i<st->subframeSize;i++)
         exc[i]=gain[0]*exc[i-pitch]+gain[1]*exc[i-pitch-1]+gain[2]*exc[i-pitch-2];
       printf ("3-tap pitch = %d, gains = [%f %f %f]\n",pitch, gain[0], gain[1], gain[2]);
-
+#else
+      pitch = st->ol_pitch;
+      closed_loop_fractional_pitch(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                                   exc, st->os_filt, st->os_filt_ord2, st->os_fact, 20, 147, 
+                                   &gain[0], &pitch, st->lpcSize,
+                                   st->subframeSize, st->stack);
+#endif
       /* Update target for adaptive codebook contribution */
       residue_zero(exc, st->bw_lpc1, res, st->subframeSize, st->lpcSize);
       syn_filt_zero(res, st->interp_qlpc, res, st->subframeSize, st->lpcSize);
@@ -327,13 +390,25 @@ void encode(EncState *st, float *in, FrameBits *bits)
       for (i=0;i<st->subframeSize;i++)
         target[i]-=res[i];
 
+      enoise=0;
+      for (i=0;i<st->subframeSize;i++)
+         enoise += target[i]*target[i];
+      snr = 10*log10((esig+1)/(enoise+1));
+      printf ("pitch SNR = %f\n", snr);
+
       syn_filt_zero(target, st->bw_lpc1, res, st->subframeSize, st->lpcSize);
       residue_zero(res, st->interp_qlpc, exc, st->subframeSize, st->lpcSize);
       residue_zero(exc, st->bw_lpc2, exc, st->subframeSize, st->lpcSize);
-      for (i=0;i<st->subframeSize;i++)
-         printf ("%f ", exc[i]);
-      printf ("\n");
-      
+      if (snr>5)
+      {
+         for (i=0;i<st->subframeSize;i++)
+         {
+            if (i%8==0&&i)
+               printf("\n");
+            printf ("%f ", exc[i]);
+         }
+         printf ("\n");
+      }
       for (i=0;i<st->subframeSize;i++)
          target[i]=st->buf2[i];
 #endif
@@ -357,7 +432,6 @@ void encode(EncState *st, float *in, FrameBits *bits)
       POP(st->stack);
       POP(st->stack);
       POP(st->stack);
-      POP(st->stack);
    }
 
    /* Store the LSPs for interpolation in the next frame */
index 053f433..af44236 100644 (file)
@@ -32,17 +32,23 @@ typedef struct EncState {
    int    windowSize;     /* Analysis (LPC) window length */
    int    lpcSize;        /* LPC order */
    int    bufSize;        /* Buffer size */
+   int    min_pitch;      /* Minimum pitch value allowed */
+   int    max_pitch;      /* Maximum pitch value allowed */
+   int    ol_pitch;       /* Open-loop pitch */
+   int    ol_voiced;      /* Open-loop voiced/non-voiced decision */
    float  gamma1;         /* Perceptual filter: A(z/gamma1) */
    float  gamma2;         /* Perceptual filter: A(z/gamma2) */
    float *stack;          /* Pseudo-stack allocation */
    int    os_fact;        /* Over-sampling factor for fractional pitch */
-   int    os_filt_ord   /* Over-sampling filter size for fractional pitch */
+   int    os_filt_ord2;   /* Over-sampling filter size for fractional pitch */
    float *os_exc;         /* Over-sampled excitation for fractional pitch */
    float *os_filt;        /* Over-sampling filter for fractional pitch */
    float *inBuf;          /* Input buffer (original signal) */
    float *frame;          /* Start of original frame */
    float *excBuf;         /* Excitation buffer */
    float *exc;            /* Start of excitation frame */
+   float *swBuf;          /* Weighted signal buffer */
+   float *sw;             /* Start of weighted signal frame */
    float *window;         /* Temporary (Hanning) window */
    float *buf2;           /* 2nd temporary buffer */
    float *autocorr;       /* auto-correlation */