Ejemplo n.º 1
0
sample LPSpectralDifferenceODF::process_frame(int signal_size, sample* signal)
{
    sample sum = 0.0;
    sample amp = 0.0;
    sample prediction = 0.0;

    // do a FFT of the current frame
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    // calculate the amplitude differences between bins from consecutive frames 
    for(int bin = 0; bin < num_bins; bin++)
    {
        amp = sqrt((out[bin][0]*out[bin][0]) + (out[bin][1]*out[bin][1]));
        /* get LP coefficients */
        burg(order, prev_amps[bin], order, order, coefs);
        /* get the difference between current and predicted values */
        linear_prediction(order, prev_amps[bin], order, coefs, 1, &prediction);
        sum += fabs(amp - prediction);
        /* move frames back by 1 */
        for(int j = 0; j < order-1; j++)
        {
            prev_amps[bin][j] = prev_amps[bin][j+1];
        }
        prev_amps[bin][order-1] = amp;
    }

    return sum;
}
Ejemplo n.º 2
0
sample LPEnergyODF::process_frame(int signal_size, sample* signal)
{
    sample odf = 0.0;
    sample prediction = 0.0;

	/* calculate signal energy */
    sample energy = 0.0;
    for(int i = 0; i < frame_size; i++)
    {
        energy += signal[i] * signal[i];
    }

    /* get LP coefficients */
    burg(order, prev_values, order, order, coefs);
    /* get the difference between current and predicted energy values */
    linear_prediction(order, prev_values, order, coefs, 1, &prediction);
    odf = fabs(energy - prediction);

    /* move energies 1 frame back then update last energy */
    for(int i = 0; i < order-1; i++)
    {
        prev_values[i] = prev_values[i+1];
    }
    prev_values[order-1] = energy;
    return odf;
}
Ejemplo n.º 3
0
SEXP Burg(SEXP x, SEXP order)
{
    x = PROTECT(coerceVector(x, REALSXP));
    int n = LENGTH(x), pmax = asInteger(order);
    SEXP coefs = PROTECT(allocVector(REALSXP, pmax * pmax)),
	var1 = PROTECT(allocVector(REALSXP, pmax + 1)),
	var2 = PROTECT(allocVector(REALSXP, pmax + 1));
    burg(n, REAL(x), pmax, REAL(coefs), REAL(var1), REAL(var2));
    SEXP ans = PROTECT(allocVector(VECSXP, 3));
    SET_VECTOR_ELT(ans, 0, coefs);
    SET_VECTOR_ELT(ans, 1, var1);
    SET_VECTOR_ELT(ans, 2, var2);
    UNPROTECT(5);
    return ans;
}
Ejemplo n.º 4
0
sample LPComplexODF::process_frame(int signal_size, sample* signal)
{
    sample sum = 0.0;
    sample amp = 0.0;
    sample prediction = 0.0;
    sample distance = 0.0;

    // do a FFT of the current frame
    memcpy(in, &signal[0], sizeof(sample)*frame_size);
    window_frame(in);
    fftw_execute(p);

    for(int bin = 0; bin < num_bins; bin++)
    {
        distance = sqrt((out[bin][0]-prev_frame[bin][0])*(out[bin][0]-prev_frame[bin][0]) +
                        (out[bin][1]-prev_frame[bin][1])*(out[bin][1]-prev_frame[bin][1]));

        /* get LP coefficients */
        burg(order, distances[bin], order, order, coefs);
        /* get the difference between current and predicted values */
        linear_prediction(order, distances[bin], order, coefs, 1, &prediction);
        sum += fabs(distance - prediction);

        /* update distances */
        for(int j = 0; j < order-1; j++)
        {
            distances[bin][j] = distances[bin][j+1];
        }
        distances[bin][order-1] = distance;

        /* update previous frame */
        prev_frame[bin][0] = out[bin][0];
        prev_frame[bin][1] = out[bin][1];
    }

    return sum;
}
Ejemplo n.º 5
0
static autoFormant Sound_to_Formant_any_inline (Sound me, double dt_in, int numberOfPoles,
	double halfdt_window, int which, double preemphasisFrequency, double safetyMargin)
{
	double dt = dt_in > 0.0 ? dt_in : halfdt_window / 4.0;
	double duration = my nx * my dx, t1;
	double dt_window = 2.0 * halfdt_window;
	long nFrames = 1 + (long) floor ((duration - dt_window) / dt);
	long nsamp_window = (long) floor (dt_window / my dx), halfnsamp_window = nsamp_window / 2;

	if (nsamp_window < numberOfPoles + 1)
		Melder_throw (U"Window too short.");
	t1 = my x1 + 0.5 * (duration - my dx - (nFrames - 1) * dt);   // centre of first frame
	if (nFrames < 1) {
		nFrames = 1;
		t1 = my x1 + 0.5 * duration;
		dt_window = duration;
		nsamp_window = my nx;
	}
	autoFormant thee = Formant_create (my xmin, my xmax, nFrames, dt, t1, (numberOfPoles + 1) / 2);   // e.g. 11 poles -> maximally 6 formants
	autoNUMvector <double> window (1, nsamp_window);
	autoNUMvector <double> frame (1, nsamp_window);
	autoNUMvector <double> cof (1, numberOfPoles);   // superfluous if which==2, but nobody uses that anyway

	autoMelderProgress progress (U"Formant analysis...");

	/* Pre-emphasis. */
	Sound_preEmphasis (me, preemphasisFrequency);

	/* Gaussian window. */
	for (long i = 1; i <= nsamp_window; i ++) {
		double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0);
		window [i] = (exp (-48.0 * (i - imid) * (i - imid) / (nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1.0 - edge);
	}

	for (long iframe = 1; iframe <= nFrames; iframe ++) {
		double t = Sampled_indexToX (thee.peek(), iframe);
		long leftSample = Sampled_xToLowIndex (me, t);
		long rightSample = leftSample + 1;
		long startSample = rightSample - halfnsamp_window;
		long endSample = leftSample + halfnsamp_window;
		double maximumIntensity = 0.0;
		if (startSample < 1) startSample = 1;
		if (endSample > my nx) endSample = my nx;
		for (long i = startSample; i <= endSample; i ++) {
			double value = Sampled_getValueAtSample (me, i, Sound_LEVEL_MONO, 0);
			if (value * value > maximumIntensity) {
				maximumIntensity = value * value;
			}
		}
		if (maximumIntensity == HUGE_VAL)
			Melder_throw (U"Sound contains infinities.");
		thy d_frames [iframe]. intensity = maximumIntensity;
		if (maximumIntensity == 0.0) continue;   // Burg cannot stand all zeroes

		/* Copy a pre-emphasized window to a frame. */
		for (long j = 1, i = startSample; j <= nsamp_window; j ++)
			frame [j] = Sampled_getValueAtSample (me, i ++, Sound_LEVEL_MONO, 0) * window [j];

		if (which == 1) {
			burg (frame.peek(), endSample - startSample + 1, cof.peek(), numberOfPoles, & thy d_frames [iframe], 0.5 / my dx, safetyMargin);
		} else if (which == 2) {
			if (! splitLevinson (frame.peek(), endSample - startSample + 1, numberOfPoles, & thy d_frames [iframe], 0.5 / my dx)) {
				Melder_clearError ();
				Melder_casual (U"(Sound_to_Formant:)"
					U" Analysis results of frame ", iframe,
					U" will be wrong."
				);
			}
		}
		Melder_progress ((double) iframe / (double) nFrames, U"Formant analysis: frame ", iframe);
	}
	Formant_sort (thee.peek());
	return thee;
}
Ejemplo n.º 6
0
int maxent ( MiscParams *misc , int ncases , int degree , Signal *sig ,
             int *nsigs , Signal ***signals , char *error )
{
   int i, j, n, ivar, nvars ;
   double *data, *temp, *work, *x, mean, var, diff, *pcorr ;
   double real, imag, theta, maxspec ;
   Signal **sptr ;

   nvars = misc->names->nreal ;

   if (! nvars) {
      strcpy ( error , "No signal names specified" ) ;
      return 1 ;
      }

   n = sig->n ;
   x = sig->sig ;

   MEMTEXT ( "MAXENT: data, work" ) ;
   data = (double *) MALLOC ( ncases * sizeof(double) ) ;
   work = (double *) MALLOC ( (3 * degree + 2 * n) * sizeof(double) ) ;

   if ((data == NULL)  ||  (work == NULL)) {
      strcpy ( error , "Insufficient memory to create signal" ) ;
      return 1 ;
      }

/*
   Compute the spectrum
*/

   burg ( n , x , degree , work+degree , work , work+2*degree ,
          work+3*degree , work+3*degree+sig->n ) ;

   mean = var = 0.0 ;
   for (i=0 ; i<n ; i++)
      mean += x[i] ;
   mean /= n ;

   for (i=0 ; i<n ; i++) {
      diff = x[i] - mean ;
      var += diff * diff ;
      }
   var /= (n * degree) ;

   pcorr = work+degree ;       // Partial autocorrelations
   for (i=0 ; i<degree ; i++)
      var *= (1.0 - pcorr[i] * pcorr[i]) ;

   if (var < 1.e-40)
      var = 1.e-40 ;

   maxspec = 0.0 ;
   for (i=0 ; i<ncases ; i++) {
      theta = PI * (double) i / (double) ncases ;
      real = 1.0 ;
      imag = 0.0 ;
      for (j=0 ; j<degree ; j++) {
         real -= work[j] * cos ( (j+1) * theta ) ;
         imag -= work[j] * sin ( (j+1) * theta ) ;
         }
      data[i] = var / (real * real  +  imag * imag  + 1.e-40) ;
      if (data[i] > maxspec)
         maxspec = data[i] ;
      }

/*
   Optional step:  Normalize so max is almost 1.0 for better display.
*/

   maxspec = 0.99999999999 / maxspec ;
   for (i=0 ; i<ncases ; i++)
      data[i] *= maxspec ;

/*
   Count how many of these signals have names not already in use.
   Then allocate additional memory for their pointers.
*/

   MEMTEXT ( "MAXENT: signals array" ) ;
   if (*nsigs) {                             // If signals already exist
      ivar = *nsigs ;                        // This many signals so far
      sptr = *signals ;                      // Array of pointers to them
      for (i=0 ; i<misc->names->n ; i++) {   // Check every new name
         if (! misc->names->len[i])          // Some may be NULL
            continue ;                       // Obviously skip them
         for (j=*nsigs-1 ; j>=0 ; j--) {     // Check every existing signal
            if (! strcmp ( misc->names->start[i] , sptr[j]->name )) // There?
               break ;                       // If found, quit looking
            }
         if (j < 0)                          // Means not there
            ++ivar ;                         // So count this new entry
         }
      sptr = (Signal **) REALLOC ( sptr , ivar * sizeof(Signal *) ) ;
      }
   else
      sptr = (Signal **) MALLOC ( nvars * sizeof(Signal *) ) ;

   if (sptr == NULL) {
      FREE ( data ) ;
      strcpy ( error , "Insufficient memory to create signal" ) ;
      return 1 ;
      }
   *signals = sptr ;

/*
   Now create new signals for each variable.
   If a signal of the same name exists, delete it first.
*/

   ivar = 0 ;
   for (i=0 ; i<misc->names->n ; i++) { // Check all names
      if (! misc->names->len[i])        // Some may be NULL
         continue ;                     // Obviously skip them
      for (j=*nsigs-1 ; j>=0 ; j--) {   // Search existing signals for same name
         if (! strcmp ( misc->names->start[i] , sptr[j]->name )) {  // There?
            MEMTEXT ( "MAXENT: delete duplicate signal" ) ;
            delete ( sptr[j] ) ;        // If so, delete this signal
            break ;                     // And quit looking
            }
         }
      if (j < 0) {                      // Means new, unique name
         j = *nsigs ;                   // Tack it onto end of signal array
         ++*nsigs ;                     // And count it
         }

      if (ivar) {   // In this case, must allocate for new signal
         MEMTEXT ( "MAXENT: temp signal" ) ;
         temp = (double *) MALLOC ( ncases * sizeof(double) ) ;
         if (temp == NULL) {
            strcpy ( error , "Insufficient memory to create signal" ) ;
            return 1 ;
            }
         memcpy ( temp , data , ncases * sizeof(double) ) ;
         }
      else
         temp = data ;

      MEMTEXT ( "MAXENT: new Signal" ) ;
      sptr[j] = new Signal ( misc->names->start[i] , ncases , temp ) ;
      if ((sptr[j] == NULL)  ||  ! sptr[j]->n) {
         if (sptr[j] != NULL) {
            delete sptr[j] ;
            sptr[j] = NULL ;
            }
         strcpy ( error , "Insufficient memory to create signal" ) ;
         return 1 ;
         }
      ++ivar ;
      sptr[j]->type = SpectrumSignal ;
      sptr[j]->source_n = n ;
      } // For all names

   MEMTEXT ( "MAXENT: work" ) ;
   FREE ( work ) ;

   return 0 ;
}