X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Flame%2Fvbrquantize.c;fp=lib%2Flame%2Fvbrquantize.c;h=8d96ab894dc45d5f6330fd9013ed5ea8e0673c69;hb=698acf324aaa52147b1486646f6549ffd95804da;hp=0000000000000000000000000000000000000000;hpb=f8d07c79494e8536e682da73cee2057740a0e4db;p=swftools.git diff --git a/lib/lame/vbrquantize.c b/lib/lame/vbrquantize.c new file mode 100644 index 0000000..8d96ab8 --- /dev/null +++ b/lib/lame/vbrquantize.c @@ -0,0 +1,1769 @@ +/* + * 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.1 2002/04/28 17:30:30 kramm Exp $ */ + +#include "config_static.h" + +#include +#include "util.h" +#include "l3side.h" +#include "reservoir.h" +#include "quantize_pvt.h" +#include "vbrquantize.h" + +#ifdef WITH_DMALLOC +#include +#endif + + + +typedef union { + float f; + int i; +} fi_union; + +#define MAGIC_FLOAT (65536*(128)) +#define MAGIC_INT 0x4b000000 + +#ifdef TAKEHIRO_IEEE754_HACK + +#define DUFFBLOCKMQ() 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) + +#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) + +#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 + +/* caution: a[] will be resorted!! + */ +FLOAT8 select_kth(FLOAT8 a[], int N, int k) +{ + int i, j, l, r; + FLOAT8 v, w; + + l = 0; + r = N-1; + while (r > l) { + v = a[r]; + i = l-1; + j = r; + for (;;) { + while (a[++i] < v) /*empty*/; + while (a[--j] > v) /*empty*/; + if (i >= j) + break; + /* swap i and j */ + w = a[i]; + a[i] = a[j]; + a[j] = w; + } + /* swap i and r */ + w = a[i]; + a[i] = a[r]; + a[r] = w; + if (i >= k) + r = i-1; + if (i <= k) + l = i+1; + } + return a[k]; +} + + + + +static FLOAT8 +calc_sfb_noise(const FLOAT8 *xr, const FLOAT8 *xr34, int bw, 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 ( 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; + xfsf += temp*temp; + } + return xfsf; +} + + + + +static FLOAT8 +calc_sfb_noise_mq( const FLOAT8 *xr, const FLOAT8 *xr34, int bw, int sf, + int mq, FLOAT8 *scratch ) +{ + int j, k; + fi_union fi; + FLOAT8 temp; + FLOAT8 sfpow, sfpow34, xfsfm = 0, xfsf = 0; + + 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 ( 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; + + scratch[j] = temp; + if ( xfsfm < temp ) xfsfm = temp; + xfsf += temp; + } + if ( mq == 1 ) return bw*select_kth(scratch,bw,bw*13/16); + + xfsf /= bw; + for ( k = 1, j = 0; j < bw; ++j ) { + if ( scratch[j] > xfsf ) { + xfsfm += scratch[j]; + ++k; + } + } + return xfsfm/k * bw; +} + + + + +static FLOAT8 +calc_sfb_noise_ave(const FLOAT8 *xr, const FLOAT8 *xr34, int bw, 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; + + xfsf_eq += xe; + xfsf_p1 += xp; + xfsf_m1 += xm; + } +#endif + + if ( xfsf_eq < xfsf_p1 ) xfsf_eq = xfsf_p1; + if ( xfsf_eq < xfsf_m1 ) xfsf_eq = xfsf_m1; + return xfsf_eq; +} + + + +INLINE int +find_scalefac( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, 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 (xfsf > l3_xmin) { + /* distortion. try a smaller scalefactor */ + sf -= delsf; + } + else { + sf_ok = sf; + sf += delsf; + } + } + } + + /* returning a scalefac without distortion, if possible + */ + return sf_ok > 45 ? sf : sf_ok; +} + +INLINE int +find_scalefac_mq( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, + int bw, int mq, FLOAT8 *scratch ) +{ + 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_mq( xr, xr34, bw, sf, mq, scratch ); + + if (xfsf < 0) { + /* scalefactors too small */ + sf += delsf; + } + else { + if (xfsf > l3_xmin) { + /* distortion. try a smaller scalefactor */ + sf -= delsf; + } + else { + sf_ok = sf; + sf += delsf; + } + } + } + + /* returning a scalefac without distortion, if possible + */ + return sf_ok > 45 ? sf : sf_ok; +} + +INLINE int +find_scalefac_ave( const FLOAT8 *xr, const FLOAT8 *xr34, FLOAT8 l3_xmin, 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 (xfsf > l3_xmin) { + /* distortion. try a smaller scalefactor */ + sf -= delsf; + } + else { + sf_ok = sf; + sf += delsf; + } + } + } + + /* returning a scalefac without distortion, if possible + */ + return sf_ok > 45 ? sf : sf_ok; +} + + +/** + * Robert Hegemann 2001-05-01 + * calculates quantization step size determined by allowed masking + */ +INLINE int +calc_scalefac( FLOAT8 l3_xmin, int bw, FLOAT8 preset_tune ) +{ + FLOAT8 const c = (preset_tune > 0 ? preset_tune + : 5.799142446); // 10 * 10^(2/3) * log10(4/3) + return (int)(c*log10(l3_xmin/bw)-.5); +} + + + +static const int max_range_short[SBMAX_s] = +{15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 0 }; + +static const int max_range_long[SBMAX_l] = +{15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0}; + +static const int max_range_long_lsf_pretab[SBMAX_l] = +{ 7,7,7,7,7,7, 3,3,3,3,3, 0,0,0,0, 0,0,0, 0,0,0, 0 }; + + + +/* + 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]; + +*/ +INLINE int +compute_scalefacs_short( + int sf[][3], const gr_info *cod_info, int scalefac[][3], int *sbg ) +{ + const int maxrange1 = 15, maxrange2 = 7; + int maxrange, maxover = 0; + int sfb, i; + int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; + + for (i = 0; i < 3; ++i) { + int maxsf1 = 0, maxsf2 = 0, minsf = 1000; + /* see if we should use subblock gain */ + for (sfb = 0; sfb < 6; ++sfb) { /* part 1 */ + if (maxsf1 < -sf[sfb][i]) maxsf1 = -sf[sfb][i]; + if (minsf > -sf[sfb][i]) minsf = -sf[sfb][i]; + } + for (; sfb < SBPSY_s; ++sfb) { /* part 2 */ + 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); + } + } + scalefac[sfb][i] = 0; + } + + 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]; +*/ +INLINE int +compute_scalefacs_long_lsf( int *sf, const gr_info * cod_info, int *scalefac ) +{ + const int * max_range = max_range_long; + 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); + } + } + } + scalefac[sfb] = 0; /* sfb21 */ + + 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]; +*/ +INLINE int +compute_scalefacs_long( int *sf, const gr_info * cod_info, int *scalefac ) +{ + int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; + int sfb; + int maxover; + + 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); + } + } + } + scalefac[sfb] = 0; /* sfb21 */ + + 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_internal_flags * gfc, + FLOAT8 * xr34, + int * l3_enc, + III_scalefac_t * scalefac, + int gr, int ch ) +{ + int status; + III_side_info_t * l3_side = & gfc->l3_side; + gr_info * 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, 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 void +short_block_sf ( + const lame_internal_flags * gfc, + const III_psy_xmin * l3_xmin, + const FLOAT8 * xr34_orig, + const FLOAT8 * xr34, + III_scalefac_t * vbrsf, + int * vbrmin, + int * vbrmax ) +{ + int j, sfb, b; + int vbrmean, vbrmn; + int sf_cache[SBMAX_s]; + int scalefac_criteria; + + if (gfc->presetTune.use) { + /* map experimentalX settings to internal selections */ + static char const map[] = {2,1,0,3,6}; + scalefac_criteria = map[gfc->presetTune.quantcomp_current]; + } + else { + scalefac_criteria = gfc->VBR->quality; + } + + 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; + + switch( scalefac_criteria ) { + default: + /* the fastest + */ + vbrsf->s[sfb][b] = calc_scalefac( l3_xmin->s[sfb][b], width, + gfc->presetTune.quantcomp_adjust_mtrh ); + break; + case 5: + case 4: + case 3: + /* the faster and sloppier mode to use at lower quality + */ + vbrsf->s[sfb][b] = find_scalefac (&xr34[j], &xr34_orig[j], + l3_xmin->s[sfb][b], width); + break; + case 2: + /* the slower and better mode to use at higher quality + */ + vbrsf->s[sfb][b] = find_scalefac_ave (&xr34[j], &xr34_orig[j], + l3_xmin->s[sfb][b], width); + break; + case 1: + /* maxnoise mode to use at higher quality + */ + vbrsf->s[sfb][b] = find_scalefac_mq (&xr34[j], &xr34_orig[j], + l3_xmin->s[sfb][b], width, + 1, gfc->VBR->scratch); + break; + case 0: + /* maxnoise mode to use at higher quality + */ + vbrsf->s[sfb][b] = find_scalefac_mq (&xr34[j], &xr34_orig[j], + l3_xmin->s[sfb][b], width, + 0, gfc->VBR->scratch); + break; + } + j += width; + } + } + + *vbrmax = -10000; + *vbrmin = +10000; + + for (b = 0; b < 3; ++b) { + + /* smoothing + */ + switch( gfc->VBR->smooth ) { + default: + case 0: + break; + + case 1: + /* make working copy, get min value, select_kth_int will reorder! + */ + for (vbrmn = +10000, sfb = 0; sfb < SBMAX_s; ++sfb) { + sf_cache[sfb] = vbrsf->s[sfb][b]; + if (vbrmn > vbrsf->s[sfb][b]) + vbrmn = vbrsf->s[sfb][b]; + } + + /* find median value, take it as mean + */ + vbrmean = select_kth_int (sf_cache, SBMAX_s, (SBMAX_s+1)/2); + + /* cut peaks + */ + for (sfb = 0; sfb < SBMAX_s; ++sfb) { + if (vbrsf->s[sfb][b] > vbrmean+(vbrmean-vbrmn)) + vbrsf->s[sfb][b] = vbrmean+(vbrmean-vbrmn); + } + break; + + case 2: + for (sfb = 0; sfb < SBMAX_s; ++sfb) { + 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; + } + break; + } + + /* get max value + */ + for (sfb = 0; sfb < SBMAX_s; ++sfb) { + if (*vbrmax < vbrsf->s[sfb][b]) + *vbrmax = vbrsf->s[sfb][b]; + if (*vbrmin > vbrsf->s[sfb][b]) + *vbrmin = vbrsf->s[sfb][b]; + } + } +} + + + /* a variation for vbr-mtrh */ +static void +long_block_sf ( + const lame_internal_flags * gfc, + const III_psy_xmin * l3_xmin, + const FLOAT8 * xr34_orig, + const FLOAT8 * xr34, + III_scalefac_t * vbrsf, + int * vbrmin, + int * vbrmax ) +{ + int sfb; + int vbrmean, vbrmn; + int sf_cache[SBMAX_l]; + int scalefac_criteria; + + if (gfc->presetTune.use) { + /* map experimentalX settings to internal selections */ + static char const map[] = {2,1,0,3,6}; + scalefac_criteria = map[gfc->presetTune.quantcomp_current]; + } + else { + scalefac_criteria = gfc->VBR->quality; + } + + 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; + + switch( scalefac_criteria ) { + default: + /* the fastest + */ + vbrsf->l[sfb] = calc_scalefac( l3_xmin->l[sfb], width, + gfc->presetTune.quantcomp_adjust_mtrh ); + break; + case 5: + case 4: + case 3: + /* the faster and sloppier mode to use at lower quality + */ + vbrsf->l[sfb] = find_scalefac (&xr34[start], &xr34_orig[start], + l3_xmin->l[sfb], width); + break; + case 2: + /* the slower and better mode to use at higher quality + */ + vbrsf->l[sfb] = find_scalefac_ave (&xr34[start], &xr34_orig[start], + l3_xmin->l[sfb], width); + break; + case 1: + /* maxnoise mode to use at higher quality + */ + vbrsf->l[sfb] = find_scalefac_mq (&xr34[start], &xr34_orig[start], + l3_xmin->l[sfb], width, + 1, gfc->VBR->scratch); + break; + case 0: + /* maxnoise mode to use at higher quality + */ + vbrsf->l[sfb] = find_scalefac_mq (&xr34[start], &xr34_orig[start], + l3_xmin->l[sfb], width, + 0, gfc->VBR->scratch); + break; + } + } + + switch( gfc->VBR->smooth ) { + default: + case 0: + break; + + case 1: + /* make working copy, get min value, select_kth_int will reorder! + */ + for (vbrmn = +10000, sfb = 0; sfb < SBMAX_l; ++sfb) { + sf_cache[sfb] = vbrsf->l[sfb]; + if (vbrmn > vbrsf->l[sfb]) + vbrmn = vbrsf->l[sfb]; + } + /* find median value, take it as mean + */ + vbrmean = select_kth_int (sf_cache, SBMAX_l, (SBMAX_l+1)/2); + + /* cut peaks + */ + for (sfb = 0; sfb < SBMAX_l; ++sfb) { + if (vbrsf->l[sfb] > vbrmean+(vbrmean-vbrmn)) + vbrsf->l[sfb] = vbrmean+(vbrmean-vbrmn); + } + break; + + case 2: + 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; + } + break; + } + + /* get max value + */ + for (*vbrmin = +10000, *vbrmax = -10000, sfb = 0; sfb < SBMAX_l; ++sfb) { + if (*vbrmax < vbrsf->l[sfb]) + *vbrmax = vbrsf->l[sfb]; + if (*vbrmin > vbrsf->l[sfb]) + *vbrmin = vbrsf->l[sfb]; + } +} + + + +/****************************************************************** + * + * short block scalefacs + * + ******************************************************************/ + +static void +short_block_scalefacs ( + const lame_internal_flags * gfc, + gr_info * cod_info, + III_scalefac_t * scalefac, + III_scalefac_t * vbrsf, + int * VBRmax ) +{ + int sfb, maxsfb, b; + int maxover, maxover0, maxover1, mover; + int v0, v1; + int minsfb; + int vbrmax = *VBRmax; + + maxover0 = 0; + maxover1 = 0; + maxsfb = gfc->sfb21_extra ? SBMAX_s : SBPSY_s; + for (sfb = 0; sfb < maxsfb; ++sfb) { + for (b = 0; b < 3; ++b) { + v0 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 2*max_range_short[sfb]); + v1 = (vbrmax - vbrsf->s[sfb][b]) - (4*14 + 4*max_range_short[sfb]); + if (maxover0 < v0) + maxover0 = v0; + if (maxover1 < v1) + maxover1 = v1; + } + } + + if ((gfc->noise_shaping == 2) && (gfc->presetTune.use && !(gfc->presetTune.athadjust_safe_noiseshaping || gfc->ATH->adjust < 1.0))) + /* 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 (cod_info->global_gain < 0) { + cod_info->global_gain = 0; + } + else + if (cod_info->global_gain > 255) { + cod_info->global_gain = 255; + } + for (sfb = 0; sfb < SBMAX_s; ++sfb) { + for (b = 0; b < 3; ++b) { + vbrsf->s[sfb][b] -= vbrmax; + } + } + maxover = compute_scalefacs_short (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 ( + const lame_internal_flags * gfc, + gr_info * cod_info, + III_scalefac_t * scalefac, + III_scalefac_t * vbrsf, + int * VBRmax ) +{ + const int * max_rangep; + int sfb, maxsfb; + int maxover, maxover0, maxover1, maxover0p, maxover1p, mover; + int v0, v1, v0p, v1p; + int vbrmax = *VBRmax; + + max_rangep = gfc->is_mpeg1 ? max_range_long : max_range_long_lsf_pretab; + + maxover0 = 0; + maxover1 = 0; + maxover0p = 0; /* pretab */ + maxover1p = 0; /* pretab */ + + maxsfb = gfc->sfb21_extra ? SBMAX_l : SBPSY_l; + for ( sfb = 0; sfb < maxsfb; ++sfb ) { + v0 = (vbrmax - vbrsf->l[sfb]) - 2*max_range_long[sfb]; + v1 = (vbrmax - vbrsf->l[sfb]) - 4*max_range_long[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) && (gfc->presetTune.use && !(gfc->presetTune.athadjust_safe_noiseshaping || gfc->ATH->adjust < 1.0))) { + /* 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 (cod_info->global_gain < 0) { + cod_info->global_gain = 0; + } + else + if (cod_info->global_gain > 255) + cod_info->global_gain = 255; + + for (sfb = 0; sfb < SBMAX_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; +} + + + +/*********************************************************************** + * + * 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 * gfc, + const gr_info * cod_info, + const III_scalefac_t * scalefac, + const FLOAT8 * xr34_orig, + FLOAT8 * xr34 ) +{ + 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]; + + if ( ifac == 0 ) { /* just copy */ + l = (end-start+7) / 8; + switch ((end-start) % 8) { + default: + case 0: do{ xr34[j] = xr34_orig[j]; ++j; + case 7: xr34[j] = xr34_orig[j]; ++j; + case 6: xr34[j] = xr34_orig[j]; ++j; + case 5: xr34[j] = xr34_orig[j]; ++j; + case 4: xr34[j] = xr34_orig[j]; ++j; + case 3: xr34[j] = xr34_orig[j]; ++j; + case 2: xr34[j] = xr34_orig[j]; ++j; + case 1: xr34[j] = xr34_orig[j]; ++j; } while (--l); + } + continue; + } + if (ifac < Q_MAX-210) + fac = IIPOW20_(ifac); + else + fac = pow (2.0, 0.1875*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 * gfc, + const gr_info * cod_info, + const III_scalefac_t * scalefac, + const FLOAT8 * xr34_orig, + FLOAT8 * xr34 ) +{ + 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]; + + start = gfc->scalefac_band.l[ sfb ]; + end = gfc->scalefac_band.l[ sfb+1 ]; + + if ( ifac == 0 ) { /* just copy */ + j = start; + l = (end-start+7) / 8; + switch ((end-start) % 8) { + default: + case 0: do{ xr34[j] = xr34_orig[j]; ++j; + case 7: xr34[j] = xr34_orig[j]; ++j; + case 6: xr34[j] = xr34_orig[j]; ++j; + case 5: xr34[j] = xr34_orig[j]; ++j; + case 4: xr34[j] = xr34_orig[j]; ++j; + case 3: xr34[j] = xr34_orig[j]; ++j; + case 2: xr34[j] = xr34_orig[j]; ++j; + case 1: xr34[j] = xr34_orig[j]; ++j; } while (--l); + } + continue; + } + if (ifac < Q_MAX-210) + fac = IIPOW20_(ifac); + else + fac = pow (2.0, 0.1875*ifac); + + /* + * 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_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, + FLOAT8 * xr34orig, + int * l3_enc, + 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 vbrsf; + III_scalefac_t vbrsf2; + gr_info *cod_info; + FLOAT8 xr34[576]; + int shortblock, ret, bits, huffbits; + int vbrmin, vbrmax, vbrmin2, vbrmax2; + int best_huffman = gfc->use_best_huffman; + int count=6; + + gfc->use_best_huffman = 0; /* we will do it later */ + + cod_info = &gfc->l3_side.gr[gr].ch[ch].tt; + shortblock = (cod_info->block_type == SHORT_TYPE); + + if (shortblock) { + short_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf2, &vbrmin2, &vbrmax2); + } else { + long_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf2, &vbrmin2, &vbrmax2); + } + vbrsf = vbrsf2; + vbrmin = vbrmin2; + vbrmax = vbrmax2; + +do { +--count; + + if (shortblock) { + short_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax); + short_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34); + } else { + long_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax); + long_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34); + } + + ret = VBR_quantize_granule (gfc, xr34, l3_enc, scalefac, gr, ch); + + if (vbrmin == vbrmax) break; + else if (cod_info->part2_3_length < minbits) { + int i; + vbrmax = vbrmin2 + (vbrmax2-vbrmin2) * count/6; + vbrmin = vbrmin2; + if (shortblock) { + for (i = 0; i < SBMAX_s; ++i) { + //vbrsf.s[i][0] = vbrmin2 + (vbrsf2.s[i][0]-vbrmin2) * count/6; + //vbrsf.s[i][1] = vbrmin2 + (vbrsf2.s[i][1]-vbrmin2) * count/6; + //vbrsf.s[i][2] = vbrmin2 + (vbrsf2.s[i][2]-vbrmin2) * count/6; + vbrsf.s[i][0] = Min(vbrsf2.s[i][0], vbrmax); + vbrsf.s[i][1] = Min(vbrsf2.s[i][1], vbrmax); + vbrsf.s[i][2] = Min(vbrsf2.s[i][2], vbrmax); + } + } + else { + for (i = 0; i < SBMAX_l; ++i) { + //vbrsf.l[i] = vbrmin2 + (vbrsf2.l[i]-vbrmin2) * count/6; + vbrsf.l[i] = Min(vbrsf2.l[i], vbrmax); + } + } + } + else if (cod_info->part2_3_length > maxbits) { + int i; + vbrmax = vbrmax2; + vbrmin = vbrmax2 + (vbrmin2-vbrmax2) * count/6; + if (shortblock) { + for (i = 0; i < SBMAX_s; ++i) { + //vbrsf.s[i][0] = vbrmax2 + (vbrsf2.s[i][0]-vbrmax2) * count/6; + //vbrsf.s[i][1] = vbrmax2 + (vbrsf2.s[i][1]-vbrmax2) * count/6; + //vbrsf.s[i][2] = vbrmax2 + (vbrsf2.s[i][2]-vbrmax2) * count/6; + vbrsf.s[i][0] = Max(vbrsf2.s[i][0], vbrmin); + vbrsf.s[i][1] = Max(vbrsf2.s[i][1], vbrmin); + vbrsf.s[i][2] = Max(vbrsf2.s[i][2], vbrmin); + } + } + else { + for (i = 0; i < SBMAX_l; ++i) { + //vbrsf.l[i] = vbrmax2 + (vbrsf2.l[i]-vbrmax2) * count/6; + vbrsf.l[i] = Max(vbrsf2.l[i], vbrmin); + } + } + } + else break; +} while(1 && ret != -1); + + + 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; + if (huffbits < 0) huffbits = 0; + 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; +} + + + + + + +/************************************************************************ + * + * 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], + 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, vbrmin; + int global_gain_adjust = 0; + + cod_info = &gfc->l3_side.gr[gr].ch[ch].tt; + shortblock = (cod_info->block_type == SHORT_TYPE); + + if (shortblock) + short_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf, &vbrmin, &vbrmax); + else + long_block_sf (gfc, l3_xmin, xr34orig, xr, &vbrsf, &vbrmin, &vbrmax); + + /* 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 (gfc, cod_info, scalefac, &vbrsf, &vbrmax); + short_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34); + } else { + long_block_scalefacs (gfc, cod_info, scalefac, &vbrsf, &vbrmax); + long_block_xr34 (gfc, cod_info, scalefac, xr34orig, xr34); + } + VBR_quantize_granule (gfc, xr34, l3_enc, 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 (gfc, xr34, l3_enc, scalefac, gr, ch); + + ++global_gain_adjust; + } + + return global_gain_adjust; +} + + + +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]; + + qadjust=0; /* start with -1 db quality improvement over quantize.c VBR */ + + l3_side = &gfc->l3_side; + + /* 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 = gfc->is_mpeg1 ? 8 : 6; + cod_info->sfb_smin = 3; + } + } + + /* quality setting */ + masking_lower_db = gfc->VBR->mask_adjust; + 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 = gfc->VBR->mask_adjust + 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], + 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); + + + +} + + + +