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

📄 psymodel.c

📁 音频编码
💻 C
📖 第 1 页 / 共 4 页
字号:
#define I1LIMIT 8   /* as in if(i>8)  */ #define I2LIMIT 23  /* as in if(i>24) -> changed 23 */ #define MLIMIT  15  /* as in if(m<15) */ static FLOAT ma_max_i1;static FLOAT ma_max_i2;static FLOAT ma_max_m;static void init_mask_add_max_values(void){    ma_max_i1 = pow(10,(I1LIMIT+1)/16.0);    ma_max_i2 = pow(10,(I2LIMIT+1)/16.0);    ma_max_m  = pow(10,(MLIMIT)/10.0);}/* addition of simultaneous masking   Naoki Shibata 2000/7 */inline static FLOAT mask_add(FLOAT m1,FLOAT m2,int k,int b, lame_internal_flags * const gfc){  static const FLOAT table1[] = {    3.3246 *3.3246 ,3.23837*3.23837,3.15437*3.15437,3.00412*3.00412,2.86103*2.86103,2.65407*2.65407,2.46209*2.46209,2.284  *2.284  ,    2.11879*2.11879,1.96552*1.96552,1.82335*1.82335,1.69146*1.69146,1.56911*1.56911,1.46658*1.46658,1.37074*1.37074,1.31036*1.31036,    1.25264*1.25264,1.20648*1.20648,1.16203*1.16203,1.12765*1.12765,1.09428*1.09428,1.0659 *1.0659 ,1.03826*1.03826,1.01895*1.01895,    1  };  static const FLOAT table2[] = {    1.33352*1.33352,1.35879*1.35879,1.38454*1.38454,1.39497*1.39497,1.40548*1.40548,1.3537 *1.3537 ,1.30382*1.30382,1.22321*1.22321,    1.14758*1.14758,    1  };  static const FLOAT table3[] = {    2.35364*2.35364,2.29259*2.29259,2.23313*2.23313,2.12675*2.12675,2.02545*2.02545,1.87894*1.87894,1.74303*1.74303,1.61695*1.61695,    1.49999*1.49999,1.39148*1.39148,1.29083*1.29083,1.19746*1.19746,1.11084*1.11084,1.03826*1.03826  };  int i;  FLOAT ratio;  if (m2 > m1) {      if (m2 < (m1*ma_max_i2))        ratio = m2/m1;      else        return (m1+m2);  } else {      if (m1 >= (m2*ma_max_i2))          return (m1+m2);      ratio = m1/m2;  }  /*i = abs(10*log10(m2 / m1)/10*16);  m = 10*log10((m1+m2)/gfc->ATH->cb[k]);*/  /* Should always be true, just checking */  assert(m1>=0);  assert(m2>=0);  assert(gfc->ATH->cb[k]>=0);  m1 += m2;  if ((unsigned int)(b+3) <= 3+3) {  /* approximately, 1 bark = 3 partitions */      /* 65% of the cases */      /* originally 'if(i > 8)' */      if (ratio >= ma_max_i1) {	  /* 43% of the total */	  return m1;      }      /* 22% of the total */      i = FAST_LOG10_X(ratio,16.0);      return m1*table2[i];  }  /* m<15 equ log10((m1+m2)/gfc->ATH->cb[k])<1.5   * equ (m1+m2)/gfc->ATH->cb[k]<10^1.5   * equ (m1+m2)<10^1.5 * gfc->ATH->cb[k]   */  i = FAST_LOG10_X(ratio, 16.0);  m2 = gfc->ATH->cb[k]*gfc->ATH->adjust;  if (m1 < ma_max_m*m2)  {      /* 3% of the total */      /* Originally if (m > 0) { */      if (m1 > m2) {	  FLOAT f, r;	  f = 1.0;	  if (i <= 13) f = table3[i];	  r = FAST_LOG10_X(m1 / m2, 10.0/15.0);	  return m1 * ((table1[i]-f)*r+f);      }      if (i > 13) return m1;      return m1*table3[i];  }  /* 10% of total */  return m1*table1[i];}static inline FLOAT NS_INTERP(FLOAT x, FLOAT y, FLOAT r){    /* was pow((x),(r))*pow((y),1-(r))*/    if(r==1.0)        return x;              /* 99.7% of the time */    if(r==0.0)	return y;    if(y>0.0)        return pow(x/y,r)*y;   /* rest of the time */     return 0.0;                /* never happens */ }static void nsPsy2dataRead(    FILE *fp,    FLOAT *eb2,    FLOAT *eb,    int chn,    int npart_l    ){    int b;    for(;;) {	static const char chname[] = {'L','R','M','S'};	char c;	fscanf(fp, "%c",&c);	for (b=0; b < npart_l; b++) {	    double e;	    fscanf(fp, "%lf",&e);	    eb2[b] = e;	}	if (feof(fp)) abort();	if (c == chname[chn]) break;	abort();    }    eb2[62] = eb2[61];    for (b=0; b < npart_l; b++ )	eb2[b] = eb2[b] * eb[b];}static FLOATpecalc_s(    III_psy_ratio *mr,    FLOAT masking_lower    ){    FLOAT pe_s;    const static FLOAT regcoef_s[] = {	11.8, /* these values are tuned only for 44.1kHz... */	13.6,	17.2,	32,	46.5,	51.3,	57.5,	67.1,	71.5,	84.6,	97.6,	130,/*	255.8 */    };    int sb, sblock;    pe_s = 1236.28/4;    for (sb = 0; sb < SBMAX_s - 1; sb++) {	for (sblock=0;sblock<3;sblock++) {	    FLOAT x;	    if (regcoef_s[sb] == 0.0		|| mr->thm.s[sb][sblock] <= 0.0		|| mr->en.s[sb][sblock]		<= (x = mr->thm.s[sb][sblock] * masking_lower))		continue;	    if (mr->en.s[sb][sblock] > x*1e10)		pe_s += regcoef_s[sb] * (10.0 * LOG10);	    else		pe_s += regcoef_s[sb] * FAST_LOG10(mr->en.s[sb][sblock] / x);	}    }    return pe_s;}static FLOATpecalc_l(    III_psy_ratio *mr,    FLOAT masking_lower    ){    FLOAT pe_l;    const static FLOAT regcoef_l[] = {	6.8, /* these values are tuned only for 44.1kHz... */	5.8,	5.8,	6.4,	6.5,	9.9,	12.1,	14.4,	15,	18.9,	21.6,	26.9,	34.2,	40.2,	46.8,	56.5,	60.7,	73.9,	85.7,	93.4,	126.1,/*	241.3 */    };    int sb;    pe_l = 1124.23/4;    for (sb = 0; sb < SBMAX_l - 1; sb++) {	FLOAT x;	if (mr->thm.l[sb] <= 0.0	    || mr->en.l[sb] <= (x = mr->thm.l[sb]*masking_lower))	    continue;	if (mr->en.l[sb] > x*1e10)	    pe_l += regcoef_l[sb] * (10.0 * LOG10);	else	    pe_l += regcoef_l[sb] * FAST_LOG10(mr->en.l[sb] / x);    }    return pe_l;}int L3psycho_anal_ns( lame_global_flags * gfp,                    const sample_t *buffer[2], int gr_out,                     FLOAT *ms_ratio,                    FLOAT *ms_ratio_next,		    III_psy_ratio masking_ratio[2][2],		    III_psy_ratio masking_MS_ratio[2][2],		    FLOAT percep_entropy[2],FLOAT percep_MS_entropy[2], 		    FLOAT energy[4],                     int blocktype_d[2]){/* 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) */    lame_internal_flags *gfc=gfp->internal_flags;    /* fft and energy calculation   */    FLOAT wsamp_L[2][BLKSIZE];    FLOAT wsamp_S[2][3][BLKSIZE_s];    /* block type  */    int blocktype[2],uselongblock[2];    /* usual variables like loop indices, etc..    */    int numchn, chn;    int b, i, j, k;    int	sb,sblock;    /* variables used for --nspsytune */    FLOAT ns_hpfsmpl[2][576];    FLOAT pcfact;    numchn = gfc->channels_out;    /* chn=2 and 3 = Mid and Side channels */    if (gfp->mode == JOINT_STEREO) numchn=4;    if (gfp->VBR==vbr_off) pcfact = gfc->ResvMax == 0 ? 0 : ((FLOAT)gfc->ResvSize)/gfc->ResvMax*0.5;    else if (gfp->VBR == vbr_rh  ||  gfp->VBR == vbr_mtrh  ||  gfp->VBR == vbr_mt) {	    /*static const FLOAT pcQns[10]={1.0,1.0,1.0,0.8,0.6,0.5,0.4,0.3,0.2,0.1};	    pcfact = pcQns[gfp->VBR_q];*/	    pcfact = 0.6;    } else pcfact = 1.0;    /**********************************************************************     *  Apply HPF of fs/4 to the input signal.     *  This is used for attack detection / handling.     **********************************************************************/    /* Don't copy the input buffer into a temporary buffer */    /* unroll the loop 2 times */    for(chn=0;chn<gfc->channels_out;chn++) {	static const FLOAT fircoef[] = {	    -8.65163e-18*2, -0.00851586*2, -6.74764e-18*2, 0.0209036*2,	    -3.36639e-17*2, -0.0438162 *2, -1.54175e-17*2, 0.0931738*2,	    -5.52212e-17*2, -0.313819  *2	};	/* apply high pass filter of fs/4 */	const sample_t * const firbuf = &buffer[chn][576-350-NSFIRLEN+192];	for (i=0;i<576;i++) {	    FLOAT sum1, sum2;	    sum1 = firbuf[i + 10];	    sum2 = 0.0;	    for (j=0;j<(NSFIRLEN-1)/2;j+=2) {		sum1 += fircoef[j  ] * (firbuf[i+j  ]+firbuf[i+NSFIRLEN-j  ]);		sum2 += fircoef[j+1] * (firbuf[i+j+1]+firbuf[i+NSFIRLEN-j-1]);	    }	    ns_hpfsmpl[chn][i] = sum1 + sum2;	}	masking_ratio    [gr_out] [chn]  .en  = gfc -> en  [chn];	masking_ratio    [gr_out] [chn]  .thm = gfc -> thm [chn];	if (numchn > 2) {	    /* MS maskings  */	    /*percep_MS_entropy         [chn-2]     = gfc -> pe  [chn];  */	    masking_MS_ratio [gr_out] [chn].en  = gfc -> en  [chn+2];	    masking_MS_ratio [gr_out] [chn].thm = gfc -> thm [chn+2];	}    }    for (chn=0; chn<numchn; chn++) {	FLOAT (*wsamp_l)[BLKSIZE];	FLOAT (*wsamp_s)[3][BLKSIZE_s];	FLOAT en_subshort[12];	FLOAT attack_intensity[12];	int ns_uselongblock = 1;	FLOAT attackThreshold;	FLOAT max[CBANDS],avg[CBANDS];	int ns_attacks[4] = {0};	FLOAT fftenergy[HBLKSIZE];	FLOAT fftenergy_s[3][HBLKSIZE_s];	/* convolution   */	FLOAT eb[CBANDS+1],eb2[CBANDS];	FLOAT thr[CBANDS+1];    /*This is the masking table:      According to tonality, values are going from 0dB (TMN)      to 9.3dB (NMT).      After additive masking computation, 8dB are added, so      final values are going from 8dB to 17.3dB    */    static const FLOAT tab[] = {        1.0/*pow(10, -0)*/,        0.79433/*pow(10, -0.1)*/,        0.63096/*pow(10, -0.2)*/,        0.63096/*pow(10, -0.2)*/,        0.63096/*pow(10, -0.2)*/,        0.63096/*pow(10, -0.2)*/,        0.63096/*pow(10, -0.2)*/,        0.25119/*pow(10, -0.6)*/,	    0.11749/*pow(10, -0.93)*/	};    /*  rh 20040301: the following loops do access one off the limits     *  so I increase  the array dimensions by one and initialize the     *  accessed values to zero     */    assert( gfc->npart_s <= CBANDS );    assert( gfc->npart_l <= CBANDS );    eb [gfc->npart_s] = 0;    thr[gfc->npart_s] = 0;    eb [gfc->npart_l] = 0;    thr[gfc->npart_l] = 0;    	/*************************************************************** 	 * determine the block type (window type)	 ***************************************************************/	/* calculate energies of each sub-shortblocks */	for (i=0; i<3; i++) {	    en_subshort[i] = gfc->nsPsy.last_en_subshort[chn][i+6];	    attack_intensity[i]		= en_subshort[i] / gfc->nsPsy.last_en_subshort[chn][i+4];	}	if (chn == 2) {	    for(i=0;i<576;i++) {		FLOAT l, r;		l = ns_hpfsmpl[0][i];		r = ns_hpfsmpl[1][i];		ns_hpfsmpl[0][i] = l+r;		ns_hpfsmpl[1][i] = l-r;	    }	}	{	    FLOAT *pf = ns_hpfsmpl[chn & 1];	    for (i=0;i<9;i++) {		FLOAT *pfe = pf + 576/9, p = 1.;		for (; pf < pfe; pf++)		    if (p < fabs(*pf))			p = fabs(*pf);		gfc->nsPsy.last_en_subshort[chn][i] = en_subshort[i+3] = p;		if (p > en_subshort[i+3-2])		    p = p / en_subshort[i+3-2];		else if (en_subshort[i+3-2] > p*10.0)		    p = en_subshort[i+3-2] / (p*10.0);		else		    p = 0.0;		attack_intensity[i+3] = p;	    }	}#if defined(HAVE_GTK)	if (gfp->analysis) {	    FLOAT x = attack_intensity[0];	    for (i=1;i<12;i++) 		if (x < attack_intensity[i])		    x = attack_intensity[i];	    gfc->pinfo->ers[gr_out][chn] = gfc->ers_save[chn];	    gfc->ers_save[chn] = x;	}#endif	/* compare energies between sub-shortblocks */	attackThreshold = (chn == 3)	    ? gfc->nsPsy.attackthre_s : gfc->nsPsy.attackthre;	for (i=0;i<12;i++) 	    if (!ns_attacks[i/3] && attack_intensity[i] > attackThreshold)		ns_attacks[i/3] = (i % 3)+1;	if (ns_attacks[0] && gfc->nsPsy.last_attacks[chn])	    ns_attacks[0] = 0;	if (gfc->nsPsy.last_attacks[chn] == 3 ||	    ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) {	    ns_uselongblock = 0;	    if (ns_attacks[1] && ns_attacks[0]) ns_attacks[1] = 0;	    if (ns_attacks[2] && ns_attacks[1]) ns_attacks[2] = 0;	    if (ns_attacks[3] && ns_attacks[2]) ns_attacks[3] = 0;	}    if (chn < 2) {        uselongblock[chn] = ns_uselongblock;    }    else {        if (ns_uselongblock == 0) {            uselongblock[0] = uselongblock[1] = 0;        }    }	/* there is a one granule delay.  Copy maskings computed last call	 * into masking_ratio to return to calling program.	 */	energy[chn]=gfc->tot_ener[chn];	/*********************************************************************	 *  compute FFTs	 *********************************************************************/	wsamp_s = wsamp_S+(chn & 1);	wsamp_l = wsamp_L+(chn & 1);	compute_ffts(gfp, fftenergy, fftenergy_s,		     wsamp_l, wsamp_s, gr_out, chn, buffer);	/* compute masking thresholds for short blocks */	for (sblock = 0; sblock < 3; sblock++) {	    FLOAT enn, thmm;	    compute_masking_s(gfc, fftenergy_s, eb, thr, chn, sblock,			      gfp->ATHlower*gfc->ATH->adjust);        b = -1;	    for (sb = 0; sb < SBMAX_s; sb++) {		enn = thmm = 0.0;		while (++b < gfc->bo_s[sb]) {		    enn  += eb[b];		    thmm += thr[b];		}		enn  += 0.5 * eb[b];    /* for the last sfb b is larger than npart_s!! */		thmm += 0.5 * thr[b];   /* rh 20040301 */		gfc->en [chn].s[sb][sblock] = enn;                assert( enn >= 0 );        assert( thmm >= 0 );        		/****   short block pre-echo control   ****/		thmm *= NS_PREECHO_ATT0;		if (ns_attacks[sblock] >= 2 || ns_attacks[sblock+1] == 1) {		    int idx = (sblock != 0) ? sblock-1 : 2;		    double p = NS_INTERP(gfc->thm[chn].s[sb][idx],					 thmm, NS_PREECHO_ATT1*pcfact);		    thmm = Min(thmm,p);		}		if (ns_attacks[sblock] == 1) {		    int idx = (sblock != 0) ? sblock-1 : 2;		    double p = NS_INTERP(gfc->thm[chn].s[sb][idx],					 thmm,NS_PREECHO_ATT2*pcfact);		    thmm = Min(thmm,p);		} else if ((sblock != 0 && ns_attacks[sblock-1] == 3)			|| (sblock == 0 && gfc->nsPsy.last_attacks[chn] == 3)) {		    int idx = (sblock != 2) ? sblock+1 : 0;		    double p = NS_INTERP(gfc->thm[chn].s[sb][idx],					 thmm,NS_PREECHO_ATT2*pcfact);		    thmm = Min(thmm,p);		}		/* pulse like signal detection for fatboy.wav and so on */		enn = en_subshort[sblock*3+3] + en_subshort[sblock*3+4]		    + en_subshort[sblock*3+5];		if (en_subshort[sblock*3+5]*6 < enn) {		    thmm *= 0.5;		    if (en_subshort[sblock*3+4]*6 < enn)			thmm *= 0.5;		}		gfc->thm[chn].s[sb][sblock] = thmm;	    }

⌨️ 快捷键说明

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