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

📄 fe_plcc.cpp

📁 这是一个语音特征提取的程序源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
						fsq = f0 * f0;			r_2 = (float)(fsq + 1.6e5);			rsss = (float)(fsq * fsq * (fsq + 1.44e6) / (r_2 * r_2 * (fsq + 9.61e6)));						cb[icount] = rsss * cb[icount];			/* add the qual-loundness curve to the weighting    */			++icount;		}    }    return (0);} /** int cosf_(m, nfilt, wcos)* computes the cosine weightings for the Inverse Discrete Fourier Transfrom* m    (in): order of plp auto regressive model* nfilt(in):* wcos (in): cosine weightings of inverse dft*/int Fe::cosf_ ( int m, int nfilt, float *wcos ){	int ii, jj;                       /* Loop counter variables     */		wcos -= 24;                              /* Parameter adjustments      */	/* [23][16] --> [j=1+24]      */		for (ii = 1; ii <= (m+1); ++ii) {		for (jj = 2; jj <= (nfilt-1); ++jj) {			wcos[jj + ii * 23] = (float)(2.0 * cos(2.0 * M_PI * (ii - 1) * (jj - 1) / (2.0 * ( nfilt - 1 ))));		}		wcos[nfilt + ii * 23] = (float)(cos(2.0 * M_PI * (ii - 1) * (jj - 1) / (2.0 * ( nfilt - 1 ))));	}		return (0);} /* * int a2gexp_ (a, gexp, i, nc, expon)* a    (in): pointer to autoregressive coefficients array* gexp(out):* i    (in): number of elements in autoregressive coefficient array* nc   (in): number of elements in output array* expon(in):  */int Fe::a2gexp_ ( float *a, float *gexp, int i, int nc, float expon){    int i_2;      	    float c[257];                       /* Local variables          */    int j, l, jb, ii, lp;    float sum;	    --a;                                       /* Parameter adjustments    */    --gexp;	    c[0] = (float)log(a[1]);    c[1] = -a[2] / a[1];    for (l = 2; l <= nc; ++l){		lp = l + 1;		if (l <= i + 1)			sum = l * a[lp] / a[1];		else			sum = 0.0;		i_2 = l;		if(l < i + 1) i_2 = l;		else i_2 = i + 1;		for (j = 2; j <= i_2; ++j){			jb = l - j + 2;			sum += a[j] * c[jb - 1] * (jb - 1) / a[1];		}		c[lp - 1] = -sum / l;	}    gexp[1] = c[0];	    if (expon != 0.0)		for (ii = 2; ii <= nc; ++ii)			gexp[ii] = (float) pow((ii-1),expon ) * c[ii - 1];		else			for (ii = 2; ii <= nc; ++ii)				gexp[ii] = c[ii - 1];						return (0);} 
/*
 * int TrigRecombFFT( cx, y, m )
 * Computers the FFT of a complex signal, using a trigonometric recombination
 * principle in order to speed up matters somewhat.
 * cx (in): pointer to input complex signal of type FeComplex
 * y (out): pointer to output FFT signal of type FeComplex
 * m  (in): the #point fft to computer (2^x format)
 * On exit returns (+1) for success and (-1) for failure
 * Usage: success = TrigRecombFFT( InSignal, FFTout, 8)
 */

int Fe::TrigRecombFFT (FeComplex *cx, FeComplex *y, int m )
{
	FeComplex *ck, *xk, *xnk;             /* array pointer variables      */
	float Realsum, Realdif;             /* real part of trig recombine  */
	float Imagsum, Imagdif;             /* imag part of trig recombine  */
	int num, k;                   /* loop counter variables       */

	/* Do FFT on combined data                  */
	num = 1 << m;
	PlpFFT( cx, m );

	/* Calculate Recombination Factors          */
	if( m != m_plpMofCF ) {
		if( CalculateCF( m ) < 0 ) {
			return( -1 );
		}
	}

	/* DC component, no multiplies              */
	y[0].m_re = cx[0].m_re + cx[0].m_im;
	y[0].m_im = 0.0;

	/* other frequencies by trig recombination  */
	ck = &m_plpCF[0];
	xk = cx + 1;
	xnk = cx + num - 1;

	for( k = 1; k < num; k++ ) {
		Realsum = ( xk->m_re + xnk->m_re ) / (float)2.0;
		Imagsum = ( xk->m_im + xnk->m_im ) / (float)2.0;
		Realdif = ( xk->m_re - xnk->m_re ) / (float)2.0;
		Imagdif = ( xk->m_im - xnk->m_im ) / (float)2.0;

		y[k].m_re = Realsum + ck->m_re * Imagsum -
					ck->m_im * Realdif;

		y[k].m_im = Imagdif - ck->m_im * Imagsum -
					ck->m_re * Realdif;

		ck++;
		xk++;
		xnk--;
	}

	return 1;
}


/*
 * FFT( x, m )
 * In-place radix 2 decimation in time FFT
 * Computes the Fast Fourier transform of a signal
 * x (in): pointer to complex array, power of 2 size of FFT
 * m (in): size fo fft = 2^m
 * Places FFT output on top of input FeComplex array.
 */

int Fe::PlpFFT( FeComplex *x, int m )
{
	FeComplex u, temp, tm;
	FeComplex *xi, *xip, *xj, *wptr;
	int i, j, k, l, le, windex;
	int n;

	/* Calculate Twiddle factors for FFT */
	if( m != m_plpMofW ) {
		if( CalculateW( m ) < 0 ) {
			return( -1 );
		}
	}

	/* n = 2^m = fft length   */
	n = 1 << m;

	/* start fft              */
	le = n;
	windex = 1;
	for( l = 0; l < m; l++ ) {
		le = le / 2;
		
		/* first iteration with no multiplies */
		for( i = 0; i < n; i = i + 2*le ) {
			xi = x + i;
			xip = xi + le;
			temp.m_re = xi->m_re + xip->m_re;
			temp.m_im = xi->m_im + xip->m_im;
			xip->m_re = xi->m_re - xip->m_re;
			xip->m_im = xi->m_im - xip->m_im;
			*xi = temp;
		}

		/* remaining iterations use to store w */
		wptr = &m_plpW[0] + windex - 1;
		for( j = 1; j < le; j++ ) {
			u = *wptr;
			for( i = j; i < n; i = i + 2*le ) {
				xi  = x + i;
				xip = xi + le;
				temp.m_re = xi->m_re + xip->m_re;
				temp.m_im = xi->m_im + xip->m_im;
				tm.m_re = xi->m_re - xip->m_re;
				tm.m_im = xi->m_im - xip->m_im;
				xip->m_re = tm.m_re * u.m_re - 
							tm.m_im * u.m_im;
				xip->m_im = tm.m_re * u.m_im +
							tm.m_im * u.m_re;
				*xi = temp;
			}
			wptr = wptr + windex;
		}
		windex = 2 * windex;
	}

	/* rearrage data by bit reversing */
	j = 0;
	for( i = 1; i < ( n - 1 ); i++ ) {
		k = n / 2;
		while( k <= j ) {
			j = j - k;
			k = k / 2;
		}
		j = j + k;
		if( i < j ) {
			xi = x + i;
			xj = x + j;
			temp = *xj;
			*xj = *xi;
			*xi = temp;
		}
	}

	return 1;
}


/* 
 * int CalculateW( m )
 * This procedure calculates the W twiddle factors for the 
 * FFT routine, thus needed only once. Then check to see if already
 * called, and do not call again.
 * m (in): number of points in FFT = (2^m)
 */

int Fe::CalculateW ( int m )
{
	double w_real, w_imag;
	m_plpMofW = m;
	int n = 1 << m;
	int le = n / 2;	
	m_plpW.resize(le - 1);
	double arg = 4.0 * atan( 1.0 ) / (float)le;
	double wrecur_real = w_real = cos( arg );
	double wrecur_imag = w_imag = -sin( arg );
	FeComplex *xj = &m_plpW[0];
	for(int j = 1; j < le; j++ ) {
		xj->m_re = (float)wrecur_real;
		xj->m_im = (float)wrecur_imag;
		xj++;
		double wtmp_real = wrecur_real * w_real - wrecur_imag * w_imag;
		wrecur_imag = wrecur_real * w_imag + wrecur_imag * w_real;
		wrecur_real = wtmp_real;
	}
	return 1;
}


/*
 * int CalculateCF( m )
 * Calculates the Trigonometric Recombination Coefficients.
 * Used only once, and never called again. With multiple FFT calls
 * saves computation time.
 * m (in): number of points in FFT transform = (2^m)
 */

int Fe::CalculateCF( int m )
{
	m_plpMofCF = m;
	int num = 1 << m;
	m_plpCF.resize(num - 1);
	double factor = 4.0 * atan( 1.0 ) / ((double)num);
	for(int k = 1; k < num; k++ ) {
		double arg = factor * ((double)k);
		m_plpCF[k-1].m_re = (float)cos( arg );
		m_plpCF[k-1].m_im = (float)sin( arg );
	}

	return 1;
}


/*****************************************************************************
*   rasta.c : RASTA processing by using Hermansky or SRI filter constants
*
*   11/30/1992 by Aki Ohshima (aki@speech1.cs.cmu.edu)
*      Separated from mfcc_lib.c.
*   10/20/1992 by Aki Ohshima (aki@speech1.cs.cmu.edu)
*      Created. RASTA processing by Nobu Hanai, modified by Aki.
****************************************************************************/

/* --------------------------------------------------------------------------
RastaFilter(mfsc, r_filter, r_f_param); 
 Where 'r_filter' is an integer and supposed to specify a kind of filter, 
 such as
 0 : no rasta filtering(just quit)
 1 : Hermansky's bandpass filetr
 2 : SRI's high pass filter
 'r_f_param' is a float and supposed to specify a filter parameter.
 0.94 : latest parameter for Hermansky's
 0.98 : previous parameter for Hermansky's
 0.97 : SRI's
 rasta filetering reduces the number of frames, and is taken care of in rasta 
 subroutine.
* ------------------------------------------------------------------------- */

/* 	History
* 	Coded by Nobutoshi Hanai      Sep 18, 1992
*    	Rasta filterling
*/

int Fe::RastaFilter(FeSpectrum *mfsc, int r_filter, float r_f_param)
{
	int		i,j;
	float		**in_dat;
	
	if (r_filter == RASTA_NO) return mfsc->m_ntime;

	/* initialize */
	in_dat = mfsc->m_specData;
	vector<float> rasta(mfsc->m_nfreq);
	vector<float> prerasta(mfsc->m_nfreq);
	
	for (j = 0; j < mfsc->m_nfreq; j++) {
		rasta[j] = 0.0;
		prerasta[j] = 0.0;
	}
	
	/* RASTA filtering */
	if (r_filter == RASTA_BY_HERMANSKY_BPF) {
	/*
	printf("RASTA filtering  -- Hermansky's\n");
		*/
		mfsc->m_ntime -= 4;
		for (i = 0; i < mfsc->m_ntime; i++){
			for (j = 0; j < mfsc->m_nfreq; ++j) {
				rasta[j] = (float)(r_f_param * prerasta[j] + 0.2 * *(in_dat[i+4] + j) + 0.1 * *(in_dat[i+3] + j) 
					- 0.1 * *(in_dat[i+1] + j) - 0.2 * *(in_dat[i] + j));
				*(in_dat[i] + j) = rasta[j];
				prerasta[j] = rasta[j];
			}
		}
	}
	else if (r_filter == RASTA_BY_SRI_HPF) {
	/*
	printf("RASTA filtering  -- SRI's\n");
		*/
		mfsc->m_ntime -= 1;
		for (i = 0; i < mfsc->m_ntime; i++){
			for (j = 0; j < mfsc->m_nfreq; ++j) {
				rasta[j] = r_f_param * prerasta[j] + *(in_dat[i+1] + j) - *(in_dat[i] + j);
				*(in_dat[i] + j) = rasta[j];
				prerasta[j] = rasta[j];
			}
		}
	}
	else {
		err_quit("ERROR : Invalid RASTA argument !!\n");
	}	
	return(mfsc->m_ntime);
}

⌨️ 快捷键说明

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