📄 psymodel.c
字号:
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 + -