static uint8_t
guess_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min)
{
    int const guess = calc_scalefac(l3_xmin, bw);
    if (guess < sf_min) return sf_min;
    if (guess >= 255) return 255;
    (void) xr;
    (void) xr34;
    return guess;
}
/* a variation for vbr-mtrh */
static int
block_sf(algo_t * that, const FLOAT l3_xmin[SFBMAX], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX])
{
    FLOAT   max_xr34;
    const FLOAT *const xr = &that->cod_info->xr[0];
    const FLOAT *const xr34_orig = &that->xr34orig[0];
    const int *const width = &that->cod_info->width[0];
    const char *const energy_above_cutoff = &that->cod_info->energy_above_cutoff[0];
    unsigned int const max_nonzero_coeff = (unsigned int) that->cod_info->max_nonzero_coeff;
    uint8_t maxsf = 0;
    int     sfb = 0, m_o = -1;
    unsigned int j = 0, i = 0;
    int const psymax = that->cod_info->psymax;

    assert(that->cod_info->max_nonzero_coeff >= 0);

    that->mingain_l = 0;
    that->mingain_s[0] = 0;
    that->mingain_s[1] = 0;
    that->mingain_s[2] = 0;
    while (j <= max_nonzero_coeff) {
        unsigned int const w = (unsigned int) width[sfb];
        unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);
        unsigned int l = w;
        uint8_t m1, m2;
        if (l > m) {
            l = m;
        }
        max_xr34 = vec_max_c(&xr34_orig[j], l);

        m1 = find_lowest_scalefac(max_xr34);
        vbrsfmin[sfb] = m1;
        if (that->mingain_l < m1) {
            that->mingain_l = m1;
        }
        if (that->mingain_s[i] < m1) {
            that->mingain_s[i] = m1;
        }
        if (++i > 2) {
            i = 0;
        }
        if (sfb < psymax && w > 2) { /* mpeg2.5 at 8 kHz doesn't use all scalefactors, unused have width 2 */
            if (energy_above_cutoff[sfb]) {
                m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1);
#if 0
                if (0) {
                    /** Robert Hegemann 2007-09-29:
                     *  It seems here is some more potential for speed improvements.
                     *  Current find method does 11-18 quantization calculations.
                     *  Using a "good guess" may help to reduce this amount.
                     */
                    uint8_t guess = calc_scalefac(l3_xmin[sfb], l);
                    DEBUGF(that->gfc, "sfb=%3d guess=%3d found=%3d diff=%3d\n", sfb, guess, m2,
                           m2 - guess);
                }
#endif
                if (maxsf < m2) {
                    maxsf = m2;
                }
                if (m_o < m2 && m2 < 255) {
                    m_o = m2;
                }
            }
            else {
                m2 = 255;
                maxsf = 255;
            }
        }
        else {
            if (maxsf < m1) {
                maxsf = m1;
            }
            m2 = maxsf;
        }
        vbrsf[sfb] = m2;
        ++sfb;
        j += w;        
    }
    for (; sfb < SFBMAX; ++sfb) {
        vbrsf[sfb] = maxsf;
        vbrsfmin[sfb] = 0;
    }
    if (m_o > -1) {
        maxsf = m_o;
        for (sfb = 0; sfb < SFBMAX; ++sfb) {
            if (vbrsf[sfb] == 255) {
                vbrsf[sfb] = m_o;
            }
        }
    }
    return maxsf;
}
Esempio n. 3
0
static void
long_block_sf(const lame_internal_flags * gfc, const gr_info * cod_info,
              const III_psy_xmin * l3_xmin, const FLOAT8 * xr34_orig, const FLOAT8 * xr34,
              III_scalefac_t * vbrsf, int *vbrmin, int *vbrmax)
{
    const unsigned int ub = cod_info->psy_lmax;
    unsigned int sfb;
    int     vbrmean, vbrmn, vbrmx, vbrclip;
    int     sf_cache[SBMAX_l];
    int     scalefac_criteria;
    static char const map[] = { 2, 1, 0, 3, 6 };

    if (gfc->presetTune.use) {
        /* map experimentalX settings to internal selections */
        scalefac_criteria = map[gfc->presetTune.quantcomp_current];
    }
    else {
        scalefac_criteria = map[gfc->VBR->quality];
    }

    for (sfb = 0; sfb < ub; ++sfb) {
        const unsigned int start = gfc->scalefac_band.l[sfb];
        const unsigned int end = gfc->scalefac_band.l[sfb + 1];
        const unsigned int width = end - start;

        switch (scalefac_criteria) {
        default:
            /*  the fastest
             */
            vbrsf->l[sfb] =
                calc_scalefac(l3_xmin->l[sfb], width, gfc->presetTune.quantcomp_adjust_mtrh);
            break;
        case 5:
        case 4:
        case 3:
            /*  the faster and sloppier mode to use at lower quality
             */
            vbrsf->l[sfb] = find_scalefac(&xr34[start], &xr34_orig[start], l3_xmin->l[sfb], width);
            break;
        case 2:
            /*  the slower and better mode to use at higher quality
             */
            vbrsf->l[sfb] =
                find_scalefac_ave(&xr34[start], &xr34_orig[start], l3_xmin->l[sfb], width);
            break;
        case 1:
            /*  maxnoise mode to use at higher quality
             */
            vbrsf->l[sfb] =
                find_scalefac_mq(&xr34[start], &xr34_orig[start], l3_xmin->l[sfb], width, 1,
                                 gfc->VBR->scratch);
            break;
        case 0:
            /*  maxnoise mode to use at higher quality
             */
            vbrsf->l[sfb] =
                find_scalefac_mq(&xr34[start], &xr34_orig[start], l3_xmin->l[sfb], width, 0,
                                 gfc->VBR->scratch);
            break;
        }
    }

    if (!gfc->sfb21_extra) {
        vbrsf->l[SBPSY_l] = vbrsf->l[SBPSY_l - 1];
    }
    switch (gfc->VBR->smooth) {
    default:
    case 0:
        /*  get max value
         */
        *vbrmin = *vbrmax = vbrsf->l[0];
        for (sfb = 1; sfb < ub; ++sfb) {
            if (*vbrmax < vbrsf->l[sfb])
                *vbrmax = vbrsf->l[sfb];
            if (*vbrmin > vbrsf->l[sfb])
                *vbrmin = vbrsf->l[sfb];
        }
        break;

    case 1:
        /*  make working copy, get min value, select_kth_int will reorder!
         */
        for (vbrmn = +1000, vbrmx = -1000, sfb = 0; sfb < ub; ++sfb) {
            sf_cache[sfb] = vbrsf->l[sfb];
            if (vbrmn > vbrsf->l[sfb])
                vbrmn = vbrsf->l[sfb];
            if (vbrmx < vbrsf->l[sfb])
                vbrmx = vbrsf->l[sfb];
        }
        /*  find median value, take it as mean 
         */
        vbrmean = select_kth_int(sf_cache, ub, (ub + 1) / 2);

        /*  cut peaks
         */
        vbrclip = vbrmean + (vbrmean - vbrmn);
        for (sfb = 0; sfb < ub; ++sfb) {
            if (vbrsf->l[sfb] > vbrclip)
                vbrsf->l[sfb] = vbrclip;
        }
        if (vbrmx > vbrclip)
            vbrmx = vbrclip;
        *vbrmin = vbrmn;
        *vbrmax = vbrmx;
        break;

    case 2:
        vbrclip = vbrsf->l[1] + MAX_SF_DELTA;
        if (vbrsf->l[0] > vbrclip)
            vbrsf->l[0] = vbrclip;
        *vbrmin = *vbrmax = vbrsf->l[0];
        for (sfb = 1; sfb < ub - 1; ++sfb) {
            vbrclip = vbrsf->l[sfb - 1] + MAX_SF_DELTA;
            if (vbrsf->l[sfb] > vbrclip)
                vbrsf->l[sfb] = vbrclip;
            vbrclip = vbrsf->l[sfb + 1] + MAX_SF_DELTA;
            if (vbrsf->l[sfb] > vbrclip)
                vbrsf->l[sfb] = vbrclip;
            if (*vbrmax < vbrsf->l[sfb])
                *vbrmax = vbrsf->l[sfb];
            if (*vbrmin > vbrsf->l[sfb])
                *vbrmin = vbrsf->l[sfb];
        }
        vbrclip = vbrsf->l[ub - 2] + MAX_SF_DELTA;
        if (vbrsf->l[ub - 1] > vbrclip)
            vbrsf->l[ub - 1] = vbrclip;
        if (*vbrmax < vbrsf->l[ub - 1])
            *vbrmax = vbrsf->l[ub - 1];
        if (*vbrmin > vbrsf->l[ub - 1])
            *vbrmin = vbrsf->l[ub - 1];
        break;
    }

}
Esempio n. 4
0
static void
short_block_sf(const lame_internal_flags * gfc, const gr_info * cod_info,
               const III_psy_xmin * l3_xmin, const FLOAT8 * xr34_orig, const FLOAT8 * xr34,
               III_scalefac_t * vbrsf, int *vbrmin, int *vbrmax)
{
    const unsigned int lb = cod_info->sfb_smin;
    const unsigned int ub = cod_info->psy_smax;
    unsigned int j, sfb, b;
    int     vbrmean, vbrmn, vbrmx, vbrclip;
    int     sf_cache[SBMAX_s];
    int     scalefac_criteria;
    static char const map[] = { 2, 1, 0, 3, 6 };

    if (gfc->presetTune.use) {
        /* map experimentalX settings to internal selections */
        scalefac_criteria = map[gfc->presetTune.quantcomp_current];
    }
    else {
        scalefac_criteria = map[gfc->VBR->quality];
    }

    for (j = 0u, sfb = lb; sfb < ub; ++sfb) {
        const unsigned int start = gfc->scalefac_band.s[sfb];
        const unsigned int end = gfc->scalefac_band.s[sfb + 1];
        const unsigned int width = end - start;
        for (b = 0u; b < 3u; ++b) {

            switch (scalefac_criteria) {
            default:
                /*  the fastest
                 */
                vbrsf->s[sfb][b] =
                    calc_scalefac(l3_xmin->s[sfb][b], width, gfc->presetTune.quantcomp_adjust_mtrh);
                break;
            case 5:
            case 4:
            case 3:
                /*  the faster and sloppier mode to use at lower quality
                 */
                vbrsf->s[sfb][b] =
                    find_scalefac(&xr34[j], &xr34_orig[j], l3_xmin->s[sfb][b], width);
                break;
            case 2:
                /*  the slower and better mode to use at higher quality
                 */
                vbrsf->s[sfb][b] =
                    find_scalefac_ave(&xr34[j], &xr34_orig[j], l3_xmin->s[sfb][b], width);
                break;
            case 1:
                /*  maxnoise mode to use at higher quality
                 */
                vbrsf->s[sfb][b] =
                    find_scalefac_mq(&xr34[j], &xr34_orig[j], l3_xmin->s[sfb][b], width, 1,
                                     gfc->VBR->scratch);
                break;
            case 0:
                /*  maxnoise mode to use at higher quality
                 */
                vbrsf->s[sfb][b] =
                    find_scalefac_mq(&xr34[j], &xr34_orig[j], l3_xmin->s[sfb][b], width, 0,
                                     gfc->VBR->scratch);
                break;
            }
            j += width;
        }
    }
    if (!gfc->sfb21_extra) {
        vbrsf->s[SBPSY_s][0] = vbrsf->s[SBPSY_s - 1u][0];
        vbrsf->s[SBPSY_s][1] = vbrsf->s[SBPSY_s - 1u][1];
        vbrsf->s[SBPSY_s][2] = vbrsf->s[SBPSY_s - 1u][2];
    }
    *vbrmax = -10000;
    *vbrmin = +10000;

    for (b = 0u; b < 3u; ++b) {

        /*  smoothing
         */
        switch (gfc->VBR->smooth) {
        default:
        case 0:
            /*  get max value
             */
            for (sfb = lb; sfb < ub; ++sfb) {
                if (*vbrmax < vbrsf->s[sfb][b])
                    *vbrmax = vbrsf->s[sfb][b];
                if (*vbrmin > vbrsf->s[sfb][b])
                    *vbrmin = vbrsf->s[sfb][b];
            }
            break;

        case 1:
            /*  make working copy, get min value, select_kth_int will reorder!
             */
            vbrmn = +1000;
            vbrmx = -1000;
            for (sfb = lb; sfb < ub; ++sfb) {
                sf_cache[sfb] = vbrsf->s[sfb][b];
                if (vbrmn > sf_cache[sfb])
                    vbrmn = sf_cache[sfb];
                if (vbrmx < sf_cache[sfb])
                    vbrmx = sf_cache[sfb];
            }
            if (*vbrmin > vbrmn)
                *vbrmin = vbrmn;

            /*  find median value, take it as mean 
             */
            vbrmean = select_kth_int(&sf_cache[lb], ub - lb, (ub - lb + 1u) / 2u);

            /*  cut peaks
             */
            vbrclip = vbrmean + (vbrmean - vbrmn);
            for (sfb = lb; sfb < ub; ++sfb) {
                if (vbrsf->s[sfb][b] > vbrclip)
                    vbrsf->s[sfb][b] = vbrclip;
            }
            if (vbrmx > vbrclip)
                vbrmx = vbrclip;
            if (*vbrmax < vbrmx)
                *vbrmax = vbrmx;
            break;

        case 2:
            vbrclip = vbrsf->s[lb + 1u][b] + MAX_SF_DELTA;
            if (vbrsf->s[lb][b] > vbrclip)
                vbrsf->s[lb][b] = vbrclip;
            if (*vbrmax < vbrsf->s[lb][b])
                *vbrmax = vbrsf->s[lb][b];
            if (*vbrmin > vbrsf->s[lb][b])
                *vbrmin = vbrsf->s[lb][b];
            for (sfb = lb + 1u; sfb < ub - 1u; ++sfb) {
                vbrclip = vbrsf->s[sfb - 1u][b] + MAX_SF_DELTA;
                if (vbrsf->s[sfb][b] > vbrclip)
                    vbrsf->s[sfb][b] = vbrclip;
                vbrclip = vbrsf->s[sfb + 1u][b] + MAX_SF_DELTA;
                if (vbrsf->s[sfb][b] > vbrclip)
                    vbrsf->s[sfb][b] = vbrclip;
                if (*vbrmax < vbrsf->s[sfb][b])
                    *vbrmax = vbrsf->s[sfb][b];
                if (*vbrmin > vbrsf->s[sfb][b])
                    *vbrmin = vbrsf->s[sfb][b];
            }
            vbrclip = vbrsf->s[ub - 2u][b] + MAX_SF_DELTA;
            if (vbrsf->s[ub - 1u][b] > vbrclip)
                vbrsf->s[ub - 1u][b] = vbrclip;
            if (*vbrmax < vbrsf->s[ub - 1u][b])
                *vbrmax = vbrsf->s[ub - 1u][b];
            if (*vbrmin > vbrsf->s[ub - 1u][b])
                *vbrmin = vbrsf->s[ub - 1u][b];
            break;
        }

    }
}