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; }
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 }