Example #1
0
autoPolynomial LPC_Frame_to_Polynomial (LPC_Frame me) {
	long degree = (long) my nCoefficients;
	autoPolynomial thee = Polynomial_create (-1, 1, degree);
	for (long i = 1; i <= degree; i++) {
		thy coefficients[i] = my a[degree - i + 1];
	}
	thy coefficients[degree + 1] = 1.0;
	return thee;
}
Example #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
}