Пример #1
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 );
}
Пример #2
0
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);
}