Blame libmp3lame/vbrquantize.c

Packit 47f805
/*
Packit 47f805
 *	MP3 quantization
Packit 47f805
 *
Packit 47f805
 *	Copyright (c) 1999-2000 Mark Taylor
Packit 47f805
 *	Copyright (c) 2000-2012 Robert Hegemann
Packit 47f805
 *
Packit 47f805
 * This library is free software; you can redistribute it and/or
Packit 47f805
 * modify it under the terms of the GNU Library General Public
Packit 47f805
 * License as published by the Free Software Foundation; either
Packit 47f805
 * version 2 of the License, or (at your option) any later version.
Packit 47f805
 *
Packit 47f805
 * This library is distributed in the hope that it will be useful,
Packit 47f805
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 47f805
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
Packit 47f805
 * Library General Public License for more details.
Packit 47f805
 *
Packit 47f805
 * You should have received a copy of the GNU Library General Public
Packit 47f805
 * License along with this library; if not, write to the
Packit 47f805
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 47f805
 * Boston, MA 02111-1307, USA.
Packit 47f805
 */
Packit 47f805
Packit 47f805
/* $Id: vbrquantize.c,v 1.142 2012/02/07 13:36:35 robert Exp $ */
Packit 47f805
Packit 47f805
#ifdef HAVE_CONFIG_H
Packit 47f805
#  include <config.h>
Packit 47f805
#endif
Packit 47f805
Packit 47f805
Packit 47f805
#include "lame.h"
Packit 47f805
#include "machine.h"
Packit 47f805
#include "encoder.h"
Packit 47f805
#include "util.h"
Packit 47f805
#include "vbrquantize.h"
Packit 47f805
#include "quantize_pvt.h"
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
struct algo_s;
Packit 47f805
typedef struct algo_s algo_t;
Packit 47f805
Packit 47f805
typedef void (*alloc_sf_f) (const algo_t *, const int *, const int *, int);
Packit 47f805
typedef uint8_t (*find_sf_f) (const FLOAT *, const FLOAT *, FLOAT, unsigned int, uint8_t);
Packit 47f805
Packit 47f805
struct algo_s {
Packit 47f805
    alloc_sf_f alloc;
Packit 47f805
    find_sf_f  find;
Packit 47f805
    const FLOAT *xr34orig;
Packit 47f805
    lame_internal_flags *gfc;
Packit 47f805
    gr_info *cod_info;
Packit 47f805
    int     mingain_l;
Packit 47f805
    int     mingain_s[3];
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*  Remarks on optimizing compilers:
Packit 47f805
 *
Packit 47f805
 *  the MSVC compiler may get into aliasing problems when accessing
Packit 47f805
 *  memory through the fi_union. declaring it volatile does the trick here
Packit 47f805
 *
Packit 47f805
 *  the calc_sfb_noise_* functions are not inlined because the intel compiler
Packit 47f805
 *  optimized executeables won't work as expected anymore
Packit 47f805
 */
Packit 47f805
Packit 47f805
#ifdef _MSC_VER
Packit 47f805
#  if _MSC_VER < 1400
Packit 47f805
#  define VOLATILE volatile
Packit 47f805
#  else
Packit 47f805
#  define VOLATILE
Packit 47f805
#  endif
Packit 47f805
#else
Packit 47f805
#  define VOLATILE
Packit 47f805
#endif
Packit 47f805
Packit 47f805
typedef VOLATILE union {
Packit 47f805
    float   f;
Packit 47f805
    int     i;
Packit 47f805
} fi_union;
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
#ifdef TAKEHIRO_IEEE754_HACK
Packit 47f805
#define DOUBLEX double
Packit 47f805
#else
Packit 47f805
#define DOUBLEX FLOAT
Packit 47f805
#endif
Packit 47f805
 
Packit 47f805
#define MAGIC_FLOAT_def (65536*(128))
Packit 47f805
#define MAGIC_INT_def    0x4b000000
Packit 47f805
Packit 47f805
#ifdef TAKEHIRO_IEEE754_HACK
Packit 47f805
#else
Packit 47f805
/*********************************************************************
Packit 47f805
 * XRPOW_FTOI is a macro to convert floats to ints.
Packit 47f805
 * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]
Packit 47f805
 *                                         ROUNDFAC= -0.0946
Packit 47f805
 *
Packit 47f805
 * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]
Packit 47f805
 *                                   ROUNDFAC=0.4054
Packit 47f805
 *********************************************************************/
Packit 47f805
#  define QUANTFAC(rx)  adj43[rx]
Packit 47f805
#  define ROUNDFAC_def 0.4054f
Packit 47f805
#  define XRPOW_FTOI(src,dest) ((dest) = (int)(src))
Packit 47f805
#endif
Packit 47f805
Packit 47f805
static int const MAGIC_INT = MAGIC_INT_def;
Packit 47f805
#ifndef TAKEHIRO_IEEE754_HACK
Packit 47f805
static DOUBLEX const ROUNDFAC = ROUNDFAC_def;
Packit 47f805
#endif
Packit 47f805
static DOUBLEX const MAGIC_FLOAT = MAGIC_FLOAT_def;
Packit 47f805
Packit 47f805
Packit 47f805
inline static  float
Packit 47f805
vec_max_c(const float * xr34, unsigned int bw)
Packit 47f805
{
Packit 47f805
    float   xfsf = 0;
Packit 47f805
    unsigned int i = bw >> 2u;
Packit 47f805
    unsigned int const remaining = (bw & 0x03u);
Packit 47f805
Packit 47f805
    while (i-- > 0) {
Packit 47f805
        if (xfsf < xr34[0]) {
Packit 47f805
            xfsf = xr34[0];
Packit 47f805
        }
Packit 47f805
        if (xfsf < xr34[1]) {
Packit 47f805
            xfsf = xr34[1];
Packit 47f805
        }
Packit 47f805
        if (xfsf < xr34[2]) {
Packit 47f805
            xfsf = xr34[2];
Packit 47f805
        }
Packit 47f805
        if (xfsf < xr34[3]) {
Packit 47f805
            xfsf = xr34[3];
Packit 47f805
        }
Packit 47f805
        xr34 += 4;
Packit 47f805
    }
Packit 47f805
    switch( remaining ) {
Packit 47f805
    case 3: if (xfsf < xr34[2]) xfsf = xr34[2];
Packit 47f805
    case 2: if (xfsf < xr34[1]) xfsf = xr34[1];
Packit 47f805
    case 1: if (xfsf < xr34[0]) xfsf = xr34[0];
Packit 47f805
    default: break;
Packit 47f805
    }
Packit 47f805
    return xfsf;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
inline static  uint8_t
Packit 47f805
find_lowest_scalefac(const FLOAT xr34)
Packit 47f805
{
Packit 47f805
    uint8_t sf_ok = 255;
Packit 47f805
    uint8_t sf = 128, delsf = 64;
Packit 47f805
    uint8_t i;
Packit 47f805
    FLOAT const ixmax_val = IXMAX_VAL;
Packit 47f805
    for (i = 0; i < 8; ++i) {
Packit 47f805
        FLOAT const xfsf = ipow20[sf] * xr34;
Packit 47f805
        if (xfsf <= ixmax_val) {
Packit 47f805
            sf_ok = sf;
Packit 47f805
            sf -= delsf;
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            sf += delsf;
Packit 47f805
        }
Packit 47f805
        delsf >>= 1;
Packit 47f805
    }
Packit 47f805
    return sf_ok;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
inline static void
Packit 47f805
k_34_4(DOUBLEX x[4], int l3[4])
Packit 47f805
{
Packit 47f805
#ifdef TAKEHIRO_IEEE754_HACK
Packit 47f805
    fi_union fi[4];
Packit 47f805
Packit 47f805
    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);
Packit 47f805
    x[0] += MAGIC_FLOAT;
Packit 47f805
    fi[0].f = x[0];
Packit 47f805
    x[1] += MAGIC_FLOAT;
Packit 47f805
    fi[1].f = x[1];
Packit 47f805
    x[2] += MAGIC_FLOAT;
Packit 47f805
    fi[2].f = x[2];
Packit 47f805
    x[3] += MAGIC_FLOAT;
Packit 47f805
    fi[3].f = x[3];
Packit 47f805
    fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT];
Packit 47f805
    fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT];
Packit 47f805
    fi[2].f = x[2] + adj43asm[fi[2].i - MAGIC_INT];
Packit 47f805
    fi[3].f = x[3] + adj43asm[fi[3].i - MAGIC_INT];
Packit 47f805
    l3[0] = fi[0].i - MAGIC_INT;
Packit 47f805
    l3[1] = fi[1].i - MAGIC_INT;
Packit 47f805
    l3[2] = fi[2].i - MAGIC_INT;
Packit 47f805
    l3[3] = fi[3].i - MAGIC_INT;
Packit 47f805
#else
Packit 47f805
    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);
Packit 47f805
    XRPOW_FTOI(x[0], l3[0]);
Packit 47f805
    XRPOW_FTOI(x[1], l3[1]);
Packit 47f805
    XRPOW_FTOI(x[2], l3[2]);
Packit 47f805
    XRPOW_FTOI(x[3], l3[3]);
Packit 47f805
    x[0] += QUANTFAC(l3[0]);
Packit 47f805
    x[1] += QUANTFAC(l3[1]);
Packit 47f805
    x[2] += QUANTFAC(l3[2]);
Packit 47f805
    x[3] += QUANTFAC(l3[3]);
Packit 47f805
    XRPOW_FTOI(x[0], l3[0]);
Packit 47f805
    XRPOW_FTOI(x[1], l3[1]);
Packit 47f805
    XRPOW_FTOI(x[2], l3[2]);
Packit 47f805
    XRPOW_FTOI(x[3], l3[3]);
Packit 47f805
#endif
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*  do call the calc_sfb_noise_* functions only with sf values
Packit 47f805
 *  for which holds: sfpow34*xr34 <= IXMAX_VAL
Packit 47f805
 */
Packit 47f805
Packit 47f805
static  FLOAT
Packit 47f805
calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, uint8_t sf)
Packit 47f805
{
Packit 47f805
    DOUBLEX x[4];
Packit 47f805
    int     l3[4];
Packit 47f805
    const FLOAT sfpow = pow20[sf + Q_MAX2]; /*pow(2.0,sf/4.0); */
Packit 47f805
    const FLOAT sfpow34 = ipow20[sf]; /*pow(sfpow,-3.0/4.0); */
Packit 47f805
Packit 47f805
    FLOAT   xfsf = 0;
Packit 47f805
    unsigned int i = bw >> 2u;
Packit 47f805
    unsigned int const remaining = (bw & 0x03u);
Packit 47f805
Packit 47f805
    while (i-- > 0) {
Packit 47f805
        x[0] = sfpow34 * xr34[0];
Packit 47f805
        x[1] = sfpow34 * xr34[1];
Packit 47f805
        x[2] = sfpow34 * xr34[2];
Packit 47f805
        x[3] = sfpow34 * xr34[3];
Packit 47f805
Packit 47f805
        k_34_4(x, l3);
Packit 47f805
Packit 47f805
        x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];
Packit 47f805
        x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];
Packit 47f805
        x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];
Packit 47f805
        x[3] = fabsf(xr[3]) - sfpow * pow43[l3[3]];
Packit 47f805
        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);
Packit 47f805
Packit 47f805
        xr += 4;
Packit 47f805
        xr34 += 4;
Packit 47f805
    }
Packit 47f805
    if (remaining) {
Packit 47f805
        x[0] = x[1] = x[2] = x[3] = 0;
Packit 47f805
        switch( remaining ) {
Packit 47f805
        case 3: x[2] = sfpow34 * xr34[2];
Packit 47f805
        case 2: x[1] = sfpow34 * xr34[1];
Packit 47f805
        case 1: x[0] = sfpow34 * xr34[0];
Packit 47f805
        }
Packit 47f805
Packit 47f805
        k_34_4(x, l3);
Packit 47f805
        x[0] = x[1] = x[2] = x[3] = 0;
Packit 47f805
Packit 47f805
        switch( remaining ) {
Packit 47f805
        case 3: x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];
Packit 47f805
        case 2: x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];
Packit 47f805
        case 1: x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];
Packit 47f805
        }
Packit 47f805
        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);
Packit 47f805
    }
Packit 47f805
    return xfsf;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
struct calc_noise_cache {
Packit 47f805
    int     valid;
Packit 47f805
    FLOAT   value;
Packit 47f805
};
Packit 47f805
Packit 47f805
typedef struct calc_noise_cache calc_noise_cache_t;
Packit 47f805
Packit 47f805
Packit 47f805
static  uint8_t
Packit 47f805
tri_calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,
Packit 47f805
                       uint8_t sf, calc_noise_cache_t * did_it)
Packit 47f805
{
Packit 47f805
    if (did_it[sf].valid == 0) {
Packit 47f805
        did_it[sf].valid = 1;
Packit 47f805
        did_it[sf].value = calc_sfb_noise_x34(xr, xr34, bw, sf);
Packit 47f805
    }
Packit 47f805
    if (l3_xmin < did_it[sf].value) {
Packit 47f805
        return 1;
Packit 47f805
    }
Packit 47f805
    if (sf < 255) {
Packit 47f805
        uint8_t const sf_x = sf + 1;
Packit 47f805
        if (did_it[sf_x].valid == 0) {
Packit 47f805
            did_it[sf_x].valid = 1;
Packit 47f805
            did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);
Packit 47f805
        }
Packit 47f805
        if (l3_xmin < did_it[sf_x].value) {
Packit 47f805
            return 1;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (sf > 0) {
Packit 47f805
        uint8_t const sf_x = sf - 1;
Packit 47f805
        if (did_it[sf_x].valid == 0) {
Packit 47f805
            did_it[sf_x].valid = 1;
Packit 47f805
            did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);
Packit 47f805
        }
Packit 47f805
        if (l3_xmin < did_it[sf_x].value) {
Packit 47f805
            return 1;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return 0;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
/**
Packit 47f805
 *  Robert Hegemann 2001-05-01
Packit 47f805
 *  calculates quantization step size determined by allowed masking
Packit 47f805
 */
Packit 47f805
static int
Packit 47f805
calc_scalefac(FLOAT l3_xmin, int bw)
Packit 47f805
{
Packit 47f805
    FLOAT const c = 5.799142446; /* 10 * 10^(2/3) * log10(4/3) */
Packit 47f805
    return 210 + (int) (c * log10f(l3_xmin / bw) - .5f);
Packit 47f805
}
Packit 47f805
Packit 47f805
static uint8_t
Packit 47f805
guess_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min)
Packit 47f805
{
Packit 47f805
    int const guess = calc_scalefac(l3_xmin, bw);
Packit 47f805
    if (guess < sf_min) return sf_min;
Packit 47f805
    if (guess >= 255) return 255;
Packit 47f805
    (void) xr;
Packit 47f805
    (void) xr34;
Packit 47f805
    return guess;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
/* the find_scalefac* routines calculate
Packit 47f805
 * a quantization step size which would
Packit 47f805
 * introduce as much noise as is allowed.
Packit 47f805
 * The larger the step size the more
Packit 47f805
 * quantization noise we'll get. The
Packit 47f805
 * scalefactors are there to lower the
Packit 47f805
 * global step size, allowing limited
Packit 47f805
 * differences in quantization step sizes
Packit 47f805
 * per band (shaping the noise).
Packit 47f805
 */
Packit 47f805
Packit 47f805
static  uint8_t
Packit 47f805
find_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,
Packit 47f805
                  uint8_t sf_min)
Packit 47f805
{
Packit 47f805
    calc_noise_cache_t did_it[256];
Packit 47f805
    uint8_t sf = 128, sf_ok = 255, delsf = 128, seen_good_one = 0, i;
Packit 47f805
    memset(did_it, 0, sizeof(did_it));
Packit 47f805
    for (i = 0; i < 8; ++i) {
Packit 47f805
        delsf >>= 1;
Packit 47f805
        if (sf <= sf_min) {
Packit 47f805
            sf += delsf;
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            uint8_t const bad = tri_calc_sfb_noise_x34(xr, xr34, l3_xmin, bw, sf, did_it);
Packit 47f805
            if (bad) {  /* distortion.  try a smaller scalefactor */
Packit 47f805
                sf -= delsf;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                sf_ok = sf;
Packit 47f805
                sf += delsf;
Packit 47f805
                seen_good_one = 1;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    /*  returning a scalefac without distortion, if possible
Packit 47f805
     */
Packit 47f805
    if (seen_good_one > 0) {
Packit 47f805
        sf = sf_ok;
Packit 47f805
    }
Packit 47f805
    if (sf <= sf_min) {
Packit 47f805
        sf = sf_min;
Packit 47f805
    }
Packit 47f805
    return sf;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/***********************************************************************
Packit 47f805
 *
Packit 47f805
 *      calc_short_block_vbr_sf()
Packit 47f805
 *      calc_long_block_vbr_sf()
Packit 47f805
 *
Packit 47f805
 *  Mark Taylor 2000-??-??
Packit 47f805
 *  Robert Hegemann 2000-10-25 made functions of it
Packit 47f805
 *
Packit 47f805
 ***********************************************************************/
Packit 47f805
Packit 47f805
/* a variation for vbr-mtrh */
Packit 47f805
static int
Packit 47f805
block_sf(algo_t * that, const FLOAT l3_xmin[SFBMAX], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX])
Packit 47f805
{
Packit 47f805
    FLOAT   max_xr34;
Packit 47f805
    const FLOAT *const xr = &that->cod_info->xr[0];
Packit 47f805
    const FLOAT *const xr34_orig = &that->xr34orig[0];
Packit 47f805
    const int *const width = &that->cod_info->width[0];
Packit 47f805
    const char *const energy_above_cutoff = &that->cod_info->energy_above_cutoff[0];
Packit 47f805
    unsigned int const max_nonzero_coeff = (unsigned int) that->cod_info->max_nonzero_coeff;
Packit 47f805
    uint8_t maxsf = 0;
Packit 47f805
    int     sfb = 0, m_o = -1;
Packit 47f805
    unsigned int j = 0, i = 0;
Packit 47f805
    int const psymax = that->cod_info->psymax;
Packit 47f805
Packit 47f805
    assert(that->cod_info->max_nonzero_coeff >= 0);
Packit 47f805
Packit 47f805
    that->mingain_l = 0;
Packit 47f805
    that->mingain_s[0] = 0;
Packit 47f805
    that->mingain_s[1] = 0;
Packit 47f805
    that->mingain_s[2] = 0;
Packit 47f805
    while (j <= max_nonzero_coeff) {
Packit 47f805
        unsigned int const w = (unsigned int) width[sfb];
Packit 47f805
        unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);
Packit 47f805
        unsigned int l = w;
Packit 47f805
        uint8_t m1, m2;
Packit 47f805
        if (l > m) {
Packit 47f805
            l = m;
Packit 47f805
        }
Packit 47f805
        max_xr34 = vec_max_c(&xr34_orig[j], l);
Packit 47f805
Packit 47f805
        m1 = find_lowest_scalefac(max_xr34);
Packit 47f805
        vbrsfmin[sfb] = m1;
Packit 47f805
        if (that->mingain_l < m1) {
Packit 47f805
            that->mingain_l = m1;
Packit 47f805
        }
Packit 47f805
        if (that->mingain_s[i] < m1) {
Packit 47f805
            that->mingain_s[i] = m1;
Packit 47f805
        }
Packit 47f805
        if (++i > 2) {
Packit 47f805
            i = 0;
Packit 47f805
        }
Packit 47f805
        if (sfb < psymax && w > 2) { /* mpeg2.5 at 8 kHz doesn't use all scalefactors, unused have width 2 */
Packit 47f805
            if (energy_above_cutoff[sfb]) {
Packit 47f805
                m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1);
Packit 47f805
#if 0
Packit 47f805
                if (0) {
Packit 47f805
                    /** Robert Hegemann 2007-09-29:
Packit 47f805
                     *  It seems here is some more potential for speed improvements.
Packit 47f805
                     *  Current find method does 11-18 quantization calculations.
Packit 47f805
                     *  Using a "good guess" may help to reduce this amount.
Packit 47f805
                     */
Packit 47f805
                    uint8_t guess = calc_scalefac(l3_xmin[sfb], l);
Packit 47f805
                    DEBUGF(that->gfc, "sfb=%3d guess=%3d found=%3d diff=%3d\n", sfb, guess, m2,
Packit 47f805
                           m2 - guess);
Packit 47f805
                }
Packit 47f805
#endif
Packit 47f805
                if (maxsf < m2) {
Packit 47f805
                    maxsf = m2;
Packit 47f805
                }
Packit 47f805
                if (m_o < m2 && m2 < 255) {
Packit 47f805
                    m_o = m2;
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                m2 = 255;
Packit 47f805
                maxsf = 255;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            if (maxsf < m1) {
Packit 47f805
                maxsf = m1;
Packit 47f805
            }
Packit 47f805
            m2 = maxsf;
Packit 47f805
        }
Packit 47f805
        vbrsf[sfb] = m2;
Packit 47f805
        ++sfb;
Packit 47f805
        j += w;        
Packit 47f805
    }
Packit 47f805
    for (; sfb < SFBMAX; ++sfb) {
Packit 47f805
        vbrsf[sfb] = maxsf;
Packit 47f805
        vbrsfmin[sfb] = 0;
Packit 47f805
    }
Packit 47f805
    if (m_o > -1) {
Packit 47f805
        maxsf = m_o;
Packit 47f805
        for (sfb = 0; sfb < SFBMAX; ++sfb) {
Packit 47f805
            if (vbrsf[sfb] == 255) {
Packit 47f805
                vbrsf[sfb] = m_o;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return maxsf;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/***********************************************************************
Packit 47f805
 *
Packit 47f805
 *  quantize xr34 based on scalefactors
Packit 47f805
 *
Packit 47f805
 *  block_xr34
Packit 47f805
 *
Packit 47f805
 *  Mark Taylor 2000-??-??
Packit 47f805
 *  Robert Hegemann 2000-10-20 made functions of them
Packit 47f805
 *
Packit 47f805
 ***********************************************************************/
Packit 47f805
Packit 47f805
static void
Packit 47f805
quantize_x34(const algo_t * that)
Packit 47f805
{
Packit 47f805
    DOUBLEX x[4];
Packit 47f805
    const FLOAT *xr34_orig = that->xr34orig;
Packit 47f805
    gr_info *const cod_info = that->cod_info;
Packit 47f805
    int const ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;
Packit 47f805
    int    *l3 = cod_info->l3_enc;
Packit 47f805
    unsigned int j = 0, sfb = 0;
Packit 47f805
    unsigned int const max_nonzero_coeff = (unsigned int) cod_info->max_nonzero_coeff;
Packit 47f805
Packit 47f805
    assert(cod_info->max_nonzero_coeff >= 0);
Packit 47f805
    assert(cod_info->max_nonzero_coeff < 576);
Packit 47f805
Packit 47f805
    while (j <= max_nonzero_coeff) {
Packit 47f805
        int const s =
Packit 47f805
            (cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep
Packit 47f805
            + cod_info->subblock_gain[cod_info->window[sfb]] * 8;
Packit 47f805
        uint8_t const sfac = (uint8_t) (cod_info->global_gain - s);
Packit 47f805
        FLOAT const sfpow34 = ipow20[sfac];
Packit 47f805
        unsigned int const w = (unsigned int) cod_info->width[sfb];
Packit 47f805
        unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);
Packit 47f805
        unsigned int i, remaining;
Packit 47f805
Packit 47f805
        assert((cod_info->global_gain - s) >= 0);
Packit 47f805
        assert(cod_info->width[sfb] >= 0);
Packit 47f805
        j += w;
Packit 47f805
        ++sfb;
Packit 47f805
        
Packit 47f805
        i = (w <= m) ? w : m;
Packit 47f805
        remaining = (i & 0x03u);
Packit 47f805
        i >>= 2u;
Packit 47f805
Packit 47f805
        while (i-- > 0) {
Packit 47f805
            x[0] = sfpow34 * xr34_orig[0];
Packit 47f805
            x[1] = sfpow34 * xr34_orig[1];
Packit 47f805
            x[2] = sfpow34 * xr34_orig[2];
Packit 47f805
            x[3] = sfpow34 * xr34_orig[3];
Packit 47f805
Packit 47f805
            k_34_4(x, l3);
Packit 47f805
Packit 47f805
            l3 += 4;
Packit 47f805
            xr34_orig += 4;
Packit 47f805
        }
Packit 47f805
        if (remaining) {
Packit 47f805
            int tmp_l3[4];
Packit 47f805
            x[0] = x[1] = x[2] = x[3] = 0;
Packit 47f805
            switch( remaining ) {
Packit 47f805
            case 3: x[2] = sfpow34 * xr34_orig[2];
Packit 47f805
            case 2: x[1] = sfpow34 * xr34_orig[1];
Packit 47f805
            case 1: x[0] = sfpow34 * xr34_orig[0];
Packit 47f805
            }
Packit 47f805
Packit 47f805
            k_34_4(x, tmp_l3);
Packit 47f805
Packit 47f805
            switch( remaining ) {
Packit 47f805
            case 3: l3[2] = tmp_l3[2];
Packit 47f805
            case 2: l3[1] = tmp_l3[1];
Packit 47f805
            case 1: l3[0] = tmp_l3[0];
Packit 47f805
            }
Packit 47f805
Packit 47f805
            l3 += remaining;
Packit 47f805
            xr34_orig += remaining;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static const uint8_t max_range_short[SBMAX_s * 3] = {
Packit 47f805
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
Packit 47f805
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
Packit 47f805
    0, 0, 0
Packit 47f805
};
Packit 47f805
Packit 47f805
static const uint8_t max_range_long[SBMAX_l] = {
Packit 47f805
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0
Packit 47f805
};
Packit 47f805
Packit 47f805
static const uint8_t max_range_long_lsf_pretab[SBMAX_l] = {
Packit 47f805
    7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
Packit 47f805
};
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*
Packit 47f805
    sfb=0..5  scalefac < 16
Packit 47f805
    sfb>5     scalefac < 8
Packit 47f805
Packit 47f805
    ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
Packit 47f805
    ol_sf =  (cod_info->global_gain-210.0);
Packit 47f805
    ol_sf -= 8*cod_info->subblock_gain[i];
Packit 47f805
    ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];
Packit 47f805
*/
Packit 47f805
Packit 47f805
static void
Packit 47f805
set_subblock_gain(gr_info * cod_info, const int mingain_s[3], int sf[])
Packit 47f805
{
Packit 47f805
    const int maxrange1 = 15, maxrange2 = 7;
Packit 47f805
    const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;
Packit 47f805
    int    *const sbg = cod_info->subblock_gain;
Packit 47f805
    unsigned int const psymax = (unsigned int) cod_info->psymax;
Packit 47f805
    unsigned int psydiv = 18;
Packit 47f805
    int     sbg0, sbg1, sbg2;
Packit 47f805
    unsigned int sfb, i;
Packit 47f805
    int     min_sbg = 7;
Packit 47f805
Packit 47f805
    if (psydiv > psymax) {
Packit 47f805
        psydiv = psymax;
Packit 47f805
    }
Packit 47f805
    for (i = 0; i < 3; ++i) {
Packit 47f805
        int     maxsf1 = 0, maxsf2 = 0, minsf = 1000;
Packit 47f805
        /* see if we should use subblock gain */
Packit 47f805
        for (sfb = i; sfb < psydiv; sfb += 3) { /* part 1 */
Packit 47f805
            int const v = -sf[sfb];
Packit 47f805
            if (maxsf1 < v) {
Packit 47f805
                maxsf1 = v;
Packit 47f805
            }
Packit 47f805
            if (minsf > v) {
Packit 47f805
                minsf = v;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        for (; sfb < SFBMAX; sfb += 3) { /* part 2 */
Packit 47f805
            int const v = -sf[sfb];
Packit 47f805
            if (maxsf2 < v) {
Packit 47f805
                maxsf2 = v;
Packit 47f805
            }
Packit 47f805
            if (minsf > v) {
Packit 47f805
                minsf = v;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
Packit 47f805
        /* boost subblock gain as little as possible so we can
Packit 47f805
         * reach maxsf1 with scalefactors
Packit 47f805
         * 8*sbg >= maxsf1
Packit 47f805
         */
Packit 47f805
        {
Packit 47f805
            int const m1 = maxsf1 - (maxrange1 << ifqstepShift);
Packit 47f805
            int const m2 = maxsf2 - (maxrange2 << ifqstepShift);
Packit 47f805
Packit 47f805
            maxsf1 = Max(m1, m2);
Packit 47f805
        }
Packit 47f805
        if (minsf > 0) {
Packit 47f805
            sbg[i] = minsf >> 3;
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            sbg[i] = 0;
Packit 47f805
        }
Packit 47f805
        if (maxsf1 > 0) {
Packit 47f805
            int const m1 = sbg[i];
Packit 47f805
            int const m2 = (maxsf1 + 7) >> 3;
Packit 47f805
            sbg[i] = Max(m1, m2);
Packit 47f805
        }
Packit 47f805
        if (sbg[i] > 0 && mingain_s[i] > (cod_info->global_gain - sbg[i] * 8)) {
Packit 47f805
            sbg[i] = (cod_info->global_gain - mingain_s[i]) >> 3;
Packit 47f805
        }
Packit 47f805
        if (sbg[i] > 7) {
Packit 47f805
            sbg[i] = 7;
Packit 47f805
        }
Packit 47f805
        if (min_sbg > sbg[i]) {
Packit 47f805
            min_sbg = sbg[i];
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    sbg0 = sbg[0] * 8;
Packit 47f805
    sbg1 = sbg[1] * 8;
Packit 47f805
    sbg2 = sbg[2] * 8;
Packit 47f805
    for (sfb = 0; sfb < SFBMAX; sfb += 3) {
Packit 47f805
        sf[sfb + 0] += sbg0;
Packit 47f805
        sf[sfb + 1] += sbg1;
Packit 47f805
        sf[sfb + 2] += sbg2;
Packit 47f805
    }
Packit 47f805
    if (min_sbg > 0) {
Packit 47f805
        for (i = 0; i < 3; ++i) {
Packit 47f805
            sbg[i] -= min_sbg;
Packit 47f805
        }
Packit 47f805
        cod_info->global_gain -= min_sbg * 8;
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*
Packit 47f805
	  ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;
Packit 47f805
	  ol_sf =  (cod_info->global_gain-210.0);
Packit 47f805
	  ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];
Packit 47f805
	  if (cod_info->preflag && sfb>=11)
Packit 47f805
	  ol_sf -= ifqstep*pretab[sfb];
Packit 47f805
*/
Packit 47f805
static void
Packit 47f805
set_scalefacs(gr_info * cod_info, const int *vbrsfmin, int sf[], const uint8_t * max_range)
Packit 47f805
{
Packit 47f805
    const int ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;
Packit 47f805
    const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;
Packit 47f805
    int    *const scalefac = cod_info->scalefac;
Packit 47f805
    int const sfbmax = cod_info->sfbmax;
Packit 47f805
    int     sfb;
Packit 47f805
    int const *const sbg = cod_info->subblock_gain;
Packit 47f805
    int const *const window = cod_info->window;
Packit 47f805
    int const preflag = cod_info->preflag;
Packit 47f805
Packit 47f805
    if (preflag) {
Packit 47f805
        for (sfb = 11; sfb < sfbmax; ++sfb) {
Packit 47f805
            sf[sfb] += pretab[sfb] * ifqstep;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    for (sfb = 0; sfb < sfbmax; ++sfb) {
Packit 47f805
        int const gain = cod_info->global_gain - (sbg[window[sfb]] * 8)
Packit 47f805
            - ((preflag ? pretab[sfb] : 0) * ifqstep);
Packit 47f805
Packit 47f805
        if (sf[sfb] < 0) {
Packit 47f805
            int const m = gain - vbrsfmin[sfb];
Packit 47f805
            /* ifqstep*scalefac >= -sf[sfb], so round UP */
Packit 47f805
            scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift;
Packit 47f805
Packit 47f805
            if (scalefac[sfb] > max_range[sfb]) {
Packit 47f805
                scalefac[sfb] = max_range[sfb];
Packit 47f805
            }
Packit 47f805
            if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) {
Packit 47f805
                scalefac[sfb] = m >> ifqstepShift;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            scalefac[sfb] = 0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    for (; sfb < SFBMAX; ++sfb) {
Packit 47f805
        scalefac[sfb] = 0; /* sfb21 */
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
#ifndef NDEBUG
Packit 47f805
static int
Packit 47f805
checkScalefactor(const gr_info * cod_info, const int vbrsfmin[SFBMAX])
Packit 47f805
{
Packit 47f805
    int const ifqstep = cod_info->scalefac_scale == 0 ? 2 : 4;
Packit 47f805
    int     sfb;
Packit 47f805
    for (sfb = 0; sfb < cod_info->psymax; ++sfb) {
Packit 47f805
        const int s =
Packit 47f805
            ((cod_info->scalefac[sfb] +
Packit 47f805
              (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep) +
Packit 47f805
            cod_info->subblock_gain[cod_info->window[sfb]] * 8;
Packit 47f805
Packit 47f805
        if ((cod_info->global_gain - s) < vbrsfmin[sfb]) {
Packit 47f805
            /*
Packit 47f805
               fprintf( stdout, "sf %d\n", sfb );
Packit 47f805
               fprintf( stdout, "min %d\n", vbrsfmin[sfb] );
Packit 47f805
               fprintf( stdout, "ggain %d\n", cod_info->global_gain );
Packit 47f805
               fprintf( stdout, "scalefac %d\n", cod_info->scalefac[sfb] );
Packit 47f805
               fprintf( stdout, "pretab %d\n", (cod_info->preflag ? pretab[sfb] : 0) );
Packit 47f805
               fprintf( stdout, "scale %d\n", (cod_info->scalefac_scale + 1) );
Packit 47f805
               fprintf( stdout, "subgain %d\n", cod_info->subblock_gain[cod_info->window[sfb]] * 8 );
Packit 47f805
               fflush( stdout );
Packit 47f805
               exit(-1);
Packit 47f805
             */
Packit 47f805
            return 0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return 1;
Packit 47f805
}
Packit 47f805
#endif
Packit 47f805
Packit 47f805
Packit 47f805
/******************************************************************
Packit 47f805
 *
Packit 47f805
 *  short block scalefacs
Packit 47f805
 *
Packit 47f805
 ******************************************************************/
Packit 47f805
Packit 47f805
static void
Packit 47f805
short_block_constrain(const algo_t * that, const int vbrsf[SFBMAX],
Packit 47f805
                      const int vbrsfmin[SFBMAX], int vbrmax)
Packit 47f805
{
Packit 47f805
    gr_info *const cod_info = that->cod_info;
Packit 47f805
    lame_internal_flags const *const gfc = that->gfc;
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    int const maxminsfb = that->mingain_l;
Packit 47f805
    int     mover, maxover0 = 0, maxover1 = 0, delta = 0;
Packit 47f805
    int     v, v0, v1;
Packit 47f805
    int     sfb;
Packit 47f805
    int const psymax = cod_info->psymax;
Packit 47f805
Packit 47f805
    for (sfb = 0; sfb < psymax; ++sfb) {
Packit 47f805
        assert(vbrsf[sfb] >= vbrsfmin[sfb]);
Packit 47f805
        v = vbrmax - vbrsf[sfb];
Packit 47f805
        if (delta < v) {
Packit 47f805
            delta = v;
Packit 47f805
        }
Packit 47f805
        v0 = v - (4 * 14 + 2 * max_range_short[sfb]);
Packit 47f805
        v1 = v - (4 * 14 + 4 * max_range_short[sfb]);
Packit 47f805
        if (maxover0 < v0) {
Packit 47f805
            maxover0 = v0;
Packit 47f805
        }
Packit 47f805
        if (maxover1 < v1) {
Packit 47f805
            maxover1 = v1;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (cfg->noise_shaping == 2) {
Packit 47f805
        /* allow scalefac_scale=1 */
Packit 47f805
        mover = Min(maxover0, maxover1);
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        mover = maxover0;
Packit 47f805
    }
Packit 47f805
    if (delta > mover) {
Packit 47f805
        delta = mover;
Packit 47f805
    }
Packit 47f805
    vbrmax -= delta;
Packit 47f805
    maxover0 -= mover;
Packit 47f805
    maxover1 -= mover;
Packit 47f805
Packit 47f805
    if (maxover0 == 0) {
Packit 47f805
        cod_info->scalefac_scale = 0;
Packit 47f805
    }
Packit 47f805
    else if (maxover1 == 0) {
Packit 47f805
        cod_info->scalefac_scale = 1;
Packit 47f805
    }
Packit 47f805
    if (vbrmax < maxminsfb) {
Packit 47f805
        vbrmax = maxminsfb;
Packit 47f805
    }
Packit 47f805
    cod_info->global_gain = vbrmax;
Packit 47f805
Packit 47f805
    if (cod_info->global_gain < 0) {
Packit 47f805
        cod_info->global_gain = 0;
Packit 47f805
    }
Packit 47f805
    else if (cod_info->global_gain > 255) {
Packit 47f805
        cod_info->global_gain = 255;
Packit 47f805
    }
Packit 47f805
    {
Packit 47f805
        int     sf_temp[SFBMAX];
Packit 47f805
        for (sfb = 0; sfb < SFBMAX; ++sfb) {
Packit 47f805
            sf_temp[sfb] = vbrsf[sfb] - vbrmax;
Packit 47f805
        }
Packit 47f805
        set_subblock_gain(cod_info, &that->mingain_s[0], sf_temp);
Packit 47f805
        set_scalefacs(cod_info, vbrsfmin, sf_temp, max_range_short);
Packit 47f805
    }
Packit 47f805
    assert(checkScalefactor(cod_info, vbrsfmin));
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/******************************************************************
Packit 47f805
 *
Packit 47f805
 *  long block scalefacs
Packit 47f805
 *
Packit 47f805
 ******************************************************************/
Packit 47f805
Packit 47f805
static void
Packit 47f805
long_block_constrain(const algo_t * that, const int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX],
Packit 47f805
                     int vbrmax)
Packit 47f805
{
Packit 47f805
    gr_info *const cod_info = that->cod_info;
Packit 47f805
    lame_internal_flags const *const gfc = that->gfc;
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    uint8_t const *max_rangep;
Packit 47f805
    int const maxminsfb = that->mingain_l;
Packit 47f805
    int     sfb;
Packit 47f805
    int     maxover0, maxover1, maxover0p, maxover1p, mover, delta = 0;
Packit 47f805
    int     v, v0, v1, v0p, v1p, vm0p = 1, vm1p = 1;
Packit 47f805
    int const psymax = cod_info->psymax;
Packit 47f805
Packit 47f805
    max_rangep = cfg->mode_gr == 2 ? max_range_long : max_range_long_lsf_pretab;
Packit 47f805
Packit 47f805
    maxover0 = 0;
Packit 47f805
    maxover1 = 0;
Packit 47f805
    maxover0p = 0;      /* pretab */
Packit 47f805
    maxover1p = 0;      /* pretab */
Packit 47f805
Packit 47f805
    for (sfb = 0; sfb < psymax; ++sfb) {
Packit 47f805
        assert(vbrsf[sfb] >= vbrsfmin[sfb]);
Packit 47f805
        v = vbrmax - vbrsf[sfb];
Packit 47f805
        if (delta < v) {
Packit 47f805
            delta = v;
Packit 47f805
        }
Packit 47f805
        v0 = v - 2 * max_range_long[sfb];
Packit 47f805
        v1 = v - 4 * max_range_long[sfb];
Packit 47f805
        v0p = v - 2 * (max_rangep[sfb] + pretab[sfb]);
Packit 47f805
        v1p = v - 4 * (max_rangep[sfb] + pretab[sfb]);
Packit 47f805
        if (maxover0 < v0) {
Packit 47f805
            maxover0 = v0;
Packit 47f805
        }
Packit 47f805
        if (maxover1 < v1) {
Packit 47f805
            maxover1 = v1;
Packit 47f805
        }
Packit 47f805
        if (maxover0p < v0p) {
Packit 47f805
            maxover0p = v0p;
Packit 47f805
        }
Packit 47f805
        if (maxover1p < v1p) {
Packit 47f805
            maxover1p = v1p;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (vm0p == 1) {
Packit 47f805
        int     gain = vbrmax - maxover0p;
Packit 47f805
        if (gain < maxminsfb) {
Packit 47f805
            gain = maxminsfb;
Packit 47f805
        }
Packit 47f805
        for (sfb = 0; sfb < psymax; ++sfb) {
Packit 47f805
            int const a = (gain - vbrsfmin[sfb]) - 2 * pretab[sfb];
Packit 47f805
            if (a <= 0) {
Packit 47f805
                vm0p = 0;
Packit 47f805
                vm1p = 0;
Packit 47f805
                break;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (vm1p == 1) {
Packit 47f805
        int     gain = vbrmax - maxover1p;
Packit 47f805
        if (gain < maxminsfb) {
Packit 47f805
            gain = maxminsfb;
Packit 47f805
        }
Packit 47f805
        for (sfb = 0; sfb < psymax; ++sfb) {
Packit 47f805
            int const b = (gain - vbrsfmin[sfb]) - 4 * pretab[sfb];
Packit 47f805
            if (b <= 0) {
Packit 47f805
                vm1p = 0;
Packit 47f805
                break;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (vm0p == 0) {
Packit 47f805
        maxover0p = maxover0;
Packit 47f805
    }
Packit 47f805
    if (vm1p == 0) {
Packit 47f805
        maxover1p = maxover1;
Packit 47f805
    }
Packit 47f805
    if (cfg->noise_shaping != 2) {
Packit 47f805
        maxover1 = maxover0;
Packit 47f805
        maxover1p = maxover0p;
Packit 47f805
    }
Packit 47f805
    mover = Min(maxover0, maxover0p);
Packit 47f805
    mover = Min(mover, maxover1);
Packit 47f805
    mover = Min(mover, maxover1p);
Packit 47f805
Packit 47f805
    if (delta > mover) {
Packit 47f805
        delta = mover;
Packit 47f805
    }
Packit 47f805
    vbrmax -= delta;
Packit 47f805
    if (vbrmax < maxminsfb) {
Packit 47f805
        vbrmax = maxminsfb;
Packit 47f805
    }
Packit 47f805
    maxover0 -= mover;
Packit 47f805
    maxover0p -= mover;
Packit 47f805
    maxover1 -= mover;
Packit 47f805
    maxover1p -= mover;
Packit 47f805
Packit 47f805
    if (maxover0 == 0) {
Packit 47f805
        cod_info->scalefac_scale = 0;
Packit 47f805
        cod_info->preflag = 0;
Packit 47f805
        max_rangep = max_range_long;
Packit 47f805
    }
Packit 47f805
    else if (maxover0p == 0) {
Packit 47f805
        cod_info->scalefac_scale = 0;
Packit 47f805
        cod_info->preflag = 1;
Packit 47f805
    }
Packit 47f805
    else if (maxover1 == 0) {
Packit 47f805
        cod_info->scalefac_scale = 1;
Packit 47f805
        cod_info->preflag = 0;
Packit 47f805
        max_rangep = max_range_long;
Packit 47f805
    }
Packit 47f805
    else if (maxover1p == 0) {
Packit 47f805
        cod_info->scalefac_scale = 1;
Packit 47f805
        cod_info->preflag = 1;
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        assert(0);      /* this should not happen */
Packit 47f805
    }
Packit 47f805
    cod_info->global_gain = vbrmax;
Packit 47f805
    if (cod_info->global_gain < 0) {
Packit 47f805
        cod_info->global_gain = 0;
Packit 47f805
    }
Packit 47f805
    else if (cod_info->global_gain > 255) {
Packit 47f805
        cod_info->global_gain = 255;
Packit 47f805
    }
Packit 47f805
    {
Packit 47f805
        int     sf_temp[SFBMAX];
Packit 47f805
        for (sfb = 0; sfb < SFBMAX; ++sfb) {
Packit 47f805
            sf_temp[sfb] = vbrsf[sfb] - vbrmax;
Packit 47f805
        }
Packit 47f805
        set_scalefacs(cod_info, vbrsfmin, sf_temp, max_rangep);
Packit 47f805
    }
Packit 47f805
    assert(checkScalefactor(cod_info, vbrsfmin));
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
bitcount(const algo_t * that)
Packit 47f805
{
Packit 47f805
    int     rc = scale_bitcount(that->gfc, that->cod_info);
Packit 47f805
Packit 47f805
    if (rc == 0) {
Packit 47f805
        return;
Packit 47f805
    }
Packit 47f805
    /*  this should not happen due to the way the scalefactors are selected  */
Packit 47f805
    ERRORF(that->gfc, "INTERNAL ERROR IN VBR NEW CODE (986), please send bug report\n");
Packit 47f805
    exit(-1);
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
quantizeAndCountBits(const algo_t * that)
Packit 47f805
{
Packit 47f805
    quantize_x34(that);
Packit 47f805
    that->cod_info->part2_3_length = noquant_count_bits(that->gfc, that->cod_info, 0);
Packit 47f805
    return that->cod_info->part2_3_length;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
tryGlobalStepsize(const algo_t * that, const int sfwork[SFBMAX],
Packit 47f805
                  const int vbrsfmin[SFBMAX], int delta)
Packit 47f805
{
Packit 47f805
    FLOAT const xrpow_max = that->cod_info->xrpow_max;
Packit 47f805
    int     sftemp[SFBMAX], i, nbits;
Packit 47f805
    int     gain, vbrmax = 0;
Packit 47f805
    for (i = 0; i < SFBMAX; ++i) {
Packit 47f805
        gain = sfwork[i] + delta;
Packit 47f805
        if (gain < vbrsfmin[i]) {
Packit 47f805
            gain = vbrsfmin[i];
Packit 47f805
        }
Packit 47f805
        if (gain > 255) {
Packit 47f805
            gain = 255;
Packit 47f805
        }
Packit 47f805
        if (vbrmax < gain) {
Packit 47f805
            vbrmax = gain;
Packit 47f805
        }
Packit 47f805
        sftemp[i] = gain;
Packit 47f805
    }
Packit 47f805
    that->alloc(that, sftemp, vbrsfmin, vbrmax);
Packit 47f805
    bitcount(that);
Packit 47f805
    nbits = quantizeAndCountBits(that);
Packit 47f805
    that->cod_info->xrpow_max = xrpow_max;
Packit 47f805
    return nbits;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
searchGlobalStepsizeMax(const algo_t * that, const int sfwork[SFBMAX],
Packit 47f805
                        const int vbrsfmin[SFBMAX], int target)
Packit 47f805
{
Packit 47f805
    gr_info const *const cod_info = that->cod_info;
Packit 47f805
    const int gain = cod_info->global_gain;
Packit 47f805
    int     curr = gain;
Packit 47f805
    int     gain_ok = 1024;
Packit 47f805
    int     nbits = LARGE_BITS;
Packit 47f805
    int     l = gain, r = 512;
Packit 47f805
Packit 47f805
    assert(gain >= 0);
Packit 47f805
    while (l <= r) {
Packit 47f805
        curr = (l + r) >> 1;
Packit 47f805
        nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);
Packit 47f805
        if (nbits == 0 || (nbits + cod_info->part2_length) < target) {
Packit 47f805
            r = curr - 1;
Packit 47f805
            gain_ok = curr;
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            l = curr + 1;
Packit 47f805
            if (gain_ok == 1024) {
Packit 47f805
                gain_ok = curr;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    if (gain_ok != curr) {
Packit 47f805
        curr = gain_ok;
Packit 47f805
        nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
sfDepth(const int sfwork[SFBMAX])
Packit 47f805
{
Packit 47f805
    int     m = 0;
Packit 47f805
    unsigned int i, j;
Packit 47f805
    for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
Packit 47f805
        int const di = 255 - sfwork[i];
Packit 47f805
        if (m < di) {
Packit 47f805
            m = di;
Packit 47f805
        }
Packit 47f805
        assert(sfwork[i] >= 0);
Packit 47f805
        assert(sfwork[i] <= 255);
Packit 47f805
    }
Packit 47f805
    assert(m >= 0);
Packit 47f805
    assert(m <= 255);
Packit 47f805
    return m;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
cutDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int cut)
Packit 47f805
{
Packit 47f805
    unsigned int i, j;
Packit 47f805
    for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
Packit 47f805
        int const x = sfwork[i];
Packit 47f805
        sf_out[i] = x < cut ? x : cut;
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
flattenDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int dm, int k, int p)
Packit 47f805
{
Packit 47f805
    unsigned int i, j;
Packit 47f805
    int     x, sfmax = 0;
Packit 47f805
    if (dm > 0) {
Packit 47f805
        for (j = SFBMAX, i = 0; j > 0; --j, ++i) {
Packit 47f805
            int const di = p - sfwork[i];
Packit 47f805
            x = sfwork[i] + (k * di) / dm;
Packit 47f805
            if (x < 0) {
Packit 47f805
                x = 0;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                if (x > 255) {
Packit 47f805
                    x = 255;
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            sf_out[i] = x;
Packit 47f805
            if (sfmax < x) {
Packit 47f805
                sfmax = x;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        for (j = SFBMAX, i = 0; j > 0u; --j, ++i) {
Packit 47f805
            x = sfwork[i];
Packit 47f805
            sf_out[i] = x;
Packit 47f805
            if (sfmax < x) {
Packit 47f805
                sfmax = x;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    return sfmax;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
tryThatOne(algo_t const* that, const int sftemp[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax)
Packit 47f805
{
Packit 47f805
    FLOAT const xrpow_max = that->cod_info->xrpow_max;
Packit 47f805
    int     nbits = LARGE_BITS;
Packit 47f805
    that->alloc(that, sftemp, vbrsfmin, vbrmax);
Packit 47f805
    bitcount(that);
Packit 47f805
    nbits = quantizeAndCountBits(that);
Packit 47f805
    nbits += that->cod_info->part2_length;
Packit 47f805
    that->cod_info->xrpow_max = xrpow_max;
Packit 47f805
    return nbits;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
outOfBitsStrategy(algo_t const* that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int target)
Packit 47f805
{
Packit 47f805
    int     wrk[SFBMAX];
Packit 47f805
    int const dm = sfDepth(sfwork);
Packit 47f805
    int const p = that->cod_info->global_gain;
Packit 47f805
    int     nbits;
Packit 47f805
Packit 47f805
    /* PART 1 */
Packit 47f805
    {
Packit 47f805
        int     bi = dm / 2;
Packit 47f805
        int     bi_ok = -1;
Packit 47f805
        int     bu = 0;
Packit 47f805
        int     bo = dm;
Packit 47f805
        for (;;) {
Packit 47f805
            int const sfmax = flattenDistribution(sfwork, wrk, dm, bi, p);
Packit 47f805
            nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
Packit 47f805
            if (nbits <= target) {
Packit 47f805
                bi_ok = bi;
Packit 47f805
                bo = bi - 1;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                bu = bi + 1;
Packit 47f805
            }
Packit 47f805
            if (bu <= bo) {
Packit 47f805
                bi = (bu + bo) / 2;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                break;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        if (bi_ok >= 0) {
Packit 47f805
            if (bi != bi_ok) {
Packit 47f805
                int const sfmax = flattenDistribution(sfwork, wrk, dm, bi_ok, p);
Packit 47f805
                nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
Packit 47f805
            }
Packit 47f805
            return;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* PART 2: */
Packit 47f805
    {
Packit 47f805
        int     bi = (255 + p) / 2;
Packit 47f805
        int     bi_ok = -1;
Packit 47f805
        int     bu = p;
Packit 47f805
        int     bo = 255;
Packit 47f805
        for (;;) {
Packit 47f805
            int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi);
Packit 47f805
            nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
Packit 47f805
            if (nbits <= target) {
Packit 47f805
                bi_ok = bi;
Packit 47f805
                bo = bi - 1;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                bu = bi + 1;
Packit 47f805
            }
Packit 47f805
            if (bu <= bo) {
Packit 47f805
                bi = (bu + bo) / 2;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                break;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        if (bi_ok >= 0) {
Packit 47f805
            if (bi != bi_ok) {
Packit 47f805
                int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi_ok);
Packit 47f805
                nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);
Packit 47f805
            }
Packit 47f805
            return;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* fall back to old code, likely to be never called */
Packit 47f805
    searchGlobalStepsizeMax(that, wrk, vbrsfmin, target);
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
static int
Packit 47f805
reduce_bit_usage(lame_internal_flags * gfc, int gr, int ch
Packit 47f805
#if 0
Packit 47f805
                 , const FLOAT xr34orig[576], const FLOAT l3_xmin[SFBMAX], int maxbits
Packit 47f805
#endif
Packit 47f805
    )
Packit 47f805
{
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
Packit 47f805
    /*  try some better scalefac storage
Packit 47f805
     */
Packit 47f805
    best_scalefac_store(gfc, gr, ch, &gfc->l3_side);
Packit 47f805
Packit 47f805
    /*  best huffman_divide may save some bits too
Packit 47f805
     */
Packit 47f805
    if (cfg->use_best_huffman == 1)
Packit 47f805
        best_huffman_divide(gfc, cod_info);
Packit 47f805
    return cod_info->part2_3_length + cod_info->part2_length;
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
int
Packit 47f805
VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576],
Packit 47f805
                 const FLOAT l3_xmin[2][2][SFBMAX], const int max_bits[2][2])
Packit 47f805
{
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    int     sfwork_[2][2][SFBMAX];
Packit 47f805
    int     vbrsfmin_[2][2][SFBMAX];
Packit 47f805
    algo_t  that_[2][2];
Packit 47f805
    int const ngr = cfg->mode_gr;
Packit 47f805
    int const nch = cfg->channels_out;
Packit 47f805
    int     max_nbits_ch[2][2] = {{0, 0}, {0 ,0}};
Packit 47f805
    int     max_nbits_gr[2] = {0, 0};
Packit 47f805
    int     max_nbits_fr = 0;
Packit 47f805
    int     use_nbits_ch[2][2] = {{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}
Packit 47f805
                                 ,{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}};
Packit 47f805
    int     use_nbits_gr[2] = { MAX_BITS_PER_GRANULE+1, MAX_BITS_PER_GRANULE+1 };
Packit 47f805
    int     use_nbits_fr = MAX_BITS_PER_GRANULE+MAX_BITS_PER_GRANULE;
Packit 47f805
    int     gr, ch;
Packit 47f805
    int     ok, sum_fr;
Packit 47f805
Packit 47f805
    /* set up some encoding parameters
Packit 47f805
     */
Packit 47f805
    for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
        max_nbits_gr[gr] = 0;
Packit 47f805
        for (ch = 0; ch < nch; ++ch) {
Packit 47f805
            max_nbits_ch[gr][ch] = max_bits[gr][ch];
Packit 47f805
            use_nbits_ch[gr][ch] = 0;
Packit 47f805
            max_nbits_gr[gr] += max_bits[gr][ch];
Packit 47f805
            max_nbits_fr += max_bits[gr][ch];
Packit 47f805
            that_[gr][ch].find = (cfg->full_outer_loop < 0) ? guess_scalefac_x34 : find_scalefac_x34;
Packit 47f805
            that_[gr][ch].gfc = gfc;
Packit 47f805
            that_[gr][ch].cod_info = &gfc->l3_side.tt[gr][ch];
Packit 47f805
            that_[gr][ch].xr34orig = xr34orig[gr][ch];
Packit 47f805
            if (that_[gr][ch].cod_info->block_type == SHORT_TYPE) {
Packit 47f805
                that_[gr][ch].alloc = short_block_constrain;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                that_[gr][ch].alloc = long_block_constrain;
Packit 47f805
            }
Packit 47f805
        }               /* for ch */
Packit 47f805
    }
Packit 47f805
    /* searches scalefactors
Packit 47f805
     */
Packit 47f805
    for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
        for (ch = 0; ch < nch; ++ch) {
Packit 47f805
            if (max_bits[gr][ch] > 0) {
Packit 47f805
                algo_t *that = &that_[gr][ch];
Packit 47f805
                int    *sfwork = sfwork_[gr][ch];
Packit 47f805
                int    *vbrsfmin = vbrsfmin_[gr][ch];
Packit 47f805
                int     vbrmax;
Packit 47f805
Packit 47f805
                vbrmax = block_sf(that, l3_xmin[gr][ch], sfwork, vbrsfmin);
Packit 47f805
                that->alloc(that, sfwork, vbrsfmin, vbrmax);
Packit 47f805
                bitcount(that);
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                /*  xr contains no energy 
Packit 47f805
                 *  l3_enc, our encoding data, will be quantized to zero
Packit 47f805
                 *  continue with next channel
Packit 47f805
                 */
Packit 47f805
            }
Packit 47f805
        }               /* for ch */
Packit 47f805
    }
Packit 47f805
    /* encode 'as is'
Packit 47f805
     */
Packit 47f805
    use_nbits_fr = 0;
Packit 47f805
    for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
        use_nbits_gr[gr] = 0;
Packit 47f805
        for (ch = 0; ch < nch; ++ch) {
Packit 47f805
            algo_t const *that = &that_[gr][ch];
Packit 47f805
            if (max_bits[gr][ch] > 0) {
Packit 47f805
                memset(&that->cod_info->l3_enc[0], 0, sizeof(that->cod_info->l3_enc));
Packit 47f805
                (void) quantizeAndCountBits(that);
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                /*  xr contains no energy 
Packit 47f805
                 *  l3_enc, our encoding data, will be quantized to zero
Packit 47f805
                 *  continue with next channel
Packit 47f805
                 */
Packit 47f805
            }
Packit 47f805
            use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);
Packit 47f805
            use_nbits_gr[gr] += use_nbits_ch[gr][ch];
Packit 47f805
        }               /* for ch */
Packit 47f805
        use_nbits_fr += use_nbits_gr[gr];
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* check bit constrains
Packit 47f805
     */
Packit 47f805
    if (use_nbits_fr <= max_nbits_fr) {
Packit 47f805
        ok = 1;
Packit 47f805
        for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
            if (use_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
Packit 47f805
                /* violates the rule that every granule has to use no more
Packit 47f805
                 * bits than MAX_BITS_PER_GRANULE
Packit 47f805
                 */
Packit 47f805
                ok = 0;
Packit 47f805
            }
Packit 47f805
            for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                    /* violates the rule that every gr_ch has to use no more
Packit 47f805
                     * bits than MAX_BITS_PER_CHANNEL
Packit 47f805
                     *
Packit 47f805
                     * This isn't explicitly stated in the ISO docs, but the
Packit 47f805
                     * part2_3_length field has only 12 bits, that makes it
Packit 47f805
                     * up to a maximum size of 4095 bits!!!
Packit 47f805
                     */
Packit 47f805
                    ok = 0;
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        if (ok) {
Packit 47f805
            return use_nbits_fr;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    
Packit 47f805
    /* OK, we are in trouble and have to define how many bits are
Packit 47f805
     * to be used for each granule
Packit 47f805
     */
Packit 47f805
    {
Packit 47f805
        ok = 1;
Packit 47f805
        sum_fr = 0;
Packit 47f805
Packit 47f805
        for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
            max_nbits_gr[gr] = 0;
Packit 47f805
            for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                    max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;
Packit 47f805
                }
Packit 47f805
                else {
Packit 47f805
                    max_nbits_ch[gr][ch] = use_nbits_ch[gr][ch];
Packit 47f805
                }
Packit 47f805
                max_nbits_gr[gr] += max_nbits_ch[gr][ch];
Packit 47f805
            }
Packit 47f805
            if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
Packit 47f805
                float   f[2] = {0.0f, 0.0f}, s = 0.0f;
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    if (max_nbits_ch[gr][ch] > 0) {
Packit 47f805
                        f[ch] = sqrt(sqrt(max_nbits_ch[gr][ch]));
Packit 47f805
                        s += f[ch];
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        f[ch] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    if (s > 0) {
Packit 47f805
                        max_nbits_ch[gr][ch] = MAX_BITS_PER_GRANULE * f[ch] / s;
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        max_nbits_ch[gr][ch] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                if (nch > 1) {
Packit 47f805
                    if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {
Packit 47f805
                        max_nbits_ch[gr][1] += max_nbits_ch[gr][0];
Packit 47f805
                        max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;
Packit 47f805
                        max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;
Packit 47f805
                    }
Packit 47f805
                    if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {
Packit 47f805
                        max_nbits_ch[gr][0] += max_nbits_ch[gr][1];
Packit 47f805
                        max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;
Packit 47f805
                        max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;
Packit 47f805
                    }
Packit 47f805
                    if (max_nbits_ch[gr][0] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                        max_nbits_ch[gr][0] = MAX_BITS_PER_CHANNEL;
Packit 47f805
                    }
Packit 47f805
                    if (max_nbits_ch[gr][1] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                        max_nbits_ch[gr][1] = MAX_BITS_PER_CHANNEL;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                max_nbits_gr[gr] = 0;
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    max_nbits_gr[gr] += max_nbits_ch[gr][ch];
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            sum_fr += max_nbits_gr[gr];
Packit 47f805
        }
Packit 47f805
        if (sum_fr > max_nbits_fr) {
Packit 47f805
            {
Packit 47f805
                float   f[2] = {0.0f, 0.0f}, s = 0.0f;
Packit 47f805
                for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
                    if (max_nbits_gr[gr] > 0) {
Packit 47f805
                        f[gr] = sqrt(max_nbits_gr[gr]);
Packit 47f805
                        s += f[gr];
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        f[gr] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
                    if (s > 0) {
Packit 47f805
                        max_nbits_gr[gr] = max_nbits_fr * f[gr] / s;
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        max_nbits_gr[gr] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            if (ngr > 1) {
Packit 47f805
                if (max_nbits_gr[0] > use_nbits_gr[0] + 125) {
Packit 47f805
                    max_nbits_gr[1] += max_nbits_gr[0];
Packit 47f805
                    max_nbits_gr[1] -= use_nbits_gr[0] + 125;
Packit 47f805
                    max_nbits_gr[0] = use_nbits_gr[0] + 125;
Packit 47f805
                }
Packit 47f805
                if (max_nbits_gr[1] > use_nbits_gr[1] + 125) {
Packit 47f805
                    max_nbits_gr[0] += max_nbits_gr[1];
Packit 47f805
                    max_nbits_gr[0] -= use_nbits_gr[1] + 125;
Packit 47f805
                    max_nbits_gr[1] = use_nbits_gr[1] + 125;
Packit 47f805
                }
Packit 47f805
                for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
                    if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {
Packit 47f805
                        max_nbits_gr[gr] = MAX_BITS_PER_GRANULE;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
                float   f[2] = {0.0f, 0.0f}, s = 0.0f;
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    if (max_nbits_ch[gr][ch] > 0) {
Packit 47f805
                        f[ch] = sqrt(max_nbits_ch[gr][ch]);
Packit 47f805
                        s += f[ch];
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        f[ch] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    if (s > 0) {
Packit 47f805
                        max_nbits_ch[gr][ch] = max_nbits_gr[gr] * f[ch] / s;
Packit 47f805
                    }
Packit 47f805
                    else {
Packit 47f805
                        max_nbits_ch[gr][ch] = 0;
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
                if (nch > 1) {
Packit 47f805
                    if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {
Packit 47f805
                        max_nbits_ch[gr][1] += max_nbits_ch[gr][0];
Packit 47f805
                        max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;
Packit 47f805
                        max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;
Packit 47f805
                    }
Packit 47f805
                    if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {
Packit 47f805
                        max_nbits_ch[gr][0] += max_nbits_ch[gr][1];
Packit 47f805
                        max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;
Packit 47f805
                        max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;
Packit 47f805
                    }
Packit 47f805
                    for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                        if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                            max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;
Packit 47f805
                        }
Packit 47f805
                    }
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        /* sanity check */
Packit 47f805
        sum_fr = 0;
Packit 47f805
        for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
            int     sum_gr = 0;
Packit 47f805
            for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                sum_gr += max_nbits_ch[gr][ch];
Packit 47f805
                if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {
Packit 47f805
                    ok = 0;
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
            sum_fr += sum_gr;
Packit 47f805
            if (sum_gr > MAX_BITS_PER_GRANULE) {
Packit 47f805
                ok = 0;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        if (sum_fr > max_nbits_fr) {
Packit 47f805
            ok = 0;
Packit 47f805
        }
Packit 47f805
        if (!ok) {
Packit 47f805
            /* we must have done something wrong, fallback to 'on_pe' based constrain */
Packit 47f805
            for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
                for (ch = 0; ch < nch; ++ch) {
Packit 47f805
                    max_nbits_ch[gr][ch] = max_bits[gr][ch];
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* we already called the 'best_scalefac_store' function, so we need to reset some
Packit 47f805
     * variables before we can do it again.
Packit 47f805
     */
Packit 47f805
    for (ch = 0; ch < nch; ++ch) {
Packit 47f805
        gfc->l3_side.scfsi[ch][0] = 0;
Packit 47f805
        gfc->l3_side.scfsi[ch][1] = 0;
Packit 47f805
        gfc->l3_side.scfsi[ch][2] = 0;
Packit 47f805
        gfc->l3_side.scfsi[ch][3] = 0;
Packit 47f805
    }
Packit 47f805
    for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
        for (ch = 0; ch < nch; ++ch) {
Packit 47f805
            gfc->l3_side.tt[gr][ch].scalefac_compress = 0;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* alter our encoded data, until it fits into the target bitrate
Packit 47f805
     */
Packit 47f805
    use_nbits_fr = 0;
Packit 47f805
    for (gr = 0; gr < ngr; ++gr) {
Packit 47f805
        use_nbits_gr[gr] = 0;
Packit 47f805
        for (ch = 0; ch < nch; ++ch) {
Packit 47f805
            algo_t const *that = &that_[gr][ch];
Packit 47f805
            use_nbits_ch[gr][ch] = 0;
Packit 47f805
            if (max_bits[gr][ch] > 0) {
Packit 47f805
                int    *sfwork = sfwork_[gr][ch];
Packit 47f805
                int const *vbrsfmin = vbrsfmin_[gr][ch];
Packit 47f805
                cutDistribution(sfwork, sfwork, that->cod_info->global_gain);
Packit 47f805
                outOfBitsStrategy(that, sfwork, vbrsfmin, max_nbits_ch[gr][ch]);
Packit 47f805
            }
Packit 47f805
            use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);
Packit 47f805
            assert(use_nbits_ch[gr][ch] <= max_nbits_ch[gr][ch]);
Packit 47f805
            use_nbits_gr[gr] += use_nbits_ch[gr][ch];
Packit 47f805
        }               /* for ch */
Packit 47f805
        use_nbits_fr += use_nbits_gr[gr];
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* check bit constrains, but it should always be ok, iff there are no bugs ;-)
Packit 47f805
     */
Packit 47f805
    if (use_nbits_fr <= max_nbits_fr) {
Packit 47f805
        return use_nbits_fr;
Packit 47f805
    }
Packit 47f805
Packit 47f805
    ERRORF(gfc, "INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report\n"
Packit 47f805
           "maxbits=%d usedbits=%d\n", max_nbits_fr, use_nbits_fr);
Packit 47f805
    exit(-1);
Packit 47f805
}