• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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