예제 #1
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *spec2cep(struct fvec *spec, int ncpts, double lift)
{   /* Construct a cepstrum directly from a spectrum */
    char *funcname = "spec2cep";
static struct fvec *output  = NULL;
static struct fvec *logspec = NULL;
static struct fvec *costab  = NULL;
    int i, j, ix;
    double tmp;

/*    int ncpts = pptr->order + 1; */
/*    int nfpts = pptr->nfilts;  */
    int nfpts = spec->length;
    double pionk = M_PI/(nfpts-1);

/*    assert(nfpts == spec->length); */

    if(output == NULL || output->length != ncpts) {  
	/* need to (re)allocate static structures */
	if (output != NULL) 	free_fvec(output);
	if (logspec != NULL) 	free_fvec(logspec);
	if (costab != NULL)	free_fvec(costab);
	output = alloc_fvec(ncpts);
	logspec = alloc_fvec(nfpts);
	costab = alloc_fvec(2*(nfpts-1));
	for(i=0; i < costab->length; ++i) {
	    costab->values[i] = cos(pionk*i);
	}
    }

    /* could maybe use the same IDFT matrix as band_to_auto? */
    for(i = 0; i < logspec->length; ++i) {
	/* spec is power, so halve to get mag ? noo */
	logspec->values[i] = 0.5 * log(spec->values[i]);
    }
    for (j = 0; j < output->length; ++j) {
	tmp = logspec->values[0] 
	      + logspec->values[logspec->length-1]*pow(-1,j);
	ix = j;
	for (i = 1; i < logspec->length-1; ++i) {
	    /* calculate inner product against cos bases */
	    /* tmp += 2 * logspec->values[i] * cos(pionk*i*j); */
	    tmp += 2*logspec->values[i] * costab->values[ix];
	    ix += j;	if(ix >= costab->length)	ix -= costab->length;
	}
	output->values[j] = tmp/(nfpts-1);
    }
#ifdef FIXC0
    /* fix the C0 coef which is too big (or compensate in inversion) */
    output->values[0] *= 0.5;
#endif /* FIXC0 */

#ifndef NO_LIFT
    /* do the liftering */
    for (i = 1; i < output->length; ++i) {
	output->values[i] *= pow((double)i, lift);
    }
#endif /* NO_LIFT */
    return(output);
}
예제 #2
0
/*
 *	This routine computes a nonlinear function of
 *	an fvec array (floats).
 *	Currently this is  just the exp, which is the inverse
 *	of the log compression used in log rasta.
 *
 *	The first time that this program is called, we do
 *	the usual allocation.
 */
struct fvec *inverse_nonlin( const struct param *pptr, struct fvec *in)
{

  int i, lastfilt;
  char *funcname;

  static struct fvec *outptr = NULL; 
  /* array for nonlinear auditory spectrum */

  funcname = "inverse_nonlin";

  if(outptr == (struct fvec *)NULL)
    {
      outptr = alloc_fvec( pptr->nfilts );
    }

  lastfilt = pptr->nfilts - pptr->first_good;

  /* We only check on the incoming vector, as the output
     is allocated here so we know how long it is. */
  fvec_check(funcname, in, lastfilt - 1);

  for(i=pptr->first_good; i<lastfilt; i++)
    {
      if(pptr->lrasta == TRUE || pptr->jrasta == TRUE)
        {
          if (in->values[i] < LOG_MAXFLOAT)
            {
              outptr->values[i] = exp((in->values[i]));
            }
          else
            {
              if (pptr->jrasta == TRUE)
                {
                  fprintf(stderr,
                          "Warning (%s): saturating inverse nonlinearity to prevent overflow.\n",
                      funcname);
                  fprintf(stderr, "You may want to scale down your input.\n\n");
                }
              else
                {
                  fprintf(stderr,
                          "Warning (%s): saturating inverse nonlinearity to prevent overflow.\n",
                      funcname);
                  fprintf(stderr,
                          "You should run rasta with the -M option.\n\n");
                }
              outptr->values[i] = MAXFLOAT;
            }
        }
      else
        {
          outptr->values[i] = in->values[i];
        }
    }

  return( outptr );
}
예제 #3
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *lpc2cep(const struct param *pptr, struct fvec *lpcptr) 
{   /* Convert the LPC params to cepstra */
static struct fvec *outptr = NULL;
    if(outptr == NULL) {
	outptr = alloc_fvec(pptr->nout);
    }
    lpc_to_cep( pptr, lpcptr, outptr, pptr->nout);
    return outptr;
}
예제 #4
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *lpc2spec(const struct param *pptr, struct fvec *lpcptr)
{   /* Convert the LPC params to a spectrum */
    int nfilts = pptr->nfilts;
static struct fvec *outptr = NULL;
    if(outptr == NULL) {
	outptr = alloc_fvec(nfilts);
    }
    /* convert lpc coefs to spectral vals */
    lpc_to_spec(lpcptr, outptr);
    return(outptr);
}	
예제 #5
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *spec2lpc(const struct param *pptr, struct fvec *in)
{   /* Find an LPC fit to a spectrum */
    static struct fvec *autoptr = NULL; /* array for autocor */
    static struct fvec *lpcptr; /* array for predictors */
    static struct fvec *outptrOLD; /* last time's output */
    float lpcgain;
    int i;
    char *funcname = "spec2lpc";
	
    if(autoptr == (struct fvec *)NULL) { /* Check for 1st time */
	/* Allocate space */
	autoptr = alloc_fvec( pptr->order + 1 );
	lpcptr = alloc_fvec( pptr->order + 1 );
	outptrOLD = alloc_fvec( pptr->order + 1 );
	for(i=0; i<outptrOLD->length; i++)
	    outptrOLD->values[i] = TINY;		
    }
    
    band_to_auto(pptr, in, autoptr);
    /* Do IDFT by multiplying cosine matrix times power values,
       getting autocorrelations */

    auto_to_lpc( pptr, autoptr, lpcptr, &lpcgain );
    /* do Durbin recursion to get predictor coefficients */

    if(lpcgain<=0) { /* in case of calculation inaccuracy */
	for(i=0; i<outptrOLD->length; i++)
	    lpcptr->values[i] = outptrOLD->values[i];
	fprintf(stderr,"Warning: inaccuracy of calculation -> using last frame\n");
    } else {
	if( pptr->gainflag == TRUE) {
	    norm_fvec( lpcptr, lpcgain );  /* divide by the gain */
	}
	/* Put in model gain */
    }
    for(i=0; i<lpcptr->length; i++)
	outptrOLD->values[i] = lpcptr->values[i];
    
    return( lpcptr );
}
예제 #6
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *toexp(struct fvec *vec)
{   /* inverse of tolog() */
static struct fvec *rslt = NULL;
    int i, npts = vec->length;
    if(rslt == NULL || rslt->length != npts) {
	if(rslt != NULL)	free_fvec(rslt);
	rslt = alloc_fvec(npts);
    }
    for (i = 0; i < npts; ++i) {
	rslt->values[i] = exp(vec->values[i]);
    }
    return rslt;
}
예제 #7
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *tolog(struct fvec *vec)
{   /* take the log of an fvec */
static struct fvec *rslt = NULL;
    int i, npts = vec->length;
    if(rslt == NULL || rslt->length != npts) {
	if(rslt != NULL)	free_fvec(rslt);
	rslt = alloc_fvec(npts);
    }
    for (i = 0; i < npts; ++i) {
	rslt->values[i] = log(vec->values[i]);
    }
    return rslt;
}
예제 #8
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *cep2spec(struct fvec *incep, int nfpts, double lift)
{   /* Invert a cepstrum into a (linear) spectrum */
    char *funcname = "cep2spec";
static struct fvec *output = NULL;

    if (output == NULL || output->length != nfpts) {
	if (output != NULL) {free_fvec(output);}
	output = alloc_fvec(nfpts);
    }
    _cep2spec(incep->values, incep->length, output->values, output->length, 
	      lift);
    return output;
}
예제 #9
0
struct fvec*
fill_frame(struct fvec* sptr,
           struct fhistory* hptr,
           struct param* pptr,
           int nframe)
{
  static struct fvec *outbufptr = NULL;
  static struct fvec *inbufptr;
  static struct fvec *window;
  int i, start, end;
  char *funcname;

  funcname = "fill_frame";

  if (outbufptr == (struct fvec*) NULL)
    /* first frame in analysis */
    {
      outbufptr = alloc_fvec(pptr->winpts);
      inbufptr = alloc_fvec(pptr->winpts); 
      window = get_win(pptr, outbufptr->length);

      if (pptr->padInput == TRUE)
        {
          const int npad = (pptr->winpts - pptr->steppts) >> 1;
          for (i = 0; i < npad; i++)
            {
              inbufptr->values[i] = sptr->values[npad - i];
            }
          for (i = npad; i < inbufptr->length; i++)
            {
              inbufptr->values[i] = sptr->values[i - npad];
            }
        }
      else
        {
          for (i = 0; i < pptr->winpts; i++)
예제 #10
0
파일: invcep.c 프로젝트: mdqyy/AMPF
struct fvec *inv_postaud(const struct param *pptr, struct fvec *input)
{   /* invert the post-audspec compression and weighting */
	int i, lastfilt;
	float step_barks;
        float f_bark_mid, f_hz_mid ;
	float ftmp, fsq;
	double tmp;
	char funcname[] = "inv_postaud";
static float inveql[MAXFILTS];
static struct fvec *output = NULL;

        /* compute filter step in Barks */
        step_barks = pptr->nyqbar / (float)(pptr->nfilts - 1);
	lastfilt = pptr->nfilts - pptr->first_good;
	if(output == (struct fvec *)NULL) { /* If first time */
	    output = alloc_fvec( pptr->nfilts );
	    
	    for(i=pptr->first_good; i<lastfilt; i++) {
		f_bark_mid = i * step_barks;
		/* get center frequency of the j-th filter in Hz */
		f_hz_mid = 300. * (exp((double)f_bark_mid / 6.)
				- exp(-(double)f_bark_mid / 6.));
		/* calculate the LOG 40 db equal-loudness curve */
		fsq = (f_hz_mid * f_hz_mid) ;
		ftmp = fsq + 1.6e5;
		inveql[i] = (ftmp / fsq) * (ftmp / fsq)
		    * ((fsq + (float)9.61e6)
		       /(fsq + (float)1.44e6));
	    }
	}
        fvec_check(funcname, input, lastfilt - 1);

	for(i=pptr->first_good; i<lastfilt; i++) {
		/* invert compression */
		tmp = pow((double)input->values[i], 1.0/COMPRESS_EXP);
		/* remove equal-loudness curve */
		output->values[i] = tmp * inveql[i];
	}

	/* Since the first critical band has center frequency at 0 Hz and
	bandwidth 1 Bark (which is about 100 Hz there) 
	we would need negative frequencies to integrate.
	In short the first filter is JUNK. Since all-pole model always
	starts its spectrum perpendicular to the y-axis (its slope is
	0 at the beginning) and the same is true at the Nyquist frequency,
	we start the auditory spectrum (and also end it) with this slope
	to get around this junky frequency bands. This is not to say
	that this operation is justified by anything but it seems
	to do no harm. - H.H. 

	8-8-93 Morgan note: in this version, as per request from H.H.,
	the number of critical band filters is a command-line option.
	Therefore, if the spacing is less than one bark, more than
	one filter on each end can be junk. Now the number of
	copied filter band outputs depends on the number
	of filters used. */

	for(i=pptr->first_good; i > 0; i--) {
		output->values[i-1] = 0;
	}
	for(i=lastfilt; i < pptr->nfilts; i++) {
		output->values[i] = 0;
	}
	return(output);
}