📄 quantize_pvt.c
字号:
/* if mid channel already has 2x more than average, dont bother */ /* mean_bits = bits per granule (for both channels) */ if (targ_bits[0] < mean_bits) targ_bits[0] += move_bits; targ_bits[1] -= move_bits; } else { targ_bits[0] += targ_bits[1] - 125; targ_bits[1] = 125; } } move_bits=targ_bits[0]+targ_bits[1]; if (move_bits > max_bits) { targ_bits[0]=(max_bits*targ_bits[0])/move_bits; targ_bits[1]=(max_bits*targ_bits[1])/move_bits; } assert (targ_bits[0] <= MAX_BITS); assert (targ_bits[1] <= MAX_BITS);}/** * Robert Hegemann 2001-04-27: * this adjusts the ATH, keeping the original noise floor * affects the higher frequencies more than the lower ones */FLOAT athAdjust( FLOAT a, FLOAT x, FLOAT athFloor ){ /* work in progress */ FLOAT const o = 90.30873362; FLOAT const p = 94.82444863; FLOAT u = FAST_LOG10_X(x, 10.0); FLOAT v = a*a; FLOAT w = 0.0; u -= athFloor; /* undo scaling */ if ( v > 1E-20 ) w = 1. + FAST_LOG10_X(v, 10.0 / o); if ( w < 0 ) w = 0.; u *= w; u += athFloor + o-p; /* redo scaling */ return pow( 10., 0.1*u );}/*************************************************************************//* calc_xmin *//*************************************************************************//* 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, gr_info * const cod_info, FLOAT * pxmin ){ lame_internal_flags *gfc = gfp->internal_flags; int sfb, gsfb, j=0, ath_over=0, k; ATH_t * ATH = gfc->ATH; const FLOAT *xr = cod_info->xr; int max_nonzero; for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) { FLOAT en0, xmin; int width, l; if (gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh) xmin = athAdjust(ATH->adjust, ATH->l[gsfb], ATH->floor); else xmin = ATH->adjust * ATH->l[gsfb]; width = cod_info->width[gsfb]; l = width >> 1; en0 = 0.0; do { en0 += xr[j] * xr[j]; j++; en0 += xr[j] * xr[j]; j++; } while (--l > 0); if (en0 > xmin) ath_over++; if (!gfp->ATHonly) { FLOAT x = ratio->en.l[gsfb]; if (x > 0.0) { x = en0 * ratio->thm.l[gsfb] * gfc->masking_lower / x; if (xmin < x) xmin = x; } } *pxmin++ = xmin * gfc->nsPsy.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 == NORM_TYPE) { k = 576; while (k-- && !xr[k]){ 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; FLOAT tmpATH; 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 = cod_info->width[gsfb]; for ( b = 0; b < 3; b++ ) { FLOAT en0 = 0.0, xmin; int l = width >> 1; do { en0 += xr[j] * xr[j]; j++; en0 += xr[j] * xr[j]; j++; } while (--l > 0); if (en0 > tmpATH) ath_over++; xmin = tmpATH; if (!gfp->ATHonly && !gfp->ATHshort) { FLOAT x = ratio->en.s[sfb][b]; if (x > 0.0) x = en0 * ratio->thm.s[sfb][b] * gfc->masking_lower / x; if (xmin < x) xmin = x; } *pxmin++ = xmin * gfc->nsPsy.shortfact[sfb]; } /* b */ if (gfp->useTemporal) { if (pxmin[-3] > pxmin[-3+1]) pxmin[-3+1] += (pxmin[-3] - pxmin[-3+1]) * gfc->decay; if (pxmin[-3+1] > pxmin[-3+2]) pxmin[-3+2] += (pxmin[-3+1] - pxmin[-3+2]) * gfc->decay; } } /* end of short block sfb loop */ return ath_over;}FLOAT calc_noise_core_c( const gr_info * const cod_info, int *startline, int l, FLOAT step){ FLOAT noise = 0; int j = *startline; const int *ix = cod_info->l3_enc; if (j> cod_info->count1) { while (l--) { FLOAT temp; temp = cod_info->xr[j];j++; noise += temp * temp; temp = cod_info->xr[j];j++; noise += temp * temp; } } else if (j> cod_info->big_values) { FLOAT ix01[2]; ix01[0] = 0; ix01[1] = step; while (l--) { FLOAT temp; temp = fabs(cod_info->xr[j]) - ix01[ix[j]];j++; noise += temp * temp; temp = fabs(cod_info->xr[j]) - ix01[ix[j]];j++; noise += temp * temp; } } else { while (l--) { FLOAT temp; temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;j++; noise += temp * temp; temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;j++; noise += temp * temp; } } *startline = j; return noise;} /*************************************************************************//* calc_noise *//*************************************************************************//* -oo dB => -1.00 *//* - 6 dB => -0.97 */ /* - 3 dB => -0.80 *//* - 2 dB => -0.64 *//* - 1 dB => -0.38 *//* 0 dB => 0.00 *//* + 1 dB => +0.49 *//* + 2 dB => +1.06 *//* + 3 dB => +1.68 *//* + 6 dB => +3.69 *//* +10 dB => +6.45 */int calc_noise( const lame_internal_flags * const gfc, const gr_info * const cod_info, const FLOAT * l3_xmin, FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise){ int sfb, l, over=0; FLOAT over_noise_db = 0; FLOAT tot_noise_db = 0; /* 0 dB relative to masking */ FLOAT max_noise = -20.0; /* -200 dB relative to masking */ int j = 0; const int *ix = cod_info->l3_enc; const int *scalefac = cod_info->scalefac; FLOAT sfb_noise[39]; res->over_SSD = 0; for (sfb = 0; sfb < cod_info->psymax; sfb++) { int s = cod_info->global_gain - (((*scalefac++) + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)) - cod_info->subblock_gain[cod_info->window[sfb]] * 8; FLOAT noise = 0.0; if (prev_noise && (prev_noise->step[sfb] == s)){ /* use previously computed values */ noise = prev_noise->noise[sfb]; j += cod_info->width[sfb]; *distort++ = noise / *l3_xmin++; noise = prev_noise->noise_log[sfb]; } else { FLOAT step = POW20(s); l = cod_info->width[sfb] >> 1; if ((j+cod_info->width[sfb])>cod_info->max_nonzero_coeff) { int usefullsize; usefullsize = cod_info->max_nonzero_coeff - j +1; if (usefullsize > 0) l = usefullsize >> 1; else l = 0; } noise = calc_noise_core_c(cod_info, &j, l, step); if (prev_noise) { /* save noise values */ prev_noise->step[sfb] = s; prev_noise->noise[sfb] = noise; } noise = *distort++ = noise / *l3_xmin++; /* multiplying here is adding in dB, but can overflow */ noise = FAST_LOG10(Max(noise,1E-20)); if (prev_noise) { /* save noise values */ prev_noise->noise_log[sfb] = noise; } } if (prev_noise) { /* save noise values */ prev_noise->global_gain = cod_info->global_gain;; } /*tot_noise *= Max(noise, 1E-20); */ tot_noise_db += noise; if (noise > 0.0) { int tmp; tmp = Max((int)(noise*10 + .5), 1); res->over_SSD += tmp*tmp; over++; /* multiplying here is adding in dB -but can overflow */ /*over_noise *= noise; */ over_noise_db += noise; } max_noise=Max(max_noise,noise); sfb_noise[sfb] = noise; } res->over_count = over; res->tot_noise = tot_noise_db; res->over_noise = over_noise_db; res->max_noise = max_noise; return over;}#ifdef HAVE_GTK/************************************************************************ * * set_pinfo() * * updates plotting data * * Mark Taylor 2000-??-?? * * Robert Hegemann: moved noise/distortion calc into it * ************************************************************************/staticvoid set_pinfo ( lame_global_flags *gfp, gr_info * const cod_info, const III_psy_ratio * const ratio, const int gr, const int ch ){ lame_internal_flags *gfc=gfp->internal_flags; int sfb, sfb2; int j,i,l,start,end,bw; FLOAT en0,en1; FLOAT ifqstep = ( cod_info->scalefac_scale == 0 ) ? .5 : 1.0; int* scalefac = cod_info->scalefac; FLOAT l3_xmin[SFBMAX], xfsf[SFBMAX]; calc_noise_result noise; calc_xmin (gfp, ratio, cod_info, l3_xmin); calc_noise (gfc, cod_info, l3_xmin, xfsf, &noise, 0); j = 0; sfb2 = cod_info->sfb_lmax; if (cod_info->block_type != SHORT_TYPE && !cod_info->mixed_block_flag) sfb2 = 22; for (sfb = 0; sfb < sfb2; sfb++) { start = gfc->scalefac_band.l[ sfb ]; end = gfc->scalefac_band.l[ sfb+1 ]; bw = end - start; for ( en0 = 0.0; j < end; j++ ) en0 += cod_info->xr[j] * cod_info->xr[j]; en0/=bw; /* convert to MDCT units */ en1=1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo-> en[gr][ch][sfb] = en1*en0; gfc->pinfo->xfsf[gr][ch][sfb] = en1*l3_xmin[sfb]*xfsf[sfb]/bw; if (ratio->en.l[sfb]>0 && !gfp->ATHonly) en0 = en0/ratio->en.l[sfb]; else en0=0.0; gfc->pinfo->thr[gr][ch][sfb] = en1*Max(en0*ratio->thm.l[sfb],gfc->ATH->l[sfb]); /* there is no scalefactor bands >= SBPSY_l */ gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0; if (cod_info->preflag && sfb>=11) gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep*pretab[sfb]; if (sfb<SBPSY_l) { assert(scalefac[sfb]>=0); /* scfsi should be decoded by caller side*/ gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep*scalefac[sfb]; } } /* for sfb */ if (cod_info->block_type == SHORT_TYPE) { sfb2 = sfb; for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++ ) { start = gfc->scalefac_band.s[ sfb ]; end = gfc->scalefac_band.s[ sfb + 1 ]; bw = end - start; for ( i = 0; i < 3; i++ ) { for ( en0 = 0.0, l = start; l < end; l++ ) { en0 += cod_info->xr[j] * cod_info->xr[j]; j++; } en0=Max(en0/bw,1e-20); /* convert to MDCT units */ en1=1e15; /* scaling so it shows up on FFT plot */ gfc->pinfo-> en_s[gr][ch][3*sfb+i] = en1*en0; gfc->pinfo->xfsf_s[gr][ch][3*sfb+i] = en1*l3_xmin[sfb2]*xfsf[sfb2]/bw; if (ratio->en.s[sfb][i]>0) en0 = en0/ratio->en.s[sfb][i]; else en0=0.0; if (gfp->ATHonly || gfp->ATHshort) en0=0; gfc->pinfo->thr_s[gr][ch][3*sfb+i] = en1*Max(en0*ratio->thm.s[sfb][i],gfc->ATH->s[sfb]); /* there is no scalefactor bands >= SBPSY_s */ gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i] = -2.0*cod_info->subblock_gain[i]; if (sfb < SBPSY_s) { gfc->pinfo->LAMEsfb_s[gr][ch][3*sfb+i] -= ifqstep*scalefac[sfb2]; } sfb2++; } } } /* block type short */ gfc->pinfo->LAMEqss [gr][ch] = cod_info->global_gain; gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length + cod_info->part2_length; gfc->pinfo->LAMEsfbits [gr][ch] = cod_info->part2_length; gfc->pinfo->over [gr][ch] = noise.over_count; gfc->pinfo->max_noise [gr][ch] = noise.max_noise * 10.0; gfc->pinfo->over_noise[gr][ch] = noise.over_noise * 10.0; gfc->pinfo->tot_noise [gr][ch] = noise.tot_noise * 10.0; gfc->pinfo->over_SSD [gr][ch] = noise.over_SSD;}/************************************************************************ * * set_frame_pinfo() * * updates plotting data for a whole frame * * Robert Hegemann 2000-10-21 * ************************************************************************/void set_frame_pinfo( lame_global_flags *gfp, III_psy_ratio ratio [2][2]){ lame_internal_flags *gfc=gfp->internal_flags; int ch; int gr; gfc->masking_lower = 1.0; /* for every granule and channel patch l3_enc and set info */ for (gr = 0; gr < gfc->mode_gr; gr ++) { for (ch = 0; ch < gfc->channels_out; ch ++) { gr_info *cod_info = &gfc->l3_side.tt[gr][ch]; int scalefac_sav[SFBMAX]; memcpy(scalefac_sav, cod_info->scalefac, sizeof(scalefac_sav)); /* reconstruct the scalefactors in case SCFSI was used */ if (gr == 1) { int sfb; for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) { if (cod_info->scalefac[sfb] < 0) /* scfsi */ cod_info->scalefac[sfb] = gfc->l3_side.tt[0][ch].scalefac[sfb]; } } set_pinfo (gfp, cod_info, &ratio[gr][ch], gr, ch); memcpy(cod_info->scalefac, scalefac_sav, sizeof(scalefac_sav)); } /* for ch */ } /* for gr */}#endif /* ifdef HAVE_GTK */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -