shithub: opus

Download patch

ref: 7b7f07120e9bb749782d044f6643d3923e4acc22
parent: 0da0d91ba7871e462933d953124da08b7081a156
author: Jean-Marc Valin <[email protected]>
date: Thu Jun 17 16:10:02 EDT 2010

fixed-point: More work on the PLC

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1514,8 +1514,8 @@
       celt_word32 e[2*MAX_PERIOD];
       celt_word16 exc[2*MAX_PERIOD];
       celt_word32 ac[LPC_ORDER+1];
-      float decay = 1;
-      float S1=0;
+      celt_word16 decay = 1;
+      celt_word32 S1=0;
       celt_word16 mem[LPC_ORDER]={0};
 
       offset = MAX_PERIOD-pitch_index;
@@ -1528,12 +1528,20 @@
                         LPC_ORDER, MAX_PERIOD);
 
          /* Noise floor -40 dB */
+#ifdef FIXED_POINT
+         ac[0] += SHR32(ac[0],13);
+#else
          ac[0] *= 1.0001;
+#endif
          /* Lag windowing */
          for (i=1;i<=LPC_ORDER;i++)
          {
             /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
+#ifdef FIXED_POINT
+            ac[i] -= MULT16_32_Q15(2*i*i, ac[i]);
+#else
             ac[i] -= ac[i]*(.008*i)*(.008*i);
+#endif
          }
 
          _celt_lpc(st->lpc+c*LPC_ORDER, ac, LPC_ORDER);
@@ -1542,7 +1550,7 @@
       /*for (i=0;i<MAX_PERIOD;i++)printf("%d ", exc[i]); printf("\n");*/
       /* Check if the waveform is decaying (and if so how fast) */
       {
-         float E1=0, E2=0;
+         celt_word32 E1=1, E2=1;
          int period;
          if (pitch_index <= MAX_PERIOD/2)
             period = pitch_index;
@@ -1550,12 +1558,12 @@
             period = MAX_PERIOD/2;
          for (i=0;i<period;i++)
          {
-            E1 += exc[MAX_PERIOD-period+i]*exc[MAX_PERIOD-period+i];
-            E2 += exc[MAX_PERIOD-2*period+i]*exc[MAX_PERIOD-2*period+i];
+            E1 += SHR32(MULT16_16(exc[MAX_PERIOD-period+i],exc[MAX_PERIOD-period+i]),8);
+            E2 += SHR32(MULT16_16(exc[MAX_PERIOD-2*period+i],exc[MAX_PERIOD-2*period+i]),8);
          }
-         decay = sqrt((E1+1)/(E2+1));
-         if (decay > 1)
-            decay = 1;
+         if (E1 > E2)
+            E1 = E2;
+         decay = celt_sqrt(frac_div32(SHR(E1,1),E2));
       }
 
       /* Copy excitation, taking decay into account */
@@ -1564,18 +1572,18 @@
          if (offset+i >= MAX_PERIOD)
          {
             offset -= pitch_index;
-            decay *= decay;
+            decay = MULT16_16_Q15(decay, decay);
          }
-         e[i] = decay*SHL32(EXTEND32(exc[offset+i]), SIG_SHIFT);
-         S1 += st->out_mem[offset+i]*1.*st->out_mem[offset+i];
+         e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
+         S1 += SHR32(MULT16_16(st->out_mem[offset+i],st->out_mem[offset+i]),8);
       }
 
       iir(e, st->lpc+c*LPC_ORDER, e, len+st->mode->overlap, LPC_ORDER, mem);
 
       {
-         float S2=0;
+         celt_word32 S2=0;
          for (i=0;i<len+overlap;i++)
-            S2 += e[i]*1.*e[i];
+            S2 += SHR32(MULT16_16(e[i],e[i]),8);
          /* This checks for an "explosion" in the synthesis (including NaNs) */
          if (!(S1 > 0.2f*S2))
          {
@@ -1583,7 +1591,7 @@
                e[i] = 0;
          } else if (S1 < S2)
          {
-            float ratio = sqrt((S1+1)/(S2+1));
+            float ratio = sqrt((S1+1.)/(S2+1.));
             for (i=0;i<len+overlap;i++)
                e[i] *= ratio;
          }
--- a/libcelt/plc.c
+++ b/libcelt/plc.c
@@ -24,7 +24,7 @@
 #endif
 
 
-float _celt_lpc(
+void _celt_lpc(
       celt_word16       *_lpc, /* out: [0...p-1] LPC coefficients      */
 const celt_word32 *ac,  /* in:  [0...p] autocorrelation values  */
 int          p
@@ -76,7 +76,6 @@
    for (i=0;i<p;i++)
       _lpc[i] = ROUND16(lpc[i],16);
 #endif
-   return error;
 }
 
 void fir(const celt_word16 *x,