⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psymodel.c

📁 MP3编码程序和资料
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *	psymodel.c * *	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. */#include "util.h"#include "encoder.h"#include "psymodel.h"#include "l3side.h"#include <assert.h>#include "tables.h"#include "fft.h"#ifdef M_LN10#define		LN_TO_LOG10		(M_LN10/10)#else#define         LN_TO_LOG10             0.2302585093#endifint L3para_read( lame_global_flags *gfp,		  FLOAT8 sfreq, int numlines[CBANDS],int numlines_s[CBANDS], 		  FLOAT8 minval[CBANDS], 		  FLOAT8 s3_l[CBANDS][CBANDS],		  FLOAT8 s3_s[CBANDS][CBANDS],		  FLOAT8 SNR_s[CBANDS],		  int bu_l[SBPSY_l], int bo_l[SBPSY_l],		  FLOAT8 w1_l[SBPSY_l], FLOAT8 w2_l[SBPSY_l],		  int bu_s[SBPSY_s], int bo_s[SBPSY_s],		  FLOAT8 w1_s[SBPSY_s], FLOAT8 w2_s[SBPSY_s],		  int *, int *, int *, int *);									int L3psycho_anal( lame_global_flags *gfp,                    short int *buffer[2],int gr_out ,                     FLOAT8 *ms_ratio,                    FLOAT8 *ms_ratio_next,		    FLOAT8 *ms_ener_ratio,		    III_psy_ratio masking_ratio[2][2],		    III_psy_ratio masking_MS_ratio[2][2],		    FLOAT8 percep_entropy[2],FLOAT8 percep_MS_entropy[2],                     int blocktype_d[2]){  lame_internal_flags *gfc=gfp->internal_flags;/* to get a good cache performance, one has to think about * the sequence, in which the variables are used.   * (Note: these static variables have been moved to the gfc-> struct, * and their order in memory is layed out in util.h) */    /* fft and energy calculation   */  FLOAT (*wsamp_l)[BLKSIZE];  FLOAT (*wsamp_s)[3][BLKSIZE_s];  FLOAT tot_ener[4];  /* convolution   */  FLOAT8 eb[CBANDS];  FLOAT8 cb[CBANDS];  FLOAT8 thr[CBANDS];    /* ratios    */  FLOAT8 ms_ratio_l=0,ms_ratio_s=0;  /* block type  */  int blocktype[2],uselongblock[2];    /* usual variables like loop indices, etc..    */  int numchn, chn, samplerate;  int   b, i, j, k;  int	sb,sblock;  FLOAT cwlimit;  /*  use a simplified spreading function: */    /*#define NEWS3  */ #if 1    /* AAC values, results in more masking over MP3 values */# define TMN 18# define NMT 6#else    /* MP3 values */# define TMN 29# define NMT 6#endif  if(gfc->psymodel_init==0) {    FLOAT8	SNR_s[CBANDS];    gfc->psymodel_init=1;    samplerate = gfp->out_samplerate;    switch(gfp->out_samplerate){    case 32000: break;    case 44100: break;    case 48000: break;    case 16000: break;    case 22050: break;    case 24000: break;    case  8000: samplerate *= 2; break;  /* kludge so mpeg2.5 uses mpeg2 tables  for now */    case 11025: samplerate *= 2; break;    case 12000: samplerate *= 2; break;    default:    ERRORF("error, invalid sampling frequency: %d Hz\n",			gfp->out_samplerate);    return -1;    }    gfc->ms_ener_ratio_old=.25;    gfc->blocktype_old[0]=STOP_TYPE;    gfc->blocktype_old[1]=STOP_TYPE;    gfc->blocktype_old[0]=SHORT_TYPE;    gfc->blocktype_old[1]=SHORT_TYPE;    for (i=0; i<4; ++i) {      for (j=0; j<CBANDS; ++j) {	gfc->nb_1[i][j]=1e20;	gfc->nb_2[i][j]=1e20;      }      for ( sb = 0; sb < SBPSY_l; sb++ ) {	gfc->en[i].l[sb] = 1e20;	gfc->thm[i].l[sb] = 1e20;      }      for (j=0; j<3; ++j) {	for ( sb = 0; sb < SBPSY_s; sb++ ) {	  gfc->en[i].s[sb][j] = 1e20;	  gfc->thm[i].s[sb][j] = 1e20;	}      }    }        /*  gfp->cwlimit = sfreq*j/1024.0;  */    gfc->cw_lower_index=6;    if (gfp->cwlimit>0)       cwlimit=gfp->cwlimit;    else      cwlimit=8.8717;    gfc->cw_upper_index = cwlimit*1000.0*1024.0/((FLOAT8)samplerate);    gfc->cw_upper_index=Min(HBLKSIZE-4,gfc->cw_upper_index);      /* j+3 < HBLKSIZE-1 */    gfc->cw_upper_index=Max(6,gfc->cw_upper_index);    for ( j = 0; j < HBLKSIZE; j++ )      gfc->cw[j] = 0.4;            i=L3para_read( gfp,(FLOAT8) samplerate,gfc->numlines_l,gfc->numlines_s,          gfc->minval,gfc->s3_l,gfc->s3_s,SNR_s,gfc->bu_l,          gfc->bo_l,gfc->w1_l,gfc->w2_l, gfc->bu_s,gfc->bo_s,          gfc->w1_s,gfc->w2_s,&gfc->npart_l_orig,&gfc->npart_l,          &gfc->npart_s_orig,&gfc->npart_s );    if (i!=0) return -1;        /* npart_l_orig   = number of partition bands before convolution */    /* npart_l  = number of partition bands after convolution */        for (i=0; i<gfc->npart_l; i++) {      for (j = 0; j < gfc->npart_l_orig; j++) {	if (gfc->s3_l[i][j] != 0.0)	  break;      }      gfc->s3ind[i][0] = j;            for (j = gfc->npart_l_orig - 1; j > 0; j--) {	if (gfc->s3_l[i][j] != 0.0)	  break;      }      gfc->s3ind[i][1] = j;    }    for (i=0; i<gfc->npart_s; i++) {      for (j = 0; j < gfc->npart_s_orig; j++) {	if (gfc->s3_s[i][j] != 0.0)	  break;      }      gfc->s3ind_s[i][0] = j;            for (j = gfc->npart_s_orig - 1; j > 0; j--) {	if (gfc->s3_s[i][j] != 0.0)	  break;      }      gfc->s3ind_s[i][1] = j;    }            /*        #include "debugscalefac.c"    */    #define rpelev 2#define rpelev2 16    /* compute norm_l, norm_s instead of relying on table data */    for ( b = 0;b < gfc->npart_l; b++ ) {      FLOAT8 norm=0;      for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ ) {	norm += gfc->s3_l[b][k];      }      for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ ) {	gfc->s3_l[b][k] /=  norm;      }      /*DEBUGF("%i  norm=%f  norm_l=%f \n",b,1/norm,norm_l[b]);*/    }    for ( b = 0;b < gfc->npart_s; b++ ) {      FLOAT8 norm=0;      for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ ) {	norm += gfc->s3_s[b][k];      }      for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ ) {	gfc->s3_s[b][k] *= SNR_s[b] / norm;      }      /*DEBUGF("%i  norm=%f  norm_s=%f \n",b,1/norm,norm_l[b]);*/    }        init_fft();  }  /************************* End of Initialization *****************************/        numchn = gfc->stereo;  /* chn=2 and 3 = Mid and Side channels */  if (gfp->mode == MPG_MD_JOINT_STEREO) numchn=4;  for (chn=0; chn<numchn; chn++) {    /* there is a one granule delay.  Copy maskings computed last call     * into masking_ratio to return to calling program.     */    if (chn<2) {          /* LR maskings  */      percep_entropy[chn] = gfc->pe[chn];       masking_ratio[gr_out][chn].thm = gfc->thm[chn];      masking_ratio[gr_out][chn].en = gfc->en[chn];    }else{      /* MS maskings  */      percep_MS_entropy[chn-2] = gfc->pe[chn];       masking_MS_ratio[gr_out][chn-2].en = gfc->en[chn];      masking_MS_ratio[gr_out][chn-2].thm = gfc->thm[chn];    }          /**********************************************************************     *  compute FFTs     **********************************************************************/    wsamp_s = gfc->wsamp_S+(chn & 1);    wsamp_l = gfc->wsamp_L+(chn & 1);    if (chn<2) {          fft_long ( *wsamp_l, chn, buffer);      fft_short( *wsamp_s, chn, buffer);    }     /* FFT data for mid and side channel is derived from L & R */    if (chn == 2)      {        for (j = BLKSIZE-1; j >=0 ; --j)        {          FLOAT l = gfc->wsamp_L[0][j];          FLOAT r = gfc->wsamp_L[1][j];          gfc->wsamp_L[0][j] = (l+r)*(FLOAT)(SQRT2*0.5);          gfc->wsamp_L[1][j] = (l-r)*(FLOAT)(SQRT2*0.5);        }        for (b = 2; b >= 0; --b)        {          for (j = BLKSIZE_s-1; j >= 0 ; --j)          {            FLOAT l = gfc->wsamp_S[0][b][j];            FLOAT r = gfc->wsamp_S[1][b][j];            gfc->wsamp_S[0][b][j] = (l+r)*(FLOAT)(SQRT2*0.5);            gfc->wsamp_S[1][b][j] = (l-r)*(FLOAT)(SQRT2*0.5);          }        }      }    /**********************************************************************     *  compute energies     **********************************************************************/                gfc->energy[0]  = (*wsamp_l)[0];    gfc->energy[0] *= gfc->energy[0];        tot_ener[chn] = gfc->energy[0]; /* sum total energy at nearly no extra cost */        for (j=BLKSIZE/2-1; j >= 0; --j)    {      FLOAT re = (*wsamp_l)[BLKSIZE/2-j];      FLOAT im = (*wsamp_l)[BLKSIZE/2+j];      gfc->energy[BLKSIZE/2-j] = (re * re + im * im) * (FLOAT)0.5;      if (BLKSIZE/2-j > 10)	tot_ener[chn] += gfc->energy[BLKSIZE/2-j];    }    for (b = 2; b >= 0; --b)    {      gfc->energy_s[b][0]  = (*wsamp_s)[b][0];      gfc->energy_s[b][0] *=  gfc->energy_s [b][0];      for (j=BLKSIZE_s/2-1; j >= 0; --j)      {        FLOAT re = (*wsamp_s)[b][BLKSIZE_s/2-j];        FLOAT im = (*wsamp_s)[b][BLKSIZE_s/2+j];        gfc->energy_s[b][BLKSIZE_s/2-j] = (re * re + im * im) * (FLOAT)0.5;      }    }  if(gfp->gtkflag) {    for (j=0; j<HBLKSIZE ; j++) {      gfc->pinfo->energy[gr_out][chn][j]=gfc->energy_save[chn][j];      gfc->energy_save[chn][j]=gfc->energy[j];    }  }        /**********************************************************************     *    compute unpredicatability of first six spectral lines            *      **********************************************************************/    for ( j = 0; j < gfc->cw_lower_index; j++ )      {	 /* calculate unpredictability measure cw */	FLOAT an, a1, a2;	FLOAT bn, b1, b2;	FLOAT rn, r1, r2;	FLOAT numre, numim, den;	a2 = gfc-> ax_sav[chn][1][j];	b2 = gfc-> bx_sav[chn][1][j];	r2 = gfc-> rx_sav[chn][1][j];	a1 = gfc-> ax_sav[chn][1][j] = gfc-> ax_sav[chn][0][j];	b1 = gfc-> bx_sav[chn][1][j] = gfc-> bx_sav[chn][0][j];	r1 = gfc-> rx_sav[chn][1][j] = gfc-> rx_sav[chn][0][j];	an = gfc-> ax_sav[chn][0][j] = (*wsamp_l)[j];	bn = gfc-> bx_sav[chn][0][j] = j==0 ? (*wsamp_l)[0] : (*wsamp_l)[BLKSIZE-j];  	rn = gfc-> rx_sav[chn][0][j] = sqrt(gfc->energy[j]);	{ /* square (x1,y1) */	  if( r1 != 0 ) {	    numre = (a1*b1);	    numim = (a1*a1-b1*b1)*(FLOAT)0.5;	    den = r1*r1;	  } else {	    numre = 1;	    numim = 0;	    den = 1;	  }	}		{ /* multiply by (x2,-y2) */	  if( r2 != 0 ) {	    FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;	    FLOAT tmp1 = -a2*numre+tmp2;	    numre =       -b2*numim+tmp2;	    numim = tmp1;	    den *= r2;	  } else {	    /* do nothing */	  }	}		{ /* r-prime factor */	  FLOAT tmp = (2*r1-r2)/den;	  numre *= tmp;	  numim *= tmp;	}	den=rn+fabs(2*r1-r2);	if( den != 0 ) {	  numre = (an+bn)*(FLOAT)0.5-numre;	  numim = (an-bn)*(FLOAT)0.5-numim;	  den = sqrt(numre*numre+numim*numim)/den;	}	gfc->cw[j] = den;      }    /**********************************************************************     *     compute unpredicatibility of next 200 spectral lines            *     **********************************************************************/     for ( j = gfc->cw_lower_index; j < gfc->cw_upper_index; j += 4 )      {/* calculate unpredictability measure cw */	FLOAT rn, r1, r2;	FLOAT numre, numim, den;		k = (j+2) / 4; 		{ /* square (x1,y1) */	  r1 = gfc->energy_s[0][k];	  if( r1 != 0 ) {	    FLOAT a1 = (*wsamp_s)[0][k]; 	    FLOAT b1 = (*wsamp_s)[0][BLKSIZE_s-k]; /* k is never 0 */	    numre = (a1*b1);	    numim = (a1*a1-b1*b1)*(FLOAT)0.5;	    den = r1;	    r1 = sqrt(r1);	  } else {	    numre = 1;	    numim = 0;	    den = 1;	  }	}			{ /* multiply by (x2,-y2) */	  r2 = gfc->energy_s[2][k];	  if( r2 != 0 ) {	    FLOAT a2 = (*wsamp_s)[2][k]; 	    FLOAT b2 = (*wsamp_s)[2][BLKSIZE_s-k];	    	    	    FLOAT tmp2 = (numim+numre)*(a2+b2)*(FLOAT)0.5;	    FLOAT tmp1 = -a2*numre+tmp2;	    numre =       -b2*numim+tmp2;	    numim = tmp1;	    	    r2 = sqrt(r2);	    den *= r2;	  } else {	    /* do nothing */	  }	}		{ /* r-prime factor */	  FLOAT tmp = (2*r1-r2)/den;	  numre *= tmp;	  numim *= tmp;	}		rn = sqrt(gfc->energy_s[1][k]);	den=rn+fabs(2*r1-r2);	if( den != 0 ) {	  FLOAT an = (*wsamp_s)[1][k]; 	  FLOAT bn = (*wsamp_s)[1][BLKSIZE_s-k];	  numre = (an+bn)*(FLOAT)0.5-numre;	  numim = (an-bn)*(FLOAT)0.5-numim;	  den = sqrt(numre*numre+numim*numim)/den;	}		gfc->cw[j+1] = gfc->cw[j+2] = gfc->cw[j+3] = gfc->cw[j] = den;      }    #if 0    for ( j = 14; j < HBLKSIZE-4; j += 4 )      {/* calculate energy from short ffts */	FLOAT8 tot,ave;	k = (j+2) / 4; 	for (tot=0, sblock=0; sblock < 3; sblock++)	  tot+=gfc->energy_s[sblock][k];	ave = gfc->energy[j+1]+ gfc->energy[j+2]+ gfc->energy[j+3]+ gfc->energy[j];	ave /= 4.;	/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -