FE_plcc.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:21k
源码类别:

语音合成与识别

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // This is a part of the Feature program.
  3. // Version: 1.0
  4. // Date: February 22, 2003
  5. // Programmer: Oh-Wook Kwon
  6. // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #include "StdAfx.h" #include "FE_feature.h"
  9. /* Table of constant values       */ static const double c_b17 = 0.33; static const double c_b28 = 10.0;
  10. int Fe::_plp_cepstrum_basic(float *sample, int frameSize, float *plp_cep, int ceporder, int norder)
  11. {
  12. _plp_basic(sample, frameSize, plp_cep, ceporder, norder);
  13. return 1;
  14. }
  15. int Fe::plp_cepstrum_basic(short *sample, int frameSize, float *plp_cep, int ceporder, int norder)
  16. {
  17. vector<float> frameA(frameSize);
  18. preprocessing(sample, frameSize, &frameA[0]);
  19. m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
  20. _plp_cepstrum_basic(&frameA[0], frameSize, plp_cep, ceporder, norder);
  21. return 1;
  22. }
  23. /*
  24. * int _plp_basic(sample, sampleN, frameSize, plp_cep, ceporder, norder)
  25. * Calculates the PLP coefficients of an input speech signal using the
  26. * algorithm of Hynek Hermanski.
  27. * sample       (in): pointer to input speech data of type float
  28. * sampleN      (in): number of data points available in array 
  29. * frameSize    (in): analysis window in samples
  30. * Expon        (in): peak enhancement factor
  31. * norder       (in): order of PLP model
  32. * ceporder     (in): order of cepstrum order
  33. * Gain         (in): gain flag (1 = gain; 0 no)
  34. * plp_cep     (out): pointer to output plp data of type float
  35. * On exit returns the number of frames.
  36. */
  37. int Fe::_plp_basic(float *sample, int frameSize, float *plp_cep, int ceporder, int norder)
  38. {
  39. float gain;                  /* gain parameter of model          */
  40. vector<float> a(norder+1);        /* auto regressive coefficients     */
  41. vector<float> rc(norder+1);       /* reflection coefficients          */
  42. plp_analysis(sample, frameSize, norder, &a[0], &rc[0], &gain, m_sampleRate);
  43. if(m_plpGain) for (int k = 0; k < norder + 1; k++) a[k] = a[k]/gain;
  44. a2gexp_(&a[0], plp_cep, norder, ceporder+1, m_plpExpon);
  45. plp_cep[0] = -plp_cep[0];
  46. return 1;
  47. }
  48. /*
  49. * plp_cep.c
  50. *
  51. * written by Hynek Hermanski
  52. *
  53. * translated by f2c (version of 30 January 1990  16:02:04).
  54. * Modified by Chuck Wooters, ICSI, 7/6/90
  55. *
  56. * further modified at OGI -- array indices in some inner loops were
  57. * replaced by pointers.  the fft routine was replaces by TrigRecombFFT.
  58. *
  59. * Cleaned Up by Johan Schalkwyk (March 1993)
  60. *
  61. * The actual processing is split up into a few pieces:
  62. *  1) power spectral analysis
  63. * 2) auditory spectrum computation
  64. * 3) compression
  65. * 4) inverse FFT
  66. * 5) autoregressive all-pole modeling (cepstral coefficients)
  67. */
  68. int Fe::init_plp()
  69. {
  70. m_plpOrder = PLP_ORDER; /* model order                  */
  71. m_plccOrder = PLP_CEP_ORDER; /* number of cepstral parameters excluding c0 */
  72. m_plpGain = TRUE; /* gain flag                    */
  73. m_plpExpon = (float)PLP_P_EXP; /* peak enhancemnt factor       */
  74. m_plpW.clear();               /* used by FFT() to hold W twiddle   */
  75. m_plpMofW = 0;
  76. m_plpCF.clear();             /* Trigonometrix Recombination Coeff  */
  77. m_plpMofCF = 0;
  78. m_plpIcall = 0;       /* Initialized data?               */
  79. m_plpNfilt = 0;
  80. return 1;
  81. }
  82. /* * int plp_analysis(speech, frameSize, m, a, rc, gain, sf) * subroutine which computes m-th order (max 15) PLP model (described by  * m+1 autoregressive coefficients a and gain or by m reflection  * coefficients rc) from frameSize-points (max 512) of speech signal with * sampling frequency sf (max 20 000 Hz) * speech (in): pointer to speech signal (of type float) * frameSize  (in): window (512 points typically) extractracted from speech * m      (in): order of model. (m+1) autoregressive coefficients * a      (in): pointer to auto regressive coefficients * rc     (in): pointer to reflection coefficients * gain   (in): pointer to model gain parameters * sf     (in): sampling frequency */ int Fe::plp_analysis(float *speech, int frameSize, int m, float *a, float *rc, float *gain, int sf) {
  83. assert(frameSize<=512);
  84. float spectr[512];         /* FFT spectrum                     */
  85.     float r[16], s;              /* reflection coefficients          */
  86.     float rcmct;
  87.     int   jfilt;                 /* loop counter variable            */
  88.     int   nspt;
  89.     float   alpmin;     float   audspe[23];          /* auditory spectrum coeff          */     int     npoint;              /* number of spectral points        */     int     nsize;                             int   nfft;                  /* number of points in fft          */
  90.     int   ib, ii, kk, mh, ip;
  91.     float   aib;     float   aip, alp[17];     int     mct, mct2;     FeComplex cx[512], cy[512];     double d_1;                         /* temp double calculation variable */
  92.     FeComplex *cxp, *cend;     float   *sp;     --speech;                            /* Parameter adjustments           */     --a;     --rc;
  93. nfft = (int) (log(frameSize) / 0.693148) + 1; /* get fft size from the window length   */
  94. nsize = (int)(pow(2.0,(nfft))+0.5);
  95. npoint = nsize / 2 + 1; /* get number of spectral points         */     if (m_plpIcall == 0) {                   /* if called for the first time,    */ audw_(npoint, &m_plpNfilt, m_plpCb, m_plpIbegen, sf);  /* compute spectral weights coefficients */ cosf_(m, m_plpNfilt, m_plpWcos);    /* compute IDFT coefficient table        */ m_plpIcall = 1; }
  96.     /**********************************/     /*  compute speech power spectrum */     /**********************************/     /* pack real signal into complex array for fast TrigRecombFFT */     cend = cx + frameSize/2;     sp = speech + 1;     for(cxp = cx;cxp < cend;cxp++){ cxp->m_re = *sp++; cxp->m_im = *sp++; }     /* for odd length input */     if( ((int)(frameSize/2)) * 2 != frameSize){ cxp->m_re = *sp; cxp->m_im = 0.0; cxp++; }     cend = cx + (1 << (nfft -1));     for(;cxp < cend;cxp++){ cxp->m_re = 0.0; cxp->m_im = 0.0; }     /* whoops; need to check for odd.. */     TrigRecombFFT(cx,cy,nfft-1); int fft_size_2=(1 << (nfft -1));
  97. for(ii=0;ii<fft_size_2;ii++){
  98. spectr[ii]=cy[ii].m_im*cy[ii].m_im + cy[ii].m_re*cy[ii].m_re;
  99. } spectr[fft_size_2]=0; /* owkwon: m_fftSpectrum[N/2]=0 */     /*****************************/     /* compute auditory spectrum */     /*****************************/     { for (jfilt = 2; jfilt <= m_plpNfilt - 1; ++jfilt) {
  100. audspe[jfilt-1] = 0.0; for (ii=0;ii<m_plpIbegen[jfilt + 22]-m_plpIbegen[jfilt - 1]+1;ii++){ audspe[jfilt-1] += spectr[m_plpIbegen[jfilt - 1] - 1 + ii] * m_plpCb[m_plpIbegen[jfilt + 45] - 1 + ii]; } }     }     /*********************************************/     /* cubic root intensity-loudness compression */     /*********************************************/ for (ii = 2; ii <= m_plpNfilt - 1; ++ii) { d_1 = audspe[ii - 1]; audspe[ii - 1] = (float) pow(d_1, c_b17); } /* the first and last point of auditory spectrum */ audspe[0] = audspe[1]; audspe[m_plpNfilt - 1] = audspe[m_plpNfilt - 2];     /**************************************/     /* inverse discrete fourier transform */     /**************************************/     { float rtmp, *audp, *audend, *wcp; nspt = (m_plpNfilt - 1) << 1; // owkwon : nspt = nfilt - 1 << 1; for (kk = 1; kk <= m + 1; ++kk){ rtmp = audspe[0]; audend = audspe + m_plpNfilt; /* translation for indices and start point */ wcp = m_plpWcos + (2 + kk * 23 - 24); for (audp = audspe + 1; audp < audend; audp++){ rtmp += *audp * *wcp++; } r[kk - 1] = rtmp/nspt; }     } if(r[0]==0){ /* to handle all-zero data */
  101. r[0]=1;
  102. }     /*************************************/     /* solution for autoregressive model */     /*************************************/     a[1]   = 1.0;     alp[0] = r[0];     rc[1]  = -r[1] / r[0];     a[2]   = rc[1];     alp[1] = r[0] + r[1] * rc[1];     for (mct = 2; mct <= m; ++mct){ s    = 0.0; mct2 = mct + 2; alpmin = alp[mct - 1]; for (ip = 1; ip <= mct; ++ip){ s += r[(mct2 - ip) - 1] * a[ip]; } rcmct = -s / alpmin; mh = mct / 2 + 1; for (ip = 2; ip <= mh; ++ip){ ib = mct2 - ip; aip = a[ip]; aib = a[ib]; a[ip] = aip + rcmct * aib; a[ib] = aib + rcmct * aip; } a[mct + 1] = rcmct; alp[mct] = alpmin - alpmin * rcmct * rcmct; rc[mct] = rcmct; }     *gain = alp[m];     return (1); }  /* * int audw_ (npoint, nflit, cb, ibegen, sf) * Computes auditory weighting functions            * npoint (in): number of points in the fft spectrum                  * nfilt  (in): number of samples of auditory spectrum                *              equally spaced on the bark scale;                      *              1st filter at dc and last at the Nyquist frequency                                                                       * cb    (out): array of weighting coefficients to simulate                *              critical band spectral resolution                         *              and equal loudness sensitivity of hearing                 *              on npoint speech power spectrum                           * ibegen(out): three-dimensional array which indicates where          *              to begin and where to end integration                 *              of speech spectrum and where the given             *              weighting function starts in array cb                 *              get Nyquist frequency in Bark */ int Fe::audw_ ( int npoint, int *nfilt, float *cb, int *ibegen, int sf) {     float  r_1, r_2;                          /* temp calculation variables */     float  d_1;     float freq, zdel, rsss;            /* Local variables            */     int i, j;     float x, z, f0, z0, f2samp, fh, fl, fnqbar;     int icount;     float fsq;     --cb;                                     /* Parameter adjustments      */     ibegen -= 24;                             /* [j=1 + 23 - 24] --> [0]    */     d_1    = sf / 1200.0;                          fnqbar = (float) (6.0 * log(d_1 + sqrt(d_1 * d_1 + 1.0)));            *nfilt = (int) fnqbar + 2; /* compute number of filters for less than 1 Bark spacing */          f2samp = (float) ((npoint - 1.0) / (sf / 2.0)); /* frequency -> fft spectral sample conversion            */          zdel = fnqbar / (float) (*nfilt - 1);    /* compute filter step in Bark */          icount = 1;                       /* loop over all weighting functions  */     for (j = 2; j <= (*nfilt - 1); ++j){ ibegen[j + 69] = icount;      /* ibgen[23][3] --> [j][3] -->[j+69]  */  z0 = zdel * (float) (j - 1); /* get center frequency of the j-th filter in Bark        */ f0 = (float) (600.0* (exp(z0/6.0) - exp(-z0/6.0))/2.0); /* get center frequency of the j-th filter in Hz          */ fl = (float) (600.0* (exp((z0 - 2.5)/6.0) - exp(-(z0 - 2.5)/6.0))/2.0); /* get low-cut frequency of j-th filter in Hz             */ r_1 = fl * f2samp; ibegen[j + 23] =  ((int) (r_1+0.5)) + 1;    /* ibgen[j.1] -> [j+23] */ if (ibegen[j + 23] < 1) ibegen[j + 23] = 1; fh = (float) (600.0*(exp((z0 + 1.3)/6.0) - exp(-(z0 + 1.3)/6.0)) /2.0); /* get high-cut frequency of j-th filter in Hz           */ r_1 = fh * f2samp; ibegen[j + 46] = ((int) (r_1 +0.5)) + 1;   /* ibgen[j.2] -> [j+46]  */ if (ibegen[j + 46] > npoint) ibegen[j + 46] = npoint; for (i = ibegen[j + 23]; i <= ibegen[j + 46]; ++i){ freq = ((float) (i - 1)) / f2samp; /* get frequency of j-th spectral point in Hz   */ x = (float)(freq / 600.0); /* get frequency of j-th spectral point in Bark */ d_1 = x; z = (float) (6.0 * log(d_1 + sqrt(d_1 * d_1 + 1.0))); z -= z0;     /* normalize by center frequency in barks:      */ if (z <= -0.5) {                          /* compute weighting */ d_1 = (float)(z + 0.5); cb[icount] = (float) pow(c_b28, d_1); } else if (z >= 0.5){ d_1 = (float)((-2.5) * (z - 0.5)); cb[icount] = (float) pow(c_b28, d_1); } else{ cb[icount] = 1.0; } /*     calculate the 40 db equal-loudness curve        */ /*     at center frequency and add it to the weighting */ 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); } 
  103. /*
  104.  * int TrigRecombFFT( cx, y, m )
  105.  * Computers the FFT of a complex signal, using a trigonometric recombination
  106.  * principle in order to speed up matters somewhat.
  107.  * cx (in): pointer to input complex signal of type FeComplex
  108.  * y (out): pointer to output FFT signal of type FeComplex
  109.  * m  (in): the #point fft to computer (2^x format)
  110.  * On exit returns (+1) for success and (-1) for failure
  111.  * Usage: success = TrigRecombFFT( InSignal, FFTout, 8)
  112.  */
  113. int Fe::TrigRecombFFT (FeComplex *cx, FeComplex *y, int m )
  114. {
  115. FeComplex *ck, *xk, *xnk;             /* array pointer variables      */
  116. float Realsum, Realdif;             /* real part of trig recombine  */
  117. float Imagsum, Imagdif;             /* imag part of trig recombine  */
  118. int num, k;                   /* loop counter variables       */
  119. /* Do FFT on combined data                  */
  120. num = 1 << m;
  121. PlpFFT( cx, m );
  122. /* Calculate Recombination Factors          */
  123. if( m != m_plpMofCF ) {
  124. if( CalculateCF( m ) < 0 ) {
  125. return( -1 );
  126. }
  127. }
  128. /* DC component, no multiplies              */
  129. y[0].m_re = cx[0].m_re + cx[0].m_im;
  130. y[0].m_im = 0.0;
  131. /* other frequencies by trig recombination  */
  132. ck = &m_plpCF[0];
  133. xk = cx + 1;
  134. xnk = cx + num - 1;
  135. for( k = 1; k < num; k++ ) {
  136. Realsum = ( xk->m_re + xnk->m_re ) / (float)2.0;
  137. Imagsum = ( xk->m_im + xnk->m_im ) / (float)2.0;
  138. Realdif = ( xk->m_re - xnk->m_re ) / (float)2.0;
  139. Imagdif = ( xk->m_im - xnk->m_im ) / (float)2.0;
  140. y[k].m_re = Realsum + ck->m_re * Imagsum -
  141. ck->m_im * Realdif;
  142. y[k].m_im = Imagdif - ck->m_im * Imagsum -
  143. ck->m_re * Realdif;
  144. ck++;
  145. xk++;
  146. xnk--;
  147. }
  148. return 1;
  149. }
  150. /*
  151.  * FFT( x, m )
  152.  * In-place radix 2 decimation in time FFT
  153.  * Computes the Fast Fourier transform of a signal
  154.  * x (in): pointer to complex array, power of 2 size of FFT
  155.  * m (in): size fo fft = 2^m
  156.  * Places FFT output on top of input FeComplex array.
  157.  */
  158. int Fe::PlpFFT( FeComplex *x, int m )
  159. {
  160. FeComplex u, temp, tm;
  161. FeComplex *xi, *xip, *xj, *wptr;
  162. int i, j, k, l, le, windex;
  163. int n;
  164. /* Calculate Twiddle factors for FFT */
  165. if( m != m_plpMofW ) {
  166. if( CalculateW( m ) < 0 ) {
  167. return( -1 );
  168. }
  169. }
  170. /* n = 2^m = fft length   */
  171. n = 1 << m;
  172. /* start fft              */
  173. le = n;
  174. windex = 1;
  175. for( l = 0; l < m; l++ ) {
  176. le = le / 2;
  177. /* first iteration with no multiplies */
  178. for( i = 0; i < n; i = i + 2*le ) {
  179. xi = x + i;
  180. xip = xi + le;
  181. temp.m_re = xi->m_re + xip->m_re;
  182. temp.m_im = xi->m_im + xip->m_im;
  183. xip->m_re = xi->m_re - xip->m_re;
  184. xip->m_im = xi->m_im - xip->m_im;
  185. *xi = temp;
  186. }
  187. /* remaining iterations use to store w */
  188. wptr = &m_plpW[0] + windex - 1;
  189. for( j = 1; j < le; j++ ) {
  190. u = *wptr;
  191. for( i = j; i < n; i = i + 2*le ) {
  192. xi  = x + i;
  193. xip = xi + le;
  194. temp.m_re = xi->m_re + xip->m_re;
  195. temp.m_im = xi->m_im + xip->m_im;
  196. tm.m_re = xi->m_re - xip->m_re;
  197. tm.m_im = xi->m_im - xip->m_im;
  198. xip->m_re = tm.m_re * u.m_re - 
  199. tm.m_im * u.m_im;
  200. xip->m_im = tm.m_re * u.m_im +
  201. tm.m_im * u.m_re;
  202. *xi = temp;
  203. }
  204. wptr = wptr + windex;
  205. }
  206. windex = 2 * windex;
  207. }
  208. /* rearrage data by bit reversing */
  209. j = 0;
  210. for( i = 1; i < ( n - 1 ); i++ ) {
  211. k = n / 2;
  212. while( k <= j ) {
  213. j = j - k;
  214. k = k / 2;
  215. }
  216. j = j + k;
  217. if( i < j ) {
  218. xi = x + i;
  219. xj = x + j;
  220. temp = *xj;
  221. *xj = *xi;
  222. *xi = temp;
  223. }
  224. }
  225. return 1;
  226. }
  227. /* 
  228.  * int CalculateW( m )
  229.  * This procedure calculates the W twiddle factors for the 
  230.  * FFT routine, thus needed only once. Then check to see if already
  231.  * called, and do not call again.
  232.  * m (in): number of points in FFT = (2^m)
  233.  */
  234. int Fe::CalculateW ( int m )
  235. {
  236. double w_real, w_imag;
  237. m_plpMofW = m;
  238. int n = 1 << m;
  239. int le = n / 2;
  240. m_plpW.resize(le - 1);
  241. double arg = 4.0 * atan( 1.0 ) / (float)le;
  242. double wrecur_real = w_real = cos( arg );
  243. double wrecur_imag = w_imag = -sin( arg );
  244. FeComplex *xj = &m_plpW[0];
  245. for(int j = 1; j < le; j++ ) {
  246. xj->m_re = (float)wrecur_real;
  247. xj->m_im = (float)wrecur_imag;
  248. xj++;
  249. double wtmp_real = wrecur_real * w_real - wrecur_imag * w_imag;
  250. wrecur_imag = wrecur_real * w_imag + wrecur_imag * w_real;
  251. wrecur_real = wtmp_real;
  252. }
  253. return 1;
  254. }
  255. /*
  256.  * int CalculateCF( m )
  257.  * Calculates the Trigonometric Recombination Coefficients.
  258.  * Used only once, and never called again. With multiple FFT calls
  259.  * saves computation time.
  260.  * m (in): number of points in FFT transform = (2^m)
  261.  */
  262. int Fe::CalculateCF( int m )
  263. {
  264. m_plpMofCF = m;
  265. int num = 1 << m;
  266. m_plpCF.resize(num - 1);
  267. double factor = 4.0 * atan( 1.0 ) / ((double)num);
  268. for(int k = 1; k < num; k++ ) {
  269. double arg = factor * ((double)k);
  270. m_plpCF[k-1].m_re = (float)cos( arg );
  271. m_plpCF[k-1].m_im = (float)sin( arg );
  272. }
  273. return 1;
  274. }
  275. /*****************************************************************************
  276. *   rasta.c : RASTA processing by using Hermansky or SRI filter constants
  277. *
  278. *   11/30/1992 by Aki Ohshima (aki@speech1.cs.cmu.edu)
  279. *      Separated from mfcc_lib.c.
  280. *   10/20/1992 by Aki Ohshima (aki@speech1.cs.cmu.edu)
  281. *      Created. RASTA processing by Nobu Hanai, modified by Aki.
  282. ****************************************************************************/
  283. /* --------------------------------------------------------------------------
  284. RastaFilter(mfsc, r_filter, r_f_param); 
  285.  Where 'r_filter' is an integer and supposed to specify a kind of filter, 
  286.  such as
  287.  0 : no rasta filtering(just quit)
  288.  1 : Hermansky's bandpass filetr
  289.  2 : SRI's high pass filter
  290.  'r_f_param' is a float and supposed to specify a filter parameter.
  291.  0.94 : latest parameter for Hermansky's
  292.  0.98 : previous parameter for Hermansky's
  293.  0.97 : SRI's
  294.  rasta filetering reduces the number of frames, and is taken care of in rasta 
  295.  subroutine.
  296. * ------------------------------------------------------------------------- */
  297. /*  History
  298. *  Coded by Nobutoshi Hanai      Sep 18, 1992
  299. *     Rasta filterling
  300. */
  301. int Fe::RastaFilter(FeSpectrum *mfsc, int r_filter, float r_f_param)
  302. {
  303. int i,j;
  304. float **in_dat;
  305. if (r_filter == RASTA_NO) return mfsc->m_ntime;
  306. /* initialize */
  307. in_dat = mfsc->m_specData;
  308. vector<float> rasta(mfsc->m_nfreq);
  309. vector<float> prerasta(mfsc->m_nfreq);
  310. for (j = 0; j < mfsc->m_nfreq; j++) {
  311. rasta[j] = 0.0;
  312. prerasta[j] = 0.0;
  313. }
  314. /* RASTA filtering */
  315. if (r_filter == RASTA_BY_HERMANSKY_BPF) {
  316. /*
  317. printf("RASTA filtering  -- Hermansky'sn");
  318. */
  319. mfsc->m_ntime -= 4;
  320. for (i = 0; i < mfsc->m_ntime; i++){
  321. for (j = 0; j < mfsc->m_nfreq; ++j) {
  322. rasta[j] = (float)(r_f_param * prerasta[j] + 0.2 * *(in_dat[i+4] + j) + 0.1 * *(in_dat[i+3] + j) 
  323. - 0.1 * *(in_dat[i+1] + j) - 0.2 * *(in_dat[i] + j));
  324. *(in_dat[i] + j) = rasta[j];
  325. prerasta[j] = rasta[j];
  326. }
  327. }
  328. }
  329. else if (r_filter == RASTA_BY_SRI_HPF) {
  330. /*
  331. printf("RASTA filtering  -- SRI'sn");
  332. */
  333. mfsc->m_ntime -= 1;
  334. for (i = 0; i < mfsc->m_ntime; i++){
  335. for (j = 0; j < mfsc->m_nfreq; ++j) {
  336. rasta[j] = r_f_param * prerasta[j] + *(in_dat[i+1] + j) - *(in_dat[i] + j);
  337. *(in_dat[i] + j) = rasta[j];
  338. prerasta[j] = rasta[j];
  339. }
  340. }
  341. }
  342. else {
  343. err_quit("ERROR : Invalid RASTA argument !!n");
  344. }
  345. return(mfsc->m_ntime);
  346. }