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];