/* * MP3 quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: vbrquantize.c,v 1.41 2001/03/12 07:26:08 markt Exp $ */ #ifdef HAVE_CONFIG_H# include <config.h>#endif #include <assert.h>#include "util.h"#include "l3side.h"#include "quantize.h"#include "reservoir.h"#include "quantize_pvt.h"#include "lame-analysis.h" #ifdef WITH_DMALLOC#include <dmalloc.h>#endif #undef MAXQUANTERROR typedef union { float f; int i;} fi_union; #define MAGIC_FLOAT (65536*(128))#define MAGIC_INT 0x4b000000 #ifdef TAKEHIRO_IEEE754_HACK #ifdef MAXQUANTERROR #define DUFFBLOCK() do { \ xp = xr34[0] * sfpow34_p1; \ xe = xr34[0] * sfpow34_eq; \ xm = xr34[0] * sfpow34_m1; \ if (xm > IXMAX_VAL) \ return -1; \ xp += MAGIC_FLOAT; \ xe += MAGIC_FLOAT; \ xm += MAGIC_FLOAT; \ fi[0].f = xp; \ fi[1].f = xe; \ fi[2].f = xm; \ fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \ fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \ fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \ fi[0].i -= MAGIC_INT; \ fi[1].i -= MAGIC_INT; \ fi[2].i -= MAGIC_INT; \ x0 = fabs(xr[0]); \ xp = x0 - pow43[fi[0].i] * sfpow_p1; \ xe = x0 - pow43[fi[1].i] * sfpow_eq; \ xm = x0 - pow43[fi[2].i] * sfpow_m1; \ xp *= xp; \ xe *= xe; \ xm *= xm; \ xfsf_eq = Max(xfsf_eq, xe); \ xfsf_p1 = Max(xfsf_p1, xp); \ xfsf_m1 = Max(xfsf_m1, xm); \ ++xr; \ ++xr34; \ } while(0) #else#define DUFFBLOCK() do { \ xp = xr34[0] * sfpow34_p1; \ xe = xr34[0] * sfpow34_eq; \ xm = xr34[0] * sfpow34_m1; \ if (xm > IXMAX_VAL) \ return -1; \ xp += MAGIC_FLOAT; \ xe += MAGIC_FLOAT; \ xm += MAGIC_FLOAT; \ fi[0].f = xp; \ fi[1].f = xe; \ fi[2].f = xm; \ fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \ fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \ fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \ fi[0].i -= MAGIC_INT; \ fi[1].i -= MAGIC_INT; \ fi[2].i -= MAGIC_INT; \ x0 = fabs(xr[0]); \ xp = x0 - pow43[fi[0].i] * sfpow_p1; \ xe = x0 - pow43[fi[1].i] * sfpow_eq; \ xm = x0 - pow43[fi[2].i] * sfpow_m1; \ xfsf_p1 += xp * xp; \ xfsf_eq += xe * xe; \ xfsf_m1 += xm * xm; \ ++xr; \ ++xr34; \ } while(0) #endif #else /********************************************************************* * XRPOW_FTOI is a macro to convert floats to ints. * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x] * ROUNDFAC= -0.0946 * * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x] * ROUNDFAC=0.4054 *********************************************************************/# define QUANTFAC(rx) adj43[rx]# define ROUNDFAC 0.4054# define XRPOW_FTOI(src,dest) ((dest) = (int)(src)) #endif static FLOAT8calc_sfb_noise(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf){ int j; fi_union fi; FLOAT8 temp; FLOAT8 xfsf=0; FLOAT8 sfpow,sfpow34; sfpow = POW20(sf+210); /*pow(2.0,sf/4.0); */ sfpow34 = IPOW20(sf+210); /*pow(sfpow,-3.0/4.0);*/ for ( j=0; j < bw ; ++j) {#if 0 int ix; if (xr34[j]*sfpow34 > IXMAX_VAL) return -1; ix=floor( xr34[j]*sfpow34); temp = fabs(xr[j])- pow43[ix]*sfpow; temp *= temp; if (ix < IXMAX_VAL) { temp2 = fabs(xr[j])- pow43[ix+1]*sfpow; temp2 *=temp2; if (temp2<temp) { temp=temp2; ++ix; } }#else if (xr34[j]*sfpow34 > IXMAX_VAL) return -1; #ifdef TAKEHIRO_IEEE754_HACK temp = sfpow34*xr34[j]; temp += MAGIC_FLOAT; fi.f = temp; fi.f = temp + (adj43asm - MAGIC_INT)[fi.i]; fi.i -= MAGIC_INT;#else temp = xr34[j]*sfpow34; XRPOW_FTOI(temp, fi.i); XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i);#endif temp = fabs(xr[j])- pow43[fi.i]*sfpow; temp *= temp; #endif #ifdef MAXQUANTERROR xfsf = Max(xfsf,temp);#else xfsf += temp;#endif }#ifdef MAXQUANTERROR return xfsf;#else return xfsf;//bw;#endif} static FLOAT8calc_sfb_noise_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf){ double xp; double xe; double xm;#ifdef TAKEHIRO_IEEE754_HACK double x0;#endif int xx[3], j; fi_union *fi = (fi_union *)xx; FLOAT8 sfpow34_eq, sfpow34_p1, sfpow34_m1; FLOAT8 sfpow_eq, sfpow_p1, sfpow_m1; FLOAT8 xfsf_eq = 0, xfsf_p1 = 0, xfsf_m1 = 0; sfpow_eq = POW20(sf + 210); /*pow(2.0,sf/4.0); */ sfpow_m1 = sfpow_eq * .8408964153; /* pow(2,(sf-1)/4.0) */ sfpow_p1 = sfpow_eq * 1.189207115; sfpow34_eq = IPOW20(sf + 210); /*pow(sfpow,-3.0/4.0);*/ sfpow34_m1 = sfpow34_eq * 1.13878863476; /* .84089 ^ -3/4 */ sfpow34_p1 = sfpow34_eq * 0.878126080187; #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) { if (xr34[j]*sfpow34_m1 > IXMAX_VAL) return -1; 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; xm = xr34[j]*sfpow34_m1; 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; #ifdef MAXQUANTERROR xfsf_eq = Max(xfsf,xm); xfsf_p1 = Max(xfsf_p1,xp); xfsf_m1 = Max(xfsf_m1,xm);#else xfsf_eq += xe; xfsf_p1 += xp; xfsf_m1 += xm;#endif }#endif if (xfsf_eq < xfsf_p1) xfsf_eq = xfsf_p1; if (xfsf_eq < xfsf_m1) xfsf_eq = xfsf_m1;#ifdef MAXQUANTERROR return xfsf_eq;#else return xfsf_eq;//bw;#endif} static intfind_scalefac(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb, const FLOAT8 l3_xmin, const int bw){ FLOAT8 xfsf; int i,sf,sf_ok,delsf; /* search will range from sf: -209 -> 45 */ sf = -82; delsf = 128; sf_ok=10000; for (i=0; i<7; i++) { delsf /= 2; xfsf = calc_sfb_noise(xr,xr34,bw,sf); if (xfsf < 0) { /* scalefactors too small */ sf += delsf; }else{ if (sf_ok==10000) sf_ok=sf; if (xfsf > l3_xmin) { /* distortion. try a smaller scalefactor */ sf -= delsf; }else{ sf_ok = sf; sf += delsf; } } } assert(sf_ok!=10000);#if 0 assert(delsf==1); /* when for loop goes up to 7 */#endif return sf;} static intfind_scalefac_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb, const FLOAT8 l3_xmin, const int bw){ FLOAT8 xfsf; int i,sf,sf_ok,delsf; /* search will range from sf: -209 -> 45 */ sf = -82; delsf = 128; sf_ok=10000; for (i=0; i<7; i++) { delsf /= 2; xfsf = calc_sfb_noise_ave(xr,xr34,bw,sf); if (xfsf < 0) { /* scalefactors too small */ sf += delsf; }else{ if (sf_ok==10000) sf_ok=sf; if (xfsf > l3_xmin) { /* distortion. try a smaller scalefactor */ sf -= delsf; }else{ sf_ok = sf; sf += delsf; } } } assert(sf_ok!=10000);#if 0 assert(delsf==1); /* when for loop goes up to 7 */#endif return sf;} /* ??? How do the following tables look like for MPEG-2-LSF ??? */ static const int max_range_short[SBPSY_s] ={15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 }; static const int max_range_long[SBPSY_l] ={15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; static const int max_range_short_lsf[SBPSY_s] ={15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 }; /*static const int max_range_short_lsf_pretab[SBPSY_s] ={}*/ static const int max_range_long_lsf[SBPSY_l] ={15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; static const int max_range_long_lsf_pretab[SBPSY_l] ={ 7,7,7,7,7,7, 3,3,3,3,3, 0,0,0,0, 0,0,0, 0,0,0 }; static int compute_scalefacs_short_lsf ( int sf[SBPSY_s][3],gr_info *cod_info, int scalefac[SBPSY_s][3],int sbg[3]){ int maxrange, maxrange1, maxrange2, maxover; int sfb, i; int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; maxover = 0; maxrange1 = max_range_short_lsf[0]; maxrange2 = max_range_short_lsf[6]; for (i=0; i<3; ++i) { int maxsf1 = 0, maxsf2 = 0, minsf = 1000; /* see if we should use subblock gain */ for (sfb = 0; sfb < SBPSY_s; sfb++) { if (sfb < 6) { if (maxsf1 < -sf[sfb][i]) maxsf1 = -sf[sfb][i]; } else { if (maxsf2 < -sf[sfb][i]) maxsf2 = -sf[sfb][i]; } if (minsf > -sf[sfb][i]) minsf = -sf[sfb][i]; } /* boost subblock gain as little as possible so we can * reach maxsf1 with scalefactors * 8*sbg >= maxsf1 */ maxsf1 = Max (maxsf1-maxrange1*ifqstep, maxsf2-maxrange2*ifqstep); sbg[i] = 0; if (minsf > 0) sbg[i] = floor (.125*minsf + .001); if (maxsf1 > 0) sbg[i] = Max (sbg[i], (maxsf1/8 + (maxsf1 % 8 != 0))); if (sbg[i] > 7) sbg[i] = 7; for (sfb = 0; sfb < SBPSY_s; sfb++) { sf[sfb][i] += 8*sbg[i]; if (sf[sfb][i] < 0) { maxrange = sfb < 6 ? maxrange1 : maxrange2; scalefac[sfb][i] = -sf[sfb][i]/ifqstep + (-sf[sfb][i]%ifqstep != 0); if (scalefac[sfb][i] > maxrange) scalefac[sfb][i] = maxrange; if (maxover < -(sf[sfb][i] + scalefac[sfb][i]*ifqstep)) maxover = -(sf[sfb][i] + scalefac[sfb][i]*ifqstep); } } } return maxover;} static intcompute_scalefacs_long_lsf ( int sf [SBPSY_l], const gr_info * const cod_info, int scalefac [SBPSY_l] ){ const int * max_range = max_range_long_lsf; int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; int sfb; int maxover; if (cod_info->preflag) { max_range = max_range_long_lsf_pretab; for (sfb = 11; sfb < SBPSY_l; sfb++) sf[sfb] += pretab[sfb] * ifqstep; } maxover = 0; for (sfb = 0; sfb < SBPSY_l; sfb++) { if (sf[sfb] < 0) { /* ifqstep*scalefac >= -sf[sfb], so round UP */ scalefac[sfb] = -sf[sfb]/ifqstep + (-sf[sfb] % ifqstep != 0); if (scalefac[sfb] > max_range[sfb]) scalefac[sfb] = max_range[sfb]; /* sf[sfb] should now be positive: */ if (-(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) { maxover = -(sf[sfb] + scalefac[sfb]*ifqstep); } } } return maxover;} /* sfb=0..5 scalefac < 16 sfb>5 scalefac < 8 ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= 8*cod_info->subblock_gain[i]; ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i]; */static int compute_scalefacs_short(int sf[SBPSY_s][3],gr_info *cod_info,int scalefac[SBPSY_s][3],int sbg[3]){ int maxrange,maxrange1,maxrange2,maxover;Lines 1–500 of 1689. Load more
/* * MP3 quantization * * Copyright (c) 1999 Mark Taylor * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ /* $Id: vbrquantize.c,v 1.41 2001/03/12 07:26:08 markt Exp $ */ #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <assert.h> #include "util.h" #include "l3side.h" #include "quantize.h" #include "reservoir.h" #include "quantize_pvt.h" #include "lame-analysis.h" #ifdef WITH_DMALLOC #include <dmalloc.h> #endif #undef MAXQUANTERROR typedef union { float f; int i; } fi_union; #define MAGIC_FLOAT (65536*(128)) #define MAGIC_INT 0x4b000000 #ifdef TAKEHIRO_IEEE754_HACK #ifdef MAXQUANTERROR #define DUFFBLOCK() do { \ xp = xr34[0] * sfpow34_p1; \ xe = xr34[0] * sfpow34_eq; \ xm = xr34[0] * sfpow34_m1; \ if (xm > IXMAX_VAL) \ return -1; \ xp += MAGIC_FLOAT; \ xe += MAGIC_FLOAT; \ xm += MAGIC_FLOAT; \ fi[0].f = xp; \ fi[1].f = xe; \ fi[2].f = xm; \ fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \ fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \ fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \ fi[0].i -= MAGIC_INT; \ fi[1].i -= MAGIC_INT; \ fi[2].i -= MAGIC_INT; \ x0 = fabs(xr[0]); \ xp = x0 - pow43[fi[0].i] * sfpow_p1; \ xe = x0 - pow43[fi[1].i] * sfpow_eq; \ xm = x0 - pow43[fi[2].i] * sfpow_m1; \ xp *= xp; \ xe *= xe; \ xm *= xm; \ xfsf_eq = Max(xfsf_eq, xe); \ xfsf_p1 = Max(xfsf_p1, xp); \ xfsf_m1 = Max(xfsf_m1, xm); \ ++xr; \ ++xr34; \ } while(0) #else #define DUFFBLOCK() do { \ xp = xr34[0] * sfpow34_p1; \ xe = xr34[0] * sfpow34_eq; \ xm = xr34[0] * sfpow34_m1; \ if (xm > IXMAX_VAL) \ return -1; \ xp += MAGIC_FLOAT; \ xe += MAGIC_FLOAT; \ xm += MAGIC_FLOAT; \ fi[0].f = xp; \ fi[1].f = xe; \ fi[2].f = xm; \ fi[0].f = xp + (adj43asm - MAGIC_INT)[fi[0].i]; \ fi[1].f = xe + (adj43asm - MAGIC_INT)[fi[1].i]; \ fi[2].f = xm + (adj43asm - MAGIC_INT)[fi[2].i]; \ fi[0].i -= MAGIC_INT; \ fi[1].i -= MAGIC_INT; \ fi[2].i -= MAGIC_INT; \ x0 = fabs(xr[0]); \ xp = x0 - pow43[fi[0].i] * sfpow_p1; \ xe = x0 - pow43[fi[1].i] * sfpow_eq; \ xm = x0 - pow43[fi[2].i] * sfpow_m1; \ xfsf_p1 += xp * xp; \ xfsf_eq += xe * xe; \ xfsf_m1 += xm * xm; \ ++xr; \ ++xr34; \ } while(0) #endif #else /********************************************************************* * XRPOW_FTOI is a macro to convert floats to ints. * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x] * ROUNDFAC= -0.0946 * * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x] * ROUNDFAC=0.4054 *********************************************************************/ # define QUANTFAC(rx) adj43[rx] # define ROUNDFAC 0.4054 # define XRPOW_FTOI(src,dest) ((dest) = (int)(src)) #endif static FLOAT8 calc_sfb_noise(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf) { int j; fi_union fi; FLOAT8 temp; FLOAT8 xfsf=0; FLOAT8 sfpow,sfpow34; sfpow = POW20(sf+210); /*pow(2.0,sf/4.0); */ sfpow34 = IPOW20(sf+210); /*pow(sfpow,-3.0/4.0);*/ for ( j=0; j < bw ; ++j) { #if 0 int ix; if (xr34[j]*sfpow34 > IXMAX_VAL) return -1; ix=floor( xr34[j]*sfpow34); temp = fabs(xr[j])- pow43[ix]*sfpow; temp *= temp; if (ix < IXMAX_VAL) { temp2 = fabs(xr[j])- pow43[ix+1]*sfpow; temp2 *=temp2; if (temp2<temp) { temp=temp2; ++ix; } } #else if (xr34[j]*sfpow34 > IXMAX_VAL) return -1; #ifdef TAKEHIRO_IEEE754_HACK temp = sfpow34*xr34[j]; temp += MAGIC_FLOAT; fi.f = temp; fi.f = temp + (adj43asm - MAGIC_INT)[fi.i]; fi.i -= MAGIC_INT; #else temp = xr34[j]*sfpow34; XRPOW_FTOI(temp, fi.i); XRPOW_FTOI(temp + QUANTFAC(fi.i), fi.i); #endif temp = fabs(xr[j])- pow43[fi.i]*sfpow; temp *= temp; #endif #ifdef MAXQUANTERROR xfsf = Max(xfsf,temp); #else xfsf += temp; #endif } #ifdef MAXQUANTERROR return xfsf; #else return xfsf;//bw; #endif } static FLOAT8 calc_sfb_noise_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int bw, const int sf) { double xp; double xe; double xm; #ifdef TAKEHIRO_IEEE754_HACK double x0; #endif int xx[3], j; fi_union *fi = (fi_union *)xx; FLOAT8 sfpow34_eq, sfpow34_p1, sfpow34_m1; FLOAT8 sfpow_eq, sfpow_p1, sfpow_m1; FLOAT8 xfsf_eq = 0, xfsf_p1 = 0, xfsf_m1 = 0; sfpow_eq = POW20(sf + 210); /*pow(2.0,sf/4.0); */ sfpow_m1 = sfpow_eq * .8408964153; /* pow(2,(sf-1)/4.0) */ sfpow_p1 = sfpow_eq * 1.189207115; sfpow34_eq = IPOW20(sf + 210); /*pow(sfpow,-3.0/4.0);*/ sfpow34_m1 = sfpow34_eq * 1.13878863476; /* .84089 ^ -3/4 */ sfpow34_p1 = sfpow34_eq * 0.878126080187; #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) { if (xr34[j]*sfpow34_m1 > IXMAX_VAL) return -1; 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; xm = xr34[j]*sfpow34_m1; 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; #ifdef MAXQUANTERROR xfsf_eq = Max(xfsf,xm); xfsf_p1 = Max(xfsf_p1,xp); xfsf_m1 = Max(xfsf_m1,xm); #else xfsf_eq += xe; xfsf_p1 += xp; xfsf_m1 += xm; #endif } #endif if (xfsf_eq < xfsf_p1) xfsf_eq = xfsf_p1; if (xfsf_eq < xfsf_m1) xfsf_eq = xfsf_m1; #ifdef MAXQUANTERROR return xfsf_eq; #else return xfsf_eq;//bw; #endif } static int find_scalefac(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb, const FLOAT8 l3_xmin, const int bw) { FLOAT8 xfsf; int i,sf,sf_ok,delsf; /* search will range from sf: -209 -> 45 */ sf = -82; delsf = 128; sf_ok=10000; for (i=0; i<7; i++) { delsf /= 2; xfsf = calc_sfb_noise(xr,xr34,bw,sf); if (xfsf < 0) { /* scalefactors too small */ sf += delsf; }else{ if (sf_ok==10000) sf_ok=sf; if (xfsf > l3_xmin) { /* distortion. try a smaller scalefactor */ sf -= delsf; }else{ sf_ok = sf; sf += delsf; } } } assert(sf_ok!=10000); #if 0 assert(delsf==1); /* when for loop goes up to 7 */ #endif return sf; } static int find_scalefac_ave(const FLOAT8 *xr, const FLOAT8 *xr34, const int sfb, const FLOAT8 l3_xmin, const int bw) { FLOAT8 xfsf; int i,sf,sf_ok,delsf; /* search will range from sf: -209 -> 45 */ sf = -82; delsf = 128; sf_ok=10000; for (i=0; i<7; i++) { delsf /= 2; xfsf = calc_sfb_noise_ave(xr,xr34,bw,sf); if (xfsf < 0) { /* scalefactors too small */ sf += delsf; }else{ if (sf_ok==10000) sf_ok=sf; if (xfsf > l3_xmin) { /* distortion. try a smaller scalefactor */ sf -= delsf; }else{ sf_ok = sf; sf += delsf; } } } assert(sf_ok!=10000); #if 0 assert(delsf==1); /* when for loop goes up to 7 */ #endif return sf; } /* ??? How do the following tables look like for MPEG-2-LSF ??? */ static const int max_range_short[SBPSY_s] = {15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 }; static const int max_range_long[SBPSY_l] = {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; static const int max_range_short_lsf[SBPSY_s] = {15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7 }; /*static const int max_range_short_lsf_pretab[SBPSY_s] = {}*/ static const int max_range_long_lsf[SBPSY_l] = {15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7}; static const int max_range_long_lsf_pretab[SBPSY_l] = { 7,7,7,7,7,7, 3,3,3,3,3, 0,0,0,0, 0,0,0, 0,0,0 }; static int compute_scalefacs_short_lsf ( int sf[SBPSY_s][3],gr_info *cod_info, int scalefac[SBPSY_s][3],int sbg[3]) { int maxrange, maxrange1, maxrange2, maxover; int sfb, i; int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; maxover = 0; maxrange1 = max_range_short_lsf[0]; maxrange2 = max_range_short_lsf[6]; for (i=0; i<3; ++i) { int maxsf1 = 0, maxsf2 = 0, minsf = 1000; /* see if we should use subblock gain */ for (sfb = 0; sfb < SBPSY_s; sfb++) { if (sfb < 6) { if (maxsf1 < -sf[sfb][i]) maxsf1 = -sf[sfb][i]; } else { if (maxsf2 < -sf[sfb][i]) maxsf2 = -sf[sfb][i]; } if (minsf > -sf[sfb][i]) minsf = -sf[sfb][i]; } /* boost subblock gain as little as possible so we can * reach maxsf1 with scalefactors * 8*sbg >= maxsf1 */ maxsf1 = Max (maxsf1-maxrange1*ifqstep, maxsf2-maxrange2*ifqstep); sbg[i] = 0; if (minsf > 0) sbg[i] = floor (.125*minsf + .001); if (maxsf1 > 0) sbg[i] = Max (sbg[i], (maxsf1/8 + (maxsf1 % 8 != 0))); if (sbg[i] > 7) sbg[i] = 7; for (sfb = 0; sfb < SBPSY_s; sfb++) { sf[sfb][i] += 8*sbg[i]; if (sf[sfb][i] < 0) { maxrange = sfb < 6 ? maxrange1 : maxrange2; scalefac[sfb][i] = -sf[sfb][i]/ifqstep + (-sf[sfb][i]%ifqstep != 0); if (scalefac[sfb][i] > maxrange) scalefac[sfb][i] = maxrange; if (maxover < -(sf[sfb][i] + scalefac[sfb][i]*ifqstep)) maxover = -(sf[sfb][i] + scalefac[sfb][i]*ifqstep); } } } return maxover; } static int compute_scalefacs_long_lsf ( int sf [SBPSY_l], const gr_info * const cod_info, int scalefac [SBPSY_l] ) { const int * max_range = max_range_long_lsf; int ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; int sfb; int maxover; if (cod_info->preflag) { max_range = max_range_long_lsf_pretab; for (sfb = 11; sfb < SBPSY_l; sfb++) sf[sfb] += pretab[sfb] * ifqstep; } maxover = 0; for (sfb = 0; sfb < SBPSY_l; sfb++) { if (sf[sfb] < 0) { /* ifqstep*scalefac >= -sf[sfb], so round UP */ scalefac[sfb] = -sf[sfb]/ifqstep + (-sf[sfb] % ifqstep != 0); if (scalefac[sfb] > max_range[sfb]) scalefac[sfb] = max_range[sfb]; /* sf[sfb] should now be positive: */ if (-(sf[sfb] + scalefac[sfb]*ifqstep) > maxover) { maxover = -(sf[sfb] + scalefac[sfb]*ifqstep); } } } return maxover; } /* sfb=0..5 scalefac < 16 sfb>5 scalefac < 8 ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4; ol_sf = (cod_info->global_gain-210.0); ol_sf -= 8*cod_info->subblock_gain[i]; ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i]; */ static int compute_scalefacs_short(int sf[SBPSY_s][3],gr_info *cod_info, int scalefac[SBPSY_s][3],int sbg[3]) { int maxrange,maxrange1,maxrange2,maxover;