rminnichinitial1fcdf7916 years agoHistory
1689 lines · 48.4 KB · C
RawDownload
/* *	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.