FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/dtx_dec.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_dec.c | |
11 * Purpose : Decode comfort noise when in DTX | |
12 * | |
13 ***************************************************************************** | |
14 */ | |
15 /* | |
16 ***************************************************************************** | |
17 * MODULE INCLUDE FILE AND VERSION ID | |
18 ***************************************************************************** | |
19 */ | |
20 #include "namespace.h" | |
21 #include "dtx_dec.h" | |
22 | |
23 /* | |
24 ***************************************************************************** | |
25 * INCLUDE FILES | |
26 ***************************************************************************** | |
27 */ | |
28 #include "tw_amr.h" | |
29 #include "typedef.h" | |
30 #include "basic_op.h" | |
31 #include "oper_32b.h" | |
32 #include "memops.h" | |
33 #include "log2.h" | |
34 #include "lsp_az.h" | |
35 #include "pow2.h" | |
36 #include "a_refl.h" | |
37 #include "b_cn_cod.h" | |
38 #include "syn_filt.h" | |
39 #include "lsp_lsf.h" | |
40 #include "reorder.h" | |
41 #include "no_count.h" | |
42 #include "q_plsf5_tab.h" | |
43 #include "lsp_tab.h" | |
44 | |
45 /* | |
46 ***************************************************************************** | |
47 * LOCAL VARIABLES AND TABLES | |
48 ***************************************************************************** | |
49 */ | |
50 #define PN_INITIAL_SEED 0x70816958L /* Pseudo noise generator seed value */ | |
51 | |
52 /*************************************************** | |
53 * Scaling factors for the lsp variability operation * | |
54 ***************************************************/ | |
55 static const Word16 lsf_hist_mean_scale[M] = { | |
56 20000, | |
57 20000, | |
58 20000, | |
59 20000, | |
60 20000, | |
61 18000, | |
62 16384, | |
63 8192, | |
64 0, | |
65 0 | |
66 }; | |
67 | |
68 /************************************************* | |
69 * level adjustment for different modes Q11 * | |
70 *************************************************/ | |
71 static const Word16 dtx_log_en_adjust[9] = | |
72 { | |
73 -1023, /* MR475 */ | |
74 -878, /* MR515 */ | |
75 -732, /* MR59 */ | |
76 -586, /* MR67 */ | |
77 -440, /* MR74 */ | |
78 -294, /* MR795 */ | |
79 -148, /* MR102 */ | |
80 0, /* MR122 */ | |
81 0, /* MRDTX */ | |
82 }; | |
83 | |
84 /* | |
85 ***************************************************************************** | |
86 * PUBLIC PROGRAM CODE | |
87 ***************************************************************************** | |
88 */ | |
89 | |
90 /* | |
91 ************************************************************************** | |
92 * | |
93 * Function : dtx_dec_reset | |
94 * | |
95 ************************************************************************** | |
96 */ | |
97 void dtx_dec_reset (dtx_decState *st) | |
98 { | |
99 int i; | |
100 | |
101 st->since_last_sid = 0; | |
102 st->true_sid_period_inv = (1 << 13); | |
103 | |
104 st->log_en = 3500; | |
105 st->old_log_en = 3500; | |
106 /* low level noise for better performance in DTX handover cases*/ | |
107 | |
108 st->L_pn_seed_rx = PN_INITIAL_SEED; | |
109 | |
110 /* Initialize state->lsp [] and state->lsp_old [] */ | |
111 Copy(lsp_init_data, &st->lsp[0], M); | |
112 Copy(lsp_init_data, &st->lsp_old[0], M); | |
113 | |
114 st->lsf_hist_ptr = 0; | |
115 st->log_pg_mean = 0; | |
116 st->log_en_hist_ptr = 0; | |
117 | |
118 /* initialize decoder lsf history */ | |
119 Copy(mean_lsf, &st->lsf_hist[0], M); | |
120 | |
121 for (i = 1; i < DTX_HIST_SIZE; i++) | |
122 { | |
123 Copy(&st->lsf_hist[0], &st->lsf_hist[M*i], M); | |
124 } | |
125 Set_zero(st->lsf_hist_mean, M*DTX_HIST_SIZE); | |
126 | |
127 /* initialize decoder log frame energy */ | |
128 for (i = 0; i < DTX_HIST_SIZE; i++) | |
129 { | |
130 st->log_en_hist[i] = st->log_en; | |
131 } | |
132 | |
133 st->log_en_adjust = 0; | |
134 | |
135 st->dtxHangoverCount = DTX_HANG_CONST; | |
136 st->decAnaElapsedCount = 32767; | |
137 | |
138 st->sid_frame = 0; | |
139 st->valid_data = 0; | |
140 st->dtxHangoverAdded = 0; | |
141 | |
142 st->dtxGlobalState = DTX; | |
143 st->data_updated = 0; | |
144 } | |
145 | |
146 /* | |
147 ************************************************************************** | |
148 * | |
149 * Function : dtx_dec | |
150 * | |
151 ************************************************************************** | |
152 */ | |
153 int dtx_dec( | |
154 dtx_decState *st, /* i/o : State struct */ | |
155 Word16 mem_syn[], /* i/o : AMR decoder state */ | |
156 D_plsfState* lsfState, /* i/o : decoder lsf states */ | |
157 gc_predState* predState, /* i/o : prediction states */ | |
158 Cb_gain_averageState* averState, /* i/o : CB gain average states */ | |
159 enum DTXStateType new_state, /* i : new DTX state */ | |
160 enum Mode mode, /* i : AMR mode */ | |
161 Word16 parm[], /* i : Vector of synthesis parameters */ | |
162 Word16 synth[], /* o : synthesised speech */ | |
163 Word16 A_t[] /* o : decoded LP filter in 4 subframes*/ | |
164 ) | |
165 { | |
166 Word16 log_en_index; | |
167 Word16 i, j; | |
168 Word16 int_fac; | |
169 Word32 L_log_en_int; | |
170 Word16 lsp_int[M]; | |
171 Word16 log_en_int_e; | |
172 Word16 log_en_int_m; | |
173 Word16 level; | |
174 Word16 acoeff[M + 1]; | |
175 Word16 refl[M]; | |
176 Word16 pred_err; | |
177 Word16 ex[L_SUBFR]; | |
178 Word16 ma_pred_init; | |
179 Word16 log_pg_e, log_pg_m; | |
180 Word16 log_pg; | |
181 Flag negative; | |
182 Word16 lsf_mean; | |
183 Word32 L_lsf_mean; | |
184 Word16 lsf_variab_index; | |
185 Word16 lsf_variab_factor; | |
186 Word16 lsf_int[M]; | |
187 Word16 lsf_int_variab[M]; | |
188 Word16 lsp_int_variab[M]; | |
189 Word16 acoeff_variab[M + 1]; | |
190 | |
191 Word16 lsf[M]; | |
192 Word32 L_lsf[M]; | |
193 Word16 ptr; | |
194 Word16 tmp_int_length; | |
195 | |
196 | |
197 /* This function is called if synthesis state is not SPEECH | |
198 * the globally passed inputs to this function are | |
199 * st->sid_frame | |
200 * st->valid_data | |
201 * st->dtxHangoverAdded | |
202 * new_state (SPEECH, DTX, DTX_MUTE) | |
203 */ | |
204 | |
205 test(); test(); | |
206 if ((st->dtxHangoverAdded != 0) && | |
207 (st->sid_frame != 0)) | |
208 { | |
209 /* sid_first after dtx hangover period */ | |
210 /* or sid_upd after dtxhangover */ | |
211 | |
212 /* set log_en_adjust to correct value */ | |
213 st->log_en_adjust = dtx_log_en_adjust[mode]; | |
214 | |
215 ptr = add(st->lsf_hist_ptr, M); move16(); | |
216 test(); | |
217 if (sub(ptr, 80) == 0) | |
218 { | |
219 ptr = 0; move16(); | |
220 } | |
221 Copy( &st->lsf_hist[st->lsf_hist_ptr],&st->lsf_hist[ptr],M); | |
222 | |
223 ptr = add(st->log_en_hist_ptr,1); move16(); | |
224 test(); | |
225 if (sub(ptr, DTX_HIST_SIZE) == 0) | |
226 { | |
227 ptr = 0; move16(); | |
228 } | |
229 move16(); | |
230 st->log_en_hist[ptr] = st->log_en_hist[st->log_en_hist_ptr]; /* Q11 */ | |
231 | |
232 /* compute mean log energy and lsp * | |
233 * from decoded signal (SID_FIRST) */ | |
234 st->log_en = 0; move16(); | |
235 for (i = 0; i < M; i++) | |
236 { | |
237 L_lsf[i] = 0; move16(); | |
238 } | |
239 | |
240 /* average energy and lsp */ | |
241 for (i = 0; i < DTX_HIST_SIZE; i++) | |
242 { | |
243 st->log_en = add(st->log_en, | |
244 shr(st->log_en_hist[i],3)); | |
245 for (j = 0; j < M; j++) | |
246 { | |
247 L_lsf[j] = L_add(L_lsf[j], | |
248 L_deposit_l(st->lsf_hist[i * M + j])); | |
249 } | |
250 } | |
251 | |
252 for (j = 0; j < M; j++) | |
253 { | |
254 lsf[j] = extract_l(L_shr(L_lsf[j],3)); /* divide by 8 */ move16(); | |
255 } | |
256 | |
257 Lsf_lsp(lsf, st->lsp, M); | |
258 | |
259 /* make log_en speech coder mode independent */ | |
260 /* added again later before synthesis */ | |
261 st->log_en = sub(st->log_en, st->log_en_adjust); | |
262 | |
263 /* compute lsf variability vector */ | |
264 Copy(st->lsf_hist, st->lsf_hist_mean, 80); | |
265 | |
266 for (i = 0; i < M; i++) | |
267 { | |
268 L_lsf_mean = 0; move32(); | |
269 /* compute mean lsf */ | |
270 for (j = 0; j < 8; j++) | |
271 { | |
272 L_lsf_mean = L_add(L_lsf_mean, | |
273 L_deposit_l(st->lsf_hist_mean[i+j*M])); | |
274 } | |
275 | |
276 lsf_mean = extract_l(L_shr(L_lsf_mean, 3)); move16(); | |
277 /* subtract mean and limit to within reasonable limits * | |
278 * moreover the upper lsf's are attenuated */ | |
279 for (j = 0; j < 8; j++) | |
280 { | |
281 /* subtract mean */ | |
282 st->lsf_hist_mean[i+j*M] = | |
283 sub(st->lsf_hist_mean[i+j*M], lsf_mean); | |
284 | |
285 /* attenuate deviation from mean, especially for upper lsf's */ | |
286 st->lsf_hist_mean[i+j*M] = | |
287 mult(st->lsf_hist_mean[i+j*M], lsf_hist_mean_scale[i]); | |
288 | |
289 /* limit the deviation */ | |
290 test(); | |
291 if (st->lsf_hist_mean[i+j*M] < 0) | |
292 { | |
293 negative = 1; move16(); | |
294 } | |
295 else | |
296 { | |
297 negative = 0; move16(); | |
298 } | |
299 st->lsf_hist_mean[i+j*M] = abs_s(st->lsf_hist_mean[i+j*M]); | |
300 | |
301 /* apply soft limit */ | |
302 test(); | |
303 if (sub(st->lsf_hist_mean[i+j*M], 655) > 0) | |
304 { | |
305 st->lsf_hist_mean[i+j*M] = | |
306 add(655, shr(sub(st->lsf_hist_mean[i+j*M], 655), 2)); | |
307 } | |
308 | |
309 /* apply hard limit */ | |
310 test(); | |
311 if (sub(st->lsf_hist_mean[i+j*M], 1310) > 0) | |
312 { | |
313 st->lsf_hist_mean[i+j*M] = 1310; move16(); | |
314 } | |
315 test(); | |
316 if (negative != 0) | |
317 { | |
318 st->lsf_hist_mean[i+j*M] = -st->lsf_hist_mean[i+j*M];move16(); | |
319 } | |
320 | |
321 } | |
322 } | |
323 } | |
324 | |
325 test(); | |
326 if (st->sid_frame != 0 ) | |
327 { | |
328 /* Set old SID parameters, always shift */ | |
329 /* even if there is no new valid_data */ | |
330 Copy(st->lsp, st->lsp_old, M); | |
331 st->old_log_en = st->log_en; move16(); | |
332 | |
333 test(); | |
334 if (st->valid_data != 0 ) /* new data available (no CRC) */ | |
335 { | |
336 /* Compute interpolation factor, since the division only works * | |
337 * for values of since_last_sid < 32 we have to limit the * | |
338 * interpolation to 32 frames */ | |
339 tmp_int_length = st->since_last_sid; move16(); | |
340 st->since_last_sid = 0; move16(); | |
341 | |
342 test(); | |
343 if (sub(tmp_int_length, 32) > 0) | |
344 { | |
345 tmp_int_length = 32; move16(); | |
346 } | |
347 test(); | |
348 if (sub(tmp_int_length, 2) >= 0) | |
349 { | |
350 move16(); | |
351 st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); | |
352 } | |
353 else | |
354 { | |
355 st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */ move16(); | |
356 } | |
357 | |
358 Init_D_plsf_3(lsfState, parm[0]); /* temporay initialization */ | |
359 D_plsf_3(lsfState, MRDTX, 0, &parm[1], st->lsp); | |
360 Set_zero(lsfState->past_r_q, M); /* reset for next speech frame */ | |
361 | |
362 log_en_index = parm[4]; move16(); | |
363 /* Q11 and divide by 4 */ | |
364 st->log_en = shl(log_en_index, (11 - 2)); move16(); | |
365 | |
366 /* Subtract 2.5 in Q11 */ | |
367 st->log_en = sub(st->log_en, (2560 * 2)); | |
368 | |
369 /* Index 0 is reserved for silence */ | |
370 test(); | |
371 if (log_en_index == 0) | |
372 { | |
373 st->log_en = MIN_16; move16(); | |
374 } | |
375 | |
376 /* no interpolation at startup after coder reset */ | |
377 /* or when SID_UPD has been received right after SPEECH */ | |
378 test(); test(); | |
379 if ((st->data_updated == 0) || | |
380 (sub(st->dtxGlobalState, SPEECH) == 0) | |
381 ) | |
382 { | |
383 Copy(st->lsp, st->lsp_old, M); | |
384 st->old_log_en = st->log_en; move16(); | |
385 } | |
386 } /* endif valid_data */ | |
387 | |
388 /* initialize gain predictor memory of other modes */ | |
389 ma_pred_init = sub(shr(st->log_en,1), 9000); move16(); | |
390 test(); | |
391 if (ma_pred_init > 0) | |
392 { | |
393 ma_pred_init = 0; move16(); | |
394 } | |
395 test(); | |
396 if (sub(ma_pred_init, -14436) < 0) | |
397 { | |
398 ma_pred_init = -14436; move16(); | |
399 } | |
400 | |
401 predState->past_qua_en[0] = ma_pred_init; move16(); | |
402 predState->past_qua_en[1] = ma_pred_init; move16(); | |
403 predState->past_qua_en[2] = ma_pred_init; move16(); | |
404 predState->past_qua_en[3] = ma_pred_init; move16(); | |
405 | |
406 /* past_qua_en for other modes than MR122 */ | |
407 ma_pred_init = mult(5443, ma_pred_init); | |
408 /* scale down by factor 20*log10(2) in Q15 */ | |
409 predState->past_qua_en_MR122[0] = ma_pred_init; move16(); | |
410 predState->past_qua_en_MR122[1] = ma_pred_init; move16(); | |
411 predState->past_qua_en_MR122[2] = ma_pred_init; move16(); | |
412 predState->past_qua_en_MR122[3] = ma_pred_init; move16(); | |
413 } /* endif sid_frame */ | |
414 | |
415 /* CN generation */ | |
416 /* recompute level adjustment factor Q11 * | |
417 * st->log_en_adjust = 0.9*st->log_en_adjust + * | |
418 * 0.1*dtx_log_en_adjust[mode]); */ | |
419 move16(); | |
420 st->log_en_adjust = add(mult(st->log_en_adjust, 29491), | |
421 shr(mult(shl(dtx_log_en_adjust[mode],5),3277),5)); | |
422 | |
423 /* Interpolate SID info */ | |
424 int_fac = shl(add(1,st->since_last_sid), 10); /* Q10 */ move16(); | |
425 int_fac = mult(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */ | |
426 | |
427 /* Maximize to 1.0 in Q10 */ | |
428 test(); | |
429 if (sub(int_fac, 1024) > 0) | |
430 { | |
431 int_fac = 1024; move16(); | |
432 } | |
433 int_fac = shl(int_fac, 4); /* Q10 -> Q14 */ | |
434 | |
435 L_log_en_int = L_mult(int_fac, st->log_en); /* Q14 * Q11->Q26 */ move32(); | |
436 for(i = 0; i < M; i++) | |
437 { | |
438 lsp_int[i] = mult(int_fac, st->lsp[i]);/* Q14 * Q15 -> Q14 */ move16(); | |
439 } | |
440 | |
441 int_fac = sub(16384, int_fac); /* 1-k in Q14 */ move16(); | |
442 | |
443 /* (Q14 * Q11 -> Q26) + Q26 -> Q26 */ | |
444 L_log_en_int = L_mac(L_log_en_int, int_fac, st->old_log_en); | |
445 for(i = 0; i < M; i++) | |
446 { | |
447 /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */ | |
448 lsp_int[i] = add(lsp_int[i], mult(int_fac, st->lsp_old[i])); move16(); | |
449 lsp_int[i] = shl(lsp_int[i], 1); /* Q14 -> Q15 */ move16(); | |
450 } | |
451 | |
452 /* compute the amount of lsf variability */ | |
453 lsf_variab_factor = sub(st->log_pg_mean,2457); /* -0.6 in Q12 */ move16(); | |
454 /* *0.3 Q12*Q15 -> Q12 */ | |
455 lsf_variab_factor = sub(4096, mult(lsf_variab_factor, 9830)); | |
456 | |
457 /* limit to values between 0..1 in Q12 */ | |
458 test(); | |
459 if (sub(lsf_variab_factor, 4096) > 0) | |
460 { | |
461 lsf_variab_factor = 4096; move16(); | |
462 } | |
463 test(); | |
464 if (lsf_variab_factor < 0) | |
465 { | |
466 lsf_variab_factor = 0; move16(); | |
467 } | |
468 lsf_variab_factor = shl(lsf_variab_factor, 3); /* -> Q15 */ move16(); | |
469 | |
470 /* get index of vector to do variability with */ | |
471 lsf_variab_index = pseudonoise(&st->L_pn_seed_rx, 3); move16(); | |
472 | |
473 /* convert to lsf */ | |
474 Lsp_lsf(lsp_int, lsf_int, M); | |
475 | |
476 /* apply lsf variability */ | |
477 Copy(lsf_int, lsf_int_variab, M); | |
478 for(i = 0; i < M; i++) | |
479 { | |
480 move16(); | |
481 lsf_int_variab[i] = add(lsf_int_variab[i], | |
482 mult(lsf_variab_factor, | |
483 st->lsf_hist_mean[i+lsf_variab_index*M])); | |
484 } | |
485 | |
486 /* make sure that LSP's are ordered */ | |
487 Reorder_lsf(lsf_int, LSF_GAP, M); | |
488 Reorder_lsf(lsf_int_variab, LSF_GAP, M); | |
489 | |
490 /* copy lsf to speech decoders lsf state */ | |
491 Copy(lsf_int, lsfState->past_lsf_q, M); | |
492 | |
493 /* convert to lsp */ | |
494 Lsf_lsp(lsf_int, lsp_int, M); | |
495 Lsf_lsp(lsf_int_variab, lsp_int_variab, M); | |
496 | |
497 /* Compute acoeffs Q12 acoeff is used for level * | |
498 * normalization and postfilter, acoeff_variab is * | |
499 * used for synthesis filter * | |
500 * by doing this we make sure that the level * | |
501 * in high frequenncies does not jump up and down */ | |
502 | |
503 Lsp_Az(lsp_int, acoeff); | |
504 Lsp_Az(lsp_int_variab, acoeff_variab); | |
505 | |
506 /* For use in postfilter */ | |
507 Copy(acoeff, &A_t[0], M + 1); | |
508 Copy(acoeff, &A_t[M + 1], M + 1); | |
509 Copy(acoeff, &A_t[2 * (M + 1)], M + 1); | |
510 Copy(acoeff, &A_t[3 * (M + 1)], M + 1); | |
511 | |
512 /* Compute reflection coefficients Q15 */ | |
513 A_Refl(&acoeff[1], refl); | |
514 | |
515 /* Compute prediction error in Q15 */ | |
516 pred_err = MAX_16; /* 0.99997 in Q15 */ move16(); | |
517 for (i = 0; i < M; i++) | |
518 { | |
519 pred_err = mult(pred_err, sub(MAX_16, mult(refl[i], refl[i]))); | |
520 } | |
521 | |
522 /* compute logarithm of prediction gain */ | |
523 Log2(L_deposit_l(pred_err), &log_pg_e, &log_pg_m); | |
524 | |
525 /* convert exponent and mantissa to Word16 Q12 */ | |
526 log_pg = shl(sub(log_pg_e,15), 12); /* Q12 */ move16(); | |
527 log_pg = shr(sub(0,add(log_pg, shr(log_pg_m, 15-12))), 1); move16(); | |
528 st->log_pg_mean = add(mult(29491,st->log_pg_mean), | |
529 mult(3277, log_pg)); move16(); | |
530 | |
531 /* Compute interpolated log energy */ | |
532 L_log_en_int = L_shr(L_log_en_int, 10); /* Q26 -> Q16 */ move32(); | |
533 | |
534 /* Add 4 in Q16 */ | |
535 L_log_en_int = L_add(L_log_en_int, 4 * 65536L); move32(); | |
536 | |
537 /* subtract prediction gain */ | |
538 L_log_en_int = L_sub(L_log_en_int, L_shl(L_deposit_l(log_pg), 4));move32(); | |
539 | |
540 /* adjust level to speech coder mode */ | |
541 L_log_en_int = L_add(L_log_en_int, | |
542 L_shl(L_deposit_l(st->log_en_adjust), 5)); move32(); | |
543 | |
544 log_en_int_e = extract_h(L_log_en_int); move16(); | |
545 move16(); | |
546 log_en_int_m = extract_l(L_shr(L_sub(L_log_en_int, | |
547 L_deposit_h(log_en_int_e)), 1)); | |
548 level = extract_l(Pow2(log_en_int_e, log_en_int_m)); /* Q4 */ move16(); | |
549 | |
550 for (i = 0; i < 4; i++) | |
551 { | |
552 /* Compute innovation vector */ | |
553 build_CN_code(&st->L_pn_seed_rx, ex); | |
554 for (j = 0; j < L_SUBFR; j++) | |
555 { | |
556 ex[j] = mult(level, ex[j]); move16(); | |
557 } | |
558 /* Synthesize */ | |
559 Syn_filt(acoeff_variab, ex, &synth[i * L_SUBFR], L_SUBFR, | |
560 mem_syn, 1); | |
561 | |
562 } /* next i */ | |
563 | |
564 /* reset codebook averaging variables */ | |
565 averState->hangVar = 20; move16(); | |
566 averState->hangCount = 0; move16(); | |
567 | |
568 test(); | |
569 if (sub(new_state, DTX_MUTE) == 0) | |
570 { | |
571 /* mute comfort noise as it has been quite a long time since | |
572 * last SID update was performed */ | |
573 | |
574 tmp_int_length = st->since_last_sid; move16(); | |
575 test(); | |
576 if (sub(tmp_int_length, 32) > 0) | |
577 { | |
578 tmp_int_length = 32; move16(); | |
579 } | |
580 | |
581 /* safety guard against division by zero */ | |
582 test(); | |
583 if(tmp_int_length <= 0) { | |
584 tmp_int_length = 8; move16(); | |
585 } | |
586 | |
587 move16(); | |
588 st->true_sid_period_inv = div_s(1 << 10, shl(tmp_int_length, 10)); | |
589 | |
590 st->since_last_sid = 0; move16(); | |
591 Copy(st->lsp, st->lsp_old, M); | |
592 st->old_log_en = st->log_en; move16(); | |
593 /* subtract 1/8 in Q11 i.e -6/8 dB */ | |
594 st->log_en = sub(st->log_en, 256); move16(); | |
595 } | |
596 | |
597 /* reset interpolation length timer | |
598 * if data has been updated. */ | |
599 test(); test(); test(); test(); | |
600 if ((st->sid_frame != 0) && | |
601 ((st->valid_data != 0) || | |
602 ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0))) | |
603 { | |
604 st->since_last_sid = 0; move16(); | |
605 st->data_updated = 1; move16(); | |
606 } | |
607 | |
608 return 0; | |
609 } | |
610 | |
611 void dtx_dec_activity_update(dtx_decState *st, | |
612 Word16 lsf[], | |
613 Word16 frame[]) | |
614 { | |
615 Word16 i; | |
616 | |
617 Word32 L_frame_en; | |
618 Word16 log_en_e, log_en_m, log_en; | |
619 | |
620 /* update lsp history */ | |
621 st->lsf_hist_ptr = add(st->lsf_hist_ptr,M); move16(); | |
622 test(); | |
623 if (sub(st->lsf_hist_ptr, 80) == 0) | |
624 { | |
625 st->lsf_hist_ptr = 0; move16(); | |
626 } | |
627 Copy(lsf, &st->lsf_hist[st->lsf_hist_ptr], M); | |
628 | |
629 /* compute log energy based on frame energy */ | |
630 L_frame_en = 0; /* Q0 */ move32(); | |
631 for (i=0; i < L_FRAME; i++) | |
632 { | |
633 L_frame_en = L_mac(L_frame_en, frame[i], frame[i]); | |
634 } | |
635 Log2(L_frame_en, &log_en_e, &log_en_m); | |
636 | |
637 /* convert exponent and mantissa to Word16 Q10 */ | |
638 log_en = shl(log_en_e, 10); /* Q10 */ | |
639 log_en = add(log_en, shr(log_en_m, 15-10)); | |
640 | |
641 /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */ | |
642 log_en = sub(log_en, 7497+1024); | |
643 | |
644 /* insert into log energy buffer, no division by two as * | |
645 * log_en in decoder is Q11 */ | |
646 st->log_en_hist_ptr = add(st->log_en_hist_ptr, 1); | |
647 test(); | |
648 if (sub(st->log_en_hist_ptr, DTX_HIST_SIZE) == 0) | |
649 { | |
650 st->log_en_hist_ptr = 0; move16(); | |
651 } | |
652 st->log_en_hist[st->log_en_hist_ptr] = log_en; /* Q11 */ move16(); | |
653 } | |
654 | |
655 /* | |
656 Table of new SPD synthesis states | |
657 | |
658 | previous SPD_synthesis_state | |
659 Incoming | | |
660 frame_type | SPEECH | DTX | DTX_MUTE | |
661 --------------------------------------------------------------- | |
662 RX_SPEECH_GOOD , | | | | |
663 RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH | |
664 ---------------------------------------------------------------- | |
665 RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE | |
666 ---------------------------------------------------------------- | |
667 RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE | |
668 ---------------------------------------------------------------- | |
669 RX_SID_UPDATE, | DTX | DTX | DTX | |
670 ---------------------------------------------------------------- | |
671 RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE | |
672 ---------------------------------------------------------------- | |
673 RX_NO_DATA | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE | |
674 |(class2 garb.)| | | |
675 ---------------------------------------------------------------- | |
676 RX_ONSET | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE | |
677 |(class2 garb.)| | | |
678 ---------------------------------------------------------------- | |
679 */ | |
680 | |
681 enum DTXStateType rx_dtx_handler( | |
682 dtx_decState *st, /* i/o : State struct */ | |
683 enum RXFrameType frame_type /* i : Frame type */ | |
684 ) | |
685 { | |
686 enum DTXStateType newState; | |
687 enum DTXStateType encState; | |
688 | |
689 /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */ | |
690 test(); test(); test(); | |
691 test(); test(); test(); | |
692 test(); test(); | |
693 if ((sub(frame_type, RX_SID_FIRST) == 0) || | |
694 (sub(frame_type, RX_SID_UPDATE) == 0) || | |
695 (sub(frame_type, RX_SID_BAD) == 0) || | |
696 (((sub(st->dtxGlobalState, DTX) == 0) || | |
697 (sub(st->dtxGlobalState, DTX_MUTE) == 0)) && | |
698 ((sub(frame_type, RX_NO_DATA) == 0) || | |
699 (sub(frame_type, RX_SPEECH_BAD) == 0) || | |
700 (sub(frame_type, RX_ONSET) == 0)))) | |
701 { | |
702 newState = DTX; move16(); | |
703 | |
704 /* stay in mute for these input types */ | |
705 test(); test(); test(); test(); test(); | |
706 if ((sub(st->dtxGlobalState, DTX_MUTE) == 0) && | |
707 ((sub(frame_type, RX_SID_BAD) == 0) || | |
708 (sub(frame_type, RX_SID_FIRST) == 0) || | |
709 (sub(frame_type, RX_ONSET) == 0) || | |
710 (sub(frame_type, RX_NO_DATA) == 0))) | |
711 { | |
712 newState = DTX_MUTE; move16(); | |
713 } | |
714 | |
715 /* evaluate if noise parameters are too old */ | |
716 /* since_last_sid is reset when CN parameters have been updated */ | |
717 st->since_last_sid = add(st->since_last_sid, 1); move16(); | |
718 | |
719 /* no update of sid parameters in DTX for a long while */ | |
720 /* Due to the delayed update of st->since_last_sid counter | |
721 SID_UPDATE frames need to be handled separately to avoid | |
722 entering DTX_MUTE for late SID_UPDATE frames | |
723 */ | |
724 test(); test(); logic16(); | |
725 if((sub(frame_type, RX_SID_UPDATE) != 0) && | |
726 (sub(st->since_last_sid, DTX_MAX_EMPTY_THRESH) > 0)) | |
727 { | |
728 newState = DTX_MUTE; move16(); | |
729 } | |
730 } | |
731 else | |
732 { | |
733 newState = SPEECH; move16(); | |
734 st->since_last_sid = 0; move16(); | |
735 } | |
736 | |
737 /* | |
738 reset the decAnaElapsed Counter when receiving CNI data the first | |
739 time, to robustify counter missmatch after handover | |
740 this might delay the bwd CNI analysis in the new decoder slightly. | |
741 */ | |
742 test(); test(); | |
743 if ((st->data_updated == 0) && | |
744 (sub(frame_type, RX_SID_UPDATE) == 0)) | |
745 { | |
746 st->decAnaElapsedCount = 0; move16(); | |
747 } | |
748 | |
749 /* update the SPE-SPD DTX hangover synchronization */ | |
750 /* to know when SPE has added dtx hangover */ | |
751 st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1); move16(); | |
752 st->dtxHangoverAdded = 0; move16(); | |
753 | |
754 test(); test(); test(); test(); test(); | |
755 if ((sub(frame_type, RX_SID_FIRST) == 0) || | |
756 (sub(frame_type, RX_SID_UPDATE) == 0) || | |
757 (sub(frame_type, RX_SID_BAD) == 0) || | |
758 (sub(frame_type, RX_ONSET) == 0) || | |
759 (sub(frame_type, RX_NO_DATA) == 0)) | |
760 { | |
761 encState = DTX; move16(); | |
762 | |
763 /* | |
764 In frame errors simulations RX_NO_DATA may occasionally mean that | |
765 a speech packet was probably sent by the encoder, | |
766 the assumed _encoder_ state should be SPEECH in such cases. | |
767 */ | |
768 | |
769 test(); logic16(); | |
770 if((sub(frame_type, RX_NO_DATA) == 0) && | |
771 (sub(newState, SPEECH) == 0)) | |
772 { | |
773 encState = SPEECH; move16(); | |
774 } | |
775 | |
776 | |
777 /* Note on RX_ONSET operation differing from RX_NO_DATA operation: | |
778 If a RX_ONSET is received in the decoder (by "accident") | |
779 it is still most likely that the encoder state | |
780 for the "ONSET frame" was DTX. | |
781 */ | |
782 } | |
783 else | |
784 { | |
785 encState = SPEECH; move16(); | |
786 } | |
787 | |
788 test(); | |
789 if (sub(encState, SPEECH) == 0) | |
790 { | |
791 st->dtxHangoverCount = DTX_HANG_CONST; move16(); | |
792 } | |
793 else | |
794 { | |
795 test(); | |
796 if (sub(st->decAnaElapsedCount, DTX_ELAPSED_FRAMES_THRESH) > 0) | |
797 { | |
798 st->dtxHangoverAdded = 1; move16(); | |
799 st->decAnaElapsedCount = 0; move16(); | |
800 st->dtxHangoverCount = 0; move16(); | |
801 } | |
802 else if (test(), st->dtxHangoverCount == 0) | |
803 { | |
804 st->decAnaElapsedCount = 0; move16(); | |
805 } | |
806 else | |
807 { | |
808 st->dtxHangoverCount = sub(st->dtxHangoverCount, 1); move16(); | |
809 } | |
810 } | |
811 | |
812 if (sub(newState, SPEECH) != 0) | |
813 { | |
814 /* DTX or DTX_MUTE | |
815 * CN data is not in a first SID, first SIDs are marked as SID_BAD | |
816 * but will do backwards analysis if a hangover period has been added | |
817 * according to the state machine above | |
818 */ | |
819 | |
820 st->sid_frame = 0; move16(); | |
821 st->valid_data = 0; move16(); | |
822 | |
823 test(); | |
824 if (sub(frame_type, RX_SID_FIRST) == 0) | |
825 { | |
826 st->sid_frame = 1; move16(); | |
827 } | |
828 else if (test(), sub(frame_type, RX_SID_UPDATE) == 0) | |
829 { | |
830 st->sid_frame = 1; move16(); | |
831 st->valid_data = 1; move16(); | |
832 } | |
833 else if (test(), sub(frame_type, RX_SID_BAD) == 0) | |
834 { | |
835 st->sid_frame = 1; move16(); | |
836 st->dtxHangoverAdded = 0; /* use old data */ move16(); | |
837 } | |
838 } | |
839 | |
840 return newState; | |
841 /* newState is used by both SPEECH AND DTX synthesis routines */ | |
842 } |