shithub: opus

Download patch

ref: 68b02b10252dec071b6824d262abeb7c635774dc
parent: 2eaba8ac1fdfadbcc9c4c357c60408c861c66937
author: Jean-Marc Valin <[email protected]>
date: Thu Feb 28 18:37:26 EST 2008

fixed-point: copied the exp2 implementation from Speex, using it for dB2Amp()

--- a/libcelt/mathops.h
+++ b/libcelt/mathops.h
@@ -124,16 +124,43 @@
 static inline celt_word16_t celt_log2(celt_word32_t x)
 {
    int i;
+   celt_word16_t n, frac;
    /*-0.41446   0.96093  -0.33981   0.15600 */
    const celt_word16_t C[4] = {-6791, 7872, -1392, 319};
    if (x==0)
       return -32767;
    i = celt_ilog2(x);
-   celt_word16_t n = VSHR32(x,i-15)-32768-16384;
-   celt_word16_t ret = ADD16(C[0], MULT16_16_Q14(n, ADD16(C[1], MULT16_16_Q14(n, ADD16(C[2], MULT16_16_Q14(n, (C[3])))))));
+   n = VSHR32(x,i-15)-32768-16384;
+   frac = ADD16(C[0], MULT16_16_Q14(n, ADD16(C[1], MULT16_16_Q14(n, ADD16(C[2], MULT16_16_Q14(n, (C[3])))))));
    /*printf ("%d %d %d %d\n", x, n, ret, SHL16(i-13,8)+SHR16(ret,14-8));*/
-   return SHL16(i-13,8)+SHR16(ret,14-8);
+   return SHL16(i-13,8)+SHR16(frac,14-8);
 }
+
+/*
+ K0 = 1
+ K1 = log(2)
+ K2 = 3-4*log(2)
+ K3 = 3*log(2) - 2
+*/
+#define D0 16384
+#define D1 11356
+#define D2 3726
+#define D3 1301
+/* Input in Q11 format, output in Q16 */
+static inline celt_word32_t celt_exp2(celt_word16_t x)
+{
+   int integer;
+   celt_word16_t frac;
+   integer = SHR16(x,11);
+   if (integer>14)
+      return 0x7fffffff;
+   else if (integer < -15)
+      return 0;
+   frac = SHL16(x-SHL16(integer,11),3);
+   frac = ADD16(D0, MULT16_16_Q14(frac, ADD16(D1, MULT16_16_Q14(frac, ADD16(D2 , MULT16_16_Q14(D3,frac))))));
+   return VSHR32(EXTEND32(frac), -integer-2);
+}
+
 
 #endif
 
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -50,12 +50,13 @@
 const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
 
 #ifdef FIXED_POINT
-static inline celt_ener_t dB2Amp( dB)
+static inline celt_ener_t dB2Amp(celt_ener_t dB)
 {
    celt_ener_t amp;
-   amp = pow(10, .05*dB)-.3;
+   amp = PSHR32(celt_exp2(dB/6.0207*8),2)-QCONST16(.3f, 14);
    if (amp < 0)
       amp = 0;
+   return amp;
 }
 
 #define DBofTWO 24661
@@ -66,12 +67,13 @@
    /* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */
 }
 #else
-static inline celt_ener_t dB2Amp( dB)
+static inline celt_ener_t dB2Amp(celt_ener_t dB)
 {
    celt_ener_t amp;
    amp = pow(10, .05*dB)-.3;
    if (amp < 0)
       amp = 0;
+   return amp;
 }
 static inline celt_word16_t amp2dB(celt_ener_t amp)
 {
@@ -158,9 +160,7 @@
    }
    for (i=0;i<m->nbEBands;i++)
    {
-      eBands[i] = ENER_SCALING*(pow(10, .05*DB_SCALING_1*oldEBands[i])-.3);
-      if (eBands[i] < 0)
-         eBands[i] = 0;
+      eBands[i] = dB2Amp(oldEBands[i]);
    }
    /*printf ("%d\n", ec_enc_tell(enc, 0)-9);*/
 
@@ -210,10 +210,7 @@
    }
    for (i=0;i<m->nbEBands;i++)
    {
-      /*printf ("%f ", error[i] - offset);*/
-      eBands[i] = ENER_SCALING*(pow(10, .05*DB_SCALING_1*oldEBands[i])-.3);
-      if (eBands[i] < 0)
-         eBands[i] = 0;
+      eBands[i] = dB2Amp(oldEBands[i]);
    }
    /*printf ("\n");*/
 }