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; }
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; } }
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; } } }