static FLOAT8 calc_sfb_noise(const FLOAT8 * xr, const FLOAT8 * xr34, unsigned int bw, int sf) { unsigned int j; fi_union fi; FLOAT8 temp; FLOAT8 xfsf = 0.0; FLOAT8 const sfpow = POW20(sf); /*pow(2.0,sf/4.0); */ FLOAT8 const sfpow34 = IPOW20(sf); /*pow(sfpow,-3.0/4.0); */ for (j = 0; j < bw; ++j) { temp = xr34[j] * sfpow34; if (temp > IXMAX_VAL) return -1; #ifdef TAKEHIRO_IEEE754_HACK temp += MAGIC_FLOAT; fi.f = temp; fi.f = temp + (adj43asm - MAGIC_INT)[fi.i]; fi.i -= MAGIC_INT; #else XRPOW_FTOI(temp, fi.i); XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i); #endif temp = fabs(xr[j]) - pow43[fi.i] * sfpow; xfsf += temp * temp; } return xfsf; }
static FLOAT8 calc_sfb_noise_mq(const FLOAT8 * xr, const FLOAT8 * xr34, int bw, int sf, int mq, FLOAT8 * scratch) { int j, k; fi_union fi; FLOAT8 temp; FLOAT8 xfsfm = 0.0, xfsf = 0.0; FLOAT8 const sfpow = POW20(sf); /*pow(2.0,sf/4.0); */ FLOAT8 const sfpow34 = IPOW20(sf); /*pow(sfpow,-3.0/4.0); */ for (j = 0; j < bw; ++j) { temp = xr34[j] * sfpow34; if (temp > IXMAX_VAL) return -1; #ifdef TAKEHIRO_IEEE754_HACK temp += MAGIC_FLOAT; fi.f = temp; fi.f = temp + (adj43asm - MAGIC_INT)[fi.i]; fi.i -= MAGIC_INT; #else XRPOW_FTOI(temp, fi.i); XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i); #endif temp = fabs(xr[j]) - pow43[fi.i] * sfpow; temp *= temp; scratch[j] = temp; if (xfsfm < temp) xfsfm = temp; xfsf += temp; } if (mq == 1) return bw * select_kth(scratch, bw, bw * 13 / 16); xfsf /= bw; for (k = 1, j = 0; j < bw; ++j) { if (scratch[j] > xfsf) { xfsfm += scratch[j]; ++k; } } return xfsfm / k * bw; }
int calc_noise(gr_info const *const cod_info, FLOAT const *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 *scalefac = cod_info->scalefac; res->over_SSD = 0; for (sfb = 0; sfb < cod_info->psymax; sfb++) { int const 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 const r_l3_xmin = 1.f / *l3_xmin++; FLOAT distort_ = 0.0f; FLOAT noise = 0.0f; if (prev_noise && (prev_noise->step[sfb] == s)) { /* use previously computed values */ j += cod_info->width[sfb]; distort_ = r_l3_xmin * prev_noise->noise[sfb]; noise = prev_noise->noise_log[sfb]; } else { FLOAT const 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; } distort_ = r_l3_xmin * noise; /* multiplying here is adding in dB, but can overflow */ noise = FAST_LOG10(Max(distort_, 1E-20f)); if (prev_noise) { /* save noise values */ prev_noise->noise_log[sfb] = noise; } }
static FLOAT8 calc_sfb_noise_ave(const FLOAT8 * xr, const FLOAT8 * xr34, int bw, int sf) { FLOAT8 xp; FLOAT8 xe; FLOAT8 xm; #ifdef TAKEHIRO_IEEE754_HACK FLOAT8 x0; unsigned int index = 0; #endif int xx[3], j; fi_union *fi = (fi_union *) xx; FLOAT8 xfsf_eq = 0.0, xfsf_p1 = 0.0, xfsf_m1 = 0.0; FLOAT8 const sfpow_eq = POW20(sf); /*pow(2.0,sf/4.0); */ FLOAT8 const sfpow_m1 = sfpow_eq * facm1; FLOAT8 const sfpow_p1 = sfpow_eq * facp1; FLOAT8 const sfpow34_eq = IPOW20(sf); /*pow(sfpow,-3.0/4.0); */ FLOAT8 const sfpow34_m1 = sfpow34_eq * fac34m1; FLOAT8 const sfpow34_p1 = sfpow34_eq * fac34p1; #ifdef TAKEHIRO_IEEE754_HACK /* * loop unrolled into "Duff's Device". Robert Hegemann */ j = (bw + 3) / 4; switch (bw % 4) { default: case 0: do { DUFFBLOCK(); case 3: DUFFBLOCK(); case 2: DUFFBLOCK(); case 1: DUFFBLOCK(); } while (--j); } #else for (j = 0; j < bw; ++j) { xm = xr34[j] * sfpow34_m1; if (xm > IXMAX_VAL) return -1; XRPOW_FTOI(xm, fi[0].i); XRPOW_FTOI(xm + QUANTFAC(fi[0].i), fi[0].i); xm = fabs(xr[j]) - pow43[fi[0].i] * sfpow_m1; xm *= xm; xe = xr34[j] * sfpow34_eq; XRPOW_FTOI(xe, fi[0].i); XRPOW_FTOI(xe + QUANTFAC(fi[0].i), fi[0].i); xe = fabs(xr[j]) - pow43[fi[0].i] * sfpow_eq; xe *= xe; xp = xr34[j] * sfpow34_p1; XRPOW_FTOI(xp, fi[0].i); XRPOW_FTOI(xp + QUANTFAC(fi[0].i), fi[0].i); xp = fabs(xr[j]) - pow43[fi[0].i] * sfpow_p1; xp *= xp; xfsf_m1 += xm; xfsf_eq += xe; xfsf_p1 += xp; } #endif if (xfsf_eq < xfsf_p1) xfsf_eq = xfsf_p1; if (xfsf_eq < xfsf_m1) xfsf_eq = xfsf_m1; return xfsf_eq; }
int calc_noise( const lame_internal_flags * const gfc, const int ix [576], const gr_info * const cod_info, const III_psy_xmin * const l3_xmin, const III_scalefac_t * const scalefac, III_psy_xmin * xfsf, calc_noise_result * const res ) { int sfb, l, i, over=0; FLOAT8 over_noise_db = 0; FLOAT8 tot_noise_db = 0; /* 0 dB relative to masking */ FLOAT8 max_noise = 1E-20; /* -200 dB relative to masking */ double klemm_noise = 1E-37; int j = 0; for (sfb = 0; sfb < cod_info->psy_lmax; sfb++) { int s = cod_info->global_gain - ((scalefac->l[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) << (cod_info->scalefac_scale + 1)); FLOAT8 step; FLOAT8 noise = 0.0; if (s<0) { step = pow(2.0, (double)(s - 210) * 0.25); }else{ /* use table lookup. allegedly faster */ step = POW20(s); } l = gfc->scalefac_band.l[sfb+1] - gfc->scalefac_band.l[sfb]; do { FLOAT8 temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step; noise += temp * temp; j++; } while (--l > 0); noise = xfsf->l[sfb] = noise / l3_xmin->l[sfb]; max_noise=Max(max_noise,noise); klemm_noise += penalties (noise); noise = FAST_LOG10(Max(noise,1E-20)); /* multiplying here is adding in dB, but can overflow */ //tot_noise *= Max(noise, 1E-20); tot_noise_db += noise; if (noise > 0.0) { over++; /* multiplying here is adding in dB -but can overflow */ //over_noise *= noise; over_noise_db += noise; } } for (sfb = cod_info->sfb_smin; sfb < cod_info->psy_smax; sfb++) { int width = gfc->scalefac_band.s[sfb+1] - gfc->scalefac_band.s[sfb]; for ( i = 0; i < 3; i++ ) { int s = cod_info->global_gain - (scalefac->s[sfb][i] << (cod_info->scalefac_scale + 1)) - cod_info->subblock_gain[i] * 8; FLOAT8 step = POW20(s); FLOAT8 noise = 0.0; l = width; do { FLOAT8 temp; temp = pow43[ix[j]] * step - fabs(cod_info->xr[j]); noise += temp * temp; j++; } while (--l > 0); noise = xfsf->s[sfb][i] = noise / l3_xmin->s[sfb][i]; max_noise = Max(max_noise,noise); klemm_noise += penalties (noise); noise = FAST_LOG10(Max(noise,1E-20)); tot_noise_db += noise; if (noise > 0.0) { over++; over_noise_db += noise; } } } res->over_count = over; res->tot_noise = 10.*tot_noise_db; res->over_noise = 10.*over_noise_db; res->max_noise = 10.*FAST_LOG10(max_noise); res->klemm_noise = klemm_noise; return over; }