shithub: opus

Download patch

ref: 22823834348e0dc2c4953fd16f53c0a895245590
parent: ba238d8793672a4fa2b5f4fd4487e55a239a28b4
author: Jean-Marc Valin <[email protected]>
date: Sat Mar 22 17:17:45 EDT 2008

fixed-point: added cheap celt_div() division using a reciprocal

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -126,7 +126,7 @@
          shift = celt_zlog2(bank[i*C+c])-13;
          E = VSHR32(bank[i*C+c], shift);
          if (E>0)
-            g = DIV32_16(QCONST32(1.f,28),MULT16_16_Q14(E,sqrtC_1[C-1]));
+            g = EXTRACT16(celt_div(QCONST32(1.f,28),MULT16_16_Q14(E,sqrtC_1[C-1])));
          else
             g = 0;
          for (j=B*eBands[i];j<B*eBands[i+1];j++)
@@ -257,7 +257,7 @@
          residual doesn't quantise well */
       Sxy = MULT16_32_Q15(QCONST16(.9f, 15), Sxy);
       /* gain = Sxy/Sxx */
-      gains[i] = DIV32_16(Sxy,ADD32(SHR32(Sxx, PGAIN_SHIFT),EPSILON));
+      gains[i] = EXTRACT16(celt_div(Sxy,ADD32(SHR32(Sxx, PGAIN_SHIFT),EPSILON)));
       /*printf ("%f ", 1-sqrt(1-gain*gain));*/
    }
    /*if(rand()%10==0)
--- a/libcelt/mathops.h
+++ b/libcelt/mathops.h
@@ -45,6 +45,7 @@
 #define celt_cos_norm(x) (cos((.5f*M_PI)*(x)))
 #define celt_atan atan
 #define celt_rcp(x) (1.f/(x))
+#define celt_div(a,b) ((a)/(b))
 
 #endif
 
@@ -201,6 +202,8 @@
       frac = -frac;
    return VSHR32(EXTEND32(frac),i-16);
 }
+
+#define celt_div(a,b) MULT32_32_Q31(a,celt_rcp(b))
 
 #endif /* FIXED_POINT */
 
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -106,7 +106,7 @@
       celt_word16_t f;   /* Q8 */
       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
       x = amp2dB(eBands[i]);
-      f = DIV32_16(SHL32(EXTEND32(x-mean-MULT16_16_Q15(coef,oldEBands[i])-prev),8),base_resolution);
+      f = EXTRACT16(celt_div(SHL32(EXTEND32(x-mean-MULT16_16_Q15(coef,oldEBands[i])-prev),8),base_resolution));
 #ifdef FIXED_POINT
       /* Rounding to nearest integer here is really important! */
       qi = (f+128)>>8;
@@ -149,7 +149,7 @@
       if (q2 > frac[i]-1)
          q2 = frac[i]-1;
       ec_enc_uint(enc, q2, frac[i]);
-      offset = DIV32_16(SHL16(q2,8)+QCONST16(.5,8),frac[i])-QCONST16(.5f,8);
+      offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac[i])-QCONST16(.5f,8));
       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
       /*printf ("%f ", error[i] - offset);*/
    }
@@ -199,7 +199,7 @@
       if (ec_dec_tell(dec, 0) - bits +EC_ILOG(frac[i])> budget)
          break;
       q2 = ec_dec_uint(dec, frac[i]);
-      offset = DIV32_16(SHL16(q2,8)+QCONST16(.5,8),frac[i])-QCONST16(.5f,8);
+      offset = EXTRACT16(celt_div(SHL16(q2,8)+QCONST16(.5,8),frac[i])-QCONST16(.5f,8));
       oldEBands[i] += PSHR32(MULT16_16(DB_SCALING*6,offset),8);
    }
    for (i=0;i<m->nbEBands;i++)
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -378,7 +378,7 @@
          xy = MAC16_16(xy, x[j], Y[i+N-j-1]);
          yy = MAC16_16(yy, Y[i+N-j-1], Y[i+N-j-1]);
       }
-      score = DIV32(MULT16_16(ROUND16(xy,14),ROUND16(xy,14)), ROUND16(yy,14));
+      score = celt_div(MULT16_16(ROUND16(xy,14),ROUND16(xy,14)), ROUND16(yy,14));
       if (score > best_score)
       {
          best_score = score;