First shot at high-band perceptual enhancement
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 12 Dec 2002 03:28:49 +0000 (03:28 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 12 Dec 2002 03:28:49 +0000 (03:28 +0000)
git-svn-id: http://svn.xiph.org/trunk/speex@4145 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/modes.c
libspeex/sb_celp.c
libspeex/sb_celp.h

index 5402d18..b7433df 100644 (file)
@@ -362,7 +362,7 @@ static SpeexSubmode wb_submode1 = {
    NULL,
    NULL,
 
-   0, 0, -1,
+   .75, .75, -1,
    36
 };
 
@@ -384,7 +384,7 @@ static SpeexSubmode wb_submode2 = {
    split_cb_shape_sign_unquant,
    &split_cb_high_lbr,
 
-   0, 0, -1,
+   .85, .6, -1,
    112
 };
 
@@ -406,7 +406,7 @@ static SpeexSubmode wb_submode3 = {
    split_cb_shape_sign_unquant,
    &split_cb_high,
 
-   0, 0, -1,
+   .75, .7, -1,
    192
 };
 
@@ -427,7 +427,7 @@ static SpeexSubmode wb_submode4 = {
    split_cb_shape_sign_unquant,
    &split_cb_high,
 
-   0, 0, -1,
+   .75, .75, -1,
    352
 };
 
index 333991f..e366e62 100644 (file)
@@ -715,7 +715,10 @@ void *sb_decoder_init(SpeexMode *m)
    st->interp_qlpc = (float*)speex_alloc((st->lpcSize+1)*sizeof(float));
 
    st->pi_gain = (float*)speex_alloc(st->nbSubframes*sizeof(float));
-   st->mem_sp = (float*)speex_alloc(st->lpcSize*sizeof(float));
+   st->mem_sp = (float*)speex_alloc(2*st->lpcSize*sizeof(float));
+   
+   st->lpc_enh_enabled=0;
+
    return st;
 }
 
@@ -751,13 +754,58 @@ void sb_decoder_destroy(void *state)
 static void sb_decode_lost(SBDecState *st, float *out, void *stack)
 {
    int i;
+   float *awk1, *awk2, *awk3;
    for (i=0;i<st->frame_size;i++)
       st->exc[i]*=0.8;
    
    st->first=1;
    
+   awk1=PUSH(stack, st->lpcSize+1, float);
+   awk2=PUSH(stack, st->lpcSize+1, float);
+   awk3=PUSH(stack, st->lpcSize+1, float);
+   
+   if (st->lpc_enh_enabled)
+   {
+      float r=.9;
+      
+      float k1,k2,k3;
+      k1=SUBMODE(lpc_enh_k1);
+      k2=SUBMODE(lpc_enh_k2);
+      k3=(1-(1-r*k1)/(1-r*k2))/r;
+      k3=k1-k2;
+      if (!st->lpc_enh_enabled)
+      {
+         k1=k2;
+         k3=0;
+      }
+      bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
+      bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
+      bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
+      /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
+   }
+   
+   
    /* Final signal synthesis from excitation */
-   iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);
+   for (i=0;i<st->frame_size;i++)
+      st->exc[i] *= .9;
+   for (i=0;i<st->frame_size;i++)
+      st->high[i]=st->exc[i];
+   if (st->lpc_enh_enabled)
+   {
+      /* Use enhanced LPC filter */
+      filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize, 
+                  st->mem_sp+st->lpcSize);
+      filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, 
+                  st->mem_sp);
+   } else {
+      /* Use regular filter */
+      for (i=0;i<st->lpcSize;i++)
+         st->mem_sp[st->lpcSize+i] = 0;
+      iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, 
+               st->mem_sp);
+   }
+   
+   /*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/
    
    /* Reconstruct the original */
    fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
@@ -777,6 +825,7 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
    int ret;
    void *stack;
    float *low_pi_gain, *low_exc, *low_innov;
+   float *awk1, *awk2, *awk3;
 
    st = (SBDecState*)state;
    stack=st->stack;
@@ -848,6 +897,10 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
          st->old_qlsp[i] = st->qlsp[i];
    }
    
+   awk1=PUSH(stack, st->lpcSize+1, float);
+   awk2=PUSH(stack, st->lpcSize+1, float);
+   awk3=PUSH(stack, st->lpcSize+1, float);
+
    for (sub=0;sub<st->nbSubframes;sub++)
    {
       float *exc, *sp, tmp, filter_ratio, el=0;
@@ -872,6 +925,28 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
       /* LSP to LPC */
       lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
 
+
+      if (st->lpc_enh_enabled)
+      {
+         float r=.9;
+         
+         float k1,k2,k3;
+         k1=SUBMODE(lpc_enh_k1);
+         k2=SUBMODE(lpc_enh_k2);
+         k3=(1-(1-r*k1)/(1-r*k2))/r;
+         k3=k1-k2;
+         if (!st->lpc_enh_enabled)
+         {
+            k1=k2;
+            k3=0;
+         }
+         bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
+         bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
+         bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
+         /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
+      }
+
+
       /* Calculate reponse ratio between the low and high filter in the middle
          of the band (4000 Hz) */
       
@@ -938,7 +1013,24 @@ int sb_decode(void *state, SpeexBits *bits, float *out)
          }
 
       }
-      iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
+
+      for (i=0;i<st->subframeSize;i++)
+         sp[i]=exc[i];
+      if (st->lpc_enh_enabled)
+      {
+         /* Use enhanced LPC filter */
+         filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp+st->lpcSize);
+         filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      } else {
+         /* Use regular filter */
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sp[st->lpcSize+i] = 0;
+         iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      }
+      /*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/
 
    }
 
@@ -1114,6 +1206,7 @@ void sb_decoder_ctl(void *state, int request, void *ptr)
       break;
    case SPEEX_SET_ENH:
       speex_decoder_ctl(st->st_low, request, ptr);
+      st->lpc_enh_enabled = *((int*)ptr);
       break;
    case SPEEX_GET_BITRATE:
       speex_decoder_ctl(st->st_low, request, ptr);
index 0240da5..cd393dd 100644 (file)
@@ -113,6 +113,7 @@ typedef struct SBDecState {
    int    lpcSize;
    int    first;
    int    sampling_rate;
+   int    lpc_enh_enabled;
 
    void  *stack;
    float *x0d, *x1d;