shithub: aacenc

Download patch

ref: b672bad1253e34d69b9069f28a82b124b4a6da04
parent: eea06700407866bfb0ec73f01394b8c2fc37d59b
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Tue Aug 22 09:09:16 EDT 2017

cutoff frequency tuned to fully utilize top band; removed mid frequency boost (it turned out useless)

--- a/libfaac/aacquant.c
+++ b/libfaac/aacquant.c
@@ -101,7 +101,7 @@
     for (sb = 0; sb < coderInfo->nr_of_sfb; sb++)
         scale_factor[sb] = 0;
 
-    if (BlocQuant(coderInfo, xr, xi, (double)aacquantCfg->quality/DEFQUAL, aacquantCfg->pow43))
+    if (BlocQuant(coderInfo, xr, xi, aacquantCfg))
     {
         UpdateRequant(coderInfo, xi, aacquantCfg->pow43);
 
--- a/libfaac/aacquant.h
+++ b/libfaac/aacquant.h
@@ -36,13 +36,15 @@
 #define POW20(x)  pow(2.0,((double)x)*.25)
 #define IPOW20(x)  pow(2.0,-((double)x)*.1875)
 
-#pragma pack(push, 1)
 typedef struct
   {
     double *pow43;
     double quality;
+    int max_cbl;
+    int max_cbs;
   } AACQuantCfg;
-#pragma pack(pop)
+
+#include "quantize.h"
 
 enum {DEFQUAL = 100, MAXQUAL = 2000, MINQUAL = 10};
 
--- a/libfaac/frame.c
+++ b/libfaac/frame.c
@@ -262,6 +262,10 @@
 
     /* set quantization quality */
     hEncoder->aacquantCfg.quality = config->quantqual;
+    BandLimit(&hEncoder->config.bandWidth,
+              hEncoder->sampleRate,
+              hEncoder->srInfo,
+              &hEncoder->aacquantCfg);
 
     // reset psymodel
     hEncoder->psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels);
@@ -620,6 +624,7 @@
             hEncoder->overlapBuff[channel],
             MOVERLAPPED);
 
+#if 0
         if (coderInfo[channel].block_type == ONLY_SHORT_WINDOW) {
             for (k = 0; k < 8; k++) {
                 specFilter(hEncoder->freqBuff[channel]+k*BLOCK_LEN_SHORT,
@@ -629,6 +634,7 @@
             specFilter(hEncoder->freqBuff[channel], sampleRate,
 					bandWidth, BLOCK_LEN_LONG);
         }
+#endif
     }
 
     /* TMP: Build sfb offset table and other stuff */
--- a/libfaac/quantize.c
+++ b/libfaac/quantize.c
@@ -25,7 +25,7 @@
 
 // band sound masking
 static void bmask(CoderInfo *coderInfo, double *xr, double *bandqual,
-                  double quality)
+                  AACQuantCfg *aacquantCfg)
 {
   int sfb, start, end, cnt;
   int last = coderInfo->lastx;
@@ -33,9 +33,15 @@
   int *cb_offset = coderInfo->sfb_offset;
   int num_cb = coderInfo->nr_of_sfb;
   double avgenrg = coderInfo->avgenrg;
-  double powm = 0.25;
-  enum {MIDF=34};
+  double powm = 0.4;
+  int nullcb;
+  double quality = (double)aacquantCfg->quality/DEFQUAL;
 
+  if (coderInfo->block_type == ONLY_SHORT_WINDOW)
+      nullcb = aacquantCfg->max_cbs;
+  else
+      nullcb = aacquantCfg->max_cbl;
+
   for (sfb = 0; sfb < num_cb; sfb++)
   {
     if (last > cb_offset[sfb])
@@ -42,7 +48,7 @@
       lastsb = sfb;
   }
 
-  for (sfb = 0; sfb < num_cb; sfb++)
+  for (sfb = 0; sfb < nullcb; sfb++)
   {
     double avge, maxe;
     double target;
@@ -72,8 +78,6 @@
     {
         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
     {
@@ -80,15 +84,17 @@
         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;
     }
 
-    target *= 1.0 / (0.75 + ((double)(start+end)/last));
+    target *= 6.5 / (1.0 + ((double)(start+end)/last));
 
-    bandqual[sfb] = 5.5 * target * quality;
+    bandqual[sfb] = target * quality;
   }
+  for (; sfb < num_cb; sfb++)
+  {
+    bandqual[sfb] = 0;
+  }
 }
 
 // use band quality levels to quantize a block
@@ -160,7 +166,7 @@
     }
 }
 
-int BlocQuant(CoderInfo *coderInfo, double *xr, int *xi, double quality, double *pow43)
+int BlocQuant(CoderInfo *coderInfo, double *xr, int *xi, AACQuantCfg *aacquantCfg)
 {
     double bandlvl[MAX_SCFAC_BANDS];
     int cnt;
@@ -172,10 +178,41 @@
     SetMemory(xi, 0, FRAME_LEN*sizeof(xi[0]));
     if (nonzero)
     {
-        bmask(coderInfo, xr, bandlvl, quality);
-        qlevel(coderInfo, xr, xi, bandlvl, pow43);
+        bmask(coderInfo, xr, bandlvl, aacquantCfg);
+        qlevel(coderInfo, xr, xi, bandlvl, aacquantCfg->pow43);
         return 1;
     }
 
     return 0;
+}
+
+void BandLimit(unsigned *bw, int rate, SR_INFO *sr, AACQuantCfg *aacquantCfg)
+{
+    // find max short frame band
+    int max = *bw * (BLOCK_LEN_SHORT << 1) / rate;
+    int cnt;
+    int l;
+
+    l = 0;
+    for (cnt = 0; cnt < sr->num_cb_short; cnt++)
+    {
+        if (l >= max)
+            break;
+        l += sr->cb_width_short[cnt];
+    }
+    aacquantCfg->max_cbs = cnt;
+    *bw = (double)l * rate / (BLOCK_LEN_SHORT << 1);
+
+    // find max long frame band
+    max = *bw * (BLOCK_LEN_LONG << 1) / rate;
+    l = 0;
+    for (cnt = 0; cnt < sr->num_cb_long; cnt++)
+    {
+        if (l >= max)
+            break;
+        l += sr->cb_width_long[cnt];
+    }
+    aacquantCfg->max_cbl = cnt;
+
+    *bw = (double)l * rate / (BLOCK_LEN_LONG << 1);
 }