Source file: /~heha/hsn/puh.zip/quantize.cpp

/* MP3 quantization
 *      Copyright 1999-2000 Mark Taylor
 *      Copyright 1999-2003 Takehiro Tominaga
 *      Copyright 2000-2011 Robert Hegemann
 *      Copyright 2001-2005 Gabriel Bouvigne
 */

#include "lame.h"
#include "machine.h"
#include "encoder.h"
#include "util.h"
#include "quantize_pvt.h"
#include "bitstream.h"
//#include "vbrquantize.h"
//#include "quantize.h"
#ifdef HAVE_XMMINTRIN_H
#include "lame_intrin.h"
#endif


/* convert from L/R <-> Mid/Side */
static void ms_convert(III_side_info_t &l3_side, int gr) {
    int     i;
    for (i = 0; i < 576; ++i) {
        FLOAT   l, r;
        l = l3_side.tt[gr][0].xr[i];
        r = l3_side.tt[gr][1].xr[i];
        l3_side.tt[gr][0].xr[i] = (l + r) * (FLOAT) (SQRT2 * 0.5);
        l3_side.tt[gr][1].xr[i] = (l - r) * (FLOAT) (SQRT2 * 0.5);
    }
}

/************************************************************************
 *
 *      init_outer_loop()
 *  mt 6/99
 *
 *  initializes cod_info, scalefac and xrpow
 *
 *  returns 0 if all energies in xr are zero, else 1
 *
 ************************************************************************/

static void init_xrpow_core_c(gr_info & cod_info, FLOAT xrpow[576], int upper, FLOAT * sum)
{
    int     i;
    FLOAT   tmp;
    *sum = 0;
    for (i = 0; i <= upper; ++i) {
        tmp = fabs(cod_info.xr[i]);
        *sum += tmp;
        xrpow[i] = sqrt(tmp * sqrt(tmp));

        if (xrpow[i] > cod_info.xrpow_max)
            cod_info.xrpow_max = xrpow[i];
    }
}

void lame_internal_flags::init_xrpow_core_init() {
    init_xrpow_core = init_xrpow_core_c;

#if defined(HAVE_XMMINTRIN_H)
    if (CPU_features.SSE)
        init_xrpow_core = init_xrpow_core_sse;
#endif
#ifndef HAVE_NASM
#ifdef MIN_ARCH_SSE
    init_xrpow_core = init_xrpow_core_sse;
#endif
#endif
}

int lame_internal_flags::init_xrpow(gr_info & cod_info, FLOAT xrpow[576]) {
    FLOAT   sum = 0;
    int     i;
    int const upper = cod_info.max_nonzero_coeff;

    assert(xrpow != NULL);
    cod_info.xrpow_max = 0;

    /*  check if there is some energy we have to quantize
     *  and calculate xrpow matching our fresh scalefactors
     */
    assert(0 <= upper && upper <= 575);
    memset(&(xrpow[upper]), 0, (576 - upper) * sizeof(xrpow[0]));


    init_xrpow_core(cod_info, xrpow, upper, &sum);

    /*  return 1 if we have something to quantize, else 0
     */
    if (sum > (FLOAT) 1E-20) {
        int     j = 0;
        if (sv_qnt.substep_shaping & 2)
            j = 1;

        for (i = 0; i < cod_info.psymax; i++)
            sv_qnt.pseudohalf[i] = j;

        return 1;
    }

    memset(&cod_info.l3_enc[0], 0, sizeof(int) * 576);
    return 0;
}





/*
Gabriel Bouvigne feb/apr 2003
Analog silence detection in partitionned sfb21
or sfb12 for short blocks

From top to bottom of sfb, changes to 0
coeffs which are below ath. It stops on the first
coeff higher than ath.
*/
void lame_internal_flags::psfb21_analogsilence(gr_info & cod_info)const{
//  ATH_t const *const ATH = gfc.ATH;
  FLOAT  *const xr = cod_info.xr;

    if (cod_info.block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT blocks */
        int     gsfb;
        int     stop = 0;
        for (gsfb = PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) {
            int const start = scalefac_band.psfb21[gsfb];
            int const end = scalefac_band.psfb21[gsfb + 1];
            int     j;
            FLOAT   ath21;
            ath21 = athAdjust(ATH->adjust_factor, ATH->psfb21[gsfb], ATH->floor, 0);

            if (sv_qnt.longfact[21] > 1e-12f)
                ath21 *= sv_qnt.longfact[21];

            for (j = end - 1; j >= start; j--) {
                if (fabs(xr[j]) < ath21)
                    xr[j] = 0;
                else {
                    stop = 1;
                    break;
                }
            }
        }
    }
    else {
        /*note: short blocks coeffs are reordered */
        int     block;
        for (block = 0; block < 3; block++) {

            int     gsfb;
            int     stop = 0;
            for (gsfb = PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) {
                int const start = scalefac_band.s[12] * 3 +
                    (scalefac_band.s[13] - scalefac_band.s[12]) * block +
                    (scalefac_band.psfb12[gsfb] - scalefac_band.psfb12[0]);
                int const end =
                    start + (scalefac_band.psfb12[gsfb + 1] - scalefac_band.psfb12[gsfb]);
                int     j;
                FLOAT   ath12;
                ath12 = athAdjust(ATH->adjust_factor, ATH->psfb12[gsfb], ATH->floor, 0);

                if (sv_qnt.shortfact[12] > 1e-12f)
                    ath12 *= sv_qnt.shortfact[12];

                for (j = end - 1; j >= start; j--) {
                    if (fabs(xr[j]) < ath12)
                        xr[j] = 0;
                    else {
                        stop = 1;
                        break;
                    }
                }
            }
        }
    }

}





void lame_internal_flags::init_outer_loop(gr_info & cod_info)const{
//  SessionConfig_t const & cfg = gfc.cfg;
    int     sfb, j;
    /*  initialize fresh cod_info
     */
    cod_info.part2_3_length = 0;
    cod_info.big_values = 0;
    cod_info.count1 = 0;
    cod_info.global_gain = 210;
    cod_info.scalefac_compress = 0;
    /* mixed_block_flag, block_type was set in psymodel.c */
    cod_info.table_select[0] = 0;
    cod_info.table_select[1] = 0;
    cod_info.table_select[2] = 0;
    cod_info.subblock_gain[0] = 0;
    cod_info.subblock_gain[1] = 0;
    cod_info.subblock_gain[2] = 0;
    cod_info.subblock_gain[3] = 0; /* this one is always 0 */
    cod_info.region0_count = 0;
    cod_info.region1_count = 0;
    cod_info.preflag = 0;
    cod_info.scalefac_scale = 0;
    cod_info.count1table_select = 0;
    cod_info.part2_length = 0;
    if (cfg.samplerate_out <= 8000) {
      cod_info.sfb_lmax = 17;
      cod_info.sfb_smin = 9;
      cod_info.psy_lmax = 17;
    }
    else {
      cod_info.sfb_lmax = SBPSY_l;
      cod_info.sfb_smin = SBPSY_s;
      cod_info.psy_lmax = sv_qnt.sfb21_extra ? SBMAX_l : SBPSY_l;
    }
    cod_info.psymax = cod_info.psy_lmax;
    cod_info.sfbmax = cod_info.sfb_lmax;
    cod_info.sfbdivide = 11;
    for (sfb = 0; sfb < SBMAX_l; sfb++) {
        cod_info.width[sfb]
            = scalefac_band.l[sfb + 1] - scalefac_band.l[sfb];
        cod_info.window[sfb] = 3; /* which is always 0. */
    }
    if (cod_info.block_type == SHORT_TYPE) {
        FLOAT   ixwork[576];
        FLOAT  *ix;

        cod_info.sfb_smin = 0;
        cod_info.sfb_lmax = 0;
        if (cod_info.mixed_block_flag) {
            /*
             *  MPEG-1:      sfbs 0-7 long block, 3-12 short blocks
             *  MPEG-2(.5):  sfbs 0-5 long block, 3-12 short blocks
             */
            cod_info.sfb_smin = 3;
            cod_info.sfb_lmax = cfg.mode_gr * 2 + 4;
        }
        if (cfg.samplerate_out <= 8000) {
            cod_info.psymax
                = cod_info.sfb_lmax
                + 3 * (9 - cod_info.sfb_smin);
            cod_info.sfbmax = cod_info.sfb_lmax + 3 * (9 - cod_info.sfb_smin);
        }
        else {
            cod_info.psymax
                = cod_info.sfb_lmax
                + 3 * ((sv_qnt.sfb21_extra ? SBMAX_s : SBPSY_s) - cod_info.sfb_smin);
            cod_info.sfbmax = cod_info.sfb_lmax + 3 * (SBPSY_s - cod_info.sfb_smin);
        }
        cod_info.sfbdivide = cod_info.sfbmax - 18;
        cod_info.psy_lmax = cod_info.sfb_lmax;
        /* re-order the short blocks, for more efficient encoding below */
        /* By Takehiro TOMINAGA */
        /*
           Within each scalefactor band, data is given for successive
           time windows, beginning with window 0 and ending with window 2.
           Within each window, the quantized values are then arranged in
           order of increasing frequency...
         */
        ix = &cod_info.xr[scalefac_band.l[cod_info.sfb_lmax]];
        memcpy(ixwork, cod_info.xr, 576 * sizeof(FLOAT));
        for (sfb = cod_info.sfb_smin; sfb < SBMAX_s; sfb++) {
            int const start = scalefac_band.s[sfb];
            int const end = scalefac_band.s[sfb + 1];
            int     window, l;
            for (window = 0; window < 3; window++) {
                for (l = start; l < end; l++) {
                    *ix++ = ixwork[3 * l + window];
                }
            }
        }

        j = cod_info.sfb_lmax;
        for (sfb = cod_info.sfb_smin; sfb < SBMAX_s; sfb++) {
            cod_info.width[j] = cod_info.width[j + 1] = cod_info.width[j + 2]
                = scalefac_band.s[sfb + 1] - scalefac_band.s[sfb];
            cod_info.window[j] = 0;
            cod_info.window[j + 1] = 1;
            cod_info.window[j + 2] = 2;
            j += 3;
        }
    }

    cod_info.count1bits = 0;
    cod_info.sfb_partition_table = nr_of_sfb_block[0][0];
    cod_info.slen[0] = 0;
    cod_info.slen[1] = 0;
    cod_info.slen[2] = 0;
    cod_info.slen[3] = 0;

    cod_info.max_nonzero_coeff = 575;

    /*  fresh scalefactors are all zero
     */
    memset(cod_info.scalefac, 0, sizeof cod_info.scalefac);

    if (cfg.vbr != vbr_mt && cfg.vbr != vbr_mtrh && cfg.vbr != vbr_abr && cfg.vbr != vbr_off) {
        psfb21_analogsilence(cod_info);
    }
}



/************************************************************************
 *
 *      bin_search_StepSize()
 *
 *  author/date??
 *
 *  binary step size search
 *  used by outer_loop to get a quantizer step size to start with
 *
 ************************************************************************/

typedef enum {
    BINSEARCH_NONE,
    BINSEARCH_UP,
    BINSEARCH_DOWN
} binsearchDirection_t;

int lame_internal_flags::bin_search_StepSize(gr_info & cod_info,
                    int desired_rate, const int ch, const FLOAT xrpow[576]) {
    int     nBits;
    int     CurrentStep = sv_qnt.CurrentStep[ch];
    int     flag_GoneOver = 0;
    int const start = sv_qnt.OldValue[ch];
    binsearchDirection_t Direction = BINSEARCH_NONE;
    cod_info.global_gain = start;
    desired_rate -= cod_info.part2_length;

    assert(CurrentStep);
    for (;;) {
        int     step;
        nBits = count_bits(xrpow, cod_info, 0);

        if (CurrentStep == 1 || nBits == desired_rate)
            break;      /* nothing to adjust anymore */

        if (nBits > desired_rate) {
            /* increase Quantize_StepSize */
            if (Direction == BINSEARCH_DOWN)
                flag_GoneOver = 1;

            if (flag_GoneOver)
                CurrentStep /= 2;
            Direction = BINSEARCH_UP;
            step = CurrentStep;
        }
        else {
            /* decrease Quantize_StepSize */
            if (Direction == BINSEARCH_UP)
                flag_GoneOver = 1;

            if (flag_GoneOver)
                CurrentStep /= 2;
            Direction = BINSEARCH_DOWN;
            step = -CurrentStep;
        }
        cod_info.global_gain += step;
        if (cod_info.global_gain < 0) {
            cod_info.global_gain = 0;
            flag_GoneOver = 1;
        }
        if (cod_info.global_gain > 255) {
            cod_info.global_gain = 255;
            flag_GoneOver = 1;
        }
    }

    assert(cod_info.global_gain >= 0);
    assert(cod_info.global_gain < 256);

    while (nBits > desired_rate && cod_info.global_gain < 255) {
        cod_info.global_gain++;
        nBits = count_bits(xrpow, cod_info, 0);
    }
    sv_qnt.CurrentStep[ch] = (start - cod_info.global_gain >= 4) ? 4 : 2;
    sv_qnt.OldValue[ch] = cod_info.global_gain;
    cod_info.part2_3_length = nBits;
    return nBits;
}




/************************************************************************
 *
 *      trancate_smallspectrums()
 *
 *  Takehiro TOMINAGA 2002-07-21
 *
 *  trancate smaller nubmers into 0 as long as the noise threshold is allowed.
 *
 ************************************************************************/
static int _cdecl floatcompare(const void *v1, const void *v2)
{
    const FLOAT &a = *reinterpret_cast<const FLOAT*>(v1),
		&b = *reinterpret_cast<const FLOAT*>(v2);
    if (a > b)
        return 1;
    if (a < b)
        return -1;
    return 0;
}

void lame_internal_flags::trancate_smallspectrums(
 gr_info & gi, const FLOAT * const l3_xmin, FLOAT * const work)const{
  int     sfb, j, width;
  FLOAT   distort[SFBMAX];
  calc_noise_result dummy;

    if ((!(sv_qnt.substep_shaping & 4) && gi.block_type == SHORT_TYPE)
        || sv_qnt.substep_shaping & 0x80)
        return;
    calc_noise(gi, l3_xmin, distort, &dummy, 0);
    for (j = 0; j < 576; j++) {
        FLOAT   xr = 0.0;
        if (gi.l3_enc[j] != 0)
            xr = fabs(gi.xr[j]);
        work[j] = xr;
    }

    j = 0;
    sfb = 8;
    if (gi.block_type == SHORT_TYPE)
        sfb = 6;
    do {
        FLOAT   allowedNoise, trancateThreshold;
        int     nsame, start;

        width = gi.width[sfb];
        j += width;
        if (distort[sfb] >= 1.0)
            continue;

        qsort(&work[j - width], width, sizeof(FLOAT), floatcompare);
        if (EQ(work[j - 1], FLOAT(0.0)))
            continue;   /* all zero sfb */

        allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb];
        trancateThreshold = 0.0;
        start = 0;
        do {
            FLOAT   noise;
            for (nsame = 1; start + nsame < width; nsame++)
                if (NEQ(work[start + j - width], work[start + j + nsame - width]))
                    break;

            noise = work[start + j - width] * work[start + j - width] * nsame;
            if (allowedNoise < noise) {
                if (start != 0)
                    trancateThreshold = work[start + j - width - 1];
                break;
            }
            allowedNoise -= noise;
            start += nsame;
        } while (start < width);
        if (EQ(trancateThreshold, FLOAT(0.0)))
            continue;

/*      printf("%e %e %e\n", */
/*             trancateThreshold/l3_xmin[sfb], */
/*             trancateThreshold/(l3_xmin[sfb]*start), */
/*             trancateThreshold/(l3_xmin[sfb]*(start+width)) */
/*          ); */
/*      if (trancateThreshold > 1000*l3_xmin[sfb]*start) */
/*          trancateThreshold = 1000*l3_xmin[sfb]*start; */

        do {
            if (fabs(gi.xr[j - width]) <= trancateThreshold)
                gi.l3_enc[j - width] = 0;
        } while (--width > 0);
    } while (++sfb < gi.psymax);

    gi.part2_3_length = noquant_count_bits(gi, 0);
}


/*************************************************************************
 *
 *      loop_break()
 *
 *  author/date??
 *
 *  Function: Returns zero if there is a scalefac which has not been
 *            amplified. Otherwise it returns one.
 *
 *************************************************************************/

inline static int
loop_break(const gr_info & cod_info)
{
    int     sfb;

    for (sfb = 0; sfb < cod_info.sfbmax; sfb++)
        if (cod_info.scalefac[sfb]
            + cod_info.subblock_gain[cod_info.window[sfb]] == 0)
            return 0;

    return 1;
}




/*  mt 5/99:  Function: Improved calc_noise for a single channel   */

/*************************************************************************
 *
 *      quant_compare()
 *
 *  author/date??
 *
 *  several different codes to decide which quantization is better
 *
 *************************************************************************/

static double
penalties(double noise)
{
    return FAST_LOG10(0.368 + 0.632 * noise * noise * noise);
}

static double
get_klemm_noise(const FLOAT * distort, const gr_info & gi)
{
    int     sfb;
    double  klemm_noise = 1E-37;
    for (sfb = 0; sfb < gi.psymax; sfb++)
        klemm_noise += penalties(distort[sfb]);

    return Max(1e-20, klemm_noise);
}

inline static int
quant_compare(const int quant_comp,
              const calc_noise_result * const best,
              calc_noise_result * const calc, const gr_info & gi, const FLOAT * distort)
{
    /*
       noise is given in decibels (dB) relative to masking thesholds.

       over_noise:  ??? (the previous comment is fully wrong)
       tot_noise:   ??? (the previous comment is fully wrong)
       max_noise:   max quantization noise

     */
    int     better;

    switch (quant_comp) {
    default:
    case 9:{
            if (best->over_count > 0) {
                /* there are distorted sfb */
                better = calc->over_SSD <= best->over_SSD;
                if (calc->over_SSD == best->over_SSD)
                    better = calc->bits < best->bits;
            }
            else {
                /* no distorted sfb */
                better = ((calc->max_noise < 0) &&
                          ((calc->max_noise * 10 + calc->bits) <=
                           (best->max_noise * 10 + best->bits)));
            }
            break;
        }

    case 0:
        better = calc->over_count < best->over_count
            || (calc->over_count == best->over_count && calc->over_noise < best->over_noise)
            || (calc->over_count == best->over_count &&
                EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);
        break;

    case 8:
        calc->max_noise = get_klemm_noise(distort, gi);
        /*lint --fallthrough */
    case 1:
        better = calc->max_noise < best->max_noise;
        break;
    case 2:
        better = calc->tot_noise < best->tot_noise;
        break;
    case 3:
        better = (calc->tot_noise < best->tot_noise)
            && (calc->max_noise < best->max_noise);
        break;
    case 4:
        better = (calc->max_noise <= 0.0 && best->max_noise > 0.2)
            || (calc->max_noise <= 0.0 &&
                best->max_noise < 0.0 &&
                best->max_noise > calc->max_noise - 0.2 && calc->tot_noise < best->tot_noise)
            || (calc->max_noise <= 0.0 &&
                best->max_noise > 0.0 &&
                best->max_noise > calc->max_noise - 0.2 &&
                calc->tot_noise < best->tot_noise + best->over_noise)
            || (calc->max_noise > 0.0 &&
                best->max_noise > -0.05 &&
                best->max_noise > calc->max_noise - 0.1 &&
                calc->tot_noise + calc->over_noise < best->tot_noise + best->over_noise)
            || (calc->max_noise > 0.0 &&
                best->max_noise > -0.1 &&
                best->max_noise > calc->max_noise - 0.15 &&
                calc->tot_noise + calc->over_noise + calc->over_noise <
                best->tot_noise + best->over_noise + best->over_noise);
        break;
    case 5:
        better = calc->over_noise < best->over_noise
            || (EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);
        break;
    case 6:
        better = calc->over_noise < best->over_noise
            || (EQ(calc->over_noise, best->over_noise) &&
                (calc->max_noise < best->max_noise
                 || (EQ(calc->max_noise, best->max_noise) && calc->tot_noise <= best->tot_noise)
                ));
        break;
    case 7:
        better = calc->over_count < best->over_count || calc->over_noise < best->over_noise;
        break;
    }


    if (best->over_count == 0) {
        /*
           If no distorted bands, only use this quantization
           if it is better, and if it uses less bits.
           Unfortunately, part2_3_length is sometimes a poor
           estimator of the final size at low bitrates.
         */
        better = better && calc->bits < best->bits;
    }


    return better;
}



/*************************************************************************
 *
 *          amp_scalefac_bands()
 *
 *  author/date??
 *
 *  Amplify the scalefactor bands that violate the masking threshold.
 *  See ISO 11172-3 Section C.1.5.4.3.5
 *
 *  distort[] = noise/masking
 *  distort[] > 1   ==> noise is not masked
 *  distort[] < 1   ==> noise is masked
 *  max_dist = maximum value of distort[]
 *
 *  Three algorithms:
 *  noise_shaping_amp
 *        0             Amplify all bands with distort[]>1.
 *
 *        1             Amplify all bands with distort[] >= max_dist^(.5);
 *                     ( 50% in the db scale)
 *
 *        2             Amplify first band with distort[] >= max_dist;
 *
 *
 *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands
 *  with distort[] >= .95*max_dist.  This is to make sure we always
 *  amplify at least one band.
 *
 *
 *************************************************************************/
void lame_internal_flags::amp_scalefac_bands(
 gr_info & cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine) {
//    SessionConfig_t const & cfg = gfc.cfg;
    int     j, sfb;
    FLOAT   ifqstep34, trigger;
    int     noise_shaping_amp;

    if (cod_info.scalefac_scale == 0) {
        ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5) */
    }
    else {
        ifqstep34 = 1.68179283050742922612; /* 2**(.75*1) */
    }

    /* compute maximum value of distort[]  */
    trigger = 0;
    for (sfb = 0; sfb < cod_info.sfbmax; sfb++) {
        if (trigger < distort[sfb])
            trigger = distort[sfb];
    }

    noise_shaping_amp = cfg.noise_shaping_amp;
    if (noise_shaping_amp == 3) {
        if (bRefine == 1)
            noise_shaping_amp = 2;
        else
            noise_shaping_amp = 1;
    }
    switch (noise_shaping_amp) {
    case 2:
        /* amplify exactly 1 band */
        break;

    case 1:
        /* amplify bands within 50% of max (on db scale) */
        if (trigger > 1.0)
            trigger = pow(trigger, FLOAT(.5));
        else
            trigger *= .95;
        break;

    case 0:
    default:
        /* ISO algorithm.  amplify all bands with distort>1 */
        if (trigger > 1.0)
            trigger = 1.0;
        else
            trigger *= .95;
        break;
    }

    j = 0;
    for (sfb = 0; sfb < cod_info.sfbmax; sfb++) {
        int const width = cod_info.width[sfb];
        int     l;
        j += width;
        if (distort[sfb] < trigger)
            continue;

        if (sv_qnt.substep_shaping & 2) {
            sv_qnt.pseudohalf[sfb] = !sv_qnt.pseudohalf[sfb];
            if (!sv_qnt.pseudohalf[sfb] && cfg.noise_shaping_amp == 2)
                return;
        }
        cod_info.scalefac[sfb]++;
        for (l = -width; l < 0; l++) {
            xrpow[j + l] *= ifqstep34;
            if (xrpow[j + l] > cod_info.xrpow_max)
                cod_info.xrpow_max = xrpow[j + l];
        }

        if (cfg.noise_shaping_amp == 2)
            return;
    }
}

/*************************************************************************
 *
 *      inc_scalefac_scale()
 *
 *  Takehiro Tominaga 2000-xx-xx
 *
 *  turns on scalefac scale and adjusts scalefactors
 *
 *************************************************************************/

static void
inc_scalefac_scale(gr_info & cod_info, FLOAT xrpow[576])
{
    int     l, j, sfb;
    const FLOAT ifqstep34 = 1.29683955465100964055;

    j = 0;
    for (sfb = 0; sfb < cod_info.sfbmax; sfb++) {
        int const width = cod_info.width[sfb];
        int     s = cod_info.scalefac[sfb];
        if (cod_info.preflag)
            s += pretab[sfb];
        j += width;
        if (s & 1) {
            s++;
            for (l = -width; l < 0; l++) {
                xrpow[j + l] *= ifqstep34;
                if (xrpow[j + l] > cod_info.xrpow_max)
                    cod_info.xrpow_max = xrpow[j + l];
            }
        }
        cod_info.scalefac[sfb] = s >> 1;
    }
    cod_info.preflag = 0;
    cod_info.scalefac_scale = 1;
}



/*************************************************************************
 *
 *      inc_subblock_gain()
 *
 *  Takehiro Tominaga 2000-xx-xx
 *
 *  increases the subblock gain and adjusts scalefactors
 *
 *************************************************************************/

int lame_internal_flags::inc_subblock_gain(gr_info & cod_info, FLOAT xrpow[576])const{
    int     sfb, window;
    int    *const scalefac = cod_info.scalefac;

    /* subbloc_gain can't do anything in the long block region */
    for (sfb = 0; sfb < cod_info.sfb_lmax; sfb++) {
        if (scalefac[sfb] >= 16)
            return 1;
    }

    for (window = 0; window < 3; window++) {
        int     s1, s2, l, j;
        s1 = s2 = 0;

        for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbdivide; sfb += 3) {
            if (s1 < scalefac[sfb])
                s1 = scalefac[sfb];
        }
        for (; sfb < cod_info.sfbmax; sfb += 3) {
            if (s2 < scalefac[sfb])
                s2 = scalefac[sfb];
        }

        if (s1 < 16 && s2 < 8)
            continue;

        if (cod_info.subblock_gain[window] >= 7)
            return 1;

        /* 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
         */
        cod_info.subblock_gain[window]++;
        j = scalefac_band.l[cod_info.sfb_lmax];
        for (sfb = cod_info.sfb_lmax + window; sfb < cod_info.sfbmax; sfb += 3) {
            FLOAT   amp;
            int const width = cod_info.width[sfb];
            int     s = scalefac[sfb];
            assert(s >= 0);
            s = s - (4 >> cod_info.scalefac_scale);
            if (s >= 0) {
                scalefac[sfb] = s;
                j += width * 3;
                continue;
            }

            scalefac[sfb] = 0;
            {
                int const gain = 210 + (s << (cod_info.scalefac_scale + 1));
                amp = IPOW20(gain);
            }
            j += width * (window + 1);
            for (l = -width; l < 0; l++) {
                xrpow[j + l] *= amp;
                if (xrpow[j + l] > cod_info.xrpow_max)
                    cod_info.xrpow_max = xrpow[j + l];
            }
            j += width * (3 - window - 1);
        }

        {
            FLOAT const amp = IPOW20(202);
            j += cod_info.width[sfb] * (window + 1);
            for (l = -cod_info.width[sfb]; l < 0; l++) {
                xrpow[j + l] *= amp;
                if (xrpow[j + l] > cod_info.xrpow_max)
                    cod_info.xrpow_max = xrpow[j + l];
            }
        }
    }
    return 0;
}



/********************************************************************
 *
 *      balance_noise()
 *
 *  Takehiro Tominaga /date??
 *  Robert Hegemann 2000-09-06: made a function of it
 *
 *  amplifies scalefactor bands,
 *   - if all are already amplified returns 0
 *   - if some bands are amplified too much:
 *      * try to increase scalefac_scale
 *      * if already scalefac_scale was set
 *          try on short blocks to increase subblock gain
 *
 ********************************************************************/
int lame_internal_flags::balance_noise(gr_info & cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine) {
//    SessionConfig_t const & cfg = gfc.cfg;
    int     status;

    amp_scalefac_bands(cod_info, distort, xrpow, bRefine);

    /* check to make sure we have not amplified too much
     * loop_break returns 0 if there is an unamplified scalefac
     * scale_bitcount returns 0 if no scalefactors are too large
     */

    status = loop_break(cod_info);

    if (status)
        return 0;       /* all bands amplified */

    /* not all scalefactors have been amplified.  so these
     * scalefacs are possibly valid.  encode them:
     */
    status = scale_bitcount(cod_info);

    if (!status)
        return 1;       /* amplified some bands not exceeding limits */

    /*  some scalefactors are too large.
     *  lets try setting scalefac_scale=1
     */
    if (cfg.noise_shaping > 1) {
        memset(sv_qnt.pseudohalf, 0, sizeof sv_qnt.pseudohalf);
        if (!cod_info.scalefac_scale) {
            inc_scalefac_scale(cod_info, xrpow);
            status = 0;
        }
        else {
            if (cod_info.block_type == SHORT_TYPE && cfg.subblock_gain > 0) {
                status = inc_subblock_gain(cod_info, xrpow)
                    || loop_break(cod_info);
            }
        }
    }

    if (!status) {
        status = scale_bitcount(cod_info);
    }
    return !status;
}



/************************************************************************
 *
 *  outer_loop ()
 *
 *  Function: The outer iteration loop controls the masking conditions
 *  of all scalefactorbands. It computes the best scalefac and
 *  global gain. This module calls the inner iteration loop
 *
 *  mt 5/99 completely rewritten to allow for bit reservoir control,
 *  mid/side channels with L/R or mid/side masking thresholds,
 *  and chooses best quantization instead of last quantization when
 *  no distortion free quantization can be found.
 *
 *  added VBR support mt 5/99
 *
 *  some code shuffle rh 9/00
 ************************************************************************/

int lame_internal_flags::outer_loop(gr_info & cod_info, const FLOAT * const l3_xmin, /* allowed distortion */
           FLOAT xrpow[576], /* coloured magnitudes of spectral */
           const int ch, const int targ_bits) {                       /* maximum allowed bits */
//    SessionConfig_t const & cfg = gfc.cfg;
    FLOAT   save_xrpow[576];
    FLOAT   distort[SFBMAX];
    calc_noise_result best_noise_info;
    int     huff_bits;
    int     better;
    int     age;
    calc_noise_data prev_noise;
    int     best_part2_3_length = 9999999;
    int     bEndOfSearch = 0;
    int     bRefine = 0;
    int     best_ggain_pass1 = 0;

    bin_search_StepSize(cod_info, targ_bits, ch, xrpow);

    if (!cfg.noise_shaping)
        /* fast mode, no noise shaping, we are ready */
        return 100;     /* default noise_info.over_count */

    memset(&prev_noise, 0, sizeof(calc_noise_data));


    /* compute the distortion in this quantization */
    /* coefficients and thresholds both l/r (or both mid/side) */
    (void) calc_noise(cod_info, l3_xmin, distort, &best_noise_info, &prev_noise);
    best_noise_info.bits = cod_info.part2_3_length;

    gr_info cod_info_w = cod_info;
    age = 0;
    /* if (cfg.vbr == vbr_rh || cfg.vbr == vbr_mtrh) */
    memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);

    while (!bEndOfSearch) {
        /* BEGIN MAIN LOOP */
        do {
            calc_noise_result noise_info;
            int     search_limit;
            int     maxggain = 255;

            /* When quantization with no distorted bands is found,
             * allow up to X new unsuccesful tries in serial. This
             * gives us more possibilities for different quant_compare modes.
             * Much more than 3 makes not a big difference, it is only slower.
             */

            if (sv_qnt.substep_shaping & 2) {
                search_limit = 20;
            }
            else {
                search_limit = 3;
            }



            /* Check if the last scalefactor band is distorted.
             * in VBR mode we can't get rid of the distortion, so quit now
             * and VBR mode will try again with more bits.
             * (makes a 10% speed increase, the files I tested were
             * binary identical, 2000/05/20 Robert Hegemann)
             * distort[] > 1 means noise > allowed noise
             */
            if (sv_qnt.sfb21_extra) {
                if (distort[cod_info_w.sfbmax] > 1.0)
                    break;
                if (cod_info_w.block_type == SHORT_TYPE
                    && (distort[cod_info_w.sfbmax + 1] > 1.0
                        || distort[cod_info_w.sfbmax + 2] > 1.0))
                    break;
            }

            /* try a new scalefactor conbination on cod_info_w */
            if (balance_noise(cod_info_w, distort, xrpow, bRefine) == 0)
                break;
            if (cod_info_w.scalefac_scale)
                maxggain = 254;

            /* inner_loop starts with the initial quantization step computed above
             * and slowly increases until the bits < huff_bits.
             * Thus it is important not to start with too large of an inital
             * quantization step.  Too small is ok, but inner_loop will take longer
             */
            huff_bits = targ_bits - cod_info_w.part2_length;
            if (huff_bits <= 0)
                break;

            /*  increase quantizer stepsize until needed bits are below maximum
             */
            while ((cod_info_w.part2_3_length
                    = count_bits(xrpow, cod_info_w, &prev_noise)) > huff_bits
                   && cod_info_w.global_gain <= maxggain)
                cod_info_w.global_gain++;

            if (cod_info_w.global_gain > maxggain)
                break;

            if (best_noise_info.over_count == 0) {

                while ((cod_info_w.part2_3_length
                        = count_bits(xrpow, cod_info_w, &prev_noise)) > best_part2_3_length
                       && cod_info_w.global_gain <= maxggain)
                    cod_info_w.global_gain++;

                if (cod_info_w.global_gain > maxggain)
                    break;
            }

            /* compute the distortion in this quantization */
            calc_noise(cod_info_w, l3_xmin, distort, &noise_info, &prev_noise);
            noise_info.bits = cod_info_w.part2_3_length;

            /* check if this quantization is better
             * than our saved quantization */
            if (cod_info.block_type != SHORT_TYPE) /* NORM, START or STOP type */
                better = cfg.quant_comp;
            else
                better = cfg.quant_comp_short;


            better = quant_compare(better, &best_noise_info, &noise_info, cod_info_w, distort);


            /* save data so we can restore this quantization later */
            if (better) {
                best_part2_3_length = cod_info.part2_3_length;
                best_noise_info = noise_info;
                cod_info = cod_info_w;
                age = 0;
                /* save data so we can restore this quantization later */
                /*if (cfg.vbr == vbr_rh || cfg.vbr == vbr_mtrh) */  {
                    /* store for later reuse */
                    memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);
                }
            }
            else {
                /* early stop? */
                if (cfg.full_outer_loop == 0) {
                    if (++age > search_limit && best_noise_info.over_count == 0)
                        break;
                    if ((cfg.noise_shaping_amp == 3) && bRefine && age > 30)
                        break;
                    if ((cfg.noise_shaping_amp == 3) && bRefine &&
                        (cod_info_w.global_gain - best_ggain_pass1) > 15)
                        break;
                }
            }
        }
        while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255);

        if (cfg.noise_shaping_amp == 3) {
            if (!bRefine) {
                /* refine search */
                cod_info_w = cod_info;
                memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);
                age = 0;
                best_ggain_pass1 = cod_info_w.global_gain;

                bRefine = 1;
            }
            else {
                /* search already refined, stop */
                bEndOfSearch = 1;
            }

        }
        else {
            bEndOfSearch = 1;
        }
    }

    assert((cod_info.global_gain + cod_info.scalefac_scale) <= 255);
    /*  finish up
     */
    if (cfg.vbr == vbr_rh || cfg.vbr == vbr_mtrh || cfg.vbr == vbr_mt)
        /* restore for reuse on next try */
        memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);
    /*  do the 'substep shaping'
     */
    else if (sv_qnt.substep_shaping & 1)
        trancate_smallspectrums(cod_info, l3_xmin, xrpow);

    return best_noise_info.over_count;
}





/************************************************************************
 *
 *      iteration_finish_one()
 *
 *  Robert Hegemann 2000-09-06
 *
 *  update reservoir status after FINAL quantization/bitrate
 *
 ************************************************************************/

void lame_internal_flags::iteration_finish_one(int gr, int ch) {
//  SessionConfig_t const & cfg = gfc.cfg;
//  III_side_info_t & l3_side = gfc.l3_side;
  gr_info & cod_info = l3_side.tt[gr][ch];

    /*  try some better scalefac storage
     */
  best_scalefac_store(gr, ch, l3_side);

    /*  best huffman_divide may save some bits too
     */
  if (cfg.use_best_huffman == 1)
        best_huffman_divide(cod_info);

    /*  update reservoir status after FINAL quantization/bitrate
     */
  ResvAdjust(cod_info);
}



/*********************************************************************
 *
 *      VBR_encode_granule()
 *
 *  2000-09-04 Robert Hegemann
 *
 *********************************************************************/

void lame_internal_flags::VBR_encode_granule(gr_info & cod_info, const FLOAT * const l3_xmin, /* allowed distortion of the scalefactor */
                   FLOAT xrpow[576], /* coloured magnitudes of spectral values */
                   const int ch, int min_bits, int max_bits)
{
    gr_info bst_cod_info;
    FLOAT   bst_xrpow[576];
    int const Max_bits = max_bits;
    int     real_bits = max_bits + 1;
    int     this_bits = (max_bits + min_bits) / 2;
    int     dbits, over, found = 0;
    int const sfb21_extra = sv_qnt.sfb21_extra;

    assert(Max_bits <= MAX_BITS_PER_CHANNEL);
    memset(bst_cod_info.l3_enc, 0, sizeof(bst_cod_info.l3_enc));

    /*  search within round about 40 bits of optimal
     */
    do {
        assert(this_bits >= min_bits);
        assert(this_bits <= max_bits);
        assert(min_bits <= max_bits);

        if (this_bits > Max_bits - 42)
            sv_qnt.sfb21_extra = 0;
        else
            sv_qnt.sfb21_extra = sfb21_extra;

        over = outer_loop(cod_info, l3_xmin, xrpow, ch, this_bits);

        /*  is quantization as good as we are looking for ?
         *  in this case: is no scalefactor band distorted?
         */
        if (over <= 0) {
            found = 1;
            /*  now we know it can be done with "real_bits"
             *  and maybe we can skip some iterations
             */
            real_bits = cod_info.part2_3_length;

            /*  store best quantization so far
             */
            bst_cod_info = cod_info;
            memcpy(bst_xrpow, xrpow, sizeof(FLOAT) * 576);

            /*  try with fewer bits
             */
            max_bits = real_bits - 32;
            dbits = max_bits - min_bits;
            this_bits = (max_bits + min_bits) / 2;
        }
        else {
            /*  try with more bits
             */
            min_bits = this_bits + 32;
            dbits = max_bits - min_bits;
            this_bits = (max_bits + min_bits) / 2;

            if (found) {
                found = 2;
                /*  start again with best quantization so far
                 */
                cod_info = bst_cod_info;
                memcpy(xrpow, bst_xrpow, sizeof(FLOAT) * 576);
            }
        }
    } while (dbits > 12);

    sv_qnt.sfb21_extra = sfb21_extra;

    /*  found=0 => nothing found, use last one
     *  found=1 => we just found the best and left the loop
     *  found=2 => we restored a good one and have now l3_enc to restore too
     */
    if (found == 2) {
        memcpy(cod_info.l3_enc, bst_cod_info.l3_enc, sizeof(int) * 576);
    }
    assert(cod_info.part2_3_length <= Max_bits);

}



/************************************************************************
 *
 *      get_framebits()
 *
 *  Robert Hegemann 2000-09-05
 *
 *  calculates
 *  * how many bits are available for analog silent granules
 *  * how many bits to use for the lowest allowed bitrate
 *  * how many bits each bitrate would provide
 *
 ************************************************************************/

void lame_internal_flags::get_framebits(int frameBits[15]) {
//    SessionConfig_t const & cfg = gfc.cfg;
    EncResult_t & eov = ov_enc;
    int     bitsPerFrame, i;

    /*  always use at least this many bits per granule per channel
     *  unless we detect analog silence, see below
     */
    eov.bitrate_index = cfg.vbr_min_bitrate_index;
    bitsPerFrame = getframebits();

    /*  bits for analog silence
     */
    eov.bitrate_index = 1;
    bitsPerFrame = getframebits();

    for (i = 1; i <= cfg.vbr_max_bitrate_index; i++) {
        eov.bitrate_index = i;
        frameBits[i] = ResvFrameBegin(&bitsPerFrame);
    }
}



/*********************************************************************
 *
 *      VBR_prepare()
 *
 *  2000-09-04 Robert Hegemann
 *
 *  * converts LR to MS coding when necessary
 *  * calculates allowed/adjusted quantization noise amounts
 *  * detects analog silent frames
 *
 *  some remarks:
 *  - lower masking depending on Quality setting
 *  - quality control together with adjusted ATH MDCT scaling
 *    on lower quality setting allocate more noise from
 *    ATH masking, and on higher quality setting allocate
 *    less noise from ATH masking.
 *  - experiments show that going more than 2dB over GPSYCHO's
 *    limits ends up in very annoying artefacts
 *
 *********************************************************************/

/* RH: this one needs to be overhauled sometime */

int lame_internal_flags::VBR_old_prepare(
                const FLOAT pe[2][2], FLOAT const ms_ener_ratio[2],
                const III_psy_ratio ratio[2][2],
                FLOAT l3_xmin[2][2][SFBMAX],
                int frameBits[16], int min_bits[2][2], int max_bits[2][2], int bands[2][2]) {
//    SessionConfig_t const & cfg = gfc.cfg;
    EncResult_t & eov = ov_enc;

    FLOAT   masking_lower_db, adjust = 0.0;
    int     gr, ch;
    int     analog_silence = 1;
    int     avg, mxb, bits = 0;

    eov.bitrate_index = cfg.vbr_max_bitrate_index;
    avg = ResvFrameBegin(&avg) / cfg.mode_gr;

    get_framebits(frameBits);

    for (gr = 0; gr < cfg.mode_gr; gr++) {
        mxb = on_pe(pe, max_bits[gr], avg, gr, 0);
        if (ov_enc.mode_ext == MPG_MD_MS_LR) {
            ms_convert(l3_side, gr);
            reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb);
        }
        for (ch = 0; ch < cfg.channels_out; ++ch) {
            gr_info & cod_info = l3_side.tt[gr][ch];

            if (cod_info.block_type != SHORT_TYPE) { /* NORM, START or STOP type */
                adjust = 1.28 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.05;
                masking_lower_db = sv_qnt.mask_adjust - adjust;
            }
            else {
                adjust = 2.56 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.14;
                masking_lower_db = sv_qnt.mask_adjust_short - adjust;
            }
            sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);

            init_outer_loop(cod_info);
            bands[gr][ch] = calc_xmin(&ratio[gr][ch], cod_info, l3_xmin[gr][ch]);
            if (bands[gr][ch])
                analog_silence = 0;

            min_bits[gr][ch] = 126;

            bits += max_bits[gr][ch];
        }
    }
    for (gr = 0; gr < cfg.mode_gr; gr++) {
        for (ch = 0; ch < cfg.channels_out; ch++) {
            if (bits > frameBits[cfg.vbr_max_bitrate_index] && bits > 0) {
                max_bits[gr][ch] *= frameBits[cfg.vbr_max_bitrate_index];
                max_bits[gr][ch] /= bits;
            }
            if (min_bits[gr][ch] > max_bits[gr][ch])
                min_bits[gr][ch] = max_bits[gr][ch];

        }               /* for ch */
    }                   /* for gr */

    return analog_silence;
}

void lame_internal_flags::bitpressure_strategy(
                     FLOAT l3_xmin[2][2][SFBMAX], const int min_bits[2][2], int max_bits[2][2]) const{
//    SessionConfig_t const & cfg = gfc.cfg;
    int     gr, ch, sfb;
    for (gr = 0; gr < cfg.mode_gr; gr++) {
        for (ch = 0; ch < cfg.channels_out; ch++) {
            gr_info const & gi = l3_side.tt[gr][ch];
            FLOAT  *pxmin = l3_xmin[gr][ch];
            for (sfb = 0; sfb < gi.psy_lmax; sfb++)
                *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_l / SBMAX_l;

            if (gi.block_type == SHORT_TYPE) {
                for (sfb = gi.sfb_smin; sfb < SBMAX_s; sfb++) {
                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;
                }
            }
            max_bits[gr][ch] = Max(min_bits[gr][ch], 0.9 * max_bits[gr][ch]);
        }
    }
}

/************************************************************************
 *
 *      VBR_iteration_loop()
 *
 *  tries to find out how many bits are needed for each granule and channel
 *  to get an acceptable quantization. An appropriate bitrate will then be
 *  choosed for quantization.  rh 8/99
 *
 *  Robert Hegemann 2000-09-06 rewrite
 *
 ************************************************************************/

void lame_internal_flags::VBR_old_iteration_loop(const FLOAT pe[2][2],
                       const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) {
  SessionConfig_t const & cfg = this->cfg;
    EncResult_t & eov = ov_enc;
    FLOAT   l3_xmin[2][2][SFBMAX];

    FLOAT   xrpow[576];
    int     bands[2][2];
    int     frameBits[15];
    int     used_bits;
    int     bits;
    int     min_bits[2][2], max_bits[2][2];
    int     mean_bits;
    int     ch, gr, analog_silence;
    III_side_info_t & l3_side = this->l3_side;

    analog_silence = VBR_old_prepare(pe, ms_ener_ratio, ratio,
                                     l3_xmin, frameBits, min_bits, max_bits, bands);

    /*---------------------------------*/
    for (;;) {

        /*  quantize granules with lowest possible number of bits
         */

        used_bits = 0;

        for (gr = 0; gr < cfg.mode_gr; gr++) {
            for (ch = 0; ch < cfg.channels_out; ch++) {
                int     ret;
                gr_info & cod_info = l3_side.tt[gr][ch];

                /*  init_outer_loop sets up cod_info, scalefac and xrpow
                 */
                ret = init_xrpow(cod_info, xrpow);
                if (ret == 0 || max_bits[gr][ch] == 0) {
                    /*  xr contains no energy
                     *  l3_enc, our encoding data, will be quantized to zero
                     */
                    continue; /* with next channel */
                }

                VBR_encode_granule(cod_info, l3_xmin[gr][ch], xrpow,
                                   ch, min_bits[gr][ch], max_bits[gr][ch]);

                /*  do the 'substep shaping'
                 */
                if (sv_qnt.substep_shaping & 1) {
                    trancate_smallspectrums(l3_side.tt[gr][ch], l3_xmin[gr][ch], xrpow);
                }

                ret = cod_info.part2_3_length + cod_info.part2_length;
                used_bits += ret;
            }           /* for ch */
        }               /* for gr */

        /*  find lowest bitrate able to hold used bits
         */
        if (analog_silence && !cfg.enforce_min_bitrate)
            /*  we detected analog silence and the user did not specify
             *  any hard framesize limit, so start with smallest possible frame
             */
            eov.bitrate_index = 1;
        else
            eov.bitrate_index = cfg.vbr_min_bitrate_index;

        for (; eov.bitrate_index < cfg.vbr_max_bitrate_index; eov.bitrate_index++) {
            if (used_bits <= frameBits[eov.bitrate_index])
                break;
        }
        bits = ResvFrameBegin(&mean_bits);

        if (used_bits <= bits)
            break;

        bitpressure_strategy(l3_xmin, (const int (*)[2])min_bits, max_bits);

    }                   /* breaks adjusted */
    /*--------------------------------------*/

  for (gr = 0; gr < cfg.mode_gr; gr++) {
    for (ch = 0; ch < cfg.channels_out; ch++) {
      iteration_finish_one(gr, ch);
    }               /* for ch */
  }                   /* for gr */
  ResvFrameEnd(mean_bits);
}



int lame_internal_flags::VBR_new_prepare(
                const FLOAT pe[2][2], const III_psy_ratio ratio[2][2],
                FLOAT l3_xmin[2][2][SFBMAX], int frameBits[16], int max_bits[2][2],
                int* max_resv) {
//    SessionConfig_t const & cfg = cfg;
    EncResult_t & eov = ov_enc;

    int     gr, ch;
    int     analog_silence = 1;
    int     avg, bits = 0;
    int     maximum_framebits;

    if (!cfg.free_format) {
        eov.bitrate_index = cfg.vbr_max_bitrate_index;
        ResvFrameBegin(&avg);
        *max_resv = sv_enc.ResvMax;

        get_framebits(frameBits);
        maximum_framebits = frameBits[cfg.vbr_max_bitrate_index];
    }
    else {
        eov.bitrate_index = 0;
        maximum_framebits = ResvFrameBegin(&avg);
        frameBits[0] = maximum_framebits;
        *max_resv = sv_enc.ResvMax;
    }

    for (gr = 0; gr < cfg.mode_gr; gr++) {
      on_pe(pe, max_bits[gr], avg, gr, 0);
      if (ov_enc.mode_ext == MPG_MD_MS_LR) {
            ms_convert(l3_side, gr);
      }
        for (ch = 0; ch < cfg.channels_out; ++ch) {
            gr_info & cod_info = l3_side.tt[gr][ch];

            sv_qnt.masking_lower = pow(10.0, sv_qnt.mask_adjust * 0.1);

            init_outer_loop(cod_info);
            if (0 != calc_xmin(&ratio[gr][ch], cod_info, l3_xmin[gr][ch]))
                analog_silence = 0;

            bits += max_bits[gr][ch];
        }
    }
    for (gr = 0; gr < cfg.mode_gr; gr++) {
        for (ch = 0; ch < cfg.channels_out; ch++) {
            if (bits > maximum_framebits && bits > 0) {
                max_bits[gr][ch] *= maximum_framebits;
                max_bits[gr][ch] /= bits;
            }

        }               /* for ch */
    }                   /* for gr */
    if (analog_silence) {
        *max_resv = 0;
    }
    return analog_silence;
}



void lame_internal_flags::VBR_new_iteration_loop(const FLOAT pe[2][2],
                       const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) {
    SessionConfig_t const & cfg = this->cfg;
    EncResult_t & eov = ov_enc;
    FLOAT   l3_xmin[2][2][SFBMAX];

    FLOAT   xrpow[2][2][576];
    int     frameBits[15];
    int     used_bits;
    int     max_bits[2][2];
    int     ch, gr, analog_silence, pad;
    III_side_info_t & l3_side = this->l3_side;

    const FLOAT (*const_l3_xmin)[2][SFBMAX] = (const FLOAT (*)[2][SFBMAX])l3_xmin;
    const FLOAT (*const_xrpow)[2][576] = (const FLOAT (*)[2][576])xrpow;
    const int (*const_max_bits)[2] = (const int (*)[2])max_bits;
    
    (void) ms_ener_ratio; /* not used */

    memset(xrpow, 0, sizeof(xrpow));

    analog_silence = VBR_new_prepare(pe, ratio, l3_xmin, frameBits, max_bits, &pad);

    for (gr = 0; gr < cfg.mode_gr; gr++) {
        for (ch = 0; ch < cfg.channels_out; ch++) {
            gr_info & cod_info = l3_side.tt[gr][ch];

            /*  init_outer_loop sets up cod_info, scalefac and xrpow
             */
            if (0 == init_xrpow(cod_info, xrpow[gr][ch])) {
                max_bits[gr][ch] = 0; /* silent granule needs no bits */
            }
        }               /* for ch */
    }                   /* for gr */

    /*  quantize granules with lowest possible number of bits
     */

    used_bits = VBR_encode_frame(const_xrpow, const_l3_xmin, const_max_bits);

    if (!cfg.free_format) {
        int     i, j;

        /*  find lowest bitrate able to hold used bits
         */
        if (analog_silence && !cfg.enforce_min_bitrate) {
            /*  we detected analog silence and the user did not specify
             *  any hard framesize limit, so start with smallest possible frame
             */
            i = 1;
        }
        else {
            i = cfg.vbr_min_bitrate_index;
        }

        for (; i < cfg.vbr_max_bitrate_index; i++) {
            if (used_bits <= frameBits[i]) 
                break;
        }
        if (i > cfg.vbr_max_bitrate_index) {
            i = cfg.vbr_max_bitrate_index;
        }
        if (pad > 0) {
            for (j = cfg.vbr_max_bitrate_index; j > i; --j) {
                int const unused = frameBits[j] - used_bits;
                if (unused <= pad) 
                    break;
            }
            eov.bitrate_index = j;
        }
        else {
            eov.bitrate_index = i;
        }
    }
    else {
#if 0
        static int mmm = 0;
        int     fff = getFramesize_kbps(used_bits);
        int     hhh = getFramesize_kbps(MAX_BITS_PER_GRANULE * cfg.mode_gr);
        if (mmm < fff)
            mmm = fff;
        printf("demand=%3d kbps  max=%3d kbps   limit=%3d kbps\n", fff, mmm, hhh);
#endif
        eov.bitrate_index = 0;
    }
    if (used_bits <= frameBits[eov.bitrate_index]) {
        /* update Reservoire status */
        int     mean_bits, fullframebits;
        fullframebits = ResvFrameBegin(&mean_bits);
        assert(used_bits <= fullframebits);
        for (gr = 0; gr < cfg.mode_gr; gr++) {
            for (ch = 0; ch < cfg.channels_out; ch++) {
                gr_info const & cod_info = l3_side.tt[gr][ch];
                ResvAdjust(cod_info);
            }
        }
        ResvFrameEnd(mean_bits);
    }
    else {
        /* SHOULD NOT HAPPEN INTERNAL ERROR
         */
        ERRORF(*this, "INTERNAL ERROR IN VBR NEW CODE, please send bug report\n");
        exit(-1);
    }
}





/********************************************************************
 *
 *  calc_target_bits()
 *
 *  calculates target bits for ABR encoding
 *
 *  mt 2000/05/31
 *
 ********************************************************************/

void lame_internal_flags::calc_target_bits(
                 const FLOAT pe[2][2],
                 FLOAT const ms_ener_ratio[2],
                 int targ_bits[2][2], int *analog_silence_bits, int *max_frame_bits) {
//  SessionConfig_t const & cfg = gfc.cfg;
  EncResult_t & eov = ov_enc;
//  III_side_info_t const & l3_side = gfc.l3_side;
  FLOAT   res_factor;
  int     totbits, mean_bits;
  int     framesize = 576 * cfg.mode_gr;

  eov.bitrate_index = cfg.vbr_max_bitrate_index;
  *max_frame_bits = ResvFrameBegin(&mean_bits);

  eov.bitrate_index = 1;
  mean_bits = getframebits() - cfg.sideinfo_len * 8;
  *analog_silence_bits = mean_bits / (cfg.mode_gr * cfg.channels_out);

  mean_bits = cfg.vbr_avg_bitrate_kbps * framesize * 1000;
  if (sv_qnt.substep_shaping & 1) mean_bits *= 1.09;
  mean_bits /= cfg.samplerate_out;
  mean_bits -= cfg.sideinfo_len * 8;
  mean_bits /= (cfg.mode_gr * cfg.channels_out);

    /*
       res_factor is the percentage of the target bitrate that should
       be used on average.  the remaining bits are added to the
       bitreservoir and used for difficult to encode frames.

       Since we are tracking the average bitrate, we should adjust
       res_factor "on the fly", increasing it if the average bitrate
       is greater than the requested bitrate, and decreasing it
       otherwise.  Reasonable ranges are from .9 to 1.0

       Until we get the above suggestion working, we use the following
       tuning:
       compression ratio    res_factor
       5.5  (256kbps)         1.0      no need for bitreservoir
       11   (128kbps)         .93      7% held for reservoir

       with linear interpolation for other values.

     */
  res_factor = .93 + .07 * (11.0 - cfg.compression_ratio) / (11.0 - 5.5);
  if (res_factor < .90) res_factor = .90;
  if (res_factor > 1.00) res_factor = 1.00;
  for (int gr = 0; gr < cfg.mode_gr; gr++) {
    int     sum = 0;
    for (int ch = 0; ch < cfg.channels_out; ch++) {
      targ_bits[gr][ch] = res_factor * mean_bits;
      if (pe[gr][ch] > 700) {
        int     add_bits = (pe[gr][ch] - 700) / 1.4;
        gr_info const & cod_info = l3_side.tt[gr][ch];
        targ_bits[gr][ch] = res_factor * mean_bits;

                /* short blocks use a little extra, no matter what the pe */
        if (cod_info.block_type == SHORT_TYPE) {
          if (add_bits < mean_bits / 2) add_bits = mean_bits / 2;
        }
                /* at most increase bits by 1.5*average */
        if (add_bits > mean_bits * 3 / 2) add_bits = mean_bits * 3 / 2;
        else if (add_bits < 0) add_bits = 0;
        targ_bits[gr][ch] += add_bits;
      }
      if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL) {
        targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;
      }
      sum += targ_bits[gr][ch];
    }               /* for ch */
    if (sum > MAX_BITS_PER_GRANULE) {
      for (int ch = 0; ch < cfg.channels_out; ++ch) {
        targ_bits[gr][ch] *= MAX_BITS_PER_GRANULE;
        targ_bits[gr][ch] /= sum;
      }
    }
  }                   /* for gr */
  if (ov_enc.mode_ext == MPG_MD_MS_LR)
   for (int gr = 0; gr < cfg.mode_gr; gr++) {
    reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits * cfg.channels_out,
     MAX_BITS_PER_GRANULE);
  }

    /*  sum target bits
     */
  totbits = 0;
  {for (int gr = 0; gr < cfg.mode_gr; gr++) {
    for (int ch = 0; ch < cfg.channels_out; ch++) {
      if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL)
       targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;
      totbits += targ_bits[gr][ch];
    }
  }}

    /*  repartion target bits if needed
     */
  if (totbits > *max_frame_bits && totbits > 0) {
    for (int gr = 0; gr < cfg.mode_gr; gr++) {
      for (int ch = 0; ch < cfg.channels_out; ch++) {
        targ_bits[gr][ch] *= *max_frame_bits;
        targ_bits[gr][ch] /= totbits;
      }
    }
  }
}


/********************************************************************
 *
 *  ABR_iteration_loop()
 *
 *  encode a frame with a disired average bitrate
 *
 *  mt 2000/05/31
 *
 ********************************************************************/

void lame_internal_flags::ABR_iteration_loop(const FLOAT pe[2][2],
                   const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) {
  SessionConfig_t const &cfg = this->cfg;
  EncResult_t & eov = ov_enc;
  FLOAT   l3_xmin[SFBMAX];
  FLOAT   xrpow[576];
  int     targ_bits[2][2];
  int     mean_bits, max_frame_bits;
  int     ath_over;
  int     analog_silence_bits;
//   *cod_info;
  III_side_info_t & l3_side = this->l3_side;

  mean_bits = 0;

  calc_target_bits(pe, ms_ener_ratio, targ_bits, &analog_silence_bits, &max_frame_bits);

    /*  encode granules
     */
  for (int gr = 0; gr < cfg.mode_gr; gr++) {
    if (ov_enc.mode_ext == MPG_MD_MS_LR) ms_convert(l3_side, gr);
    for (int ch = 0; ch < cfg.channels_out; ch++) {
      FLOAT   adjust, masking_lower_db;
      gr_info&cod_info = l3_side.tt[gr][ch];
      if (cod_info.block_type != SHORT_TYPE) { /* NORM, START or STOP type */
                /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */
        adjust = 0;
        masking_lower_db = sv_qnt.mask_adjust - adjust;
      }else{
                /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */
        adjust = 0;
        masking_lower_db = sv_qnt.mask_adjust_short - adjust;
      }
      sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);
            /*  cod_info, scalefac and xrpow get initialized in init_outer_loop
             */
      init_outer_loop(cod_info);
      if (init_xrpow(cod_info, xrpow)) {
                /*  xr contains energy we will have to encode
                 *  calculate the masking abilities
                 *  find some good quantization in outer_loop
                 */
        ath_over = calc_xmin(&ratio[gr][ch], cod_info, l3_xmin);
        if (!ath_over) /* analog silence */
         targ_bits[gr][ch] = analog_silence_bits;
         outer_loop(cod_info, l3_xmin, xrpow, ch, targ_bits[gr][ch]);
      }
      iteration_finish_one(gr, ch);
    }               /* ch */
  }                   /* gr */

    /*  find a bitrate which can refill the resevoir to positive size.
     */
  for (eov.bitrate_index = cfg.vbr_min_bitrate_index;
         eov.bitrate_index <= cfg.vbr_max_bitrate_index; eov.bitrate_index++) {
    if (ResvFrameBegin(&mean_bits)>=0) break;
  }
  assert(eov.bitrate_index <= cfg.vbr_max_bitrate_index);

  ResvFrameEnd(mean_bits);
}


/************************************************************************
 *
 *      CBR_iteration_loop()
 *
 *  author/date??
 *
 *  encodes one frame of MP3 data with constant bitrate
 *
 ************************************************************************/

void lame_internal_flags::CBR_iteration_loop(const FLOAT pe[2][2],
	const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2]) {
  SessionConfig_t const & cfg = this->cfg;
  FLOAT   l3_xmin[SFBMAX];
  FLOAT   xrpow[576];
  int     targ_bits[2];
  int     mean_bits, max_bits;
  III_side_info_t &l3_side = this->l3_side;
//  gr_info *cod_info;

  (void) ResvFrameBegin(&mean_bits);

    /* quantize! */
  for (int gr = 0; gr < cfg.mode_gr; gr++) {
        /*  calculate needed bits         */
    max_bits = on_pe(pe, targ_bits, mean_bits, gr, gr);
    if (ov_enc.mode_ext == MPG_MD_MS_LR) {
      ms_convert(l3_side, gr);
      reduce_side(targ_bits, ms_ener_ratio[gr], mean_bits, max_bits);
    }
    for (int ch = 0; ch < cfg.channels_out; ch++) {
      FLOAT   adjust, masking_lower_db;
      gr_info&cod_info = l3_side.tt[gr][ch];

      if (cod_info.block_type != SHORT_TYPE) { /* NORM, START or STOP type */
                /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */
        adjust = 0;
        masking_lower_db = sv_qnt.mask_adjust - adjust;
      }else{
                /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */
        adjust = 0;
        masking_lower_db = sv_qnt.mask_adjust_short - adjust;
      }
      sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);

            /*  init_outer_loop sets up cod_info, scalefac and xrpow
             */
      init_outer_loop(cod_info);
      if (init_xrpow(cod_info, xrpow)) {
                /*  xr contains energy we will have to encode
                 *  calculate the masking abilities
                 *  find some good quantization in outer_loop
                 */
        calc_xmin(&ratio[gr][ch], cod_info, l3_xmin);
        outer_loop(cod_info, l3_xmin, xrpow, ch, targ_bits[ch]);
      }
      iteration_finish_one(gr, ch);
      assert(cod_info.part2_3_length <= MAX_BITS_PER_CHANNEL);
      assert(cod_info.part2_3_length <= targ_bits[ch]);
    }               /* for ch */
  }                   /* for gr */
  ResvFrameEnd(mean_bits);
}
Detected encoding: ASCII (7 bit)2