annotate libtwamr/levinson.c @ 581:e2d5cad04cbf

libgsmhr1 RxFE: store CN R0+LPC separately from speech In the original GSM 06.06 code the ECU for speech mode is entirely separate from the CN generator, maintaining separate state. (The main intertie between them is the speech vs CN state variable, distinguishing between speech and CN BFIs, in addition to the CN-specific function of distinguishing between initial and update SIDs.) In the present RxFE implementation I initially thought that we could use the same saved_frame buffer for both ECU and CN, overwriting just the first 4 params (R0 and LPC) when a valid SID comes in. However, I now realize it was a bad idea: the original code has a corner case (long sequence of speech-mode BFIs to put the ECU in state 6, then SID and CN-mode BFIs, then a good speech frame) that would be broken by that buffer reuse approach. We could eliminate this corner case by resetting the ECU state when passing through a CN insertion period, but doing so would needlessly increase the behavioral diffs between GSM 06.06 and our version. Solution: use a separate CN-specific buffer for CN R0+LPC parameters, and match the behavior of GSM 06.06 code in this regard.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Feb 2025 10:02:45 +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 }