FE_plcc.cpp
上传用户:italyroyal
上传日期:2013-05-06
资源大小:473k
文件大小:21k
- ///////////////////////////////////////////////////////////////////////////////
- // This is a part of the Feature program.
- // Version: 1.0
- // Date: February 22, 2003
- // Programmer: Oh-Wook Kwon
- // Copyright(c) 2003 Oh-Wook Kwon. All rights reserved. owkwon@ucsd.edu
- ///////////////////////////////////////////////////////////////////////////////
- #include "StdAfx.h"
#include "FE_feature.h"
-
/* Table of constant values */
static const double c_b17 = 0.33;
static const double c_b28 = 10.0;
- int Fe::_plp_cepstrum_basic(float *sample, int frameSize, float *plp_cep, int ceporder, int norder)
- {
- _plp_basic(sample, frameSize, plp_cep, ceporder, norder);
- return 1;
- }
- int Fe::plp_cepstrum_basic(short *sample, int frameSize, float *plp_cep, int ceporder, int norder)
- {
- vector<float> frameA(frameSize);
- preprocessing(sample, frameSize, &frameA[0]);
- m_window.Windowing(&frameA[0], frameSize, WIN_HAMMING);
- _plp_cepstrum_basic(&frameA[0], frameSize, plp_cep, ceporder, norder);
- return 1;
- }
- /*
- * int _plp_basic(sample, sampleN, frameSize, plp_cep, ceporder, norder)
- * Calculates the PLP coefficients of an input speech signal using the
- * algorithm of Hynek Hermanski.
- * sample (in): pointer to input speech data of type float
- * sampleN (in): number of data points available in array
- * frameSize (in): analysis window in samples
- * Expon (in): peak enhancement factor
- * norder (in): order of PLP model
- * ceporder (in): order of cepstrum order
- * Gain (in): gain flag (1 = gain; 0 no)
- * plp_cep (out): pointer to output plp data of type float
- * On exit returns the number of frames.
- */
- int Fe::_plp_basic(float *sample, int frameSize, float *plp_cep, int ceporder, int norder)
- {
- float gain; /* gain parameter of model */
- vector<float> a(norder+1); /* auto regressive coefficients */
- vector<float> rc(norder+1); /* reflection coefficients */
- plp_analysis(sample, frameSize, norder, &a[0], &rc[0], &gain, m_sampleRate);
- if(m_plpGain) for (int k = 0; k < norder + 1; k++) a[k] = a[k]/gain;
- a2gexp_(&a[0], plp_cep, norder, ceporder+1, m_plpExpon);
- plp_cep[0] = -plp_cep[0];
- return 1;
- }
- /*
- * plp_cep.c
- *
- * written by Hynek Hermanski
- *
- * translated by f2c (version of 30 January 1990 16:02:04).
- * Modified by Chuck Wooters, ICSI, 7/6/90
- *
- * further modified at OGI -- array indices in some inner loops were
- * replaced by pointers. the fft routine was replaces by TrigRecombFFT.
- *
- * Cleaned Up by Johan Schalkwyk (March 1993)
- *
- * The actual processing is split up into a few pieces:
- * 1) power spectral analysis
- * 2) auditory spectrum computation
- * 3) compression
- * 4) inverse FFT
- * 5) autoregressive all-pole modeling (cepstral coefficients)
- */
- int Fe::init_plp()
- {
- m_plpOrder = PLP_ORDER; /* model order */
- m_plccOrder = PLP_CEP_ORDER; /* number of cepstral parameters excluding c0 */
- m_plpGain = TRUE; /* gain flag */
- m_plpExpon = (float)PLP_P_EXP; /* peak enhancemnt factor */
- m_plpW.clear(); /* used by FFT() to hold W twiddle */
- m_plpMofW = 0;
- m_plpCF.clear(); /* Trigonometrix Recombination Coeff */
- m_plpMofCF = 0;
- m_plpIcall = 0; /* Initialized data? */
- m_plpNfilt = 0;
- return 1;
- }
-
/*
* 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)
{
- assert(frameSize<=512);
- float spectr[512]; /* FFT spectrum */
- float r[16], s; /* reflection coefficients */
- float rcmct;
- int jfilt; /* loop counter variable */
- int nspt;
- float alpmin;
float audspe[23]; /* auditory spectrum coeff */
int npoint; /* number of spectral points */
int nsize;
int nfft; /* number of points in fft */
- int ib, ii, kk, mh, ip;
- float aib;
float aip, alp[17];
int mct, mct2;
FeComplex cx[512], cy[512];
double d_1; /* temp double calculation variable */
-
- FeComplex *cxp, *cend;
float *sp;
--speech; /* Parameter adjustments */
--a;
--rc;
- nfft = (int) (log(frameSize) / 0.693148) + 1; /* get fft size from the window length */
- nsize = (int)(pow(2.0,(nfft))+0.5);
- 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;
}
-
- /**********************************/
/* 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));
- for(ii=0;ii<fft_size_2;ii++){
- spectr[ii]=cy[ii].m_im*cy[ii].m_im + cy[ii].m_re*cy[ii].m_re;
- }
spectr[fft_size_2]=0; /* owkwon: m_fftSpectrum[N/2]=0 */
/*****************************/
/* compute auditory spectrum */
/*****************************/
{
for (jfilt = 2; jfilt <= m_plpNfilt - 1; ++jfilt) {
- 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 */
- r[0]=1;
- }
/*************************************/
/* 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);
}
-
/*
- * 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'sn");
- */
- 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'sn");
- */
- 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);
- }