comparison libtwamr/dtx_enc.c @ 407:5a1d18542f8a

libtwamr: integrate dtx_dec.c and dtx_enc.c
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 07 May 2024 00:05:12 +0000
parents
children
comparison
equal deleted inserted replaced
406:85e9768d497f 407:5a1d18542f8a
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 : dtx_enc.c
11 * Purpose : DTX mode computation of SID parameters
12 *
13 ********************************************************************************
14 */
15
16 /*
17 ********************************************************************************
18 * MODULE INCLUDE FILE AND VERSION ID
19 ********************************************************************************
20 */
21 #include "namespace.h"
22 #include "dtx_enc.h"
23
24 /*
25 ********************************************************************************
26 * INCLUDE FILES
27 ********************************************************************************
28 */
29 #include "tw_amr.h"
30 #include "typedef.h"
31 #include "basic_op.h"
32 #include "oper_32b.h"
33 #include "q_plsf.h"
34 #include "memops.h"
35 #include "log2.h"
36 #include "lsp_lsf.h"
37 #include "reorder.h"
38 #include "no_count.h"
39 #include "lsp_tab.h"
40
41 /*
42 ********************************************************************************
43 * PUBLIC PROGRAM CODE
44 ********************************************************************************
45 */
46
47 /*
48 **************************************************************************
49 *
50 * Function : dtx_enc_reset
51 *
52 **************************************************************************
53 */
54 void dtx_enc_reset (dtx_encState *st)
55 {
56 Word16 i;
57
58 st->hist_ptr = 0;
59 st->log_en_index = 0;
60 st->init_lsf_vq_index = 0;
61 st->lsp_index[0] = 0;
62 st->lsp_index[1] = 0;
63 st->lsp_index[2] = 0;
64
65 /* Init lsp_hist[] */
66 for(i = 0; i < DTX_HIST_SIZE; i++)
67 {
68 Copy(lsp_init_data, &st->lsp_hist[i * M], M);
69 }
70
71 /* Reset energy history */
72 Set_zero(st->log_en_hist, M);
73
74 st->dtxHangoverCount = DTX_HANG_CONST;
75 st->decAnaElapsedCount = 32767;
76 }
77
78 /*
79 **************************************************************************
80 *
81 * Function : dtx_enc
82 *
83 **************************************************************************
84 */
85 int dtx_enc(dtx_encState *st, /* i/o : State struct */
86 Word16 computeSidFlag, /* i : compute SID */
87 Q_plsfState *qSt, /* i/o : Qunatizer state struct */
88 gc_predState* predState, /* i/o : State struct */
89 Word16 **anap /* o : analysis parameters */
90 )
91 {
92 Word16 i,j;
93 Word16 log_en;
94 Word16 lsf[M];
95 Word16 lsp[M];
96 Word16 lsp_q[M];
97 Word32 L_lsp[M];
98
99 /* VOX mode computation of SID parameters */
100 test (); test ();
101 if ((computeSidFlag != 0))
102 {
103 /* compute new SID frame if safe i.e don't
104 * compute immediately after a talk spurt */
105 log_en = 0; move16 ();
106 for (i = 0; i < M; i++)
107 {
108 L_lsp[i] = 0; move16 ();
109 }
110
111 /* average energy and lsp */
112 for (i = 0; i < DTX_HIST_SIZE; i++)
113 {
114 log_en = add(log_en,
115 shr(st->log_en_hist[i],2));
116
117 for (j = 0; j < M; j++)
118 {
119 L_lsp[j] = L_add(L_lsp[j],
120 L_deposit_l(st->lsp_hist[i * M + j]));
121 }
122 }
123
124 log_en = shr(log_en, 1);
125 for (j = 0; j < M; j++)
126 {
127 lsp[j] = extract_l(L_shr(L_lsp[j], 3)); /* divide by 8 */
128 }
129
130 /* quantize logarithmic energy to 6 bits */
131 st->log_en_index = add(log_en, 2560); /* +2.5 in Q10 */
132 st->log_en_index = add(st->log_en_index, 128); /* add 0.5/4 in Q10 */
133 st->log_en_index = shr(st->log_en_index, 8);
134
135 test ();
136 if (sub(st->log_en_index, 63) > 0)
137 {
138 st->log_en_index = 63; move16 ();
139 }
140 test ();
141 if (st->log_en_index < 0)
142 {
143 st->log_en_index = 0; move16 ();
144 }
145
146 /* update gain predictor memory */
147 log_en = shl(st->log_en_index, -2+10); /* Q11 and divide by 4 */
148 log_en = sub(log_en, 2560); /* add 2.5 in Q11 */
149
150 log_en = sub(log_en, 9000);
151 test ();
152 if (log_en > 0)
153 {
154 log_en = 0; move16 ();
155 }
156 test ();
157 if (sub(log_en, -14436) < 0)
158 {
159 log_en = -14436; move16 ();
160 }
161
162 /* past_qua_en for other modes than MR122 */
163 predState->past_qua_en[0] = log_en; move16 ();
164 predState->past_qua_en[1] = log_en; move16 ();
165 predState->past_qua_en[2] = log_en; move16 ();
166 predState->past_qua_en[3] = log_en; move16 ();
167
168 /* scale down by factor 20*log10(2) in Q15 */
169 log_en = mult(5443, log_en);
170
171 /* past_qua_en for mode MR122 */
172 predState->past_qua_en_MR122[0] = log_en; move16 ();
173 predState->past_qua_en_MR122[1] = log_en; move16 ();
174 predState->past_qua_en_MR122[2] = log_en; move16 ();
175 predState->past_qua_en_MR122[3] = log_en; move16 ();
176
177 /* make sure that LSP's are ordered */
178 Lsp_lsf(lsp, lsf, M);
179 Reorder_lsf(lsf, LSF_GAP, M);
180 Lsf_lsp(lsf, lsp, M);
181
182 /* Quantize lsp and put on parameter list */
183 Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
184 &st->init_lsf_vq_index);
185 }
186
187 *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */ move16 ();
188
189 *(*anap)++ = st->lsp_index[0]; /* 8 bits */ move16 ();
190 *(*anap)++ = st->lsp_index[1]; /* 9 bits */ move16 ();
191 *(*anap)++ = st->lsp_index[2]; /* 9 bits */ move16 ();
192
193
194 *(*anap)++ = st->log_en_index; /* 6 bits */ move16 ();
195 /* = 35 bits */
196
197 return 0;
198 }
199
200 /*
201 **************************************************************************
202 *
203 * Function : dtx_buffer
204 * Purpose : handles the DTX buffer
205 *
206 **************************************************************************
207 */
208 int dtx_buffer(dtx_encState *st, /* i/o : State struct */
209 Word16 lsp_new[], /* i : LSP vector */
210 Word16 speech[] /* i : speech samples */
211 )
212 {
213 Word16 i;
214 Word32 L_frame_en;
215 Word16 log_en_e;
216 Word16 log_en_m;
217 Word16 log_en;
218
219 /* update pointer to circular buffer */
220 st->hist_ptr = add(st->hist_ptr, 1);
221 test ();
222 if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
223 {
224 st->hist_ptr = 0; move16 ();
225 }
226
227 /* copy lsp vector into buffer */
228 Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
229
230 /* compute log energy based on frame energy */
231 L_frame_en = 0; /* Q0 */ move32 ();
232 for (i=0; i < L_FRAME; i++)
233 {
234 L_frame_en = L_mac(L_frame_en, speech[i], speech[i]);
235 }
236 Log2(L_frame_en, &log_en_e, &log_en_m);
237
238 /* convert exponent and mantissa to Word16 Q10 */
239 log_en = shl(log_en_e, 10); /* Q10 */
240 log_en = add(log_en, shr(log_en_m, 15-10));
241
242 /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
243 log_en = sub(log_en, 8521);
244
245 /* insert into log energy buffer with division by 2 */
246 log_en = shr(log_en, 1);
247 st->log_en_hist[st->hist_ptr] = log_en; /* Q10 */ move16 ();
248
249 return 0;
250 }
251
252 /*
253 **************************************************************************
254 *
255 * Function : tx_dtx_handler
256 * Purpose : adds extra speech hangover to analyze speech on the decoding side.
257 *
258 **************************************************************************
259 */
260 Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */
261 Word16 vad_flag, /* i : vad decision */
262 enum Mode *usedMode /* i/o : mode changed or not */
263 )
264 {
265 Word16 compute_new_sid_possible;
266
267 /* this state machine is in synch with the GSMEFR txDtx machine */
268 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
269
270 compute_new_sid_possible = 0; move16();
271
272 test();
273 if (vad_flag != 0)
274 {
275 st->dtxHangoverCount = DTX_HANG_CONST; move16();
276 }
277 else
278 { /* non-speech */
279 test();
280 if (st->dtxHangoverCount == 0)
281 { /* out of decoder analysis hangover */
282 st->decAnaElapsedCount = 0; move16();
283 *usedMode = MRDTX; move16();
284 compute_new_sid_possible = 1; move16();
285 }
286 else
287 { /* in possible analysis hangover */
288 st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
289
290 /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
291 test ();
292 if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
293 DTX_ELAPSED_FRAMES_THRESH) < 0)
294 {
295 *usedMode = MRDTX; move16();
296 /* if short time since decoder update, do not add extra HO */
297 }
298 /*
299 else
300 override VAD and stay in
301 speech mode *usedMode
302 and add extra hangover
303 */
304 }
305 }
306
307 return compute_new_sid_possible;
308 }