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

📄 psymodel.c

📁 MP3编码程序和资料
💻 C
📖 第 1 页 / 共 3 页
字号:
	  DEBUGF("energy / tot %i %5.2f   %e  %e\n",j,ave/(tot*16./3.),	  ave,tot*16./3.);	*/	gfc->energy[j+1] = gfc->energy[j+2] = gfc->energy[j+3] =  gfc->energy[j]=tot;      }#endif                                    /**********************************************************************     *    Calculate the energy and the unpredictability in the threshold   *     *    calculation partitions                                           *     **********************************************************************/    b = 0;    for (j = 0; j < gfc->cw_upper_index && gfc->numlines_l[b] && b<gfc->npart_l_orig; )      {	FLOAT8 ebb, cbb;	ebb = gfc->energy[j];	cbb = gfc->energy[j] * gfc->cw[j];	j++;	for (i = gfc->numlines_l[b] - 1; i > 0; i--)	  {	    ebb += gfc->energy[j];	    cbb += gfc->energy[j] * gfc->cw[j];	    j++;	  }	eb[b] = ebb;	cb[b] = cbb;	b++;      }    for (; b < gfc->npart_l_orig; b++ )      {	FLOAT8 ebb = gfc->energy[j++];	assert(gfc->numlines_l[b]);	for (i = gfc->numlines_l[b] - 1; i > 0; i--)	  {	    ebb += gfc->energy[j++];	  }	eb[b] = ebb;	cb[b] = ebb * 0.4;      }    /**********************************************************************     *      convolve the partitioned energy and unpredictability           *     *      with the spreading function, s3_l[b][k]                        *     ******************************************************************** */    gfc->pe[chn] = 0;		/*  calculate percetual entropy */    for ( b = 0;b < gfc->npart_l; b++ )      {	FLOAT8 tbb,ecb,ctb;	ecb = 0;	ctb = 0;	for ( k = gfc->s3ind[b][0]; k <= gfc->s3ind[b][1]; k++ )	  {	    ecb += gfc->s3_l[b][k] * eb[k];	/* sprdngf for Layer III */	    ctb += gfc->s3_l[b][k] * cb[k];	  }	/* calculate the tonality of each threshold calculation partition 	 * calculate the SNR in each threshhold calculation partition 	 * tonality = -0.299 - .43*log(ctb/ecb);	 * tonality = 0:           use NMT   (lots of masking)	 * tonality = 1:           use TMN   (little masking)	 *//* ISO values */#define CONV1 (-.299)#define CONV2 (-.43)	tbb = ecb;	if (tbb != 0)	  {	    tbb = ctb / tbb;	    if (tbb <= exp((1-CONV1)/CONV2)) 	      { /* tonality near 1 */		tbb = exp(-LN_TO_LOG10 * TMN);	      }	    else if (tbb >= exp((0-CONV1)/CONV2)) 	      {/* tonality near 0 */		tbb = exp(-LN_TO_LOG10 * NMT);	      }	    else	      {		/* convert to tonality index */		/* tonality small:   tbb=1 */		/* tonality large:   tbb=-.299 */		tbb = CONV1 + CONV2*log(tbb);		tbb = exp(-LN_TO_LOG10 * ( TMN*tbb + (1-tbb)*NMT) );	      }	  }	/* at this point, tbb represents the amount the spreading function	 * will be reduced.  The smaller the value, the less masking.	 * minval[] = 1 (0db)     says just use tbb.	 * minval[]= .01 (-20db)  says reduce spreading function by 	 *                        at least 20db.  	 */	tbb = Min(gfc->minval[b], tbb);	ecb *= tbb;	/* long block pre-echo control.   */	/* rpelev=2.0, rpelev2=16.0 */	/* note: all surges in PE are because of this pre-echo formula	 * for thr[b].  If it this is not used, PE is always around 600	 */	/* dont use long block pre-echo control if previous granule was 	 * a short block.  This is to avoid the situation:   	 * frame0:  quiet (very low masking)  	 * frame1:  surge  (triggers short blocks)	 * frame2:  regular frame.  looks like pre-echo when compared to 	 *          frame0, but all pre-echo was in frame1.	 */	//	ecb = Max(ecb,gfc->ATH_partitionbands[b]);	if (gfc->blocktype_old[chn] == SHORT_TYPE )	  thr[b] = ecb; /* Min(ecb, rpelev*gfc->nb_1[chn][b]); */	else	  thr[b] = Min(ecb, Min(rpelev*gfc->nb_1[chn][b],rpelev2*gfc->nb_2[chn][b]) );	gfc->nb_2[chn][b] = gfc->nb_1[chn][b];	gfc->nb_1[chn][b] = ecb;	{	  FLOAT8 thrpe;	  thrpe = Max(thr[b],gfc->ATH_partitionbands[b]);	  /*	    printf("%i thr=%e   ATH=%e  \n",b,thr[b],gfc->ATH_partitionbands[b]);	  */	  if (thrpe < eb[b])	    gfc->pe[chn] -= gfc->numlines_l[b] * log(thrpe / eb[b]);	}      }        /***************************************************************      * determine the block type (window type) based on L & R channels     *      ***************************************************************/    {  /* compute PE for all 4 channels */      FLOAT mn,mx,ma=0,mb=0,mc=0;            for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)	{	  ma += gfc->energy_s[0][j];	  mb += gfc->energy_s[1][j];	  mc += gfc->energy_s[2][j];	}      mn = Min(ma,mb);      mn = Min(mn,mc);      mx = Max(ma,mb);      mx = Max(mx,mc);            /* bit allocation is based on pe.  */      if (mx>mn) {	FLOAT8 tmp = 400*log(mx/(1e-12+mn));	if (tmp>gfc->pe[chn]) gfc->pe[chn]=tmp;      }      /* block type is based just on L or R channel */            if (chn<2) {	uselongblock[chn] = 1;		/* tuned for t1.wav.  doesnt effect most other samples */	if (gfc->pe[chn] > 3000) 	  uselongblock[chn]=0;		if ( mx > 30*mn ) 	  {/* big surge of energy - always use short blocks */	    uselongblock[chn] = 0;	  } 	else if ((mx > 10*mn) && (gfc->pe[chn] > 1000))	  {/* medium surge, medium pe - use short blocks */	    uselongblock[chn] = 0;	  }		/* disable short blocks */	if (gfp->no_short_blocks)	  uselongblock[chn]=1;      }    }    if (gfp->gtkflag) {      FLOAT mn,mx,ma=0,mb=0,mc=0;      for ( j = HBLKSIZE_s/2; j < HBLKSIZE_s; j ++)      {        ma += gfc->energy_s[0][j];        mb += gfc->energy_s[1][j];        mc += gfc->energy_s[2][j];      }      mn = Min(ma,mb);      mn = Min(mn,mc);      mx = Max(ma,mb);      mx = Max(mx,mc);      gfc->pinfo->ers[gr_out][chn]=gfc->ers_save[chn];      gfc->ers_save[chn]=(mx/(1e-12+mn));      gfc->pinfo->pe[gr_out][chn]=gfc->pe_save[chn];      gfc->pe_save[chn]=gfc->pe[chn];    }    /***************************************************************      * compute masking thresholds for both short and long blocks     ***************************************************************/    /* longblock threshold calculation (part 2) */    for ( sb = 0; sb < SBPSY_l; sb++ )      {#if 1  /* additive masking */	FLOAT8 enn = gfc->w1_l[sb] * eb[gfc->bu_l[sb]] + gfc->w2_l[sb] * eb[gfc->bo_l[sb]];	FLOAT8 thmm = gfc->w1_l[sb] *thr[gfc->bu_l[sb]] + gfc->w2_l[sb] * thr[gfc->bo_l[sb]];	for ( b = gfc->bu_l[sb]+1; b < gfc->bo_l[sb]; b++ )	  {	    enn  += eb[b];	    thmm += thr[b];	  }#else	FLOAT8 enn = gfc->w1_l[sb] * eb[gfc->bu_l[sb]] + gfc->w2_l[sb] * eb[gfc->bo_l[sb]];	FLOAT8 thmm = Min(thr[gfc->bu_l[sb]],thr[gfc->bo_l[sb]]);	for ( b = gfc->bu_l[sb]+1; b < gfc->bo_l[sb]; b++ )	  {	    enn  += eb[b];	    thmm = Min(thr[b],thmm);	  }	thmm*=(1+gfc->bo_l[sb]-gfc->bu_l[sb]);#endif	gfc->en[chn].l[sb] = enn;	gfc->thm[chn].l[sb] = thmm;      }        /* threshold calculation for short blocks */    for ( sblock = 0; sblock < 3; sblock++ )      {	j = 0;	for ( b = 0; b < gfc->npart_s_orig; b++ )	  {	    FLOAT ecb = gfc->energy_s[sblock][j++];	    for (i = 1 ; i<gfc->numlines_s[b]; ++i)	      {		ecb += gfc->energy_s[sblock][j++];	      }	    eb[b] = ecb;	  }	for ( b = 0; b < gfc->npart_s; b++ )	  {	    FLOAT8 ecb = 0;	    for ( k = gfc->s3ind_s[b][0]; k <= gfc->s3ind_s[b][1]; k++ )	      {		ecb += gfc->s3_s[b][k] * eb[k];	      }	    thr[b] = Max (1e-6, ecb);	  }	for ( sb = 0; sb < SBPSY_s; sb++ )	  {	    FLOAT8 enn  = gfc->w1_s[sb] * eb[gfc->bu_s[sb]] + gfc->w2_s[sb] * eb[gfc->bo_s[sb]];	    FLOAT8 thmm = gfc->w1_s[sb] *thr[gfc->bu_s[sb]] + gfc->w2_s[sb] * thr[gfc->bo_s[sb]];	    for ( b = gfc->bu_s[sb]+1; b < gfc->bo_s[sb]; b++ )	      {		enn  += eb[b];		thmm += thr[b];	      }	    gfc->en[chn].s[sb][sblock] = enn;	    gfc->thm[chn].s[sb][sblock] = thmm;	  }      }  } /* end loop over chn */  /* compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper */  if ( numchn==4 /* mid/side and r/l */) {    FLOAT8 rside,rmid,mld;    int chmid=2,chside=3;         for ( sb = 0; sb < SBPSY_l; sb++ ) {      /* use this fix if L & R masking differs by 2db or less */      /* if db = 10*log10(x2/x1) < 2 */      /* if (x2 < 1.58*x1) { */      if (gfc->thm[0].l[sb] <= 1.58*gfc->thm[1].l[sb]	  && gfc->thm[1].l[sb] <= 1.58*gfc->thm[0].l[sb]) {	mld = gfc->mld_l[sb]*gfc->en[chside].l[sb];	rmid = Max(gfc->thm[chmid].l[sb], Min(gfc->thm[chside].l[sb],mld));	mld = gfc->mld_l[sb]*gfc->en[chmid].l[sb];	rside = Max(gfc->thm[chside].l[sb],Min(gfc->thm[chmid].l[sb],mld));	gfc->thm[chmid].l[sb]=rmid;	gfc->thm[chside].l[sb]=rside;      }    }    for ( sb = 0; sb < SBPSY_s; sb++ ) {      for ( sblock = 0; sblock < 3; sblock++ ) {	if (gfc->thm[0].s[sb][sblock] <= 1.58*gfc->thm[1].s[sb][sblock]	    && gfc->thm[1].s[sb][sblock] <= 1.58*gfc->thm[0].s[sb][sblock]) {	  mld = gfc->mld_s[sb]*gfc->en[chside].s[sb][sblock];	  rmid = Max(gfc->thm[chmid].s[sb][sblock],Min(gfc->thm[chside].s[sb][sblock],mld));	  mld = gfc->mld_s[sb]*gfc->en[chmid].s[sb][sblock];	  rside = Max(gfc->thm[chside].s[sb][sblock],Min(gfc->thm[chmid].s[sb][sblock],mld));	  gfc->thm[chmid].s[sb][sblock]=rmid;	  gfc->thm[chside].s[sb][sblock]=rside;	}      }    }  }        if (gfp->mode == MPG_MD_JOINT_STEREO)  {    /* determin ms_ratio from masking thresholds*/    /* use ms_stereo (ms_ratio < .35) if average thresh. diff < 5 db */    FLOAT8 db,x1,x2,sidetot=0,tot=0;    for (sb= SBPSY_l/4 ; sb< SBPSY_l; sb ++ ) {      x1 = Min(gfc->thm[0].l[sb],gfc->thm[1].l[sb]);      x2 = Max(gfc->thm[0].l[sb],gfc->thm[1].l[sb]);      /* thresholds difference in db */      if (x2 >= 1000*x1)  db=3;      else db = log10(x2/x1);        /*  DEBUGF("db = %f %e %e  \n",db,gfc->thm[0].l[sb],gfc->thm[1].l[sb]);*/      sidetot += db;      tot++;    }    ms_ratio_l= (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */    ms_ratio_l = Min(ms_ratio_l,0.5);        sidetot=0; tot=0;    for ( sblock = 0; sblock < 3; sblock++ )      for ( sb = SBPSY_s/4; sb < SBPSY_s; sb++ ) {	x1 = Min(gfc->thm[0].s[sb][sblock],gfc->thm[1].s[sb][sblock]);	x2 = Max(gfc->thm[0].s[sb][sblock],gfc->thm[1].s[sb][sblock]);	/* thresholds difference in db */	if (x2 >= 1000*x1)  db=3;	else db = log10(x2/x1);  	sidetot += db;	tot++;      }    ms_ratio_s = (sidetot/tot)*0.7; /* was .35*(sidetot/tot)/5.0*10 */    ms_ratio_s = Min(ms_ratio_s,.5);  }  /***************************************************************    * determin final block type   ***************************************************************/  for (chn=0; chn<gfc->stereo; chn++) {    blocktype[chn] = NORM_TYPE;  }  if (gfc->stereo==2) {    if (!gfp->allow_diff_short || gfp->mode==MPG_MD_JOINT_STEREO) {      /* force both channels to use the same block type */      /* this is necessary if the frame is to be encoded in ms_stereo.  */      /* But even without ms_stereo, FhG  does this */      int bothlong= (uselongblock[0] && uselongblock[1]);      if (!bothlong) {	uselongblock[0]=0;	uselongblock[1]=0;      }    }  }      /* update the blocktype of the previous granule, since it depends on what   * happend in this granule */  for (chn=0; chn<gfc->stereo; chn++) {    if ( uselongblock[chn])      {				/* no attack : use long blocks */	switch( gfc->blocktype_old[chn] ) 	  {	  case NORM_TYPE:	  case STOP_TYPE:	    blocktype[chn] = NORM_TYPE;	    break;	  case SHORT_TYPE:	    blocktype[chn] = STOP_TYPE; 	    break;	  case START_TYPE:	    ERRORF( "Error in block selecting\n" );	    LAME_ERROR_EXIT();	    break; /* problem */	  }      } else   {	/* attack : use short blocks */	blocktype[chn] = SHORT_TYPE;	if ( gfc->blocktype_old[chn] == NORM_TYPE ) {	  gfc->blocktype_old[chn] = START_TYPE;	}	if ( gfc->blocktype_old[chn] == STOP_TYPE ) {	  gfc->blocktype_old[chn] = SHORT_TYPE ;	}      }        blocktype_d[chn] = gfc->blocktype_old[chn];  /* value returned to calling program */    gfc->blocktype_old[chn] = blocktype[chn];    /* save for next call to l3psy_anal */  }    if (blocktype_d[0]==2)     *ms_ratio = gfc->ms_ratio_s_old;  else    *ms_ratio = gfc->ms_ratio_l_old;  gfc->ms_ratio_s_old = ms_ratio_s;  gfc->ms_ratio_l_old = ms_ratio_l;  /* we dont know the block type of this frame yet - assume long */  *ms_ratio_next = ms_ratio_l;  /*********************************************************************/  /* compute side_energy / (side+mid)_energy */  /* 0 = no energy in side channel */  /* .5 = half of total energy in side channel */  /*********************************************************************/  if (numchn==4)  {    FLOAT tmp = tot_ener[3]+tot_ener[2];    *ms_ener_ratio = gfc->ms_ener_ratio_old;    gfc->ms_ener_ratio_old=0;    if (tmp>0) gfc->ms_ener_ratio_old=tot_ener[3]/tmp;  } else    /* we didn't compute ms_ener_ratios */    *ms_ener_ratio = 0;  return 0;}int L3para_read(lame_global_flags *gfp, FLOAT8 sfreq, int *numlines_l,int *numlines_s, FLOAT8 *minval,FLOAT8 s3_l[CBANDS][CBANDS], FLOAT8 s3_s[CBANDS][CBANDS],FLOAT8 *SNR, int *bu_l, int *bo_l, FLOAT8 *w1_l, FLOAT8 *w2_l, int *bu_s, int *bo_s, FLOAT8 *w1_s, FLOAT8 *w2_s,int *npart_l_orig,int *npart_l,int *npart_s_orig,int *npart_s){  lame_internal_flags *gfc=gfp->internal_flags;  FLOAT8 freq_tp;  FLOAT8 bval_l[CBANDS], bval_s[CBANDS];  int   cbmax=0, cbmax_tp;  FLOAT8 *p = psy_data;  int  sbmax ;  int  i,j,k2,loop;  int freq_scale=1;  int partition[HBLKSIZE];  /******************************************************************/  /* Read long block data */  /******************************************************************/  for(loop=0;loop<6;loop++)    {      freq_tp = *p++;      cbmax_tp = (int) *p++;      cbmax_tp++;

⌨️ 快捷键说明

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