3 // http://kbs.cs.tu-berlin.de/~jutta/gsm/lpc.html
5 #define P_MAX 8 /* order p of LPC analysis, typically 8..14 */
7 /* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
9 double /* returns minimum mean square error */
11 double const * ac, /* in: [0...p] autocorrelation values */
12 double * ref, /* out: [0...p-1] reflection coef's */
13 double * lpc) /* [0...p-1] LPC coefficients */
15 int i, j; double r, error = ac[0];
18 for (i = 0; i < P_MAX; i++) ref[i] = 0; return 0; }
20 for (i = 0; i < P_MAX; i++) {
22 /* Sum up this iteration's reflection coefficient.
25 for (j = 0; j < i; j++) r -= lpc[j] * ac[i - j];
28 /* Update LPC coefficients and total error.
31 for (j = 0; j < i/2; j++) {
33 lpc[j] += r * lpc[i-1-j];
34 lpc[i-1-j] += r * tmp;
36 if (i % 2) lpc[j] += lpc[j] * r;
43 /* I. Sch"ur's recursion from 1917 is related to the Levinson-Durbin
44 * method, but faster on parallel architectures; where Levinson-Durbin
45 * would take time proportional to p * log(p), Sch"ur only requires
46 * time proportional to p. The GSM coder uses an integer version of
47 * the Sch"ur recursion.
49 double /* returns the minimum mean square error */
50 schur( double const * ac, /* in: [0...p] autocorrelation c's */
51 double * ref) /* out: [0...p-1] reflection c's */
53 int i, m; double r, error = ac[0], G[2][P_MAX];
56 for (i = 0; i < P_MAX; i++) ref[i] = 0;
60 /* Initialize rows of the generator matrix G to ac[1...P]
62 for (i = 0; i < P_MAX; i++) G[0][i] = G[1][i] = ac[i+1];
66 /* Calculate this iteration's reflection
67 * coefficient and error.
69 ref[i] = r = -G[1][0] / error;
72 if (++i >= P_MAX) return error;
74 /* Update the generator matrix.
76 * Unlike the Levinson-Durbin summing of reflection
77 * coefficients, this loop could be distributed to
78 * p processors who each take only constant time.
80 for (m = 0; m < P_MAX - i; m++) {
81 G[1][m] = G[1][m+1] + r * G[0][m];
82 G[0][m] = G[1][m+1] * r + G[0][m];