[xiph-commits] r10735 - trunk/ghost/libghost

jm at svn.xiph.org jm at svn.xiph.org
Mon Jan 16 22:24:25 PST 2006


Author: jm
Date: 2006-01-16 22:24:22 -0800 (Mon, 16 Jan 2006)
New Revision: 10735

Modified:
   trunk/ghost/libghost/ghost.c
   trunk/ghost/libghost/ghost.h
Log:
residual encoded as shaped noise


Modified: trunk/ghost/libghost/ghost.c
===================================================================
--- trunk/ghost/libghost/ghost.c	2006-01-17 01:29:28 UTC (rev 10734)
+++ trunk/ghost/libghost/ghost.c	2006-01-17 06:24:22 UTC (rev 10735)
@@ -51,7 +51,25 @@
       y[i] = SATURATE(yi,805306368);
    }
 }
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word32_t xi,yi,nyi;
 
+   for (i=0;i<N;i++)
+   {
+      xi=SATURATE(x[i],805306368);
+      yi = SATURATE(xi + SHL32(mem[0],2),805306368);
+      nyi = NEG32(yi);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_32_Q15(mem[j+1],den[j],nyi);
+      }
+      mem[ord-1] = MULT16_32_Q15(den[ord-1],nyi);
+      y[i] = yi;
+   }
+}
+
 spx_word32_t _spx_lpc(
 spx_coef_t       *lpc, /* out: [0...p-1] LPC coefficients      */
 const spx_word16_t *ac,  /* in:  [0...p] autocorrelation values  */
@@ -78,11 +96,11 @@
 #ifdef FIXED_POINT
       r = DIV32_16(rr,ADD16(error,16));
 #else
-      r = rr/(error+.003*ac[0]);
+      r = rr/(error+.0000003*ac[0]);
 #endif
       /*  Update LPC coefficients and total error */
       lpc[i] = r;
-      for (j = 0; j < i>>1; j++) 
+      for (j = 0; j < i>>1; j++)
       {
          spx_word16_t tmp  = lpc[j];
          lpc[j]     = MAC16_16_Q13(lpc[j],r,lpc[i-1-j]);
@@ -105,7 +123,7 @@
    st->advance = 192;
    st->overlap = 64;
    st->lpc_length = 384;
-   st->lpc_order = 20;
+   st->lpc_order = 40;
    st->pcm_buf = calloc(PCM_BUF_SIZE,sizeof(float));
    st->current_frame = st->pcm_buf + PCM_BUF_SIZE/2 - st->length/2;
    st->new_pcm = st->pcm_buf + PCM_BUF_SIZE - st->advance;
@@ -120,6 +138,7 @@
 
    st->syn_memory = calloc(st->overlap,sizeof(float));
    st->noise_mem = calloc(st->lpc_order,sizeof(float));
+   st->noise_mem2 = calloc(st->lpc_order,sizeof(float));
    for (i=0;i<st->length;i++)
    {
       st->analysis_window[i] = 1;
@@ -130,9 +149,15 @@
       st->synthesis_window[i] = .5-.5*cos(M_PI*i/st->overlap);
       st->synthesis_window[st->length-i-1] = .5-.5*cos(M_PI*(i+1)/st->overlap);
    }
+#if 1
    for (i=0;i<st->lpc_length;i++)
-      st->lpc_window[i] = .5-.5*cos(M_PI*i/st->lpc_length);
-   
+      st->lpc_window[i] = .5-.5*cos(2*M_PI*i/st->lpc_length);
+#else
+   for (i=0;i<st->lpc_order;i++)
+      st->lpc_window[i]=0;
+   for (i=st->lpc_order;i<st->lpc_length;i++)
+      st->lpc_window[i] = .5-.5*cos(2*M_PI*(i-st->lpc_order)/(st->lpc_length-st->lpc_order));
+#endif
    st->big_fft = spx_fft_init(PCM_BUF_SIZE);
    st->lpc_fft = spx_fft_init(st->lpc_length);
    for (i=0;i<PCM_BUF_SIZE;i++)
@@ -208,18 +233,13 @@
       for (i=st->advance;i<st->length;i++)
       st->syn_memory[i-st->advance]=y[i];*/
       
+      float noise_window[st->lpc_length];
       float noise_ac[st->lpc_length];
       float noise_psd[st->lpc_length];
       for (i=0;i<st->lpc_length;i++)
-         noise_ac[i] = st->lpc_window[i]*st->new_noise[i];
-      spx_fft_float(st->lpc_fft, noise_ac, noise_psd);
-      /*for (i=1;i<(st->lpc_length>>1);i++)
-      {
-         noise_psd[i] = noise_psd[2*i-1]*noise_psd[2*i-1] + noise_psd[2*i]*noise_psd[2*i];
-      }
-      noise_psd[0] = noise_psd[0]*noise_psd[0];
-      noise_psd[(st->lpc_length>>1)-1] = noise_psd[st->lpc_length-1]*noise_psd[st->lpc_length-1];
-      */
+         noise_window[i] = st->lpc_window[i]*st->new_noise[i+st->length-st->lpc_length];
+      /* Don't know why, but spectral version sometimes results in an unstable LPC filter */
+      /*spx_fft_float(st->lpc_fft, noise_window, noise_psd);
       
       noise_psd[0] *= noise_psd[0];
       for (i=1;i<st->lpc_length-1;i+=2)
@@ -228,15 +248,67 @@
       }
       noise_psd[st->lpc_length-1] *= noise_psd[st->lpc_length-1];
       spx_ifft_float(st->lpc_fft, noise_psd, noise_ac);
+      */
+      for (i=0;i<st->lpc_order+1;i++)
+      {
+         int j;
+         double tmp = 0;
+         for (j=0;j<st->lpc_length-i;j++)
+            tmp += (double)noise_window[j]*(double)noise_window[i+j];
+         noise_ac[i] = tmp;
+      }
+      for (i=0;i<st->lpc_order+1;i++)
+      noise_ac[i] *= exp(-.0001*i*i);
       noise_ac[0] *= 1.0001;
+      noise_ac[0] += 1;
       
       float lpc[st->lpc_order];
       _spx_lpc(lpc, noise_ac, st->lpc_order);
-      fir_mem2(st->new_noise, lpc, pcm, st->advance, st->lpc_order, st->noise_mem);
-      //iir_mem2(st->new_noise, lpc, pcm, st->advance, st->lpc_order, st->noise_mem);
+      /*for (i=0;i<st->lpc_order;i++)
+      lpc[i] *= pow(.9,i+1);*/
+      /*for (i=0;i<st->lpc_order;i++)
+         printf ("%f ", lpc[i]);
+      printf ("\n");*/
+      //for (i=0;i<st->lpc_order;i++)
+      if (0)
+      {
+         for (i=0;i<st->lpc_order+1;i++)
+            printf ("%f ", noise_ac[i]);
+         printf ("\n");
+         for (i=0;i<st->lpc_order;i++)
+         printf ("%f ", lpc[i]);
+         printf ("\n");
+         /*for (i=0;i<st->lpc_length;i++)
+         printf ("%f ", noise_window[i]);
+         printf ("\n");
+         for (i=0;i<st->lpc_length;i++)
+            printf ("%f ", st->lpc_window[i]);
+         printf ("\n");
+         for (i=0;i<st->lpc_length;i++)
+            printf ("%f ", st->new_noise[i+st->length-st->lpc_length]);
+         printf ("\n");*/
+         exit(1);
+      }
+      float noise[st->advance];
+      fir_mem2(st->new_noise, lpc, noise, st->advance, st->lpc_order, st->noise_mem);
       
+      //Replace whitened residual by white noise
+      if (1) {
+         float ener = 0;
+         for (i=0;i<st->advance;i++)
+            ener += noise[i]*noise[i];
+         ener = sqrt(ener/st->advance);
+         for (i=0;i<st->advance;i++)
+            noise[i] = ener*sqrt(12.)*((((float)(rand()))/RAND_MAX)-.5);
+      }
+      
+      iir_mem2(noise, lpc, noise, st->advance, st->lpc_order, st->noise_mem2);
+      
+      /*for (i=0;i<st->advance;i++)
+      pcm[i] = st->current_frame[i]-st->new_noise[i];*/
+      
       for (i=0;i<st->advance;i++)
-      pcm[i] = st->current_frame[i]-st->new_noise[i];
+         pcm[i] = st->current_frame[i]-st->new_noise[i] + noise[i];
       
    }
    

Modified: trunk/ghost/libghost/ghost.h
===================================================================
--- trunk/ghost/libghost/ghost.h	2006-01-17 01:29:28 UTC (rev 10734)
+++ trunk/ghost/libghost/ghost.h	2006-01-17 06:24:22 UTC (rev 10735)
@@ -35,6 +35,7 @@
    
    float *syn_memory;
    float *noise_mem;
+   float *noise_mem2;
    
    float *noise_buf;
    float *new_noise;



More information about the commits mailing list