non-causal comb filter
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sat, 1 Apr 2006 12:07:33 +0000 (12:07 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Sat, 1 Apr 2006 12:07:33 +0000 (12:07 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@11075 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/filters.c
libspeex/nb_celp.c

index c1ad704..f684747 100644 (file)
@@ -495,10 +495,15 @@ void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N,
 
 #ifdef NEW_ENHANCER
 
-
+#if 0
 float shift_filt[3][7] = {{-9.9369e-04, 3.1831e-02, -1.3889e-01, 6.0910e-01, 6.0910e-01, -1.3889e-01, 3.1831e-02},
                           {-0.0029937, 0.0345613, -0.1350474, 0.8904793, 0.2714479, -0.0710304, 0.0135403},
                           {0.0135403, -0.0710304, 0.2714479, 0.8904793, -0.1350474, 0.0345613,  -0.0029937}};
+#else
+float shift_filt[3][7] = {{-0.011915, 0.046995, -0.152373, 0.614108, 0.614108, -0.152373, 0.046995},
+                          {-0.0324855, 0.0859768, -0.2042986, 0.9640297, 0.2086420, -0.0302054, -0.0063646},
+                          {-0.0063646, -0.0302054, 0.2086420, 0.9640297, -0.2042986, 0.0859768, -0.0324855}};
+#endif
 
 int interp_pitch(
 spx_sig_t *exc,          /*decoded excitation*/
@@ -541,13 +546,6 @@ int len
          }
       }
    }
-   float frac = 0;
-   if (maxi==1)
-      frac = .5;
-   if (maxi==2)
-      frac = .25;
-   if (maxi==3)
-      frac = -.25;
    for (i=0;i<len;i++)
    {
       interp[i] = 0;
@@ -561,7 +559,6 @@ int len
          interp[i] = exc[i-(pitch-maxj+3)];
       }
    }
-   //printf ("%d %d %d %f\n", pitch, maxi, maxj, pitch-maxj+3-frac);
    return pitch-maxj+3;
 }
       
@@ -583,60 +580,87 @@ char *stack
    spx_sig_t iexc[4*nsf];
    spx_coef_t *awk;
    float tot_gain, curr_gain;
-   //spx_mem_t *wmem;
    float old_ener, new_ener;
-   float corr[120];
+   float corr[100];
+   int corr_pitch;
+   spx_word32_t max_corr;
+   float max_ener;
    /* Estimating pitch... */
    
    /* Weighted LPC */
-   //bw_lpc(QCONST16(.7,15), ak, awk, p);
-   //iir_mem2(exc, awk, new_exc, nsf, p, wmem);
    
-   float ener_1 = 1.f/(1+inner_prod(exc, exc, nsf));
    /* Correlation on weighted signal */
-   pitch_xcorr(exc, exc-139, corr, nsf, 120, stack);
-   int corr_pitch=139;
-   spx_word32_t max_corr=corr[119];
-   for (i=119;i>=0;i--)
+   pitch_xcorr(exc, exc-119, corr, nsf, 100, stack);
+   corr_pitch=119;
+   max_corr=corr[99];
+   max_ener = sqrt(1+inner_prod(exc-119, exc-119, nsf));
+   for (i=99;i>=0;i--)
    {
+      float tmp1, tmp2;
+      tmp1 = corr[i]*max_ener;
+      tmp2 = max_corr*sqrt(1+inner_prod(exc-i-20, exc-i-20, nsf));
       /* Some tweaks to reduce pitch-doubling */
+#if 1
       if (corr[i]>max_corr || (corr[i]>.6*max_corr && ABS(2*(i+20)-corr_pitch) < 3 )
           || (corr[i]>.6*max_corr && ABS(3*(i+20)-corr_pitch) < 3 ) || (corr[i]>.6*max_corr && ABS(4*(i+20)-corr_pitch) < 4 )
           || (corr[i]>.7*max_corr && ABS(5*(i+20)-corr_pitch) < 4 ))
+#else
+      if (tmp1>tmp2 || (tmp1>.6*tmp2 && ABS(2*(i+20)-corr_pitch) < 3 )
+          || (tmp1>.6*tmp2 && ABS(3*(i+20)-corr_pitch) < 3 ) || (tmp1>.6*tmp2 && ABS(4*(i+20)-corr_pitch) < 4 )
+          || (tmp1>.7*tmp2 && ABS(5*(i+20)-corr_pitch) < 4 ))
+#endif
       {
          if (corr[i] > max_corr)
+         {
             max_corr = corr[i];
+            max_ener = sqrt(1+inner_prod(exc-i-20, exc-i-20, nsf));
+         }
          corr_pitch=i+20;
       }
    }
    interp_pitch(exc, iexc, corr_pitch, 80);
-   interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);
-   interp_pitch(exc, iexc+2*nsf, 3*corr_pitch, 80);
-   interp_pitch(exc, iexc+3*nsf, 4*corr_pitch, 80);
+   if (corr_pitch>40)
+      interp_pitch(exc, iexc+nsf, 2*corr_pitch, 80);
+   else
+      interp_pitch(exc, iexc+nsf, -corr_pitch, 80);
+
+   interp_pitch(exc, iexc+2*nsf, 2*corr_pitch, 80);
+   interp_pitch(exc, iexc+3*nsf, 3*corr_pitch, 80);
    
-   //printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);
-   for (i=0;i<120;i++)
-      corr[i] *= ener_1;
-   //print_vec(corr, 120, "pitch");
-      
-   float pgain = .5*inner_prod(iexc,exc,nsf)/sqrt(1+inner_prod(iexc,iexc,nsf)*inner_prod(exc,exc,nsf)) + .5*inner_prod(iexc+nsf,exc,nsf)/sqrt(1+inner_prod(iexc+nsf,iexc+nsf,nsf)*inner_prod(exc,exc,nsf));
-   //printf ("%f\n", pgain);
-   if (pgain < 0)
-      pgain = 0;
-   if (pgain > 1)
-      pgain = 1;
-   tot_gain = comb_gain*2*(.5/sqrt(1.01-pgain*pgain)-.35);
-   if (tot_gain>1)
-      tot_gain=1;
-   if (comb_gain > tot_gain)
-      comb_gain = tot_gain;
-      
-   for (i=0;i<nsf;i++)
-      new_exc[i] = exc[i] + comb_gain*(iexc[i] + .2*iexc[i+nsf]);
+   /*printf ("%d %d %f\n", pitch, corr_pitch, max_corr*ener_1);*/
+   
+   float gg1 = sqrt((1+inner_prod(exc,exc,nsf))/(1+inner_prod(iexc,iexc,nsf)));
+   float gg2 = sqrt((1+inner_prod(exc,exc,nsf))/(1+inner_prod(iexc+nsf,iexc+nsf,nsf)));
+   float pgain1 = inner_prod(iexc,exc,nsf)/sqrt(1+inner_prod(iexc,iexc,nsf)*inner_prod(exc,exc,nsf));
+   float pgain2 = inner_prod(iexc+nsf,exc,nsf)/sqrt(1+inner_prod(iexc+nsf,iexc+nsf,nsf)*inner_prod(exc,exc,nsf));
+   float c1, c2;
+   float g1, g2;
+   float ngain;
+   if (comb_gain>0)
+   {
+      c1 = .4*comb_gain+.07;
+      c2 = .5+1.72*(c1-.07);
+   } else 
+   {
+      c1=c2=0;
+   }
+   g1 = c1/pow(1-pgain1*pgain1, c2);
+   g2 = c1/pow(1-pgain2*pgain2, c2);
+   if (g1>1)
+      g1 = 1;
+   if (g2 > 1)
+      g2 = 1;
+   if (corr_pitch>40)
+   {
+      for (i=0;i<nsf;i++)
+         new_exc[i] = exc[i] + (.7*g1*gg1*iexc[i] + .3*g2*gg2*iexc[i+nsf]);
+   } else {
+      for (i=0;i<nsf;i++)
+         new_exc[i] = exc[i] + (.6*g1*gg1*iexc[i] + .6*g2*gg2*iexc[i+nsf]);
+   }
    new_ener = compute_rms(new_exc, nsf);
    old_ener = compute_rms(exc, nsf);
-   float ngain = old_ener/(1+new_ener);
-      //printf ("%f\n", ngain);
+   ngain = old_ener/(1+new_ener);
    for (i=0;i<nsf;i++)
       new_exc[i] *= ngain;
 }
index df001a7..b5686c4 100644 (file)
@@ -1063,7 +1063,7 @@ void *nb_decoder_init(const SpeexMode *m)
 
    st->inBuf = speex_alloc((st->frameSize)*sizeof(spx_sig_t));
    st->frame = st->inBuf;
-   st->excBuf = speex_alloc((st->frameSize + PITCH_PERIODS*st->max_pitch + 1)*sizeof(spx_sig_t));
+   st->excBuf = speex_alloc((st->frameSize + PITCH_PERIODS*st->max_pitch + 1 + 50)*sizeof(spx_sig_t));
    st->exc = st->excBuf + PITCH_PERIODS*st->max_pitch + 1;
    for (i=0;i<st->frameSize;i++)
       st->inBuf[i]=0;
@@ -1272,6 +1272,7 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
    int wideband;
    int m;
    char *stack;
+   VARDECL(spx_coef_t *ak);
    VARDECL(spx_coef_t *awk1);
    VARDECL(spx_coef_t *awk2);
    VARDECL(spx_coef_t *awk3);
@@ -1491,9 +1492,10 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
    }
 #endif
 
-   ALLOC(awk1, st->lpcSize+1, spx_coef_t);
-   ALLOC(awk2, st->lpcSize+1, spx_coef_t);
-   ALLOC(awk3, st->lpcSize+1, spx_coef_t);
+   ALLOC(ak, st->lpcSize, spx_coef_t);
+   ALLOC(awk1, st->lpcSize, spx_coef_t);
+   ALLOC(awk2, st->lpcSize, spx_coef_t);
+   ALLOC(awk3, st->lpcSize, spx_coef_t);
 
    if (st->submodeID==1)
    {
@@ -1734,11 +1736,8 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
    }
    
 #ifdef NEW_ENHANCER
-   if (1)
-   {
-      multicomb(st->exc, st->frame, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, pitch, pitch_gain, SUBMODE(comb_gain), stack);
-      multicomb(st->exc+80, st->frame+80, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, pitch, pitch_gain, SUBMODE(comb_gain), stack);
-   }
+   multicomb(st->exc-40, st->frame, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, pitch, pitch_gain, SUBMODE(comb_gain), stack);
+   multicomb(st->exc+40, st->frame+80, st->interp_qlpc, st->lpcSize, 2*st->subframeSize, pitch, pitch_gain, SUBMODE(comb_gain), stack);
 #endif
    /*Loop on subframes */
    for (sub=0;sub<st->nbSubframes;sub++)
@@ -1760,9 +1759,13 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
       /* Make sure the LSP's are stable */
       lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
 
-
       /* Compute interpolated LPCs (unquantized) */
-      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
+      lsp_to_lpc(st->interp_qlsp, ak, st->lpcSize, stack);
+
+#ifndef NEW_ENHANCER
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_qlpc[i] = ak[i];
+#endif
 
       /* Compute enhanced synthesis filter */
       if (st->lpc_enh_enabled)
@@ -1797,6 +1800,9 @@ int nb_decode(void *state, SpeexBits *bits, void *vout)
          iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
                   st->mem_sp);
       }
+      
+      for (i=0;i<st->lpcSize;i++)
+         st->interp_qlpc[i] = ak[i];
 
    }
    /*Copy output signal*/