shithub: aacenc

Download patch

ref: aa345aeb4988ccf5f4deda10aa062d1c8fa5d17a
parent: 78f557631d6db1737704e1a01f13a533b5869449
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Tue Oct 31 10:27:17 EDT 2017

initial version of PNS coding

--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+	* initial version of PNS coding
 	* Intensity Stereo coding
 	* more speed improvements
 	* finer bandwidth/cutoff setting
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -94,7 +94,8 @@
     HELP_IO,
     HELP_MP4,
     HELP_ADVANCED,
-    OPT_JOINT
+    OPT_JOINT,
+    OPT_PNS
 };
 
 typedef struct {
@@ -187,6 +188,7 @@
     {"--joint 0\tDisable joint stereo coding.\n"},
     {"--joint 1\tUse Mid/Side coding.\n"},
     {"--joint 2\tUse Intensity Stereo coding.\n"},
+    {"--pns <0 .. 10>\tPNS level; 0=disabled.\n"},
     {"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"},
     {"--shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n"
     "\t\tlong).\n"},
@@ -424,7 +426,8 @@
     faacEncConfigurationPtr myFormat;
     unsigned int mpegVersion = MPEG2;
     unsigned int objectType = LOW;
-    static int jointmode = JOINT_IS;
+    int jointmode = -1;
+    int pnslevel = -1;
     static int useTns = 0;
     enum container_format container = NO_CONTAINER;
     enum stream_format stream = ADTS_STREAM;
@@ -509,6 +512,7 @@
             {"help-advanced", 0, 0, HELP_ADVANCED},
             {"raw", 0, 0, 'r'},
             {"joint", required_argument, 0, OPT_JOINT},
+            {"pns", required_argument, 0, OPT_PNS},
             {"cutoff", 1, 0, 'c'},
             {"quality", 1, 0, 'q'},
             {"pcmraw", 0, 0, 'P'},
@@ -755,6 +759,9 @@
         case OPT_JOINT:
             jointmode = atoi(optarg);
             break;
+        case OPT_PNS:
+            pnslevel = atoi(optarg);
+            break;
         case '?':
         default:
             help('?');
@@ -891,7 +898,10 @@
     }
     if (infile->channels >= 6)
         myFormat->useLfe = 1;
-    myFormat->jointmode = jointmode;
+    if (jointmode >= 0)
+        myFormat->jointmode = jointmode;
+    if (pnslevel >= 0)
+        myFormat->pnslevel = pnslevel;
     if (quantqual > 0)
     {
         myFormat->quantqual = quantqual;
@@ -958,6 +968,8 @@
     else
         fprintf(stderr, "Quantization quality: %ld\n", quantqual);
     fprintf(stderr, "Bandwidth: %d Hz\n", cutOff);
+    if (myFormat->pnslevel > 0)
+        fprintf(stderr, "PNS level: %d\n", myFormat->pnslevel);
     fprintf(stderr, "Object type: ");
     switch (objectType)
     {
@@ -983,6 +995,8 @@
         fprintf(stderr, " + IS");
         break;
     }
+    if (myFormat->pnslevel > 0)
+        fprintf(stderr, " + PNS");
     fprintf(stderr, "\n");
 
     fprintf(stderr, "Container format: ");
--- a/include/faaccfg.h
+++ b/include/faaccfg.h
@@ -121,8 +121,8 @@
 		WAVE 5.1		2, 0, 1, 4, 5, 3
 		AIFF 5.1		2, 0, 3, 1, 4, 5 
 	*/
-	int channel_map[64];	
-
+    int channel_map[64];
+    int pnslevel;
 } faacEncConfiguration, *faacEncConfigurationPtr;
 
 #pragma pack(pop)
--- a/libfaac/frame.c
+++ b/libfaac/frame.c
@@ -189,6 +189,11 @@
 
     hEncoder->config.quantqual = config->quantqual;
 
+    if (config->pnslevel < 0)
+        config->pnslevel = 0;
+    if (config->pnslevel > 10)
+        config->pnslevel = 10;
+    hEncoder->aacquantCfg.pnslevel = config->pnslevel;
     /* set quantization quality */
     hEncoder->aacquantCfg.quality = config->quantqual;
     CalcBW(&hEncoder->config.bandWidth,
@@ -252,6 +257,7 @@
     hEncoder->config.mpegVersion = MPEG4;
     hEncoder->config.aacObjectType = LOW;
     hEncoder->config.jointmode = JOINT_IS;
+    hEncoder->config.pnslevel = 4;
     hEncoder->config.useLfe = 1;
     hEncoder->config.useTns = 0;
     hEncoder->config.bitRate = 64000;
--- a/libfaac/huff2.c
+++ b/libfaac/huff2.c
@@ -513,9 +513,12 @@
     int diff, length;
     int lastsf;
     int lastis;
+    int lastpns;
+    int initpns = 1;
 
     lastsf = coder->global_gain;
     lastis = 0;
+    lastpns = coder->global_gain - 90;
 
     // fixme: move range check to quantizer
     for (cnt = 0; cnt < coder->bandcnt; cnt++)
@@ -534,6 +537,35 @@
             bits += length;
 
             lastis += diff;
+
+            if (write)
+                PutBit(stream, book12[60 + diff].data, length);
+        }
+        else if (book == HCB_PNS)
+        {
+            diff = coder->sf[cnt] - lastpns;
+
+            if (initpns)
+            {
+                initpns = 0;
+
+                length = 9;
+                bits += length;
+                lastpns += diff;
+
+                if (write)
+                    PutBit(stream, diff + 256, length);
+                continue;
+            }
+
+            if (diff > 60)
+                diff = 60;
+            if (diff < -60)
+                diff = -60;
+
+            length = book12[60 + diff].len;
+            bits += length;
+            lastpns += diff;
 
             if (write)
                 PutBit(stream, book12[60 + diff].data, length);
--- a/libfaac/huff2.h
+++ b/libfaac/huff2.h
@@ -22,6 +22,7 @@
 enum {
     HCB_ZERO = 0,
     HCB_ESC = 11,
+    HCB_PNS = 13,
     HCB_INTENSITY2 = 14,
     HCB_INTENSITY = 15,
     HCB_NONE
--- a/libfaac/quantize.c
+++ b/libfaac/quantize.c
@@ -142,7 +142,8 @@
 static void qlevel(CoderInfo *coderInfo,
                    const double *xr0,
                    const double *bandqual,
-                   int gnum
+                   int gnum,
+                   int pnslevel
                   )
 {
     int sb, cnt;
@@ -153,6 +154,7 @@
     static const double sfstep = 20 / 1.50515;
 #endif
     int gsize = coderInfo->groups.len[gnum];
+    double pnsthr = 0.1 * pnslevel;
 #ifdef __SSE2__
     int cpuid[4];
     int sse2 = 0;
@@ -173,6 +175,7 @@
       double sfacfix;
       int sfac;
       double rmsx;
+      double etot;
       int xitab[8 * MAXSHORTBAND];
       int *xi;
       int start, end;
@@ -181,11 +184,6 @@
 
       if (coderInfo->book[coderInfo->bandcnt] != HCB_NONE)
       {
-#if 0
-          int book = coderInfo->book[coderInfo->bandcnt];
-          if ((book != HCB_INTENSITY) && (book != HCB_INTENSITY2))
-              printf("book[%d]:%d\n",coderInfo->bandcnt, book);
-#endif
           coderInfo->bandcnt++;
           continue;
       }
@@ -193,7 +191,7 @@
       start = coderInfo->sfb_offset[sb];
       end = coderInfo->sfb_offset[sb+1];
 
-      rmsx = 0.0;
+      etot = 0.0;
       xr = xr0;
       for (win = 0; win < gsize; win++)
       {
@@ -200,25 +198,30 @@
           for (cnt = start; cnt < end; cnt++)
           {
               double e = xr[cnt] * xr[cnt];
-              rmsx += e;
+              etot += e;
           }
           xr += BLOCK_LEN_SHORT;
       }
-      rmsx /= ((end - start) * gsize);
-      rmsx = sqrt(rmsx);
+      etot /= (double)gsize;
+      rmsx = sqrt(etot / (end - start));
 
       if ((rmsx < NOISEFLOOR) || (!bandqual[sb]))
       {
-#if 0
-          coderInfo->book[coderInfo->bandcnt] = HCB_ZERO;
-          coderInfo->sf[coderInfo->bandcnt++] = 0;
-#else
           coderInfo->book[coderInfo->bandcnt++] = HCB_ZERO;
-#endif
           continue;
       }
 
-      //printf("qual:%f/%f\n", bandqual[sb], bandqual[sb]/rmsx);
+#ifndef DRM
+      if (bandqual[sb] < pnsthr)
+      {
+          coderInfo->book[coderInfo->bandcnt] = HCB_PNS;
+          coderInfo->sf[coderInfo->bandcnt] +=
+              lrint(log10(etot) * (0.5 * sfstep));
+          coderInfo->bandcnt++;
+          continue;
+      }
+#endif
+
       sfac = lrint(log10(bandqual[sb] / rmsx) * sfstep);
       if ((SF_OFFSET - sfac) < 10)
           sfacfix = 0.0;
@@ -236,7 +239,6 @@
               for (cnt = 0; cnt < end; cnt += 4)
               {
                   __m128 x = {xr[cnt], xr[cnt + 1], xr[cnt + 2], xr[cnt + 3]};
-                  //printf("%f/%f\n", xr[cnt], xr[cnt] * sfacfix);
 
                   x = _mm_max_ps(x, -x);
                   x *= (__m128){sfacfix, sfacfix, sfacfix, sfacfix};
@@ -245,7 +247,6 @@
                   x += (__m128){MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER, MAGIC_NUMBER};
 
                   *(__m128i*)(xi + cnt) = _mm_cvttps_epi32(x);
-                  //printf("%d/%d/%d/%d\n", xi[cnt],xi[cnt+1],xi[cnt+2],xi[cnt+3]);
               }
               for (cnt = 0; cnt < end; cnt++)
               {
@@ -284,10 +285,6 @@
     double *gxr;
 
     coder->global_gain = 0;
-#if 0
-    for (cnt = 0; cnt < coder->sfbn; cnt++)
-        coder->sf[cnt] = SF_OFFSET;
-#endif
 
     coder->bandcnt = 0;
     coder->datacnt = 0;
@@ -306,7 +303,7 @@
         {
             bmask(coder, gxr, bandlvl, cnt,
                   (double)aacquantCfg->quality/DEFQUAL);
-            qlevel(coder, gxr, bandlvl, cnt);
+            qlevel(coder, gxr, bandlvl, cnt, aacquantCfg->pnslevel);
             gxr += coder->groups.len[cnt] * BLOCK_LEN_SHORT;
         }
 
@@ -341,7 +338,7 @@
                 lastis += diff;
                 coder->sf[cnt] = lastis;
             }
-            else if (book)
+            else if (book != HCB_PNS)
             {
                 int diff = coder->sf[cnt] - lastsf;
 
--- a/libfaac/quantize.h
+++ b/libfaac/quantize.h
@@ -25,11 +25,11 @@
 
 typedef struct
 {
-    //double *pow43;
     double quality;
     int max_cbl;
     int max_cbs;
     int max_l;
+    int pnslevel;
 } AACQuantCfg;
 
 #include "quantize.h"
--- a/libfaac/stereo.c
+++ b/libfaac/stereo.c
@@ -29,6 +29,7 @@
 {
     int sfb;
     int win;
+    int sfmin;
 
     if (!phthr)
         return;
@@ -35,7 +36,14 @@
 
     phthr = 1.0 / phthr;
 
-    for (sfb = 0; sfb < cl->sfbn; sfb++)
+    if (cl->block_type == ONLY_SHORT_WINDOW)
+        sfmin = 1;
+    else
+        sfmin = 8;
+
+    (*sfcnt) += sfmin;
+
+    for (sfb = sfmin; sfb < cl->sfbn; sfb++)
     {
         int l, start, end;
         double sum, diff;
@@ -44,14 +52,6 @@
         const double step = 10/1.50515;
         double ethr;
         double vfix, efix;
-
-#if 1
-        if (sfb < 1)
-        {
-            (*sfcnt)++;
-            continue;
-        }
-#endif
 
         start = cl->sfb_offset[sfb];
         end = cl->sfb_offset[sfb + 1];