annotate libtwamr/levinson.c @ 513:03a40ac2e931

libgsmhr1: implement validation for *.cod frames
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 25 Aug 2024 19:00:03 +0000
parents c713061b6edf
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }