Пример #1
0
static int Sound_into_LPC_Frame_burg (Sound me, LPC_Frame thee) {
	int status = NUMburg (my z[1], my nx, thy a, thy nCoefficients, &thy gain);
	thy gain *= my nx;
	for (long i = 1; i <= thy nCoefficients; i++) {
		thy a[i] = -thy a[i];
	}
	return status;
}
Пример #2
0
static void burg (double sample [], long nsamp_window, double cof [], int nPoles,
	Formant_Frame frame, double nyquistFrequency, double safetyMargin)
{
	double a0;
	NUMburg (sample, nsamp_window, cof, nPoles, & a0);

	/*
	 * Convert LP coefficients to polynomial.
	 */
	autoPolynomial polynomial = Polynomial_create (-1, 1, nPoles);
	for (int i = 1; i <= nPoles; i ++)
		polynomial -> coefficients [i] = - cof [nPoles - i + 1];
	polynomial -> coefficients [nPoles + 1] = 1.0;

	/*
	 * Find the roots of the polynomial.
	 */
	autoRoots roots = Polynomial_to_Roots (polynomial.peek());
	Roots_fixIntoUnitCircle (roots.peek());

	Melder_assert (frame -> nFormants == 0 && ! frame -> formant);

	/*
	 * First pass: count the formants.
	 * The roots come in conjugate pairs, so we need only count those above the real axis.
	 */
	for (int i = roots -> min; i <= roots -> max; i ++) if (roots -> v [i]. im >= 0) {
		double f = fabs (atan2 (roots -> v [i].im, roots -> v [i].re)) * nyquistFrequency / NUMpi;
		if (f >= safetyMargin && f <= nyquistFrequency - safetyMargin)
			frame -> nFormants ++;
	}

	/*
	 * Create space for formant data.
	 */
	if (frame -> nFormants > 0)
		frame -> formant = NUMvector <structFormant_Formant> (1, frame -> nFormants);

	/*
	 * Second pass: fill in the formants.
	 */
	int iformant = 0;
	for (int i = roots -> min; i <= roots -> max; i ++) if (roots -> v [i]. im >= 0.0) {
		double f = fabs (atan2 (roots -> v [i].im, roots -> v [i].re)) * nyquistFrequency / NUMpi;
		if (f >= safetyMargin && f <= nyquistFrequency - safetyMargin) {
			Formant_Formant formant = & frame -> formant [++ iformant];
			formant -> frequency = f;
			formant -> bandwidth = -
				log (roots -> v [i].re * roots -> v [i].re + roots -> v [i].im * roots -> v [i].im) * nyquistFrequency / NUMpi;
		}
	}
	Melder_assert (iformant == frame -> nFormants);   // may fail if some frequency is NaN
}
Пример #3
0
autoSpectrum Spectrum_lpcSmoothing (Spectrum me, int numberOfPeaks, double preemphasisFrequency) {
	try {
		double gain, a [100];
		long numberOfCoefficients = 2 * numberOfPeaks;

		autoSound sound = Spectrum_to_Sound (me);
		NUMpreemphasize_f (sound -> z [1], sound -> nx, sound -> dx, preemphasisFrequency);	 	
		
		NUMburg (sound -> z [1], sound -> nx, a, numberOfCoefficients, & gain);
		for (long i = 1; i <= numberOfCoefficients; i ++) a [i] = - a [i];
		autoSpectrum thee = Data_copy (me);

		long nfft = 2 * (thy nx - 1);
		long ndata = numberOfCoefficients < nfft ? numberOfCoefficients : nfft - 1;
		double scale = 10 * (gain > 0 ? sqrt (gain) : 1) / numberOfCoefficients;
		autoNUMvector <double> data (1, nfft);
		data [1] = 1;
		for (long i = 1; i <= ndata; i ++)
			data [i + 1] = a [i];
		NUMrealft (data.peek(), nfft, 1);
		double *re = thy z [1];
		double *im = thy z [2];
		re [1] = scale / data [1];
		im [1] = 0.0;
		long halfnfft = nfft / 2;
		for (long i = 2; i <= halfnfft; i ++) {
			double real = data [i + i - 1], imag = data [i + i];
			re [i] = scale / sqrt (real * real + imag * imag) / (1 + thy dx * (i - 1) / preemphasisFrequency);
			im [i] = 0;
		}
		re [halfnfft + 1] = scale / data [2] / (1 + thy dx * halfnfft / preemphasisFrequency);
		im [halfnfft + 1] = 0.0;
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not smoothed.");
	}
}