예제 #1
0
int
calc_xmin(lame_internal_flags const *gfc,
          III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin)
{
    SessionConfig_t const *const cfg = &gfc->cfg;
    int     sfb, gsfb, j = 0, ath_over = 0, k;
    ATH_t const *const ATH = gfc->ATH;
    const FLOAT *const xr = cod_info->xr;
    int     max_nonzero;

    for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) {
        FLOAT   en0, xmin;
        FLOAT   rh1, rh2, rh3;
        int     width, l;

        xmin = athAdjust(ATH->adjust_factor, ATH->l[gsfb], ATH->floor, cfg->ATHfixpoint);
        xmin *= gfc->sv_qnt.longfact[gsfb];

        width = cod_info->width[gsfb];
        rh1 = xmin / width;
#ifdef DBL_EPSILON
        rh2 = DBL_EPSILON;
#else
        rh2 = 2.2204460492503131e-016;
#endif
        en0 = 0.0;
        for (l = 0; l < width; ++l) {
            FLOAT const xa = xr[j++];
            FLOAT const x2 = xa * xa;
            en0 += x2;
            rh2 += (x2 < rh1) ? x2 : rh1;
        }
        if (en0 > xmin)
            ath_over++;

        if (en0 < xmin) {
            rh3 = en0;
        }
        else if (rh2 < xmin) {
            rh3 = xmin;
        }
        else {
            rh3 = rh2;
        }
        xmin = rh3;
        {
            FLOAT const e = ratio->en.l[gsfb];
            if (e > 1e-12f) {
                FLOAT   x;
                x = en0 * ratio->thm.l[gsfb] / e;
                x *= gfc->sv_qnt.longfact[gsfb];
                if (xmin < x)
                    xmin = x;
            }
        }
        xmin = Max(xmin, DBL_EPSILON);
        cod_info->energy_above_cutoff[gsfb] = (en0 > xmin+1e-14f) ? 1 : 0;
        *pxmin++ = xmin;
    }                   /* end of long block loop */




    /*use this function to determine the highest non-zero coeff */
    max_nonzero = 0;
    for (k = 575; k > 0; --k) {
        if (fabs(xr[k]) > 1e-12f) {
            max_nonzero = k;
            break;
        }
    }
    if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
        max_nonzero |= 1; /* only odd numbers */
    }
    else {
        max_nonzero /= 6; /* 3 short blocks */
        max_nonzero *= 6;
        max_nonzero += 5;
    }

    if (gfc->sv_qnt.sfb21_extra == 0 && cfg->samplerate_out < 44000) {
      int const sfb_l = (cfg->samplerate_out <= 8000) ? 17 : 21;
      int const sfb_s = (cfg->samplerate_out <= 8000) ?  9 : 12;
      int   limit = 575;
      if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
          limit = gfc->scalefac_band.l[sfb_l]-1;
      }
      else {
          limit = 3*gfc->scalefac_band.s[sfb_s]-1;
      }
      if (max_nonzero > limit) {
          max_nonzero = limit;
      }
    }
    cod_info->max_nonzero_coeff = max_nonzero;



    for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) {
        int     width, b, l;
        FLOAT   tmpATH;

        tmpATH = athAdjust(ATH->adjust_factor, ATH->s[sfb], ATH->floor, cfg->ATHfixpoint);
        tmpATH *= gfc->sv_qnt.shortfact[sfb];
        
        width = cod_info->width[gsfb];
        for (b = 0; b < 3; b++) {
            FLOAT   en0 = 0.0, xmin = tmpATH;
            FLOAT   rh1, rh2, rh3;

            rh1 = tmpATH / width;
#ifdef DBL_EPSILON
            rh2 = DBL_EPSILON;
#else
            rh2 = 2.2204460492503131e-016;
#endif
            for (l = 0; l < width; ++l) {
                FLOAT const xa = xr[j++];
                FLOAT const x2 = xa * xa;
                en0 += x2;
                rh2 += (x2 < rh1) ? x2 : rh1;
            }
            if (en0 > tmpATH)
                ath_over++;
            
            if (en0 < tmpATH) {
                rh3 = en0;
            }
            else if (rh2 < tmpATH) {
                rh3 = tmpATH;
            }
            else {
                rh3 = rh2;
            }
            xmin = rh3;
            {
                FLOAT const e = ratio->en.s[sfb][b];
                if (e > 1e-12f) {
                    FLOAT   x;
                    x = en0 * ratio->thm.s[sfb][b] / e;
                    x *= gfc->sv_qnt.shortfact[sfb];
                    if (xmin < x)
                        xmin = x;
                }
            }
            xmin = Max(xmin, DBL_EPSILON);
            cod_info->energy_above_cutoff[gsfb+b] = (en0 > xmin+1e-14f) ? 1 : 0;
            *pxmin++ = xmin;
        }               /* b */
        if (cfg->use_temporal_masking_effect) {
            if (pxmin[-3] > pxmin[-3 + 1])
                pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay;
            if (pxmin[-3 + 1] > pxmin[-3 + 2])
                pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay;
        }
    }                   /* end of short block sfb loop */

    return ath_over;
}
예제 #2
0
/*
  Calculate the allowed distortion for each scalefactor band,
  as determined by the psychoacoustic model.
  xmin(sb) = ratio(sb) * en(sb) / bw(sb)

  returns number of sfb's with energy > ATH
*/
static int
calc_xmin_(lame_internal_flags const *gfc,
           III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin)
{
    SessionConfig_t const *const cfg = &gfc->cfg;
    int     sfb, gsfb, j = 0, ath_over = 0, k;
    ATH_t const *const ATH = gfc->ATH;
    const FLOAT *const xr = cod_info->xr;
    int     max_nonzero;
    FLOAT   masking_lower = gfc->sv_qnt.masking_lower;

    for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) {
        FLOAT   en0, xmin;
        int     width, l;

        if (cfg->vbr == vbr_rh)
            xmin = athAdjust(ATH->adjust, ATH->l[gsfb], ATH->floor);
        else
            xmin = ATH->adjust * ATH->l[gsfb];

        en0 = 0.0;
        width = cod_info->width[gsfb];
        for (l = 0; l < width; ++l) {
            FLOAT const xa = xr[j++];
            FLOAT const x2 = xa * xa;
            en0 += x2;
        }
        if (en0 > xmin)
            ath_over++;

        if (!cfg->ATHonly) {
            FLOAT const e = ratio->en.l[gsfb];
            if (e > 0.0f) {
                FLOAT   x;
                x = en0 * ratio->thm.l[gsfb] * masking_lower / e;
                if (xmin < x)
                    xmin = x;
            }
        }

        *pxmin++ = xmin * gfc->sv_qnt.longfact[gsfb];
    }                   /* end of long block loop */




    /*use this function to determine the highest non-zero coeff */
    max_nonzero = 575;
    if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
        k = 576;
        while (k-- && EQ(xr[k], 0)) {
            max_nonzero = k;
        }
    }
    cod_info->max_nonzero_coeff = max_nonzero;



    for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) {
        int     width, b, l;
        FLOAT   tmpATH;
        if (cfg->vbr == vbr_rh)
            tmpATH = athAdjust(ATH->adjust, ATH->s[sfb], ATH->floor);
        else
            tmpATH = ATH->adjust * ATH->s[sfb];

        width = cod_info->width[gsfb];
        for (b = 0; b < 3; b++) {
            FLOAT   en0 = 0.0, xmin;

            for (l = 0; l < width; ++l) {
                FLOAT const xa = xr[j++];
                FLOAT const x2 = xa * xa;
                en0 += x2;
            }
            if (en0 > tmpATH)
                ath_over++;

            xmin = tmpATH;

            if (!cfg->ATHonly && !cfg->ATHshort) {
                FLOAT const e = ratio->en.s[sfb][b];
                if (e > 0.0f) {
                    FLOAT   x;
                    x = en0 * ratio->thm.s[sfb][b] * masking_lower / e;

                    if (xmin < x)
                        xmin = x;
                }
            }

            *pxmin++ = xmin * gfc->sv_qnt.shortfact[sfb];
        }               /* b */
        if (cfg->use_temporal_masking_effect) {
            if (pxmin[-3] > pxmin[-3 + 1])
                pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay;
            if (pxmin[-3 + 1] > pxmin[-3 + 2])
                pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay;
        }
    }                   /* end of short block sfb loop */

    return ath_over;
}
예제 #3
0
static int
calc_xmin_new(lame_internal_flags const *gfc,
           III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin)
{
    SessionConfig_t const *const cfg = &gfc->cfg;
    int     sfb, gsfb, j = 0, ath_over = 0, k;
    ATH_t const *const ATH = gfc->ATH;
    const FLOAT *const xr = cod_info->xr;
    int     max_nonzero;

    for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) {
        FLOAT   en0, xmin;
        FLOAT   rh1, rh2;
        int     width, l;

        xmin = athAdjust(ATH->adjust, ATH->l[gsfb], ATH->floor);

        width = cod_info->width[gsfb];
        rh1 = xmin / width;
#ifdef DBL_EPSILON
        rh2 = DBL_EPSILON;
#else
        rh2 = 2.2204460492503131e-016;
#endif
        en0 = 0.0;
        for (l = 0; l < width; ++l) {
            FLOAT const xa = xr[j++];
            FLOAT const x2 = xa * xa;
            en0 += x2;
            rh2 += (x2 < rh1) ? x2 : rh1;
        }
        if (en0 > xmin)
            ath_over++;

        if (gsfb == SBPSY_l) {
            FLOAT   x = xmin * gfc->sv_qnt.longfact[gsfb];
            if (rh2 < x) {
                rh2 = x;
            }
        }

        xmin = rh2;

        if (!cfg->ATHonly) {
            FLOAT const e = ratio->en.l[gsfb];
            if (e > 0.0f) {
                FLOAT   x;
                x = en0 * ratio->thm.l[gsfb] / e;

                x *= gfc->sv_qnt.longfact[gsfb];
                if (xmin < x)
                    xmin = x;
            }
        }

        *pxmin++ = xmin;
    }                   /* end of long block loop */




    /*use this function to determine the highest non-zero coeff */
    max_nonzero = 575;
    if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */
        k = 576;
        while (k-- && EQ(xr[k], 0)) {
            max_nonzero = k;
        }
    }
    cod_info->max_nonzero_coeff = max_nonzero;



    for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) {
        int     width, b, l;
        FLOAT   tmpATH;

        tmpATH = athAdjust(ATH->adjust, ATH->s[sfb], ATH->floor);

        width = cod_info->width[gsfb];
        for (b = 0; b < 3; b++) {
            FLOAT   en0 = 0.0, xmin;
            FLOAT   rh1, rh2;

            rh1 = tmpATH / width;
#ifdef DBL_EPSILON
            rh2 = DBL_EPSILON;
#else
            rh2 = 2.2204460492503131e-016;
#endif
            for (l = 0; l < width; ++l) {
                FLOAT const xa = xr[j++];
                FLOAT const x2 = xa * xa;
                en0 += x2;
                rh2 += (x2 < rh1) ? x2 : rh1;
            }
            if (en0 > tmpATH)
                ath_over++;
            if (sfb == SBPSY_s) {
                FLOAT   x = tmpATH * gfc->sv_qnt.shortfact[sfb];
                if (rh2 < x) {
                    rh2 = x;
                }
            }

            xmin = rh2;

            if (!cfg->ATHonly && !cfg->ATHshort) {
                FLOAT const e = ratio->en.s[sfb][b];
                if (e > 0.0f) {
                    FLOAT   x;
                    x = en0 * ratio->thm.s[sfb][b] / e;

                    x *= gfc->sv_qnt.shortfact[sfb];
                    if (xmin < x)
                        xmin = x;
                }
            }

            *pxmin++ = xmin;
        }               /* b */
        if (cfg->use_temporal_masking_effect) {
            if (pxmin[-3] > pxmin[-3 + 1])
                pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay;
            if (pxmin[-3 + 1] > pxmin[-3 + 2])
                pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay;
        }
    }                   /* end of short block sfb loop */

    return ath_over;
}
예제 #4
0
/*
  Calculate the allowed distortion for each scalefactor band,
  as determined by the psychoacoustic model.
  xmin(sb) = ratio(sb) * en(sb) / bw(sb)

  returns number of sfb's with energy > ATH
*/
int calc_xmin( 
        lame_global_flags *gfp,
        const III_psy_ratio * const ratio,
	const gr_info       * const cod_info, 
              III_psy_xmin  * const l3_xmin ) 
{
    lame_internal_flags *gfc = gfp->internal_flags;
    int sfb, j=0, ath_over=0;
    FLOAT8 xmin, tmpATH;
    ATH_t * ATH = gfc->ATH;
    const FLOAT8 *xr = cod_info->xr;

    for (sfb = 0; sfb < cod_info->psy_lmax; sfb++) {
	FLOAT en0 = 0.0;
	int width, l;
	if ( gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh )
	    tmpATH = athAdjust( ATH->adjust, ATH->l[sfb], ATH->floor );
	else
	    tmpATH = ATH->adjust * ATH->l[sfb];

	width = gfc->scalefac_band.l[sfb+1] - gfc->scalefac_band.l[sfb];
	l = width;
	do {
	    en0 += xr[j] * xr[j];
	    j++;
	} while (--l > 0);

	/* why is it different from short blocks <?> */
	if ( !gfc->nsPsy.use ) en0 /= width;   

	xmin = tmpATH;
	if (!gfp->ATHonly) {
	    xmin = ratio->en.l[sfb];
	    if (xmin > 0.0)
		xmin = en0 * ratio->thm.l[sfb] * gfc->masking_lower / xmin;
	    if (xmin < tmpATH) 
		xmin = tmpATH;
	}
	/* why is it different from short blocks <?> */
	if ( !gfc->nsPsy.use ) {
	    xmin *= width;
	}
	else {
	    if      (sfb <=  6) xmin *= gfc->nsPsy.bass;
	    else if (sfb <= 13) xmin *= gfc->nsPsy.alto;
	    else if (sfb <= 20) xmin *= gfc->nsPsy.treble;
	    else                xmin *= gfc->nsPsy.sfb21;
	    if ((gfp->VBR == vbr_off || gfp->VBR == vbr_abr) && gfp->quality <= 1)
		xmin *= 0.001;
	}
	l3_xmin->l[sfb] = xmin;
	if (en0 > tmpATH) ath_over++;
    }   /* end of long block loop */

    for (sfb = cod_info->sfb_smin; sfb < cod_info->psy_smax; sfb++) {
	int width, b;
	if ( gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh )
	    tmpATH = athAdjust( ATH->adjust, ATH->s[sfb], ATH->floor );
	else
	    tmpATH = ATH->adjust * ATH->s[sfb];

	width = gfc->scalefac_band.s[sfb+1] - gfc->scalefac_band.s[sfb];
	for ( b = 0; b < 3; b++ ) {
	    FLOAT en0 = 0.0;
	    int l = width;
	    do {
		en0 += xr[j] * xr[j];
		j++;
	    } while (--l > 0);
	    en0 /= width;

	    xmin = tmpATH;
	    if (!gfp->ATHonly && !gfp->ATHshort) {
		xmin = ratio->en.s[sfb][b];
		if (xmin > 0.0)
		    xmin = en0 * ratio->thm.s[sfb][b] * gfc->masking_lower / xmin;
		if (xmin < tmpATH) 
		    xmin = tmpATH;
	    }
	    xmin *= width;

	    if (gfc->nsPsy.use) {
		if      (sfb <=  5) xmin *= gfc->nsPsy.bass;
		else if (sfb <= 10) xmin *= gfc->nsPsy.alto;
		else                xmin *= gfc->nsPsy.treble;
		if ((gfp->VBR == vbr_off || gfp->VBR == vbr_abr) && gfp->quality <= 1)
		    xmin *= 0.001;
	    }
	    l3_xmin->s[sfb][b] = xmin;
	    if (en0 > tmpATH) ath_over++;
	}   /* b */
	if (gfp->useTemporal) {
	    for ( b = 1; b < 3; b++ ) {
		xmin = l3_xmin->s[sfb][b] * (1.0 - gfc->decay)
		    + l3_xmin->s[sfb][b-1] * gfc->decay;
		if (l3_xmin->s[sfb][b] < xmin)
		    l3_xmin->s[sfb][b] = xmin;
	    }
        }   /* sfb */
    }   /* end of short block loop */

    return ath_over;
}