ref: 012fb04f17da3b0e13568caad3546fa375b411b6
parent: 399e53a4955871b3da8130c3d9d3000ccc57f848
author: knik <knik>
date: Mon May 12 13:52:47 EDT 2003
CalcAllowedDist: modified noise allocation FixNoise: max-quant-value exit condition
--- a/libfaac/aacquant.c
+++ b/libfaac/aacquant.c
@@ -17,7 +17,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: aacquant.c,v 1.18 2003/05/01 10:29:06 knik Exp $
+ * $Id: aacquant.c,v 1.19 2003/05/12 17:52:47 knik Exp $
*/
#include <math.h>
@@ -362,18 +362,33 @@
double *xr, double *xmin, int quality)
{
int sfb, start, end, l;
- const double globalthr = 37.0 / (double)quality;
- int last = cb_offset[num_cb];
+ const double globalthr = 31.1 / (double)quality;
+ int last = 0, lastsb = 0;
double totnrg = 0.0;
static const double minfix = 1.5;
- for (l = 0; l < last; l++)
+ end = cb_offset[num_cb];
+ for (l = 0; l < end; l++)
+ {
+ if (xr[l])
+ {
+ last = l;
totnrg += xr[l] * xr[l];
+ }
+ }
+ last++;
totnrg /= last;
for (sfb = 0; sfb < num_cb; sfb++)
{
+ if (last > cb_offset[sfb])
+ lastsb = sfb;
+ }
+
+
+ for (sfb = 0; sfb < num_cb; sfb++)
+ {
double thr, tmp;
double enrg = 0.0;
@@ -380,12 +395,18 @@
start = cb_offset[sfb];
end = cb_offset[sfb + 1];
+ if (sfb > lastsb)
+ {
+ xmin[sfb] = 0;
+ continue;
+ }
+
for (l = start; l < end; l++)
enrg += xr[l]*xr[l];
- thr = pow((double)(end-start)*totnrg/enrg, 0.5*(num_cb-sfb)/num_cb + 0.0);
+ thr = pow((double)(end-start)*totnrg/enrg, 0.425*(lastsb-sfb)/lastsb + 0.075);
- tmp = minfix * pow((double)(start + 400) / (double)last, 0.6);
+ tmp = minfix * (double)(start + 400) / (double)last;
if (tmp < thr)
thr = tmp;
@@ -415,23 +436,26 @@
int sfac;
double fac;
int dist;
+ double sfacfix0 = 1.0, dist0 = 1e50;
+ double maxx;
- if (!xmin[sb])
- continue;
-
start = coderInfo->sfb_offset[sb];
end = coderInfo->sfb_offset[sb+1];
- tmp = 0.0;
+ if (!xmin[sb])
+ goto nullsfb;
+
+ maxx = 0.0;
for (i = start; i < end; i++)
{
- if (xr_pow[i] > tmp)
- tmp = xr_pow[i];
+ if (xr_pow[i] > maxx)
+ maxx = xr_pow[i];
}
- //printf("band %d: tmp: %f\n", sb, tmp);
- if (tmp < 10.0)
+ //printf("band %d: maxx: %f\n", sb, maxx);
+ if (maxx < 10.0)
{
+ nullsfb:
for (i = start; i < end; i++)
xi[i] = 0;
coderInfo->scale_factor[sb] = 10;
@@ -438,10 +462,11 @@
continue;
}
- sfacfix = 1.0 / tmp;
+ sfacfix = 1.0 / maxx;
sfac = log(sfacfix) * log_ifqstep - 0.5;
for (i = start; i < end; i++)
xr_pow[i] *= sfacfix;
+ maxx *= sfacfix;
coderInfo->scale_factor[sb] = sfac;
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end);
//printf("\tsfac: %d\n", sfac);
@@ -462,10 +487,44 @@
quantvol = sqrt(quantvol/(double)(end-start)) * (double)(end-start);
//printf("\tdiffvol: %f, qvol: %f\n", diffvol, quantvol);
- dist = (diffvol / quantvol) > xmin[sb];
- fac = 0.0;
+ tmp = diffvol / quantvol;
+
if (fabs(fixstep) > maxstep)
{
+ double dd = 0.5*(tmp / xmin[sb] - 1.0);
+
+ if (fabs(dd) < fabs(fixstep))
+ {
+ fixstep = dd;
+
+ if (fabs(fixstep) < maxstep)
+ fixstep = maxstep * ((fixstep > 0) ? 1 : -1);
+ }
+ }
+
+ if (fixstep > 0)
+ {
+ if (tmp < dist0)
+ {
+ dist0 = tmp;
+ sfacfix0 = sfacfix;
+ }
+ else
+ {
+ if (fixstep > .1)
+ fixstep = .1;
+ }
+ }
+ else
+ {
+ dist0 = tmp;
+ sfacfix0 = sfacfix;
+ }
+
+ dist = (tmp > xmin[sb]);
+ fac = 0.0;
+ if (fabs(fixstep) >= maxstep)
+ {
if ((dist && (fixstep < 0))
|| (!dist && (fixstep > 0)))
{
@@ -481,10 +540,24 @@
if (fac != 0.0)
{
+ if (maxx * fac >= IXMAX_VAL)
+ {
+ // restore best noise
+ fac = sfacfix0 / sfacfix;
+ for (i = start; i < end; i++)
+ xr_pow[i] *= fac;
+ maxx *= fac;
+ sfacfix *= fac;
+ coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
+ QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end);
+ continue;
+ }
+
if (coderInfo->scale_factor[sb] < -10)
{
for (i = start; i < end; i++)
xr_pow[i] *= fac;
+ maxx *= fac;
sfacfix *= fac;
coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5;
QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end);