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; }
static int FixNoise(CoderInfo *coderInfo, const double *xr, double *xr_pow, int *xi, double *xmin, double *pow43, double *adj43) { int i, sb; int start, end; double diffvol; double tmp; const double ifqstep = pow(2.0, 0.1875); const double log_ifqstep = 1.0 / log(ifqstep); const double maxstep = 0.05; for (sb = 0; sb < coderInfo->nr_of_sfb; sb++) { double sfacfix; double fixstep = 0.25; int sfac; double fac; int dist; double sfacfix0 = 1.0, dist0 = 1e50; double maxx; start = coderInfo->sfb_offset[sb]; end = coderInfo->sfb_offset[sb+1]; if (!xmin[sb]) goto nullsfb; maxx = 0.0; for (i = start; i < end; i++) { if (xr_pow[i] > maxx) maxx = xr_pow[i]; } //printf("band %d: maxx: %f\n", sb, maxx); if (maxx < 10.0) { nullsfb: for (i = start; i < end; i++) xi[i] = 0; coderInfo->scale_factor[sb] = 10; continue; } sfacfix = 1.0 / maxx; sfac = (int)(log(sfacfix) * log_ifqstep - 0.5); for (i = start; i < end; i++) xr_pow[i] *= sfacfix; maxx *= sfacfix; coderInfo->scale_factor[sb] = sfac; QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end, adj43); //printf("\tsfac: %d\n", sfac); calcdist: diffvol = 0.0; for (i = start; i < end; i++) { tmp = xi[i]; diffvol += tmp * tmp; // ~x^(3/2) } if (diffvol < 1e-6) diffvol = 1e-6; tmp = pow(diffvol / (double)(end - start), -0.666); if (fabs(fixstep) > maxstep) { double dd = 0.5*(tmp / xmin[sb] - 1.0); if (fabs(dd) < fabs(fixstep)) { fixstep = dd; if (fabs(fixstep) < maxstep) fixstep = maxstep * ((fixstep > 0) ? 1 : -1); } } if (fixstep > 0) { if (tmp < dist0) { dist0 = tmp; sfacfix0 = sfacfix; } else { if (fixstep > .1) fixstep = .1; } } else { dist0 = tmp; sfacfix0 = sfacfix; } dist = (tmp > xmin[sb]); fac = 0.0; if (fabs(fixstep) >= maxstep) { if ((dist && (fixstep < 0)) || (!dist && (fixstep > 0))) { fixstep = -0.5 * fixstep; } fac = 1.0 + fixstep; } else if (dist) { fac = 1.0 + fabs(fixstep); } if (fac != 0.0) { if (maxx * fac >= IXMAX_VAL) { // restore best noise fac = sfacfix0 / sfacfix; for (i = start; i < end; i++) xr_pow[i] *= fac; maxx *= fac; sfacfix *= fac; coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5; QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end, adj43); continue; } if (coderInfo->scale_factor[sb] < -10) { for (i = start; i < end; i++) xr_pow[i] *= fac; maxx *= fac; sfacfix *= fac; coderInfo->scale_factor[sb] = log(sfacfix) * log_ifqstep - 0.5; QuantizeBand(xr_pow, xi, IPOW20(coderInfo->global_gain), start, end, adj43); goto calcdist; } } } return 0; }
int count_bits( lame_internal_flags * const gfc, int * const ix, const FLOAT8 * const xr, gr_info * const gi) { int bits = 0; int i, a1, a2; /* since quantize_xrpow uses table lookup, we need to check this first: */ FLOAT8 w = (IXMAX_VAL) / IPOW20(gi->global_gain); for ( i = 0; i < 576; i++ ) { if (xr[i] > w) return LARGE_BITS; } if (gfc->quantization) quantize_xrpow(xr, ix, IPOW20(gi->global_gain)); else quantize_xrpow_ISO(xr, ix, IPOW20(gi->global_gain)); if (gfc->noise_shaping_amp==3) { int sfb; // 0.634521682242439 = 0.5946*2**(.5*0.1875) FLOAT8 roundfac = 0.634521682242439 / IPOW20(gi->global_gain+gi->scalefac_scale); i = 0; for (sfb = 0; sfb < gi->sfb_lmax; sfb++) { int end; if (!gfc->pseudohalf.l[sfb]) continue; end = gfc->scalefac_band.l[sfb+1]; for (; i < end; i++) if (xr[i] < roundfac) ix[i] = 0; } for (sfb = gi->sfb_smin; sfb < SBPSY_s; sfb++) { int start, end, win; start = gfc->scalefac_band.s[sfb]; end = gfc->scalefac_band.s[sfb+1]; for (win = 0; win < 3; win++) { int j; if (!gfc->pseudohalf.s[sfb][win]) continue; for (j = start; j < end; j++, i++) if (xr[i] < roundfac) ix[i] = 0; } } } i=576; /* Determine count1 region */ for (; i > 1; i -= 2) if (ix[i - 1] | ix[i - 2]) break; gi->count1 = i; /* Determines the number of bits to encode the quadruples. */ a1 = a2 = 0; for (; i > 3; i -= 4) { int p; /* hack to check if all values <= 1 */ if ((unsigned int)(ix[i-1] | ix[i-2] | ix[i-3] | ix[i-4]) > 1) break; p = ((ix[i-4] * 2 + ix[i-3]) * 2 + ix[i-2]) * 2 + ix[i-1]; a1 += t32l[p]; a2 += t33l[p]; } bits = a1; gi->count1table_select = 0; if (a1 > a2) { bits = a2; gi->count1table_select = 1; } gi->count1bits = bits; gi->big_values = i; if (i == 0) return bits; if (gi->block_type == SHORT_TYPE) { a1=3*gfc->scalefac_band.s[3]; if (a1 > gi->big_values) a1 = gi->big_values; a2 = gi->big_values; }else if (gi->block_type == NORM_TYPE) { assert(i <= 576); /* bv_scf has 576 entries (0..575) */ a1 = gi->region0_count = gfc->bv_scf[i-2]; a2 = gi->region1_count = gfc->bv_scf[i-1]; assert(a1+a2+2 < SBPSY_l); a2 = gfc->scalefac_band.l[a1 + a2 + 2]; a1 = gfc->scalefac_band.l[a1 + 1]; if (a2 < i) gi->table_select[2] = gfc->choose_table(ix + a2, ix + i, &bits); } else { gi->region0_count = 7; /*gi->region1_count = SBPSY_l - 7 - 1;*/ gi->region1_count = SBMAX_l -1 - 7 - 1; a1 = gfc->scalefac_band.l[7 + 1]; a2 = i; if (a1 > a2) { a1 = a2; } } /* have to allow for the case when bigvalues < region0 < region1 */ /* (and region0, region1 are ignored) */ a1 = Min(a1,i); a2 = Min(a2,i); assert( a1 >= 0 ); assert( a2 >= 0 ); /* Count the number of bits necessary to code the bigvalues region. */ if (0 < a1) gi->table_select[0] = gfc->choose_table(ix, ix + a1, &bits); if (a1 < a2) gi->table_select[1] = gfc->choose_table(ix + a1, ix + a2, &bits); return bits; }
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; }