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);
}