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

📄 mbs_dist.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 3 页
字号:
	phontoson(PY, SY);	phontoson(PN, SN);	if (debug_level >= 4) {	    print_darray(1, n + 1,			 "spread spectrum (sone)", BSIZE - 3, SX);	    print_darray(2, n + 1,			 "spread spectrum (sone)", BSIZE - 3, SY);	    print_darray(0, 0,			 "noise spectrum (sone)", BSIZE - 3, SN);	}	/* COMPUTE FRAME DISTORTION */	frame_distortion = measure(SX, SY, SN);	if (debug_level >= 3)	    fprintf(stderr, "%s: frame %ld distortion %g\n",		    PROG, n + 1, frame_distortion);	/* OVERALL AVERAGE DISTORTION */	if (included) {	    num_proc++;	    sum_distortion += frame_distortion;	}	/* WRITE FRAME OUTPUT */	if (!a_specified) {	    *outdata = frame_distortion;	    *outflag = included;	    if (outhd->common.tag) {		*outtag = *intag1;	    }	    if (debug_level >= 3)		fprintf(stderr, "%s: writing output record %ld\n",			PROG, n + 1);	    put_fea_rec(outrec, outhd, outfile);	}    } /* end for (n = 0; ... ) */        /*     * WRAP UP     */    if (debug_level >= 1)	fprintf(stderr,		"%s: sum of %ld distortions out of %ld processed is %g.\n",		PROG, num_proc, n, sum_distortion);    if (a_specified || A_specified) {	printf("%g\n", (num_proc == 0) ? 0 : sum_distortion/num_proc);    }    return 0;	/* equivalent to exit(0); */}/* * Convert FEA_SPEC data to spec_type PWR */voidspec_to_pwr(int     num,	    float   *src,	    float   *src_im,	    int     src_type,	    double  *dest){    int     j;    switch (src_type)    {    case SPTYP_PWR:	for (j = 0; j < num; j++)	    dest[j] = src[j];	break;    case SPTYP_DB:	for (j = 0; j < num; j++)	    dest[j] = pow(10.0, 0.1*src[j]);	break;    case SPTYP_REAL:	for (j = 0; j < num; j++)	    dest[j] = src[j]*src[j];	break;    case SPTYP_CPLX:	for (j = 0; j < num; j++)	    dest[j] = src[j]*src[j] + src_im[j]*src_im[j];	break;    default:	ERROR("unrecognized spec_type");    }}/* * Integrate power spectral density over frame */doubleframe_pwr(int       num,	  double    *pwr_spec,	  double    df){    int     j;    double  sum;    sum = 0.5*(pwr_spec[0] + pwr_spec[num-1]);    for (j = 1; j < num - 1; j++)	sum += pwr_spec[j];    return sum*df;}/* Initialize an array of equally spaced frequencies */double *init_freqs(int      num,	   double   fmax){    int     j;    double  *freqs;    double  den;    TRYALLOC(double, num, freqs, "frequencies");    den = (double) (num - 1);    for (j = 0; j < num; j++)	freqs[j] = (j / den) * fmax;    return freqs;}/* * Initialize spread function. */double *init_spread_func(){    static double spread_func[2*BSIZE-1];    double  *S = &spread_func[BSIZE-1];    int     k;    double  x;    for (k = 1 - BSIZE; k < BSIZE; k++) {	x = (double) k + 0.474;	x = 15.81 + 7.5*x - 17.5*sqrt(1.0 + x*x);	S[k] = pow(10.0, 0.1*x);    }    return S;}/* * Initialize absolute hearing threshold in dB by the formula of Terhardt. * *  thrshld(f) = { 3.64(f/1000)^(-0.8) - 6.5exp[-0.6(f/1000 - 3.3)^2] *                 + 0.001(f/1000)^4 } * * Reference :  Terhardt, E., Stoll, G. and Seewann, M, "Algorithm for *        extraction of pitch and pitch salience from complex tonal *        signals", J. Acoust. Soc. Am., vol. 71(3), Mar., 1982. */double *init_thresh(int num, double *freqs){    static double ABS_TH[BSIZE];    int     i, j, k;    double  f;    double  *L;    double  fsq, t, SUM;    TRYALLOC(double, num, L, "working storage for \"init_thresh\"");    L[0] = 0.0;    for (i = 1; i < num; i++) {        f = freqs[i]/1000.0;        fsq = f * f;        t = f - 3.3;        L[i] =	    3.64 / pow(f, 0.8)		- 6.5 * exp(-0.6 * t * t)		    + 0.001 * fsq * fsq;    }    for (i = 1; i <= BSIZE; i++) {        SUM = 0.0;        k = 0;        for (j = 1; j < num; j++) {            if (BARK[i-1] <= freqs[j] && freqs[j] < BARK[i]) {                SUM += L[j];                k++;            }        }        if (k == 0)            ABS_TH[i-1] = 0.0;        else            ABS_TH[i-1] = SUM / k;    }    return ABS_TH;}/* * Normalize a power spectrum to an overall average power of * 375000.0, assuming that "mean_pwr" gives the value before * normalization, and "pwr_spec" indicates the current frame. * The original "mbsd" normalizes the _unwindowed_ sampled * data to an overall RMS of 1000.0.  This is as close as we * can come in terms of the mean square of the hanning-windowed * signal.  (The mean square value of the hanning window function * is 0.375). */voidnormalize(int       num,	  double    *pwr_spec,	  double    mean_pwr,	  double    factor){    int     j;    double  ratio;    if (mean_pwr == 0)	return;    ratio = factor*375000.0/mean_pwr;    for (j = 0; j < num; j++)	pwr_spec[j] *= ratio;    pwr_spec[0] *= 0.5;}/* * Decide whether to include current frame in computation of overall * average distortion. */intcheck_frame(double  pwr1,	    double  pwr2,	    double  XTHRESH,	    double  YTHRESH){    return (pwr1 > XTHRESH && pwr2 > YTHRESH);}/* * Compute critical-band spectrum from power spectrum. */voidbk_frq(int	num,       double	*freqs,       double	*pwr_spec,       double	*bk_spec){    int     i, j;    for (i = 0; i < BSIZE; i++) {	bk_spec[i] = 0.0;	for (j = 0; j < num; j++) {	    if (BARK[i] <= freqs[j] && freqs[j] < BARK[i+1])		bk_spec[i] += pwr_spec[j];	}    }}/* * Apply spreading function to critical-band spectrum * to compute spread critical-band spectrum. */voidspread(double *bk_spec, double *spread_spec){    int     i, j;    for (i = 0; i < BSIZE; i++) {	spread_spec[i] = 0;	for (j = 0; j < BSIZE; j++)	    spread_spec[i] += S[i-j] * bk_spec[j];    }}/* * Convert spread Bark spectrum to phons. */voiddbtophon(double *spread_spec, double *phon_spec){    int     i, j;    double  t1;    double  Ti;    for (i = 0; i < BSIZE-3; i++) {	Ti = 10.0 * log10(spread_spec[i+3]);	for (j = 0; j < PHSIZE; j++) {	    if (Ti < eqlcon[j][i])		break;	}	if (j == 0) {	    phon_spec[i] = phons[0];	} else if (j == PHSIZE) {	    phon_spec[i] = phons[PHSIZE-1];	} else {	    t1 = (Ti - eqlcon[j-1][i]) / (eqlcon[j][i] - eqlcon[j-1][i]);	    phon_spec[i] = phons[j-1] + t1 * (phons[j] - phons[j-1]);	}    }}/* * Convert spectrum in phons to sones. */voidphontoson(double *phon_spec, double *sone_spec){    int     i;    for (i = 0; i < BSIZE-3; i++) {        if (phon_spec[i] >= 40.0) {	    sone_spec[i] = pow(2.0, 0.1*(phon_spec[i] - 40.0));	}	else {	    sone_spec[i] = pow(phon_spec[i] / 40.0, 2.642);	}    }}/* * Compute frame distortion. */doublemeasure(double *orig, double *dist, double *noise){    int     i;    double  d;    double  t;    d = 0.0;    for (i = 0; i < BSIZE - 3; i++) {	t = fabs(orig[i] - dist[i]) - noise[i];	if (t > 0.0)	    d += t;    }    return d;}/* * Spectral flatness measure (based on the ratio of the arithmetic * and geometric means). */doublesfm(int num, double *pwr_spec){    double  alpha;    double  a_mean;		/* arithmetic mean */    double  g_mean;		/* geometric mean */    int     i;    a_mean = 0;    g_mean = 0;    for (i = 0; i < num; i++) {	a_mean += pwr_spec[i];	g_mean += log(pwr_spec[i]);    }    a_mean = a_mean / (double) num;    g_mean = exp(g_mean / (double) num);    alpha = 10.0 * log10(g_mean / a_mean) / (-60.0);    if (alpha > 1.0)	alpha = 1.0;    return alpha;}/* * Noise masking threshold. */voidthresh2(double alpha, double *spread_spec, double *noise_thr){    int     i;    double  t;    for (i = 0; i < BSIZE; i++) {        t = alpha * (14.5 + (double) i + 1.0) + (1.0 - alpha) * 5.5;	t = 10.0 * log10(spread_spec[i]) - t;	if (t < ABS_TH[i])	    t = ABS_TH[i];	noise_thr[i] = pow(10.0, t/10.0);    }}/* * Formatted printout of float array for debugging. */voidprint_farray(int    filenum,	     long   recnum,	     char   *text,	     long   numelem,	     float  *data){    long    j;    if (filenum == 0)	fprintf(stderr, "%s: %s ...", PROG, text);    else	fprintf(stderr, "%s: file %d record %ld %s ...",		PROG, filenum, recnum, text);    for (j = 0; j < numelem; j++) {	if (j%5 == 0)	    fprintf(stderr, "\n [%ld]\t", j);	fprintf(stderr, " %13.6g", data[j]);    }    fprintf(stderr, "\n");}/* * Formatted printout of double array for debugging */voidprint_darray(int    filenum,	     long   recnum,	     char   *text,	     long   numelem,	     double *data){    long    j;    if (filenum == 0)	fprintf(stderr, "%s: %s ...", PROG, text);    else	fprintf(stderr, "%s: file %d record %ld %s ...",		PROG, filenum, recnum, text);    for (j = 0; j < numelem; j++) {	if (j%5 == 0)	    fprintf(stderr, "\n [%ld]\t", j);	fprintf(stderr, " %13.6g", data[j]);    }    fprintf(stderr, "\n");}

⌨️ 快捷键说明

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