/*
* MP3 quantization
*
* Copyright (c) 1999 Mark Taylor
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* 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: vbrquantize.c,v 1.41 2001/03/12 07:26:08 markt Exp $ */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <assert.h>
#include "util.h"
#include "l3side.h"
#include "quantize.h"
#include "reservoir.h"
#include "quantize_pvt.h"
#include "lame-analysis.h"
#ifdef WITH_DMALLOC
#include <dmalloc.h>
#endif
#undef MAXQUANTERROR
typedef union {
float f;
int i;
} fi_union;
#define MAGIC_FLOAT (65536*(128))
#define MAGIC_INT 0x4b000000
#ifdef TAKEHIRO_IEEE754_HACK
#ifdef MAXQUANTERROR
#define DUFFBLOCK() do { \
xp = xr34[0] * sfpow34_p1; \
xe = xr34[0] * sfpow34_eq; \
xm = xr34[0] * sfpow34_m1; \
if (xm > IXMAX_VAL) \
return -1; \
xp += MAGIC_FLOAT; \
xe += MAGIC_FLOAT; \
xm += MAGIC_FLOAT; \
fi[0].f = xp; \
fi[1].f = xe; \
fi[2].f = xm; \
fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \
fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \
fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \
fi[0].i -= MAGIC_INT; \
fi[1].i -= MAGIC_INT; \
fi[2].i -= MAGIC_INT; \
x0 = fabs(xr[0]); \
xp = x0 - pow43[fi[0].i] * sfpow_p1; \
xe = x0 - pow43[fi[1].i] * sfpow_eq; \
xm = x0 - pow43[fi[2].i] * sfpow_m1; \
xp *= xp; \
xe *= xe; \
xm *= xm; \
xfsf_eq = Max(xfsf_eq, xe); \
xfsf_p1 = Max(xfsf_p1, xp); \
xfsf_m1 = Max(xfsf_m1, xm); \
++xr; \
++xr34; \
} while(0)
#else
#define DUFFBLOCK() do { \
xp = xr34[0] * sfpow34_p1; \
xe = xr34[0] * sfpow34_eq; \
xm = xr34[0] * sfpow34_m1; \
if (xm > IXMAX_VAL) \
return -1; \
xp += MAGIC_FLOAT; \
xe += MAGIC_FLOAT; \
xm += MAGIC_FLOAT; \
fi[0].f = xp; \
fi[1].f = xe; \
fi[2].f = xm; \
fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \
fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \
fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \
fi[0].i -= MAGIC_INT; \
fi[1].i -= MAGIC_INT; \
fi[2].i -= MAGIC_INT; \
x0 = fabs(xr[0]); \
xp = x0 - pow43[fi[0].i] * sfpow_p1; \
xe = x0 - pow43[fi[1].i] * sfpow_eq; \
xm = x0 - pow43[fi[2].i] * sfpow_m1; \
xfsf_p1 += xp * xp; \
xfsf_eq += xe * xe; \
xfsf_m1 += xm * xm; \
++xr; \
++xr34; \
} while(0)
#endif
#else
/*********************************************************************
* XRPOW_FTOI is a macro to convert floats to ints.
* if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
* ROUNDFAC= -0.0946
*
* if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
* ROUNDFAC=0.4054
*********************************************************************/
# define QUANTFAC(rx) adj43[rx]
# define ROUNDFAC 0.4054
# define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
#endif
static FLOAT8
calc_sfb_noise(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf)
{
int j;
fi_union fi;
FLOAT8 temp;
FLOAT8 xfsf=0;
FLOAT8 sfpow,sfpow34;
sfpow = POW20(sf+210); /*pow(2.0,sf/4.0); */
sfpow34 = IPOW20(sf+210); /*pow(sfpow,-3.0/4.0);*/
for ( j=0; j < bw ; ++j) {
#if 0
int ix;
if (xr34[j]*sfpow34 > IXMAX_VAL) return -1;
ix=floor( xr34[j]*sfpow34);
temp = fabs(xr[j])- pow43[ix]*sfpow;
temp *= temp;
if (ix < IXMAX_VAL) {
temp2 = fabs(xr[j])- pow43[ix+1]*sfpow;
temp2 *=temp2;
if (temp2<temp) {
temp=temp2;
++ix;
}
}
#else
if (xr34[j]*sfpow34 > IXMAX_VAL) return -1;
#ifdef TAKEHIRO_IEEE754_HACK
temp = sfpow34*xr34[j];
temp += MAGIC_FLOAT;
fi.f = temp;
fi.f = temp + (adj43asm - MAGIC_INT)[fi.i];
fi.i -= MAGIC_INT;
#else
temp = xr34[j]*sfpow34;
XRPOW_FTOI(temp, fi.i);
XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i);
#endif
temp = fabs(xr[j])- pow43[fi.i]*sfpow;
temp *= temp;
#endif
#ifdef MAXQUANTERROR
xfsf = Max(xfsf,temp);
#else
xfsf += temp;
#endif
}
#ifdef MAXQUANTERROR
return xfsf;
#else
return xfsf;//bw;
#endif
}
static FLOAT8
calc_sfb_noise_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf)
{
double xp;
double xe;
double xm;
#ifdef TAKEHIRO_IEEE754_HACK
double x0;
#endif
int xx[3], j;
fi_union *fi = (fi_union *)xx;
FLOAT8 sfpow34_eq, sfpow34_p1, sfpow34_m1;
FLOAT8 sfpow_eq, sfpow_p1, sfpow_m1;
FLOAT8 xfsf_eq = 0, xfsf_p1 = 0, xfsf_m1 = 0;
sfpow_eq = POW20(sf + 210); /*pow(2.0,sf/4.0); */
sfpow_m1 = sfpow_eq * .8408964153; /* pow(2,(sf-1)/4.0) */
sfpow_p1 = sfpow_eq * 1.189207115;
sfpow34_eq = IPOW20(sf + 210); /*pow(sfpow,-3.0/4.0);*/
sfpow34_m1 = sfpow34_eq * 1.13878863476; /* .84089 ^ -3/4 */
sfpow34_p1 = sfpow34_eq * 0.878126080187;
#ifdef TAKEHIRO_IEEE754_HACK
/*
* loop unrolled into "Duff's Device". Robert Hegemann
*/
j = (bw+3) / 4;
switch (bw % 4) {
default:
case 0: do{ DUFFBLOCK();
case 3: DUFFBLOCK();
case 2: DUFFBLOCK();
case 1: DUFFBLOCK(); } while (--j);
}
#else
for (j = 0; j < bw; ++j) {
if (xr34[j]*sfpow34_m1 > IXMAX_VAL) return -1;
xe = xr34[j]*sfpow34_eq;
XRPOW_FTOI(xe, fi[0].i);
XRPOW_FTOI(xe + QUANTFAC(fi[0].i), fi[0].i);
xe = fabs(xr[j])- pow43[fi[0].i]*sfpow_eq;
xe *= xe;
xp = xr34[j]*sfpow34_p1;
XRPOW_FTOI(xp, fi[0].i);
XRPOW_FTOI(xp + QUANTFAC(fi[0].i), fi[0].i);
xp = fabs(xr[j])- pow43[fi[0].i]*sfpow_p1;
xp *= xp;
xm = xr34[j]*sfpow34_m1;
XRPOW_FTOI(xm, fi[0].i);
XRPOW_FTOI(xm + QUANTFAC(fi[0].i), fi[0].i);
xm = fabs(xr[j])- pow43[fi[0].i]*sfpow_m1;
xm *= xm;
#ifdef MAXQUANTERROR
xfsf_eq = Max(xfsf,xm);
xfsf_p1 = Max(xfsf_p1,xp);
xfsf_m1 = Max(xfsf_m1,xm);
#else
xfsf_eq += xe;
xfsf_p1 += xp;
xfsf_m1 += xm;
#endif
}
#endif
if (xfsf_eq < xfsf_p1)
xfsf_eq = xfsf_p1;
if (xfsf_eq < xfsf_m1)
xfsf_eq = xfsf_m1;
#ifdef MAXQUANTERROR
return xfsf_eq;
#else
return xfsf_eq;//bw;
#endif
}
static int
find_scalefac(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb,
const FLOAT8 l3_xmin, const int bw)
{
FLOAT8 xfsf;
int i,sf,sf_ok,delsf;
/* search will range from sf: -209 -> 45 */
sf = -82;
delsf = 128;
sf_ok=10000;
for (i=0; i<7; i++) {
delsf /= 2;
xfsf = calc_sfb_noise(xr,xr34,bw,sf);
if (xfsf < 0) {
/* scalefactors too small */
sf += delsf;
}else{
if (sf_ok==10000) sf_ok=sf;
if (xfsf > l3_xmin) {
/* distortion. try a smaller scalefactor */
sf -= delsf;
}else{
sf_ok = sf;
sf += delsf;
}
}
}
assert(sf_ok!=10000);
#if 0
assert(delsf==1); /* when for loop goes up to 7 */
#endif
return sf;
}
static int
find_scalefac_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb,
const FLOAT8 l3_xmin, const int bw)
{
FLOAT8 xfsf;
int i,sf,sf_ok,delsf;
/* search will range from sf: -209 -> 45 */
sf = -82;
delsf = 128;
sf_ok=10000;
for (i=0; i<7; i++) {
delsf /= 2;
xfsf = calc_sfb_noise_ave(xr,xr34,bw,sf);
if (xfsf < 0) {
/* scalefactors too small */
sf += delsf;
}else{
if (sf_ok==10000) sf_ok=sf;
if (xfsf > l3_xmin) {
/* distortion. try a smaller scalefactor */
sf -= delsf;
}else{
sf_ok = sf;
sf += delsf;
}
}
}
assert(sf_ok!=10000);
#if 0
assert(delsf==1); /* when for loop goes up to 7 */
#endif
return sf;
}
/* ???
How do the following tables look like for MPEG-2-LSF
??? */
static const int max_range_short[SBPSY_s] =
{15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 };
static const int max_range_long[SBPSY_l] =
{15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
static const int max_range_short_lsf[SBPSY_s] =
{15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 };
/*static const int max_range_short_lsf_pretab[SBPSY_s] =
{}*/
static const int max_range_long_lsf[SBPSY_l] =
{15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
static const int max_range_long_lsf_pretab[SBPSY_l] =
{ 7,7,7,7,7,7, 3,3,3,3,3, 0,0,0,0, 0,0,0, 0,0,0 };
static int
compute_scalefacs_short_lsf (
int sf[SBPSY_s][3],gr_info *cod_info, int scalefac[SBPSY_s][3],int sbg[3])
{
int maxrange, maxrange1, maxrange2, maxover;
int sfb, i;
int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
maxover = 0;
maxrange1 = max_range_short_lsf[0];
maxrange2 = max_range_short_lsf[6];
for (i=0; i<3; ++i) {
int maxsf1 = 0, maxsf2 = 0, minsf = 1000;
/* see if we should use subblock gain */
for (sfb = 0; sfb < SBPSY_s; sfb++) {
if (sfb < 6) {
if (maxsf1 < -sf[sfb][i])
maxsf1 = -sf[sfb][i];
} else {
if (maxsf2 < -sf[sfb][i])
maxsf2 = -sf[sfb][i];
}
if (minsf > -sf[sfb][i])
minsf = -sf[sfb][i];
}
/* boost subblock gain as little as possible so we can
* reach maxsf1 with scalefactors
* 8*sbg >= maxsf1
*/
maxsf1 = Max (maxsf1-maxrange1*ifqstep, maxsf2-maxrange2*ifqstep);
sbg[i] = 0;
if (minsf > 0)
sbg[i] = floor (.125*minsf + .001);
if (maxsf1 > 0)
sbg[i] = Max (sbg[i], (maxsf1/8 + (maxsf1 % 8 != 0)));
if (sbg[i] > 7)
sbg[i] = 7;
for (sfb = 0; sfb < SBPSY_s; sfb++) {
sf[sfb][i] += 8*sbg[i];
if (sf[sfb][i] < 0) {
maxrange = sfb < 6 ? maxrange1 : maxrange2;
scalefac[sfb][i]
= -sf[sfb][i]/ifqstep + (-sf[sfb][i]%ifqstep != 0);
if (scalefac[sfb][i] > maxrange)
scalefac[sfb][i] = maxrange;
if (maxover < -(sf[sfb][i] + scalefac[sfb][i]*ifqstep))
maxover = -(sf[sfb][i] + scalefac[sfb][i]*ifqstep);
}
}
}
return maxover;
}
static int
compute_scalefacs_long_lsf (
int sf [SBPSY_l],
const gr_info * const cod_info,
int scalefac [SBPSY_l] )
{
const int * max_range = max_range_long_lsf;
int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
int sfb;
int maxover;
if (cod_info->preflag) {
max_range = max_range_long_lsf_pretab;
for (sfb = 11; sfb < SBPSY_l; sfb++)
sf[sfb] += pretab[sfb] * ifqstep;
}
maxover = 0;
for (sfb = 0; sfb < SBPSY_l; sfb++) {
if (sf[sfb] < 0) {
/* ifqstep*scalefac >= -sf[sfb], so round UP */
scalefac[sfb] = -sf[sfb]/ifqstep + (-sf[sfb] % ifqstep != 0);
if (scalefac[sfb] > max_range[sfb])
scalefac[sfb] = max_range[sfb];
/* sf[sfb] should now be positive: */
if (-(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) {
maxover = -(sf[sfb] + scalefac[sfb]*ifqstep);
}
}
}
return maxover;
}
/*
sfb=0..5 scalefac < 16
sfb>5 scalefac < 8
ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
ol_sf = (cod_info->global_gain-210.0);
ol_sf -= 8*cod_info->subblock_gain[i];
ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];
*/
static int
compute_scalefacs_short(int sf[SBPSY_s][3],gr_info *cod_info,
int scalefac[SBPSY_s][3],int sbg[3])
{
int maxrange,maxrange1,maxrange2,maxover;
int sfb,i;
int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
maxover=0;
maxrange1 = 15;
maxrange2 = 7;
for (i=0; i<3; ++i) {
int maxsf1=0,maxsf2=0,minsf=1000;
/* see if we should use subblock gain */
for ( sfb = 0; sfb < SBPSY_s; sfb++ ) {
if (sfb < 6) {
if (-sf[sfb][i]>maxsf1) maxsf1 = -sf[sfb][i];
} else {
if (-sf[sfb][i]>maxsf2) maxsf2 = -sf[sfb][i];
}
if (-sf[sfb][i]<minsf) minsf = -sf[sfb][i];
}
/* boost subblock gain as little as possible so we can
* reach maxsf1 with scalefactors
* 8*sbg >= maxsf1
*/
maxsf1 = Max(maxsf1-maxrange1*ifqstep,maxsf2-maxrange2*ifqstep);
sbg[i]=0;
if (minsf >0 ) sbg[i] = floor(.125*minsf + .001);
if (maxsf1 > 0) sbg[i] = Max(sbg[i],(maxsf1/8 + (maxsf1 % 8 != 0)));
if (sbg[i] > 7) sbg[i]=7;
for ( sfb = 0; sfb < SBPSY_s; sfb++ ) {
sf[sfb][i] += 8*sbg[i];
if (sf[sfb][i] < 0) {
maxrange = sfb < 6 ? maxrange1 : maxrange2;
scalefac[sfb][i]= -sf[sfb][i]/ifqstep + (-sf[sfb][i]%ifqstep != 0);
if (scalefac[sfb][i]>maxrange) scalefac[sfb][i]=maxrange;
if (-(sf[sfb][i] + scalefac[sfb][i]*ifqstep) >maxover) {
maxover=-(sf[sfb][i] + scalefac[sfb][i]*ifqstep);
}
}
}
}
return maxover;
}
/*
ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
ol_sf = (cod_info->global_gain-210.0);
ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];
if (cod_info->preflag && sfb>=11)
ol_sf -= ifqstep*pretab[sfb];
*/
static int
compute_scalefacs_long(int sf[SBPSY_l],gr_info *cod_info,int scalefac[SBPSY_l])
{
int sfb;
int maxover;
int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
if (cod_info->preflag)
for ( sfb = 11; sfb < SBPSY_l; sfb++ )
sf[sfb] += pretab[sfb]*ifqstep;
maxover=0;
for ( sfb = 0; sfb < SBPSY_l; sfb++ ) {
if (sf[sfb]<0) {
/* ifqstep*scalefac >= -sf[sfb], so round UP */
scalefac[sfb]= -sf[sfb]/ifqstep + (-sf[sfb] % ifqstep != 0);
if (scalefac[sfb] > max_range_long[sfb]) scalefac[sfb]=max_range_long[sfb];
/* sf[sfb] should now be positive: */
if ( -(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) {
maxover = -(sf[sfb] + scalefac[sfb]*ifqstep);
}
}
}
return maxover;
}
/************************************************************************
*
* quantize and encode with the given scalefacs and global gain
*
* compute scalefactors, l3_enc, and return number of bits needed to encode
*
*
************************************************************************/
static int
VBR_quantize_granule(
lame_global_flags *gfp,
FLOAT8 xr34[576],
int l3_enc[576],
const III_psy_ratio * const ratio,
III_scalefac_t * const scalefac,
const int gr,
const int ch)
{
lame_internal_flags *gfc=gfp->internal_flags;
int status;
gr_info *cod_info;
III_side_info_t * l3_side;
l3_side = &gfc->l3_side;
cod_info = &l3_side->gr[gr].ch[ch].tt;
/* encode scalefacs */
if ( gfc->is_mpeg1 )
status=scale_bitcount(scalefac, cod_info);
else
status=scale_bitcount_lsf(gfc,scalefac, cod_info);
if (status!=0) {
return -1;
}
/* quantize xr34 */
cod_info->part2_3_length = count_bits(gfc,l3_enc,xr34,cod_info);
if (cod_info->part2_3_length >= LARGE_BITS) return -2;
cod_info->part2_3_length += cod_info->part2_length;
if (gfc->use_best_huffman==1) {
best_huffman_divide(gfc, gr, ch, cod_info, l3_enc);
}
return 0;
}
/***********************************************************************
*
* calc_short_block_vbr_sf()
* calc_long_block_vbr_sf()
*
* Mark Taylor 2000-??-??
* Robert Hegemann 2000-10-25 made functions of it
*
***********************************************************************/
static const int MAX_SF_DELTA = 4;
static int
short_block_vbr_sf (
const lame_internal_flags * const gfc,
const III_psy_xmin * const l3_xmin,
const FLOAT8 xr34_orig[576],
const FLOAT8 xr34 [576],
III_scalefac_t * const vbrsf )
{
int j, sfb, b;
int vbrmax = -10000; /* initialize for maximum search */
for (j = 0, sfb = 0; sfb < SBMAX_s; sfb++) {
for (b = 0; b < 3; b++) {
const int start = gfc->scalefac_band.s[ sfb ];
const int end = gfc->scalefac_band.s[ sfb+1 ];
const int width = end - start;
vbrsf->s[sfb][b] = find_scalefac_ave (&xr34[j], &xr34_orig[j],
sfb, l3_xmin->s[sfb][b], width);
j += width;
}
}
for (sfb = 0; sfb < SBMAX_s; sfb++) {
for (b = 0; b < 3; b++) {
if (sfb > 0)
if (vbrsf->s[sfb][b] > vbrsf->s[sfb-1][b]+MAX_SF_DELTA)
vbrsf->s[sfb][b] = vbrsf->s[sfb-1][b]+MAX_SF_DELTA;
if (sfb < SBMAX_s-1)
if (vbrsf->s[sfb][b] > vbrsf->s[sfb+1][b]+MAX_SF_DELTA)
vbrsf->s[sfb][b] = vbrsf->s[sfb+1][b]+MAX_SF_DELTA;
if (vbrmax < vbrsf->s[sfb][b])
vbrmax = vbrsf->s[sfb][b];
}
}
return vbrmax;
}
static int
long_block_vbr_sf (
const lame_internal_flags * const gfc,
const III_psy_xmin * const l3_xmin,
const FLOAT8 xr34_orig[576],
const FLOAT8 xr34 [576],
III_scalefac_t * const vbrsf )
{
int sfb;
int vbrmax = -10000; /* initialize for maximum search */
for (sfb = 0; sfb < SBMAX_l; sfb++) {
const int start = gfc->scalefac_band.l[ sfb ];
const int end = gfc->scalefac_band.l[ sfb+1 ];
const int width = end - start;
vbrsf->l[sfb] = find_scalefac_ave (&xr34[start], &xr34_orig[start],
sfb, l3_xmin->l[sfb], width);
}
for (sfb = 0; sfb < SBMAX_l; sfb++) {
if (sfb > 0)
if (vbrsf->l[sfb] > vbrsf->l[sfb-1]+MAX_SF_DELTA)
vbrsf->l[sfb] = vbrsf->l[sfb-1]+MAX_SF_DELTA;
if (sfb < SBMAX_l-1)
if (vbrsf->l[sfb] > vbrsf->l[sfb+1]+MAX_SF_DELTA)
vbrsf->l[sfb] = vbrsf->l[sfb+1]+MAX_SF_DELTA;
if (vbrmax < vbrsf->l[sfb])
vbrmax = vbrsf->l[sfb];
}
return vbrmax;
}
/* a variation for vbr-mtrh */
static int
short_block_sf (
const lame_internal_flags * const gfc,
const III_psy_xmin * const l3_xmin,
const FLOAT8 xr34_orig[576],
const FLOAT8 xr34 [576],
III_scalefac_t * const vbrsf )
{
int j, sfb, b;
int vbrmean, vbrmin, vbrmax;
int sf_cache[SBMAX_s];
for (j = 0, sfb = 0; sfb < SBMAX_s; sfb++) {
for (b = 0; b < 3; b++) {
const int start = gfc->scalefac_band.s[ sfb ];
const int end = gfc->scalefac_band.s[ sfb+1 ];
const int width = end - start;
if (0 == gfc->noise_shaping_amp) {
/* the faster and sloppier mode to use at lower quality
*/
vbrsf->s[sfb][b] = find_scalefac (&xr34[j], &xr34_orig[j], sfb,
l3_xmin->s[sfb][b], width);
}
else {
/* the slower and better mode to use at higher quality
*/
vbrsf->s[sfb][b] = find_scalefac_ave (&xr34[j], &xr34_orig[j],
sfb, l3_xmin->s[sfb][b], width);
}
j += width;
}
}
vbrmax = -10000;
for (b = 0; b < 3; b++) {
/* make working copy, select_kth_int will reorder!
*/
for (sfb = 0; sfb < SBMAX_s; sfb++)
sf_cache[sfb] = vbrsf->s[sfb][b];
/* find median value, take it as mean
*/
vbrmean = select_kth_int (sf_cache, SBMAX_s, (SBMAX_s+1)/2);
/* get min value
*/
vbrmin = 10000;
for (sfb = 0; sfb < SBMAX_s; sfb++) {
if (vbrmin > vbrsf->s[sfb][b])
vbrmin = vbrsf->s[sfb][b];
}
/* patch sfb12
*/
vbrsf->s[SBPSY_s][b] = Min (vbrsf->s[SBPSY_s][b], vbrmean);
vbrsf->s[SBPSY_s][b] = Max (vbrsf->s[SBPSY_s][b], vbrmin-(vbrmean-vbrmin));
/* cut peaks
*/
for (sfb = 0; sfb < SBMAX_s; sfb++) {
if (vbrsf->s[sfb][b] > vbrmean+(vbrmean-vbrmin))
vbrsf->s[sfb][b] = vbrmean+(vbrmean-vbrmin);
}
/* get max value
*/
for (sfb = 0; sfb < SBMAX_s; sfb++) {
if (vbrmax < vbrsf->s[sfb][b])
vbrmax = vbrsf->s[sfb][b];
}
}
return vbrmax;
}
/* a variation for vbr-mtrh */
static int
long_block_sf (
const lame_internal_flags * const gfc,
const III_psy_xmin * const l3_xmin,
const FLOAT8 xr34_orig[576],
const FLOAT8 xr34 [576],
III_scalefac_t * const vbrsf )
{
int sfb;
int vbrmean, vbrmin, vbrmax;
int sf_cache[SBMAX_l];
for (sfb = 0; sfb < SBMAX_l; sfb++) {
const int start = gfc->scalefac_band.l[ sfb ];
const int end = gfc->scalefac_band.l[ sfb+1 ];
const int width = end - start;
if (0 == gfc->noise_shaping_amp) {
/* the faster and sloppier mode to use at lower quality
*/
vbrsf->l[sfb] = find_scalefac (&xr34[start], &xr34_orig[start],
sfb, l3_xmin->l[sfb], width);
}
else {
/* the slower and better mode to use at higher quality
*/
vbrsf->l[sfb] = find_scalefac_ave (&xr34[start], &xr34_orig[start],
sfb, l3_xmin->l[sfb], width);
}
}
/* make working copy, select_kth_int will reorder!
*/
for (sfb = 0; sfb < SBMAX_l; sfb++)
sf_cache[sfb] = vbrsf->l[sfb];
/* find median value, take it as mean
*/
vbrmean = select_kth_int (sf_cache, SBMAX_l, (SBMAX_l+1)/2);
/* get min value
*/
vbrmin = +10000;
for (sfb = 0; sfb < SBMAX_l; sfb++) {
if (vbrmin > vbrsf->l[sfb])
vbrmin = vbrsf->l[sfb];
}
/* patch sfb21
*/
vbrsf->l[SBPSY_l] = Min (vbrsf->l[SBPSY_l], vbrmean);
vbrsf->l[SBPSY_l] = Max (vbrsf->l[SBPSY_l], vbrmin-(vbrmean-vbrmin));
/* cut peaks
*/
for (sfb = 0; sfb < SBMAX_l; sfb++) {
if (vbrsf->l[sfb] > vbrmean+(vbrmean-vbrmin))
vbrsf->l[sfb] = vbrmean+(vbrmean-vbrmin);
}
/* get max value
*/
vbrmax = -10000;
for (sfb = 0; sfb < SBMAX_l; sfb++) {
if (vbrmax < vbrsf->l[sfb])
vbrmax = vbrsf->l[sfb];
}
return vbrmax;
}
/******************************************************************
*
* short block scalefacs
*
******************************************************************/
static void
short_block_scalefacs (
lame_global_flags *gfp,
gr_info * const cod_info,
III_scalefac_t * const scalefac,
III_scalefac_t * const vbrsf,
int * const VBRmax )
{
lame_internal_flags *gfc=gfp->internal_flags;
const int * max_range;
int sfb, b;
int maxover, maxover0, maxover1, mover;
int v0, v1;
int minsfb;
int vbrmax = *VBRmax;
max_range = gfc->is_mpeg1 ? max_range_short : max_range_short_lsf;
maxover0 = 0;
maxover1 = 0;
for (sfb = 0; sfb < SBPSY_s; sfb++) {
for (b = 0; b < 3; b++) {
v0 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 2*max_range[sfb]);
v1 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 4*max_range[sfb]);
if (maxover0 < v0)
maxover0 = v0;
if (maxover1 < v1)
maxover1 = v1;
}
}
if (gfc->noise_shaping == 2)
/* allow scalefac_scale=1 */
mover = Min (maxover0, maxover1);
else
mover = maxover0;
vbrmax -= mover;
maxover0 -= mover;
maxover1 -= mover;
if (maxover0 == 0)
cod_info->scalefac_scale = 0;
else if (maxover1 == 0)
cod_info->scalefac_scale = 1;
/* sf = (cod_info->global_gain-210.0) */
cod_info->global_gain = vbrmax + 210;
assert(cod_info->global_gain < 256);
if (vbr_mtrh == gfp->VBR && cod_info->global_gain > 1) {
/* just to be safe, reduce global_gain by one
*/
cod_info->global_gain -= 1;
}
if (cod_info->global_gain > 255)
cod_info->global_gain = 255;
for (sfb = 0; sfb < SBPSY_s; sfb++) {
for (b = 0; b < 3; b++) {
vbrsf->s[sfb][b] -= vbrmax;
}
}
if ( gfc->is_mpeg1 )
maxover = compute_scalefacs_short (vbrsf->s, cod_info, scalefac->s,
cod_info->subblock_gain);
else
maxover = compute_scalefacs_short_lsf (vbrsf->s, cod_info, scalefac->s,
cod_info->subblock_gain);
assert (maxover <= 0);
/* adjust global_gain so at least 1 subblock gain = 0 */
minsfb = 999; /* prepare for minimum search */
for (b = 0; b < 3; b++)
if (minsfb > cod_info->subblock_gain[b])
minsfb = cod_info->subblock_gain[b];
if (minsfb > cod_info->global_gain/8)
minsfb = cod_info->global_gain/8;
vbrmax -= 8*minsfb;
cod_info->global_gain -= 8*minsfb;
for (b = 0; b < 3; b++)
cod_info->subblock_gain[b] -= minsfb;
*VBRmax = vbrmax;
}
/******************************************************************
*
* long block scalefacs
*
******************************************************************/
static void
long_block_scalefacs (
lame_global_flags *gfp,
gr_info * const cod_info,
III_scalefac_t * const scalefac,
III_scalefac_t * const vbrsf,
int * const VBRmax )
{
lame_internal_flags *gfc=gfp->internal_flags;
const int * max_range;
const int * max_rangep;
int sfb;
int maxover, maxover0, maxover1, maxover0p, maxover1p, mover;
int v0, v1, v0p, v1p;
int vbrmax = *VBRmax;
max_range = gfc->is_mpeg1 ? max_range_long : max_range_long_lsf;
max_rangep = gfc->is_mpeg1 ? max_range_long : max_range_long_lsf_pretab;
maxover0 = 0;
maxover1 = 0;
maxover0p = 0; /* pretab */
maxover1p = 0; /* pretab */
for ( sfb = 0; sfb < SBPSY_l; sfb++ ) {
v0 = (vbrmax - vbrsf->l[sfb]) - 2*max_range[sfb];
v1 = (vbrmax - vbrsf->l[sfb]) - 4*max_range[sfb];
v0p = (vbrmax - vbrsf->l[sfb]) - 2*(max_rangep[sfb]+pretab[sfb]);
v1p = (vbrmax - vbrsf->l[sfb]) - 4*(max_rangep[sfb]+pretab[sfb]);
if (maxover0 < v0)
maxover0 = v0;
if (maxover1 < v1)
maxover1 = v1;
if (maxover0p < v0p)
maxover0p = v0p;
if (maxover1p < v1p)
maxover1p = v1p;
}
mover = Min (maxover0, maxover0p);
if (gfc->noise_shaping == 2) {
/* allow scalefac_scale=1 */
mover = Min (mover, maxover1);
mover = Min (mover, maxover1p);
}
vbrmax -= mover;
maxover0 -= mover;
maxover0p -= mover;
maxover1 -= mover;
maxover1p -= mover;
if (maxover0 <= 0) {
cod_info->scalefac_scale = 0;
cod_info->preflag = 0;
vbrmax -= maxover0;
} else if (maxover0p <= 0) {
cod_info->scalefac_scale = 0;
cod_info->preflag = 1;
vbrmax -= maxover0p;
} else if (maxover1 == 0) {
cod_info->scalefac_scale = 1;
cod_info->preflag = 0;
} else if (maxover1p == 0) {
cod_info->scalefac_scale = 1;
cod_info->preflag = 1;
} else {
assert(0); /* this should not happen */
}
/* sf = (cod_info->global_gain-210.0) */
cod_info->global_gain = vbrmax + 210;
assert (cod_info->global_gain < 256);
if (vbr_mtrh == gfp->VBR && cod_info->global_gain > 1) {
/* just to be safe, reduce global gain by one
*/
cod_info->global_gain -= 1;
}
if (cod_info->global_gain > 255)
cod_info->global_gain = 255;
for (sfb = 0; sfb < SBPSY_l; sfb++)
vbrsf->l[sfb] -= vbrmax;
if ( gfc->is_mpeg1 == 1 )
maxover = compute_scalefacs_long (vbrsf->l, cod_info, scalefac->l);
else
maxover = compute_scalefacs_long_lsf (vbrsf->l, cod_info, scalefac->l);
assert (maxover <= 0);
*VBRmax = vbrmax;
}
/***********************************************************************
*
* calc_fac()
*
* Mark Taylor 2000-??-??
* Robert Hegemann 2000-10-20 made functions of it
*
***********************************************************************/
static FLOAT8 calc_fac ( const int ifac )
{
if (ifac+210 < Q_MAX)
return 1/IPOW20 (ifac+210);
else
return pow (2.0, 0.75*ifac/4.0);
}
/***********************************************************************
*
* quantize xr34 based on scalefactors
*
* calc_short_block_xr34
* calc_long_block_xr34
*
* Mark Taylor 2000-??-??
* Robert Hegemann 2000-10-20 made functions of them
*
***********************************************************************/
static void
short_block_xr34 (
const lame_internal_flags * const gfc,
const gr_info * const cod_info,
const III_scalefac_t * const scalefac,
const FLOAT8 xr34_orig[576],
FLOAT8 xr34 [576] )
{
int sfb, l, j, b;
int ifac, ifqstep, start, end;
FLOAT8 fac;
/* even though there is no scalefactor for sfb12
* subblock gain affects upper frequencies too, that's why
* we have to go up to SBMAX_s
*/
ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
for ( j = 0, sfb = 0; sfb < SBMAX_s; sfb++ ) {
start = gfc->scalefac_band.s[ sfb ];
end = gfc->scalefac_band.s[ sfb+1 ];
for (b = 0; b < 3; b++) {
ifac = 8*cod_info->subblock_gain[b]+ifqstep*scalefac->s[sfb][b];
fac = calc_fac( ifac );
/*
* loop unrolled into "Duff's Device". Robert Hegemann
*/
l = (end-start+7) / 8;
switch ((end-start) % 8) {
default:
case 0: do{ xr34[j] = xr34_orig[j]*fac; j++;
case 7: xr34[j] = xr34_orig[j]*fac; j++;
case 6: xr34[j] = xr34_orig[j]*fac; j++;
case 5: xr34[j] = xr34_orig[j]*fac; j++;
case 4: xr34[j] = xr34_orig[j]*fac; j++;
case 3: xr34[j] = xr34_orig[j]*fac; j++;
case 2: xr34[j] = xr34_orig[j]*fac; j++;
case 1: xr34[j] = xr34_orig[j]*fac; j++; } while (--l);
}
}
}
}
static void
long_block_xr34 (
const lame_internal_flags * const gfc,
const gr_info * const cod_info,
const III_scalefac_t * const scalefac,
const FLOAT8 xr34_orig[576],
FLOAT8 xr34 [576] )
{
int sfb, l, j;
int ifac, ifqstep, start, end;
FLOAT8 fac;
ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
for ( sfb = 0; sfb < SBMAX_l; sfb++ ) {
ifac = ifqstep*scalefac->l[sfb];
if (cod_info->preflag)
ifac += ifqstep*pretab[sfb];
fac = calc_fac( ifac );
start = gfc->scalefac_band.l[ sfb ];
end = gfc->scalefac_band.l[ sfb+1 ];
/*
* loop unrolled into "Duff's Device". Robert Hegemann
*/
j = start;
l = (end-start+7) / 8;
switch ((end-start) % 8) {
default:
case 0: do{ xr34[j] = xr34_orig[j]*fac; j++;
case 7: xr34[j] = xr34_orig[j]*fac; j++;
case 6: xr34[j] = xr34_orig[j]*fac; j++;
case 5: xr34[j] = xr34_orig[j]*fac; j++;
case 4: xr34[j] = xr34_orig[j]*fac; j++;
case 3: xr34[j] = xr34_orig[j]*fac; j++;
case 2: xr34[j] = xr34_orig[j]*fac; j++;
case 1: xr34[j] = xr34_orig[j]*fac; j++; } while (--l);
}
}
}
/************************************************************************
*
* VBR_noise_shaping()
*
* compute scalefactors, l3_enc, and return number of bits needed to encode
*
* return code: 0 scalefactors were found with all noise < masking
*
* n>0 scalefactors required too many bits. global gain
* was decreased by n
* If n is large, we should probably recompute scalefacs
* with a lower quality.
*
* n<0 scalefactors used less than minbits.
* global gain was increased by n.
* If n is large, might want to recompute scalefacs
* with a higher quality setting?
*
************************************************************************/
static int
VBR_noise_shaping (
lame_global_flags *gfp,
FLOAT8 xr [576],
FLOAT8 xr34orig [576],
III_psy_ratio *ratio,
int l3_enc [576],
int digital_silence,
int minbits,
int maxbits,
III_scalefac_t *scalefac,
III_psy_xmin *l3_xmin,
int gr,
int ch )
{
lame_internal_flags *gfc=gfp->internal_flags;
III_scalefac_t save_sf;
III_scalefac_t vbrsf;
gr_info *cod_info;
FLOAT8 xr34[576];
int shortblock;
int vbrmax;
int global_gain_adjust = 0;
cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
shortblock = (cod_info->block_type == SHORT_TYPE);
if (shortblock)
vbrmax = short_block_vbr_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf);
else
vbrmax = long_block_vbr_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf);
/* save a copy of vbrsf, incase we have to recomptue scalefacs */
memcpy (&save_sf, &vbrsf, sizeof(III_scalefac_t));
do {
memset (scalefac, 0, sizeof(III_scalefac_t));
if (shortblock) {
short_block_scalefacs (gfp, cod_info, scalefac, &vbrsf, &vbrmax);
short_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34);
} else {
long_block_scalefacs (gfp, cod_info, scalefac, &vbrsf, &vbrmax);
long_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34);
}
VBR_quantize_granule (gfp, xr34, l3_enc, ratio, scalefac, gr, ch);
/* decrease noise until we use at least minbits
*/
if (cod_info->part2_3_length < minbits) {
if (digital_silence) break;
//if (cod_info->part2_3_length == cod_info->part2_length) break;
if (vbrmax+210 == 0) break;
/* decrease global gain, recompute scale factors */
--vbrmax;
--global_gain_adjust;
memcpy (&vbrsf, &save_sf, sizeof(III_scalefac_t));
}
} while (cod_info->part2_3_length < minbits);
/* inject noise until we meet our bit limit
*/
while (cod_info->part2_3_length > Min (maxbits, MAX_BITS)) {
/* increase global gain, keep existing scale factors */
++cod_info->global_gain;
if (cod_info->global_gain > 255)
ERRORF (gfc,"%ld impossible to encode ??? frame! bits=%d\n",
// gfp->frameNum, cod_info->part2_3_length);
-1, cod_info->part2_3_length);
VBR_quantize_granule (gfp, xr34, l3_enc, ratio, scalefac, gr, ch);
++global_gain_adjust;
}
return global_gain_adjust;
}
/************************************************************************
*
* VBR_noise_shaping2()
*
* may result in a need of too many bits, then do it CBR like
*
* Robert Hegemann 2000-10-25
*
***********************************************************************/
int
VBR_noise_shaping2 (
lame_global_flags *gfp,
FLOAT8 xr [576],
FLOAT8 xr34orig [576],
III_psy_ratio * const ratio,
int l3_enc [576],
int digital_silence,
int minbits,
int maxbits,
III_scalefac_t * const scalefac,
III_psy_xmin * const l3_xmin,
int gr,
int ch )
{
lame_internal_flags *gfc=gfp->internal_flags;
III_scalefac_t vbrsf;
gr_info *cod_info;
FLOAT8 xr34[576];
int shortblock, ret, bits, huffbits;
int vbrmax, best_huffman = gfc->use_best_huffman;
cod_info = &gfc->l3_side.gr[gr].ch[ch].tt;
shortblock = (cod_info->block_type == SHORT_TYPE);
if (shortblock) {
vbrmax = short_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf);
short_block_scalefacs (gfp, cod_info, scalefac, &vbrsf, &vbrmax);
short_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34);
} else {
vbrmax = long_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf);
long_block_scalefacs (gfp, cod_info, scalefac, &vbrsf, &vbrmax);
long_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34);
}
gfc->use_best_huffman = 0; /* we will do it later */
ret = VBR_quantize_granule (gfp, xr34, l3_enc, ratio, scalefac, gr, ch);
gfc->use_best_huffman = best_huffman;
if (ret == -1) /* Houston, we have a problem */
return -1;
if (cod_info->part2_3_length < minbits) {
huffbits = minbits - cod_info->part2_length;
bits = bin_search_StepSize (gfc, cod_info, huffbits,
gfc->OldValue[ch], xr34, l3_enc);
gfc->OldValue[ch] = cod_info->global_gain;
cod_info->part2_3_length = bits + cod_info->part2_length;
}
if (cod_info->part2_3_length > maxbits) {
huffbits = maxbits - cod_info->part2_length;
bits = bin_search_StepSize (gfc, cod_info, huffbits,
gfc->OldValue[ch], xr34, l3_enc);
gfc->OldValue[ch] = cod_info->global_gain;
cod_info->part2_3_length = bits;
if (bits > huffbits) {
bits = inner_loop (gfc, cod_info, huffbits, xr34, l3_enc);
cod_info->part2_3_length = bits;
}
if (bits >= LARGE_BITS) /* Houston, we have a problem */
return -2;
cod_info->part2_3_length += cod_info->part2_length;
}
if (cod_info->part2_length >= LARGE_BITS) /* Houston, we have a problem */
return -2;
assert (cod_info->global_gain < 256);
return 0;
}
void
VBR_quantize(lame_global_flags *gfp,
FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2],
FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2],
int l3_enc[2][2][576],
III_scalefac_t scalefac[2][2])
{
lame_internal_flags *gfc=gfp->internal_flags;
III_psy_xmin l3_xmin[2][2];
int minbits,maxbits,max_frame_bits,totbits,gr,ch,i,bits_ok;
int bitsPerFrame,mean_bits;
int analog_silence;
FLOAT8 qadjust;
III_side_info_t * l3_side;
gr_info *cod_info;
int digital_silence[2][2];
FLOAT8 masking_lower_db=0;
FLOAT8 xr34[2][2][576];
// static const FLOAT8 dbQ[10]={-6.0,-5.0,-4.0,-3.0, -2.0, -1.0, -.25, .5, 1.25, 2.0};
/* from quantize.c VBR algorithm */
/*static const FLOAT8 dbQ[10]=
{-5.5,-4.25,-3.0,-2.50, -1.75, -.75, -.5, -.25, .25, .75};*/
/* a third dbQ table ?!? */
static const FLOAT8 dbQ[10]=
{-6.06,-4.4,-2.9,-1.57, -0.4, 0.61, 1.45, 2.13, 2.65, 3.0};
qadjust=0; /* start with -1 db quality improvement over quantize.c VBR */
l3_side = &gfc->l3_side;
//gfc->ATHlower += (4-gfp->VBR_q)*4.0;
//if (gfc->ATHlower < 0) gfc->ATHlower=0;
/* now find out: if the frame can be considered analog silent
* if each granule can be considered digital silent
* and calculate l3_xmin and the fresh xr34 array
*/
assert( gfp->VBR_q <= 9 );
assert( gfp->VBR_q >= 0 );
analog_silence=1;
for (gr = 0; gr < gfc->mode_gr; gr++) {
/* copy data to be quantized into xr */
if (gfc->mode_ext==MPG_MD_MS_LR) {
ms_convert(xr[gr],xr[gr]);
}
for (ch = 0; ch < gfc->channels_out; ch++) {
/* if in the following sections the quality would not be adjusted
* then we would only have to call calc_xmin once here and
* could drop subsequently calls (rh 2000/07/17)
*/
int over_ath;
cod_info = &l3_side->gr[gr].ch[ch].tt;
cod_info->part2_3_length=LARGE_BITS;
if (cod_info->block_type == SHORT_TYPE) {
cod_info->sfb_lmax = 0; /* No sb*/
cod_info->sfb_smin = 0;
} else {
/* MPEG 1 doesnt use last scalefactor band */
cod_info->sfb_lmax = SBPSY_l;
cod_info->sfb_smin = SBPSY_s; /* No sb */
if (cod_info->mixed_block_flag) {
cod_info->sfb_lmax = 8;
cod_info->sfb_smin = 3;
}
}
/* quality setting */
masking_lower_db = dbQ[gfp->VBR_q];
if (pe[gr][ch]>750) {
masking_lower_db -= Min(10,4*(pe[gr][ch]-750.)/750.);
}
gfc->masking_lower = pow(10.0,masking_lower_db/10);
/* masking thresholds */
over_ath = calc_xmin(gfp,xr[gr][ch],&ratio[gr][ch],cod_info,&l3_xmin[gr][ch]);
/* if there are bands with more energy than the ATH
* then we say the frame is not analog silent */
if (over_ath) {
analog_silence = 0;
}
/* if there is no line with more energy than 1e-20
* then this granule is considered to be digital silent
* plus calculation of xr34 */
digital_silence[gr][ch] = 1;
for(i=0;i<576;i++) {
FLOAT8 temp=fabs(xr[gr][ch][i]);
xr34[gr][ch][i]=sqrt(sqrt(temp)*temp);
digital_silence[gr][ch] &= temp < 1E-20;
}
} /* ch */
} /* gr */
/* compute minimum allowed bits from minimum allowed bitrate */
if (analog_silence) {
gfc->bitrate_index=1;
} else {
gfc->bitrate_index=gfc->VBR_min_bitrate;
}
getframebits(gfp, &bitsPerFrame, &mean_bits);
minbits = (mean_bits/gfc->channels_out);
/* compute maximum allowed bits from max allowed bitrate */
gfc->bitrate_index=gfc->VBR_max_bitrate;
getframebits(gfp, &bitsPerFrame, &mean_bits);
max_frame_bits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
maxbits=2.5*(mean_bits/gfc->channels_out);
{
/* compute a target mean_bits based on compression ratio
* which was set based on VBR_q
*/
int bit_rate = gfp->out_samplerate*16*gfc->channels_out/(1000.0*gfp->compression_ratio);
bitsPerFrame = (bit_rate*gfp->framesize*1000)/gfp->out_samplerate;
mean_bits = (bitsPerFrame - 8*gfc->sideinfo_len) / gfc->mode_gr;
}
minbits = Max(minbits,125);
minbits=Max(minbits,.40*(mean_bits/gfc->channels_out));
maxbits=Min(maxbits,2.5*(mean_bits/gfc->channels_out));
/*
* loop over all ch,gr, encoding anything with bits > .5*(max_frame_bits/4)
*
* If a particular granule uses way too many bits, it will be re-encoded
* on the next iteration of the loop (with a lower quality setting).
* But granules which dont use
* use too many bits will not be re-encoded.
*
* minbits: minimum allowed bits for 1 granule 1 channel
* maxbits: maximum allowwed bits for 1 granule 1 channel
* max_frame_bits: maximum allowed bits for entire frame
* (max_frame_bits/4) estimate of average bits per granule per channel
*
*/
do {
totbits=0;
for (gr = 0; gr < gfc->mode_gr; gr++) {
int minbits_lr[2];
minbits_lr[0]=minbits;
minbits_lr[1]=minbits;
#if 0
if (gfc->mode_ext==MPG_MD_MS_LR) {
FLOAT8 fac;
fac = .33*(.5-ms_ener_ratio[gr])/.5;
if (fac<0) fac=0;
if (fac>.5) fac=.5;
minbits_lr[0] = (1+fac)*minbits;
minbits_lr[1] = Max(125,(1-fac)*minbits);
}
#endif
for (ch = 0; ch < gfc->channels_out; ch++) {
int adjusted,shortblock;
cod_info = &l3_side->gr[gr].ch[ch].tt;
/* ENCODE this data first pass, and on future passes unless it uses
* a very small percentage of the max_frame_bits */
if (cod_info->part2_3_length > (max_frame_bits/(2*gfc->channels_out*gfc->mode_gr))) {
shortblock = (cod_info->block_type == SHORT_TYPE);
/* Adjust allowed masking based on quality setting */
if (qadjust!=0 /*|| shortblock*/) {
masking_lower_db = dbQ[gfp->VBR_q] + qadjust;
/*
if (shortblock) masking_lower_db -= 4;
*/
if (pe[gr][ch]>750)
masking_lower_db -= Min(10,4*(pe[gr][ch]-750.)/750.);
gfc->masking_lower = pow(10.0,masking_lower_db/10);
calc_xmin( gfp, xr[gr][ch], ratio[gr]+ch, cod_info, l3_xmin[gr]+ch);
}
/* digital silent granules do not need the full round trip,
* but this can be optimized later on
*/
adjusted = VBR_noise_shaping (gfp,xr[gr][ch],xr34[gr][ch],
ratio[gr]+ch,l3_enc[gr][ch],
digital_silence[gr][ch],
minbits_lr[ch],
maxbits,scalefac[gr]+ch,
l3_xmin[gr]+ch,gr,ch);
if (adjusted>10) {
/* global_gain was changed by a large amount to get bits < maxbits */
/* quality is set to high. we could set bits = LARGE_BITS
* to force re-encoding. But most likely the other channels/granules
* will also use too many bits, and the entire frame will
* be > max_frame_bits, forcing re-encoding below.
*/
// cod_info->part2_3_bits = LARGE_BITS;
}
}
totbits += cod_info->part2_3_length;
}
}
bits_ok=1;
if (totbits>max_frame_bits) {
/* lower quality */
qadjust += Max(.125,Min(1,(totbits-max_frame_bits)/300.0));
/* adjusting minbits and maxbits is necessary too
* cos lowering quality is not enough in rare cases
* when each granule still needs almost maxbits, it wont fit */
minbits = Max(125,minbits*0.975);
maxbits = Max(minbits,maxbits*0.975);
// DEBUGF("%i totbits>max_frame_bits totbits=%i maxbits=%i \n",gfp->frameNum,totbits,max_frame_bits);
// DEBUGF("next masking_lower_db = %f \n",masking_lower_db + qadjust);
bits_ok=0;
}
} while (!bits_ok);
/* find optimal scalefac storage. Cant be done above because
* might enable scfsi which breaks the interation loops */
totbits=0;
for (gr = 0; gr < gfc->mode_gr; gr++) {
for (ch = 0; ch < gfc->channels_out; ch++) {
best_scalefac_store(gfc, gr, ch, l3_enc, l3_side, scalefac);
totbits += l3_side->gr[gr].ch[ch].tt.part2_3_length;
}
}
if (analog_silence && !gfp->VBR_hard_min) {
gfc->bitrate_index = 1;
} else {
gfc->bitrate_index = gfc->VBR_min_bitrate;
}
for( ; gfc->bitrate_index < gfc->VBR_max_bitrate; gfc->bitrate_index++ ) {
getframebits (gfp, &bitsPerFrame, &mean_bits);
maxbits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
if (totbits <= maxbits) break;
}
if (gfc->bitrate_index == gfc->VBR_max_bitrate) {
getframebits (gfp, &bitsPerFrame, &mean_bits);
maxbits = ResvFrameBegin(gfp, l3_side, mean_bits, bitsPerFrame);
}
// DEBUGF("%i total_bits=%i max_frame_bits=%i index=%i \n",gfp->frameNum,totbits,max_frame_bits,gfc->bitrate_index);
for (gr = 0; gr < gfc->mode_gr; gr++) {
for (ch = 0; ch < gfc->channels_out; ch++) {
cod_info = &l3_side->gr[gr].ch[ch].tt;
ResvAdjust (gfc, cod_info, l3_side, mean_bits);
/*******************************************************************
* set the sign of l3_enc from the sign of xr
*******************************************************************/
for ( i = 0; i < 576; i++) {
if (xr[gr][ch][i] < 0) l3_enc[gr][ch][i] *= -1;
}
}
}
ResvFrameEnd (gfc, l3_side, mean_bits);
}
|