1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
20
21 3GPP TS 26.173
22 ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23 Available from http://www.3gpp.org
24
25 (C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Filename: dtx_decoder_amr_wb.cpp
35
36 Date: 05/08/2007
37
38 ------------------------------------------------------------------------------
39 REVISION HISTORY
40
41
42 Description:
43
44 ------------------------------------------------------------------------------
45 INPUT AND OUTPUT DEFINITIONS
46
47
48 ------------------------------------------------------------------------------
49 FUNCTION DESCRIPTION
50
51 DTX functions
52
53 ------------------------------------------------------------------------------
54 REQUIREMENTS
55
56
57 ------------------------------------------------------------------------------
58 REFERENCES
59
60 ------------------------------------------------------------------------------
61 PSEUDO-CODE
62
63 ------------------------------------------------------------------------------
64 */
65
66
67 /*----------------------------------------------------------------------------
68 ; INCLUDES
69 ----------------------------------------------------------------------------*/
70
71 #include "pv_amr_wb_type_defs.h"
72 #include "pvamrwbdecoder_basic_op.h"
73 #include "pvamrwb_math_op.h"
74 #include "pvamrwbdecoder_cnst.h"
75 #include "pvamrwbdecoder_acelp.h" /* prototype of functions */
76 #include "get_amr_wb_bits.h"
77 #include "dtx.h"
78
79 /*----------------------------------------------------------------------------
80 ; MACROS
81 ; Define module specific macros here
82 ----------------------------------------------------------------------------*/
83
84
85 /*----------------------------------------------------------------------------
86 ; DEFINES
87 ; Include all pre-processor statements here. Include conditional
88 ; compile variables also.
89 ----------------------------------------------------------------------------*/
90
91 /*----------------------------------------------------------------------------
92 ; LOCAL FUNCTION DEFINITIONS
93 ; Function Prototype declaration
94 ----------------------------------------------------------------------------*/
95
96 /*----------------------------------------------------------------------------
97 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
98 ; Variable declaration - defined here and used outside this module
99 ----------------------------------------------------------------------------*/
100
101 /*----------------------------------------------------------------------------
102 ; EXTERNAL FUNCTION REFERENCES
103 ; Declare functions defined elsewhere and referenced in this module
104 ----------------------------------------------------------------------------*/
105
106 /*----------------------------------------------------------------------------
107 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
108 ; Declare variables used in this module but defined elsewhere
109 ----------------------------------------------------------------------------*/
110
111 /*----------------------------------------------------------------------------
112 ; FUNCTION CODE
113 ----------------------------------------------------------------------------*/
114 /*
115 * Function : dtx_dec_amr_wb_reset
116 */
dtx_dec_amr_wb_reset(dtx_decState * st,const int16 isf_init[])117 int16 dtx_dec_amr_wb_reset(dtx_decState * st, const int16 isf_init[])
118 {
119 int16 i;
120
121
122 if (st == (dtx_decState *) NULL)
123 {
124 /* dtx_dec_amr_wb_reset invalid parameter */
125 return (-1);
126 }
127 st->since_last_sid = 0;
128 st->true_sid_period_inv = (1 << 13); /* 0.25 in Q15 */
129
130 st->log_en = 3500;
131 st->old_log_en = 3500;
132 /* low level noise for better performance in DTX handover cases */
133
134 st->cng_seed = RANDOM_INITSEED;
135
136 st->hist_ptr = 0;
137
138 /* Init isf_hist[] and decoder log frame energy */
139 pv_memcpy((void *)st->isf, (void *)isf_init, M*sizeof(*isf_init));
140
141 pv_memcpy((void *)st->isf_old, (void *)isf_init, M*sizeof(*isf_init));
142
143 for (i = 0; i < DTX_HIST_SIZE; i++)
144 {
145 pv_memcpy((void *)&st->isf_hist[i * M], (void *)isf_init, M*sizeof(*isf_init));
146 st->log_en_hist[i] = st->log_en;
147 }
148
149 st->dtxHangoverCount = DTX_HANG_CONST;
150 st->decAnaElapsedCount = 32767;
151
152 st->sid_frame = 0;
153 st->valid_data = 0;
154 st->dtxHangoverAdded = 0;
155
156 st->dtxGlobalState = SPEECH;
157 st->data_updated = 0;
158
159 st->dither_seed = RANDOM_INITSEED;
160 st->CN_dith = 0;
161
162 return 0;
163 }
164
165
166 /*
167 Table of new SPD synthesis states
168
169 | previous SPD_synthesis_state
170 Incoming |
171 frame_type | SPEECH | DTX | DTX_MUTE
172 ---------------------------------------------------------------
173 RX_SPEECH_GOOD , | | |
174 RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH
175 ----------------------------------------------------------------
176 RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE
177 ----------------------------------------------------------------
178 RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE
179 ----------------------------------------------------------------
180 RX_SID_UPDATE, | DTX | DTX | DTX
181 ----------------------------------------------------------------
182 RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE
183 ----------------------------------------------------------------
184 RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE
185 RX_SPARE |(class2 garb.)| |
186 ----------------------------------------------------------------
187 */
188
189 /*----------------------------------------------------------------------------
190 ; FUNCTION CODE
191 ----------------------------------------------------------------------------*/
192
193 /*
194 * Function : dtx_dec_amr_wb
195 */
dtx_dec_amr_wb(dtx_decState * st,int16 * exc2,int16 new_state,int16 isf[],int16 ** prms)196 int16 dtx_dec_amr_wb(
197 dtx_decState * st, /* i/o : State struct */
198 int16 * exc2, /* o : CN excitation */
199 int16 new_state, /* i : New DTX state */
200 int16 isf[], /* o : CN ISF vector */
201 int16 ** prms
202 )
203 {
204 int16 log_en_index;
205 int16 ind[7];
206 int16 i, j;
207 int16 int_fac;
208 int16 gain;
209
210 int32 L_isf[M], L_log_en_int, level32, ener32;
211 int16 ptr;
212 int16 tmp_int_length;
213 int16 tmp, exp, exp0, log_en_int_e, log_en_int_m, level;
214
215 /* This function is called if synthesis state is not SPEECH the globally passed inputs to this function
216 * are st->sid_frame st->valid_data st->dtxHangoverAdded new_state (SPEECH, DTX, DTX_MUTE) */
217
218 if ((st->dtxHangoverAdded != 0) &&
219 (st->sid_frame != 0))
220 {
221 /* sid_first after dtx hangover period */
222 /* or sid_upd after dtxhangover */
223
224 /* consider twice the last frame */
225 ptr = st->hist_ptr + 1;
226
227 if (ptr == DTX_HIST_SIZE)
228 ptr = 0;
229
230 pv_memcpy((void *)&st->isf_hist[ptr * M], (void *)&st->isf_hist[st->hist_ptr * M], M*sizeof(*st->isf_hist));
231
232 st->log_en_hist[ptr] = st->log_en_hist[st->hist_ptr];
233
234 /* compute mean log energy and isf from decoded signal (SID_FIRST) */
235 st->log_en = 0;
236 for (i = 0; i < M; i++)
237 {
238 L_isf[i] = 0;
239 }
240
241 /* average energy and isf */
242 for (i = 0; i < DTX_HIST_SIZE; i++)
243 {
244 /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer log_en is in Q10 */
245 st->log_en = add_int16(st->log_en, st->log_en_hist[i]);
246
247 for (j = 0; j < M; j++)
248 {
249 L_isf[j] = add_int32(L_isf[j], (int32)(st->isf_hist[i * M + j]));
250 }
251 }
252
253 /* st->log_en in Q9 */
254 st->log_en >>= 1;
255
256 /* Add 2 in Q9, in order to have only positive values for Pow2 */
257 /* this value is subtracted back after Pow2 function */
258 st->log_en += 1024;
259
260 if (st->log_en < 0)
261 st->log_en = 0;
262
263 for (j = 0; j < M; j++)
264 {
265 st->isf[j] = (int16)(L_isf[j] >> 3); /* divide by 8 */
266 }
267
268 }
269
270 if (st->sid_frame != 0)
271 {
272 /* Set old SID parameters, always shift */
273 /* even if there is no new valid_data */
274
275 pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
276
277 st->old_log_en = st->log_en;
278
279 if (st->valid_data != 0) /* new data available (no CRC) */
280 {
281 /* st->true_sid_period_inv = 1.0f/st->since_last_sid; */
282 /* Compute interpolation factor, since the division only works * for values of since_last_sid <
283 * 32 we have to limit the * interpolation to 32 frames */
284 tmp_int_length = st->since_last_sid;
285
286
287 if (tmp_int_length > 32)
288 {
289 tmp_int_length = 32;
290 }
291
292 if (tmp_int_length >= 2)
293 {
294 st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
295 }
296 else
297 {
298 st->true_sid_period_inv = 1 << 14; /* 0.5 it Q15 */
299 }
300
301 ind[0] = Serial_parm(6, prms);
302 ind[1] = Serial_parm(6, prms);
303 ind[2] = Serial_parm(6, prms);
304 ind[3] = Serial_parm(5, prms);
305 ind[4] = Serial_parm(5, prms);
306
307 Disf_ns(ind, st->isf);
308
309 log_en_index = Serial_parm(6, prms);
310
311 /* read background noise stationarity information */
312 st->CN_dith = Serial_parm_1bit(prms);
313
314 /* st->log_en = (float)log_en_index / 2.625 - 2.0; */
315 /* log2(E) in Q9 (log2(E) lies in between -2:22) */
316 st->log_en = shl_int16(log_en_index, 15 - 6);
317
318 /* Divide by 2.625 */
319 st->log_en = mult_int16(st->log_en, 12483);
320 /* Subtract 2 in Q9 is done later, after Pow2 function */
321
322 /* no interpolation at startup after coder reset */
323 /* or when SID_UPD has been received right after SPEECH */
324
325 if ((st->data_updated == 0) || (st->dtxGlobalState == SPEECH))
326 {
327 pv_memcpy((void *)st->isf_old, (void *)st->isf, M*sizeof(*st->isf));
328
329 st->old_log_en = st->log_en;
330 }
331 } /* endif valid_data */
332 } /* endif sid_frame */
333
334
335 if ((st->sid_frame != 0) && (st->valid_data != 0))
336 {
337 st->since_last_sid = 0;
338 }
339 /* Interpolate SID info */
340 int_fac = shl_int16(st->since_last_sid, 10); /* Q10 */
341 int_fac = mult_int16(int_fac, st->true_sid_period_inv); /* Q10 * Q15 -> Q10 */
342
343 /* Maximize to 1.0 in Q10 */
344
345 if (int_fac > 1024)
346 {
347 int_fac = 1024;
348 }
349 int_fac = shl_int16(int_fac, 4); /* Q10 -> Q14 */
350
351 L_log_en_int = mul_16by16_to_int32(int_fac, st->log_en); /* Q14 * Q9 -> Q24 */
352
353 for (i = 0; i < M; i++)
354 {
355 isf[i] = mult_int16(int_fac, st->isf[i]);/* Q14 * Q15 -> Q14 */
356 }
357
358 int_fac = 16384 - int_fac; /* 1-k in Q14 */
359
360 /* ( Q14 * Q9 -> Q24 ) + Q24 -> Q24 */
361 L_log_en_int = mac_16by16_to_int32(L_log_en_int, int_fac, st->old_log_en);
362
363 for (i = 0; i < M; i++)
364 {
365 /* Q14 + (Q14 * Q15 -> Q14) -> Q14 */
366 isf[i] = add_int16(isf[i], mult_int16(int_fac, st->isf_old[i]));
367 isf[i] = shl_int16(isf[i], 1); /* Q14 -> Q15 */
368 }
369
370 /* If background noise is non-stationary, insert comfort noise dithering */
371 if (st->CN_dith != 0)
372 {
373 CN_dithering(isf, &L_log_en_int, &st->dither_seed);
374 }
375 /* L_log_en_int corresponds to log2(E)+2 in Q24, i.e log2(gain)+1 in Q25 */
376 /* Q25 -> Q16 */
377 L_log_en_int >>= 9;
378
379 /* Find integer part */
380 log_en_int_e = extract_h(L_log_en_int);
381
382 /* Find fractional part */
383 log_en_int_m = (int16)(sub_int32(L_log_en_int, L_deposit_h(log_en_int_e)) >> 1);
384
385 /* Subtract 2 from L_log_en_int in Q9, i.e divide the gain by 2 (energy by 4) */
386 /* Add 16 in order to have the result of pow2 in Q16 */
387 log_en_int_e += 15;
388
389 /* level = (float)( pow( 2.0f, log_en ) ); */
390 level32 = power_of_2(log_en_int_e, log_en_int_m); /* Q16 */
391
392 exp0 = normalize_amr_wb(level32);
393 level32 <<= exp0; /* level in Q31 */
394 exp0 = 15 - exp0;
395 level = (int16)(level32 >> 16); /* level in Q15 */
396
397 /* generate white noise vector */
398 for (i = 0; i < L_FRAME; i++)
399 {
400 exc2[i] = noise_gen_amrwb(&(st->cng_seed)) >> 4;
401 }
402
403 /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
404
405 /* energy of generated excitation */
406 ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
407
408 one_ov_sqrt_norm(&ener32, &exp);
409
410 gain = extract_h(ener32);
411
412 gain = mult_int16(level, gain); /* gain in Q15 */
413
414 exp += exp0;
415
416 /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
417 exp += 4;
418
419 for (i = 0; i < L_FRAME; i++)
420 {
421 tmp = mult_int16(exc2[i], gain); /* Q0 * Q15 */
422 exc2[i] = shl_int16(tmp, exp);
423 }
424
425
426 if (new_state == DTX_MUTE)
427 {
428 /* mute comfort noise as it has been quite a long time since last SID update was performed */
429
430 tmp_int_length = st->since_last_sid;
431
432 if (tmp_int_length > 32)
433 {
434 tmp_int_length = 32;
435 }
436
437 st->true_sid_period_inv = div_16by16(1 << 10, shl_int16(tmp_int_length, 10));
438
439 st->since_last_sid = 0;
440 st->old_log_en = st->log_en;
441 /* subtract 1/8 in Q9 (energy), i.e -3/8 dB */
442 st->log_en -= 64;
443 }
444 /* reset interpolation length timer if data has been updated. */
445
446 if ((st->sid_frame != 0) &&
447 ((st->valid_data != 0) ||
448 ((st->valid_data == 0) && (st->dtxHangoverAdded) != 0)))
449 {
450 st->since_last_sid = 0;
451 st->data_updated = 1;
452 }
453 return 0;
454 }
455
456
457 /*----------------------------------------------------------------------------
458 ; FUNCTION CODE
459 ----------------------------------------------------------------------------*/
460
dtx_dec_amr_wb_activity_update(dtx_decState * st,int16 isf[],int16 exc[])461 void dtx_dec_amr_wb_activity_update(
462 dtx_decState * st,
463 int16 isf[],
464 int16 exc[])
465 {
466 int16 i;
467
468 int32 L_frame_en;
469 int16 log_en_e, log_en_m, log_en;
470
471
472 st->hist_ptr++;
473
474 if (st->hist_ptr == DTX_HIST_SIZE)
475 {
476 st->hist_ptr = 0;
477 }
478 pv_memcpy((void *)&st->isf_hist[st->hist_ptr * M], (void *)isf, M*sizeof(*isf));
479
480
481 /* compute log energy based on excitation frame energy in Q0 */
482 L_frame_en = 0;
483 for (i = 0; i < L_FRAME; i++)
484 {
485 L_frame_en = mac_16by16_to_int32(L_frame_en, exc[i], exc[i]);
486 }
487 L_frame_en >>= 1;
488
489 /* log_en = (float)log10(L_frame_en/(float)L_FRAME)/(float)log10(2.0f); */
490 amrwb_log_2(L_frame_en, &log_en_e, &log_en_m);
491
492 /* convert exponent and mantissa to int16 Q7. Q7 is used to simplify averaging in dtx_enc */
493 log_en = shl_int16(log_en_e, 7); /* Q7 */
494 log_en += log_en_m >> 8;
495
496 /* Divide by L_FRAME = 256, i.e subtract 8 in Q7 = 1024 */
497 log_en -= 1024;
498
499 /* insert into log energy buffer */
500 st->log_en_hist[st->hist_ptr] = log_en;
501
502 return;
503 }
504
505
506 /*
507 Table of new SPD synthesis states
508
509 | previous SPD_synthesis_state
510 Incoming |
511 frame_type | SPEECH | DTX | DTX_MUTE
512 ---------------------------------------------------------------
513 RX_SPEECH_GOOD , | | |
514 RX_SPEECH_PR_DEGRADED | SPEECH | SPEECH | SPEECH
515 ----------------------------------------------------------------
516 RX_SPEECH_BAD, | SPEECH | DTX | DTX_MUTE
517 ----------------------------------------------------------------
518 RX_SID_FIRST, | DTX | DTX/(DTX_MUTE)| DTX_MUTE
519 ----------------------------------------------------------------
520 RX_SID_UPDATE, | DTX | DTX | DTX
521 ----------------------------------------------------------------
522 RX_SID_BAD, | DTX | DTX/(DTX_MUTE)| DTX_MUTE
523 ----------------------------------------------------------------
524 RX_NO_DATA, | SPEECH | DTX/(DTX_MUTE)| DTX_MUTE
525 RX_SPARE |(class2 garb.)| |
526 ----------------------------------------------------------------
527 */
528
529
530 /*----------------------------------------------------------------------------
531 ; FUNCTION CODE
532 ----------------------------------------------------------------------------*/
533
rx_amr_wb_dtx_handler(dtx_decState * st,int16 frame_type)534 int16 rx_amr_wb_dtx_handler(
535 dtx_decState * st, /* i/o : State struct */
536 int16 frame_type /* i : Frame type */
537 )
538 {
539 int16 newState;
540 int16 encState;
541
542 /* DTX if SID frame or previously in DTX{_MUTE} and (NO_RX OR BAD_SPEECH) */
543
544
545
546 if ((frame_type == RX_SID_FIRST) ||
547 (frame_type == RX_SID_UPDATE) ||
548 (frame_type == RX_SID_BAD) ||
549 (((st->dtxGlobalState == DTX) ||
550 (st->dtxGlobalState == DTX_MUTE)) &&
551 ((frame_type == RX_NO_DATA) ||
552 (frame_type == RX_SPEECH_BAD) ||
553 (frame_type == RX_SPEECH_LOST))))
554 {
555 newState = DTX;
556
557 /* stay in mute for these input types */
558
559 if ((st->dtxGlobalState == DTX_MUTE) &&
560 ((frame_type == RX_SID_BAD) ||
561 (frame_type == RX_SID_FIRST) ||
562 (frame_type == RX_SPEECH_LOST) ||
563 (frame_type == RX_NO_DATA)))
564 {
565 newState = DTX_MUTE;
566 }
567 /* evaluate if noise parameters are too old */
568 /* since_last_sid is reset when CN parameters have been updated */
569 st->since_last_sid = add_int16(st->since_last_sid, 1);
570
571 /* no update of sid parameters in DTX for a long while */
572
573 if (st->since_last_sid > DTX_MAX_EMPTY_THRESH)
574 {
575 newState = DTX_MUTE;
576 }
577 }
578 else
579 {
580 newState = SPEECH;
581 st->since_last_sid = 0;
582 }
583
584 /* reset the decAnaElapsed Counter when receiving CNI data the first time, to robustify counter missmatch
585 * after handover this might delay the bwd CNI analysis in the new decoder slightly. */
586
587 if ((st->data_updated == 0) &&
588 (frame_type == RX_SID_UPDATE))
589 {
590 st->decAnaElapsedCount = 0;
591 }
592 /* update the SPE-SPD DTX hangover synchronization */
593 /* to know when SPE has added dtx hangover */
594 st->decAnaElapsedCount = add_int16(st->decAnaElapsedCount, 1);
595 st->dtxHangoverAdded = 0;
596
597
598 if ((frame_type == RX_SID_FIRST) ||
599 (frame_type == RX_SID_UPDATE) ||
600 (frame_type == RX_SID_BAD) ||
601 (frame_type == RX_NO_DATA))
602 {
603 encState = DTX;
604 }
605 else
606 {
607 encState = SPEECH;
608 }
609
610
611 if (encState == SPEECH)
612 {
613 st->dtxHangoverCount = DTX_HANG_CONST;
614 }
615 else
616 {
617
618 if (st->decAnaElapsedCount > DTX_ELAPSED_FRAMES_THRESH)
619 {
620 st->dtxHangoverAdded = 1;
621 st->decAnaElapsedCount = 0;
622 st->dtxHangoverCount = 0;
623 }
624 else if (st->dtxHangoverCount == 0)
625 {
626 st->decAnaElapsedCount = 0;
627 }
628 else
629 {
630 st->dtxHangoverCount--;
631 }
632 }
633
634 if (newState != SPEECH)
635 {
636 /* DTX or DTX_MUTE CN data is not in a first SID, first SIDs are marked as SID_BAD but will do
637 * backwards analysis if a hangover period has been added according to the state machine above */
638
639 st->sid_frame = 0;
640 st->valid_data = 0;
641
642
643 if (frame_type == RX_SID_FIRST)
644 {
645 st->sid_frame = 1;
646 }
647 else if (frame_type == RX_SID_UPDATE)
648 {
649 st->sid_frame = 1;
650 st->valid_data = 1;
651 }
652 else if (frame_type == RX_SID_BAD)
653 {
654 st->sid_frame = 1;
655 st->dtxHangoverAdded = 0; /* use old data */
656 }
657 }
658 return newState;
659 /* newState is used by both SPEECH AND DTX synthesis routines */
660 }
661
662
663 /*----------------------------------------------------------------------------
664 ; FUNCTION CODE
665 ----------------------------------------------------------------------------*/
666
aver_isf_history(int16 isf_old[],int16 indices[],int32 isf_aver[])667 void aver_isf_history(
668 int16 isf_old[],
669 int16 indices[],
670 int32 isf_aver[]
671 )
672 {
673 int16 i, j, k;
674 int16 isf_tmp[2 * M];
675 int32 L_tmp;
676
677 /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
678 /* the median ISF vector prior to the averaging */
679 for (k = 0; k < 2; k++)
680 {
681
682 if (indices[k] + 1 != 0)
683 {
684 for (i = 0; i < M; i++)
685 {
686 isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
687 isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
688 }
689 }
690 }
691
692 /* Perform the ISF averaging */
693 for (j = 0; j < M; j++)
694 {
695 L_tmp = 0;
696
697 for (i = 0; i < DTX_HIST_SIZE; i++)
698 {
699 L_tmp = add_int32(L_tmp, (int32)(isf_old[i * M + j]));
700 }
701 isf_aver[j] = L_tmp;
702 }
703
704 /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
705 for (k = 0; k < 2; k++)
706 {
707
708 if (indices[k] + 1 != 0)
709 {
710 for (i = 0; i < M; i++)
711 {
712 isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
713 }
714 }
715 }
716
717 return;
718 }
719
720
721 /*----------------------------------------------------------------------------
722 ; FUNCTION CODE
723 ----------------------------------------------------------------------------*/
724
find_frame_indices(int16 isf_old_tx[],int16 indices[],dtx_encState * st)725 void find_frame_indices(
726 int16 isf_old_tx[],
727 int16 indices[],
728 dtx_encState * st
729 )
730 {
731 int32 L_tmp, summin, summax, summax2nd;
732 int16 i, j, tmp;
733 int16 ptr;
734
735 /* Remove the effect of the oldest frame from the column */
736 /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */
737 /* not updated since it will be removed later. */
738
739 tmp = DTX_HIST_SIZE_MIN_ONE;
740 j = -1;
741 for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
742 {
743 j += tmp;
744 st->sumD[i] = sub_int32(st->sumD[i], st->D[j]);
745 tmp--;
746 }
747
748 /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */
749 /* corresponding to the oldest frame is removed. The sum of */
750 /* the distances between the latest isf and other isfs, */
751 /* i.e. the element sumD[0], will be computed during this call. */
752 /* Hence this element is initialized to zero. */
753
754 for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
755 {
756 st->sumD[i] = st->sumD[i - 1];
757 }
758 st->sumD[0] = 0;
759
760 /* Remove the oldest frame from the distance matrix. */
761 /* Note that the distance matrix is replaced by a one- */
762 /* dimensional array to save static memory. */
763
764 tmp = 0;
765 for (i = 27; i >= 12; i -= tmp)
766 {
767 tmp++;
768 for (j = tmp; j > 0; j--)
769 {
770 st->D[i - j + 1] = st->D[i - j - tmp];
771 }
772 }
773
774 /* Compute the first column of the distance matrix D */
775 /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
776
777 ptr = st->hist_ptr;
778 for (i = 1; i < DTX_HIST_SIZE; i++)
779 {
780 /* Compute the distance between the latest isf and the other isfs. */
781 ptr--;
782
783 if (ptr < 0)
784 {
785 ptr = DTX_HIST_SIZE_MIN_ONE;
786 }
787 L_tmp = 0;
788 for (j = 0; j < M; j++)
789 {
790 tmp = sub_int16(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
791 L_tmp = mac_16by16_to_int32(L_tmp, tmp, tmp);
792 }
793 st->D[i - 1] = L_tmp;
794
795 /* Update also the column sums. */
796 st->sumD[0] = add_int32(st->sumD[0], st->D[i - 1]);
797 st->sumD[i] = add_int32(st->sumD[i], st->D[i - 1]);
798 }
799
800 /* Find the minimum and maximum distances */
801 summax = st->sumD[0];
802 summin = st->sumD[0];
803 indices[0] = 0;
804 indices[2] = 0;
805 for (i = 1; i < DTX_HIST_SIZE; i++)
806 {
807
808 if (st->sumD[i] > summax)
809 {
810 indices[0] = i;
811 summax = st->sumD[i];
812 }
813
814 if (st->sumD[i] < summin)
815 {
816 indices[2] = i;
817 summin = st->sumD[i];
818 }
819 }
820
821 /* Find the second largest distance */
822 summax2nd = -2147483647L;
823 indices[1] = -1;
824 for (i = 0; i < DTX_HIST_SIZE; i++)
825 {
826
827 if ((st->sumD[i] > summax2nd) && (i != indices[0]))
828 {
829 indices[1] = i;
830 summax2nd = st->sumD[i];
831 }
832 }
833
834 for (i = 0; i < 3; i++)
835 {
836 indices[i] = sub_int16(st->hist_ptr, indices[i]);
837
838 if (indices[i] < 0)
839 {
840 indices[i] = add_int16(indices[i], DTX_HIST_SIZE);
841 }
842 }
843
844 /* If maximum distance/MED_THRESH is smaller than minimum distance */
845 /* then the median ISF vector replacement is not performed */
846 tmp = normalize_amr_wb(summax);
847 summax <<= tmp;
848 summin <<= tmp;
849 L_tmp = mul_16by16_to_int32(amr_wb_round(summax), INV_MED_THRESH);
850
851 if (L_tmp <= summin)
852 {
853 indices[0] = -1;
854 }
855 /* If second largest distance/MED_THRESH is smaller than */
856 /* minimum distance then the median ISF vector replacement is */
857 /* not performed */
858 summax2nd = shl_int32(summax2nd, tmp);
859 L_tmp = mul_16by16_to_int32(amr_wb_round(summax2nd), INV_MED_THRESH);
860
861 if (L_tmp <= summin)
862 {
863 indices[1] = -1;
864 }
865 return;
866 }
867
868
869 /*----------------------------------------------------------------------------
870 ; FUNCTION CODE
871 ----------------------------------------------------------------------------*/
872
dithering_control(dtx_encState * st)873 int16 dithering_control(dtx_encState * st)
874 {
875 int16 i, tmp, mean, CN_dith, gain_diff;
876 int32 ISF_diff;
877
878 /* determine how stationary the spectrum of background noise is */
879 ISF_diff = 0;
880 for (i = 0; i < 8; i++)
881 {
882 ISF_diff = add_int32(ISF_diff, st->sumD[i]);
883 }
884 if ((ISF_diff >> 26) > 0)
885 {
886 CN_dith = 1;
887 }
888 else
889 {
890 CN_dith = 0;
891 }
892
893 /* determine how stationary the energy of background noise is */
894 mean = 0;
895 for (i = 0; i < DTX_HIST_SIZE; i++)
896 {
897 mean = add_int16(mean, st->log_en_hist[i]);
898 }
899 mean >>= 3;
900 gain_diff = 0;
901 for (i = 0; i < DTX_HIST_SIZE; i++)
902 {
903 tmp = sub_int16(st->log_en_hist[i], mean);
904 tmp = tmp - (tmp < 0);
905
906 gain_diff += tmp ^(tmp >> 15); /* tmp ^sign(tmp) */;
907 }
908 if (gain_diff > GAIN_THR)
909 {
910 CN_dith = 1;
911 }
912 return CN_dith;
913 }
914
915
916 /*----------------------------------------------------------------------------
917 ; FUNCTION CODE
918 ----------------------------------------------------------------------------*/
919
CN_dithering(int16 isf[M],int32 * L_log_en_int,int16 * dither_seed)920 void CN_dithering(
921 int16 isf[M],
922 int32 * L_log_en_int,
923 int16 * dither_seed
924 )
925 {
926 int16 temp, temp1, i, dither_fac, rand_dith;
927 int16 rand_dith2;
928
929 /* Insert comfort noise dithering for energy parameter */
930 rand_dith = noise_gen_amrwb(dither_seed) >> 1;
931 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
932 rand_dith += rand_dith2;
933 *L_log_en_int = add_int32(*L_log_en_int, mul_16by16_to_int32(rand_dith, GAIN_FACTOR));
934
935 if (*L_log_en_int < 0)
936 {
937 *L_log_en_int = 0;
938 }
939 /* Insert comfort noise dithering for spectral parameters (ISF-vector) */
940 dither_fac = ISF_FACTOR_LOW;
941
942 rand_dith = noise_gen_amrwb(dither_seed) >> 1;
943 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
944 rand_dith += rand_dith2;
945 temp = add_int16(isf[0], mult_int16_r(rand_dith, dither_fac));
946
947 /* Make sure that isf[0] will not get negative values */
948 if (temp < ISF_GAP)
949 {
950 isf[0] = ISF_GAP;
951 }
952 else
953 {
954 isf[0] = temp;
955 }
956
957 for (i = 1; i < M - 1; i++)
958 {
959 dither_fac = add_int16(dither_fac, ISF_FACTOR_STEP);
960
961 rand_dith = noise_gen_amrwb(dither_seed) >> 1;
962 rand_dith2 = noise_gen_amrwb(dither_seed) >> 1;
963 rand_dith += rand_dith2;
964 temp = add_int16(isf[i], mult_int16_r(rand_dith, dither_fac));
965 temp1 = sub_int16(temp, isf[i - 1]);
966
967 /* Make sure that isf spacing remains at least ISF_DITH_GAP Hz */
968 if (temp1 < ISF_DITH_GAP)
969 {
970 isf[i] = isf[i - 1] + ISF_DITH_GAP;
971 }
972 else
973 {
974 isf[i] = temp;
975 }
976 }
977
978 /* Make sure that isf[M-2] will not get values above 16384 */
979 if (isf[M - 2] > 16384)
980 {
981 isf[M - 2] = 16384;
982 }
983 return;
984 }
985