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; } } }
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; } }
/************************************************************************ * * VBR_iteration_loop() * * ************************************************************************/ void VBR_iteration_loop_new (lame_global_flags *gfp, FLOAT8 pe[2][2], FLOAT8 ms_ener_ratio[2], FLOAT8 xr[2][2][576], III_psy_ratio ratio[2][2], III_side_info_t * l3_side, int l3_enc[2][2][576], III_scalefac_t scalefac[2][2]) { III_psy_xmin l3_xmin[2][2]; FLOAT8 masking_lower_db; FLOAT8 ifqstep; int start,end,bw,sfb, i,ch, gr, over; III_psy_xmin vbrsf; FLOAT8 vbrmax; iteration_init(gfp,l3_side,l3_enc); /* Adjust allowed masking based on quality setting */ /* db_lower varies from -10 to +8 db */ masking_lower_db = -10 + 2*gfp->VBR_q; /* adjust by -6(min)..0(max) depending on bitrate */ masking_lower = pow(10.0,masking_lower_db/10); masking_lower = 1; for (gr = 0; gr < gfp->mode_gr; gr++) { if (convert_mdct) ms_convert(xr[gr],xr[gr]); for (ch = 0; ch < gfp->stereo; ch++) { FLOAT8 xr34[576]; gr_info *cod_info = &l3_side->gr[gr].ch[ch].tt; int shortblock; over = 0; shortblock = (cod_info->block_type == SHORT_TYPE); for(i=0;i<576;i++) { FLOAT8 temp=fabs(xr[gr][ch][i]); xr34[i]=sqrt(sqrt(temp)*temp); } calc_xmin( gfp,xr[gr][ch], &ratio[gr][ch], cod_info, &l3_xmin[gr][ch]); vbrmax=0; if (shortblock) { for ( sfb = 0; sfb < SBPSY_s; sfb++ ) { for ( i = 0; i < 3; i++ ) { start = scalefac_band.s[ sfb ]; end = scalefac_band.s[ sfb+1 ]; bw = end - start; vbrsf.s[sfb][i] = find_scalefac(&xr[gr][ch][3*start+i],&xr34[3*start+i],3,sfb, masking_lower*l3_xmin[gr][ch].s[sfb][i],bw); if (vbrsf.s[sfb][i]>vbrmax) vbrmax=vbrsf.s[sfb][i]; } } }else{ for ( sfb = 0; sfb < SBPSY_l; sfb++ ) { start = scalefac_band.l[ sfb ]; end = scalefac_band.l[ sfb+1 ]; bw = end - start; vbrsf.l[sfb] = find_scalefac(&xr[gr][ch][start],&xr34[start],1,sfb, masking_lower*l3_xmin[gr][ch].l[sfb],bw); if (vbrsf.l[sfb]>vbrmax) vbrmax = vbrsf.l[sfb]; } } /* compute scalefactors */ /* sf = (cod_info->global_gain-210.0)/4.0; */ cod_info->global_gain = floor(4*vbrmax +210 + .5); if (shortblock) { for ( sfb = 0; sfb < SBPSY_s; sfb++ ) { for ( i = 0; i < 3; i++ ) { vbrsf.s[sfb][i] -= vbrmax; } } cod_info->scalefac_scale = 0; if (compute_scalefacs_short(vbrsf.s,cod_info,scalefac[gr][ch].s) > 0) { cod_info->scalefac_scale = 1; if (compute_scalefacs_short(vbrsf.s,cod_info,scalefac[gr][ch].s) >0) { /* what do we do now? */ exit(32); } } }else{ for ( sfb = 0; sfb < SBPSY_l; sfb++ ) vbrsf.l[sfb] -= vbrmax; /* can we get away with scalefac_scale=0? */ cod_info->scalefac_scale = 0; if (compute_scalefacs_long(vbrsf.l,cod_info,scalefac[gr][ch].l) > 0) { cod_info->scalefac_scale = 1; if (compute_scalefacs_long(vbrsf.l,cod_info,scalefac[gr][ch].l) >0) { /* what do we do now? */ exit(32); } } } } /* ch */ } /* gr */ }