comparison libtwamr/ec_gains.c @ 362:9cbd1b5d061f

libtwamr: integrate ec_gains.c
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 06 May 2024 02:08:43 +0000
parents
children
comparison
equal deleted inserted replaced
361:9aa554f8cf39 362:9cbd1b5d061f
1 /*
2 ********************************************************************************
3 *
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
5 * R99 Version 3.3.0
6 * REL-4 Version 4.1.0
7 *
8 ********************************************************************************
9 *
10 * File : ec_gains.c
11 * Purpose: : Error concealment for pitch and codebook gains
12 *
13 ********************************************************************************
14 */
15
16 /*
17 ********************************************************************************
18 * MODULE INCLUDE FILE AND VERSION ID
19 ********************************************************************************
20 */
21 #include "namespace.h"
22 #include "ec_gains.h"
23
24 /*
25 ********************************************************************************
26 * INCLUDE FILES
27 ********************************************************************************
28 */
29 #include "typedef.h"
30 #include "basic_op.h"
31 #include "oper_32b.h"
32 #include "no_count.h"
33 #include "cnst.h"
34 #include "gmed_n.h"
35 #include "gc_pred.h"
36 #include "gains_tab.h"
37
38 /*
39 ********************************************************************************
40 * PUBLIC PROGRAM CODE
41 ********************************************************************************
42 */
43
44 /*
45 **************************************************************************
46 *
47 * Function : ec_gain_code_reset
48 * Purpose : Resets state memory
49 *
50 **************************************************************************
51 */
52 void ec_gain_code_reset (ec_gain_codeState *state)
53 {
54 Word16 i;
55
56 for ( i = 0; i < 5; i++)
57 state->gbuf[i] = 1;
58 state->past_gain_code = 0;
59 state->prev_gc = 1;
60 }
61
62 /*
63 **************************************************************************
64 *
65 * Function : ec_gain_code
66 * Purpose : conceal the codebook gain
67 * Call this function only in BFI (instead of normal gain
68 * decoding function)
69 *
70 **************************************************************************
71 */
72 void ec_gain_code (
73 ec_gain_codeState *st, /* i/o : State struct */
74 gc_predState *pred_state, /* i/o : MA predictor state */
75 Word16 state, /* i : state of the state machine */
76 Word16 *gain_code /* o : decoded innovation gain */
77 )
78 {
79 static const Word16 cdown[7] =
80 {
81 32767, 32112, 32112, 32112,
82 32112, 32112, 22937
83 };
84
85 Word16 tmp;
86 Word16 qua_ener_MR122;
87 Word16 qua_ener;
88
89 /* calculate median of last five gain values */
90 tmp = gmed_n (st->gbuf,5); move16 ();
91
92 /* new gain = minimum(median, past_gain) * cdown[state] */
93 test ();
94 if (sub (tmp, st->past_gain_code) > 0)
95 {
96 tmp = st->past_gain_code; move16 ();
97 }
98 tmp = mult (tmp, cdown[state]);
99 *gain_code = tmp; move16 ();
100
101 /* update table of past quantized energies with average of
102 * current values
103 */
104 gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
105 gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
106 }
107
108 /*
109 **************************************************************************
110 *
111 * Function : ec_gain_code_update
112 * Purpose : update the codebook gain concealment state;
113 * limit gain_code if the previous frame was bad
114 * Call this function always after decoding (or concealing)
115 * the gain
116 *
117 **************************************************************************
118 */
119 void ec_gain_code_update (
120 ec_gain_codeState *st, /* i/o : State struct */
121 Word16 bfi, /* i : flag: frame is bad */
122 Word16 prev_bf, /* i : flag: previous frame was bad */
123 Word16 *gain_code /* i/o : decoded innovation gain */
124 )
125 {
126 Word16 i;
127
128 /* limit gain_code by previous good gain if previous frame was bad */
129 test ();
130 if (bfi == 0)
131 {
132 test ();
133 if (prev_bf != 0)
134 {
135 test ();
136 if (sub (*gain_code, st->prev_gc) > 0)
137 {
138 *gain_code = st->prev_gc; move16 ();
139 }
140 }
141 st->prev_gc = *gain_code; move16 ();
142 }
143
144 /* update EC states: previous gain, gain buffer */
145 st->past_gain_code = *gain_code; move16 ();
146
147 for (i = 1; i < 5; i++)
148 {
149 st->gbuf[i - 1] = st->gbuf[i]; move16 ();
150 }
151 st->gbuf[4] = *gain_code; move16 ();
152
153 return;
154 }
155
156 /*
157 **************************************************************************
158 *
159 * Function: ec_gain_pitch_reset
160 * Purpose: Resets state memory
161 *
162 **************************************************************************
163 */
164 void ec_gain_pitch_reset (ec_gain_pitchState *state)
165 {
166 Word16 i;
167
168 for(i = 0; i < 5; i++)
169 state->pbuf[i] = 1640;
170 state->past_gain_pit = 0;
171 state->prev_gp = 16384;
172 }
173
174 /*
175 **************************************************************************
176 *
177 * Function : ec_gain_pitch
178 * Purpose : conceal the pitch gain
179 * Call this function only in BFI (instead of normal gain
180 * decoding function)
181 *
182 **************************************************************************
183 */
184 void ec_gain_pitch (
185 ec_gain_pitchState *st, /* i/o : state variables */
186 Word16 state, /* i : state of the state machine */
187 Word16 *gain_pitch /* o : pitch gain (Q14) */
188 )
189 {
190 static const Word16 pdown[7] =
191 {
192 32767, 32112, 32112, 26214,
193 9830, 6553, 6553
194 };
195
196 Word16 tmp;
197
198 /* calculate median of last five gains */
199 tmp = gmed_n (st->pbuf, 5); move16 ();
200
201 /* new gain = minimum(median, past_gain) * pdown[state] */
202 test ();
203 if (sub (tmp, st->past_gain_pit) > 0)
204 {
205 tmp = st->past_gain_pit; move16 ();
206 }
207 *gain_pitch = mult (tmp, pdown[state]);
208 }
209
210 /*
211 **************************************************************************
212 *
213 * Function : ec_gain_pitch_update
214 * Purpose : update the pitch gain concealment state;
215 * limit gain_pitch if the previous frame was bad
216 * Call this function always after decoding (or concealing)
217 * the gain
218 *
219 **************************************************************************
220 */
221 void ec_gain_pitch_update (
222 ec_gain_pitchState *st, /* i/o : state variables */
223 Word16 bfi, /* i : flag: frame is bad */
224 Word16 prev_bf, /* i : flag: previous frame was bad */
225 Word16 *gain_pitch /* i/o : pitch gain */
226 )
227 {
228 Word16 i;
229
230 test ();
231 if (bfi == 0)
232 {
233 test ();
234 if (prev_bf != 0)
235 {
236 test ();
237 if (sub (*gain_pitch, st->prev_gp) > 0)
238 {
239 *gain_pitch = st->prev_gp;
240 }
241 }
242 st->prev_gp = *gain_pitch; move16 ();
243 }
244
245 st->past_gain_pit = *gain_pitch; move16 ();
246
247 test ();
248 if (sub (st->past_gain_pit, 16384) > 0) /* if (st->past_gain_pit > 1.0) */
249 {
250 st->past_gain_pit = 16384; move16 ();
251 }
252 for (i = 1; i < 5; i++)
253 {
254 st->pbuf[i - 1] = st->pbuf[i]; move16 ();
255 }
256 st->pbuf[4] = st->past_gain_pit; move16 ();
257 }