shithub: aacenc

Download patch

ref: 3bb78ff95652753063e590ab641750f43857a994
parent: ba44d0b56d6d8e00669a211e44ce67781c753f67
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Mon Aug 14 05:29:00 EDT 2017

quantizer: use unscaled data for most calculations

--- a/libfaac/quantize.c
+++ b/libfaac/quantize.c
@@ -31,8 +31,7 @@
   int *cb_offset = coderInfo->sfb_offset;
   int num_cb = coderInfo->nr_of_sfb;
   double avgenrg = coderInfo->avgenrg;
-  double pows = 0.16;
-  double powl = 0.9 * pows;
+  double powm = 0.25;
   enum {MIDF=34};
 
   for (sfb = 0; sfb < num_cb; sfb++)
@@ -69,34 +68,35 @@
 #define NOISETONE 0.2
     if (coderInfo->block_type == ONLY_SHORT_WINDOW)
     {
-        target = NOISETONE * pow(avge/avgenrg, pows);
-        target += (1.0 - NOISETONE) * 0.45 * pow(maxe/avgenrg, powl);
+        target = NOISETONE * pow(avge/avgenrg, powm);
+        target += (1.0 - NOISETONE) * 0.45 * pow(maxe/avgenrg, powm);
 
         target *= 0.9 + (40.0 / (fabs(start + end - MIDF) + 32));
     }
     else
     {
-        target = NOISETONE * pow(avge/avgenrg, pows);
-        target += (1.0 - NOISETONE) * 0.45 * pow(maxe/avgenrg, powl);
+        target = NOISETONE * pow(avge/avgenrg, powm);
+        target += (1.0 - NOISETONE) * 0.45 * pow(maxe/avgenrg, powm);
 
         target *= 0.9 + (40.0 / (0.125 * fabs(start + end - (8*MIDF)) + 32));
 
         target *= 0.45;
     }
-    bandqual[sfb] = 5.0 * target * quality;
+    bandqual[sfb] = 3.0 * target * quality;
   }
 }
 
 // use band quality levels to quantize a block
 static void qlevel(CoderInfo *coderInfo,
-                   const double *xr34,
+                   const double *xr,
                    int *xi,
                    const double *bandqual)
 {
     int sb, cnt;
     int start, end;
-    const double ifqstep = pow(2.0, 0.1875);
-    const double log_ifqstep = 1.0 / log(ifqstep);
+    // 1.5dB step
+    static const double sfstep = 20.0 / 1.5 / log(10);
+    static const double sfstep_1 = 1.0 / sfstep;
 
     for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
     {
@@ -103,16 +103,23 @@
       double sfacfix;
       int sfac;
       double maxx;
+      double rmsx;
 
       start = coderInfo->sfb_offset[sb];
       end = coderInfo->sfb_offset[sb+1];
 
       maxx = 0.0;
+      rmsx = 0.0;
       for (cnt = start; cnt < end; cnt++)
       {
-          if (xr34[cnt] > maxx)
-            maxx = xr34[cnt];
+          double e = xr[cnt] * xr[cnt];
+          if (maxx < e)
+            maxx = e;
+          rmsx += e;
       }
+      rmsx /= (end - start);
+      rmsx = sqrt(rmsx);
+      maxx = sqrt(maxx);
 
       if (maxx < 10.0)
       {
@@ -122,32 +129,32 @@
           continue;
       }
 
-      sfac = (int)(log(bandqual[sb] / maxx) * log_ifqstep - 0.5);
+      sfac = (int)(log(bandqual[sb] / rmsx) * sfstep - 0.5);
+      sfacfix = exp(sfac * sfstep_1);
       coderInfo->scale_factor[sb] = sfac;
-      sfacfix = exp(sfac / log_ifqstep);
       for (cnt = start; cnt < end; cnt++)
-          xi[cnt] = (int)(sfacfix * xr34[cnt] + 0.5);
+      {
+          double tmp = fabs(xr[cnt]) * sfacfix;
+          tmp = sqrt(tmp * sqrt(tmp));
+          xi[cnt] = (int)(tmp + 0.5);
+      }
     }
 }
 
 int BlocQuant(CoderInfo *coderInfo, double *xr, int *xi, double quality)
 {
-    double xr34[FRAME_LEN];
     double bandlvl[MAX_SCFAC_BANDS];
     int cnt;
     int nonzero = 0;
 
-    for (cnt = 0; cnt < FRAME_LEN; cnt++) {
-        double temp = fabs(xr[cnt]);
-        xr34[cnt] = sqrt(temp * sqrt(temp));
-        nonzero += (temp > 1E-20);
-    }
+    for (cnt = 0; cnt < FRAME_LEN; cnt++)
+        nonzero += (fabs(xr[cnt]) > 1E-20);
 
     SetMemory(xi, 0, FRAME_LEN*sizeof(xi[0]));
     if (nonzero)
     {
         bmask(coderInfo, xr, bandlvl, quality);
-        qlevel(coderInfo, xr34, xi, bandlvl);
+        qlevel(coderInfo, xr, xi, bandlvl);
         return 1;
     }