FreeCalypso > hg > gsm-codec-lib
annotate libtwamr/levinson.c @ 468:4104b0390fab
efrtest: new program gsmefr-dlcap-sync
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 13 May 2024 07:21:09 +0000 |
parents | c713061b6edf |
children |
rev | line source |
---|---|
385
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
1 /* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
2 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
3 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
5 * R99 Version 3.3.0 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
6 * REL-4 Version 4.1.0 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
7 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
8 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
9 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
10 * File : levinson.c |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
11 * Purpose : Levinson-Durbin algorithm in double precision. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
12 * : To compute the LP filter parameters from the |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
13 * : speech autocorrelations. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
14 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
15 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
16 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
17 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
18 /* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
19 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
20 * MODULE INCLUDE FILE AND VERSION ID |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
21 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
22 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
23 #include "namespace.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
24 #include "levinson.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
25 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
26 /* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
27 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
28 * INCLUDE FILES |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
29 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
30 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
31 #include "typedef.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
32 #include "basic_op.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
33 #include "oper_32b.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
34 #include "no_count.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
35 #include "cnst.h" |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
36 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
37 /* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
38 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
39 * LOCAL VARIABLES AND TABLES |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
40 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
41 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
42 /*---------------------------------------------------------------* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
43 * Constants (defined in "cnst.h") * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
44 *---------------------------------------------------------------* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
45 * M : LPC order |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
46 *---------------------------------------------------------------*/ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
47 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
48 /* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
49 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
50 * PUBLIC PROGRAM CODE |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
51 ***************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
52 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
53 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
54 /************************************************************************* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
55 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
56 * Function: Levinson_reset |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
57 * Purpose: Initializes state memory to zero |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
58 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
59 ************************************************************************** |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
60 */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
61 void Levinson_reset (LevinsonState *state) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
62 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
63 Word16 i; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
64 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
65 state->old_A[0] = 4096; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
66 for(i = 1; i < M + 1; i++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
67 state->old_A[i] = 0; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
68 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
69 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
70 /************************************************************************* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
71 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
72 * FUNCTION: Levinson() |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
73 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
74 * PURPOSE: Levinson-Durbin algorithm in double precision. To compute the |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
75 * LP filter parameters from the speech autocorrelations. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
76 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
77 * DESCRIPTION: |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
78 * R[i] autocorrelations. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
79 * A[i] filter coefficients. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
80 * K reflection coefficients. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
81 * Alpha prediction gain. |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
82 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
83 * Initialisation: |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
84 * A[0] = 1 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
85 * K = -R[1]/R[0] |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
86 * A[1] = K |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
87 * Alpha = R[0] * (1-K**2] |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
88 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
89 * Do for i = 2 to M |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
90 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
91 * S = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
92 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
93 * K = -S / Alpha |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
94 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
95 * An[j] = A[j] + K*A[i-j] for j=1 to i-1 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
96 * where An[i] = new A[i] |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
97 * An[i]=K |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
98 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
99 * Alpha=Alpha * (1-K**2) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
100 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
101 * END |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
102 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
103 *************************************************************************/ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
104 int Levinson ( |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
105 LevinsonState *st, |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
106 Word16 Rh[], /* i : Rh[m+1] Vector of autocorrelations (msb) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
107 Word16 Rl[], /* i : Rl[m+1] Vector of autocorrelations (lsb) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
108 Word16 A[], /* o : A[m] LPC coefficients (m = 10) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
109 Word16 rc[] /* o : rc[4] First 4 reflection coefficients */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
110 ) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
111 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
112 Word16 i, j; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
113 Word16 hi, lo; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
114 Word16 Kh, Kl; /* reflexion coefficient; hi and lo */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
115 Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
116 Word16 Ah[M + 1], Al[M + 1]; /* LPC coef. in double prec. */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
117 Word16 Anh[M + 1], Anl[M + 1];/* LPC coef.for next iteration in double |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
118 prec. */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
119 Word32 t0, t1, t2; /* temporary variable */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
120 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
121 /* K = A[1] = -R[1] / R[0] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
122 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
123 t1 = L_Comp (Rh[1], Rl[1]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
124 t2 = L_abs (t1); /* abs R[1] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
125 t0 = Div_32 (t2, Rh[0], Rl[0]); /* R[1]/R[0] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
126 test (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
127 if (t1 > 0) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
128 t0 = L_negate (t0); /* -R[1]/R[0] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
129 L_Extract (t0, &Kh, &Kl); /* K in DPF */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
130 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
131 rc[0] = round (t0); move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
132 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
133 t0 = L_shr (t0, 4); /* A[1] in */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
134 L_Extract (t0, &Ah[1], &Al[1]); /* A[1] in DPF */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
135 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
136 /* Alpha = R[0] * (1-K**2) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
137 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
138 t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
139 t0 = L_abs (t0); /* Some case <0 !! */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
140 t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
141 L_Extract (t0, &hi, &lo); /* DPF format */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
142 t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
143 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
144 /* Normalize Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
145 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
146 alp_exp = norm_l (t0); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
147 t0 = L_shl (t0, alp_exp); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
148 L_Extract (t0, &alp_h, &alp_l); /* DPF format */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
149 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
150 /*--------------------------------------* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
151 * ITERATIONS I=2 to M * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
152 *--------------------------------------*/ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
153 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
154 for (i = 2; i <= M; i++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
155 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
156 /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) + R[i] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
157 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
158 t0 = 0; move32 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
159 for (j = 1; j < i; j++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
160 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
161 t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j])); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
162 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
163 t0 = L_shl (t0, 4); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
164 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
165 t1 = L_Comp (Rh[i], Rl[i]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
166 t0 = L_add (t0, t1); /* add R[i] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
167 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
168 /* K = -t0 / Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
169 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
170 t1 = L_abs (t0); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
171 t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
172 test (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
173 if (t0 > 0) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
174 t2 = L_negate (t2); /* K =-t0/Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
175 t2 = L_shl (t2, alp_exp); /* denormalize; compare to Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
176 L_Extract (t2, &Kh, &Kl); /* K in DPF */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
177 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
178 test (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
179 if (sub (i, 5) < 0) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
180 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
181 rc[i - 1] = round (t2); move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
182 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
183 /* Test for unstable filter. If unstable keep old A(z) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
184 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
185 test (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
186 if (sub (abs_s (Kh), 32750) > 0) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
187 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
188 for (j = 0; j <= M; j++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
189 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
190 A[j] = st->old_A[j]; move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
191 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
192 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
193 for (j = 0; j < 4; j++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
194 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
195 rc[j] = 0; move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
196 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
197 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
198 return 0; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
199 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
200 /*------------------------------------------* |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
201 * Compute new LPC coeff. -> An[i] * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
202 * An[j]= A[j] + K*A[i-j] , j=1 to i-1 * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
203 * An[i]= K * |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
204 *------------------------------------------*/ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
205 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
206 for (j = 1; j < i; j++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
207 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
208 t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
209 t0 = L_add(t0, L_Comp(Ah[j], Al[j])); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
210 L_Extract (t0, &Anh[j], &Anl[j]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
211 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
212 t2 = L_shr (t2, 4); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
213 L_Extract (t2, &Anh[i], &Anl[i]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
214 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
215 /* Alpha = Alpha * (1-K**2) */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
216 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
217 t0 = Mpy_32 (Kh, Kl, Kh, Kl); /* K*K */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
218 t0 = L_abs (t0); /* Some case <0 !! */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
219 t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
220 L_Extract (t0, &hi, &lo); /* DPF format */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
221 t0 = Mpy_32 (alp_h, alp_l, hi, lo); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
222 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
223 /* Normalize Alpha */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
224 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
225 j = norm_l (t0); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
226 t0 = L_shl (t0, j); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
227 L_Extract (t0, &alp_h, &alp_l); /* DPF format */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
228 alp_exp = add (alp_exp, j); /* Add normalization to |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
229 alp_exp */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
230 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
231 /* A[j] = An[j] */ |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
232 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
233 for (j = 1; j <= i; j++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
234 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
235 Ah[j] = Anh[j]; move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
236 Al[j] = Anl[j]; move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
237 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
238 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
239 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
240 A[0] = 4096; move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
241 for (i = 1; i <= M; i++) |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
242 { |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
243 t0 = L_Comp (Ah[i], Al[i]); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
244 st->old_A[i] = A[i] = round (L_shl (t0, 1));move16 (); move16 (); |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
245 } |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
246 |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
247 return 0; |
c713061b6edf
libtwamr: integrate levinson.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff
changeset
|
248 } |