xref: /aosp_15_r20/frameworks/av/media/module/codecs/amrnb/enc/src/dtx_enc.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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.073
22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23     Available from http://www.3gpp.org
24 
25 (C) 2004, 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  Pathname: ./audio/gsm-amr/c/src/dtx_enc.c
35  Funtions: dtx_enc_init
36            dtx_enc_reset
37            dtx_enc_exit
38            dtx_enc
39            dtx_buffer
40            tx_dtx_handler
41 
42      Date: 06/08/2000
43 
44 ------------------------------------------------------------------------------
45  REVISION HISTORY
46 
47  Description: Updated template used to PV coding template. First attempt at
48           optimizing C code.
49 
50  Description: Updated file per comments gathered from Phase 2/3 review.
51           Synched up with new template (Inputs/Outputs section). Deleted
52           lines leftover from original code prior to the code section of
53           dtx_enc_exit function. Deleted confusing comment in the log_en
54           calculation in dtx_enc function. Restructured IF statement in
55           the calculation of the sum of squares of speech signals in
56           dtx_buffer.
57 
58  Description: Added setting of Overflow flag in inlined code.
59 
60  Description: Synchronized file with UTMS version 3.2.0. Updated coding
61               template. Removed unnecessary include files.
62 
63  Description: Made the following changes per comments from Phase 2/3 review:
64               1. Modified FOR loops to count down.
65               2. Fixed typecasting issue with TI C compiler.
66               3. Fixed comment in dtx_enc pseudo-code.
67               4. Added dtx_enc code comment pertaining to possible assembly
68                  implementation.
69 
70  Description: Added calls to add() in tx_dtx_handler. Updated copyright year.
71 
72  Description: Pass in pointer to overflow flag to all functions requiring this
73               flag. This is to make the library EPOC compatible.
74 
75  Description:  For dtx_enc_reset() only
76               1. Replaced copy() with memcpy.
77               2. Eliminated include file copy.h
78               3. Eliminated printf statement
79               For dtx_buffer()
80               1. Replaced copy() with memcpy.
81               2. Eliminated math operations that unnecessary checked for
82                  saturation, in some cases this by shifting before adding and
83                  in other cases by evaluating the operands
84               3. Unrolled loop to speed up execution
85 
86  Description:  For dtx_buffer()
87               1. Modified scaling and added check for saturation. Previous
88                  scaling was correct but altered precision, this cause bit
89                  exactness test failure.
90 
91  Description:  For dtx_buffer()
92               1. Modified scaling and saturation checks. Previous
93                  scaling was correct but altered precision, this cause bit
94                  exactness test failure for dtx vad2.
95 
96  Description:  Replaced OSCL mem type functions and eliminated include
97                files that now are chosen by OSCL definitions
98 
99  Description:  Replaced "int" and/or "char" with OSCL defined types.
100 
101  Description:
102 
103 ------------------------------------------------------------------------------
104  MODULE DESCRIPTION
105 
106  This file contains the various functions that perform the computation of the
107  Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX)
108  mode.
109 
110 ------------------------------------------------------------------------------
111 */
112 
113 
114 /*----------------------------------------------------------------------------
115 ; INCLUDES
116 ----------------------------------------------------------------------------*/
117 #include <stdlib.h>
118 #include <string.h>
119 
120 #include "dtx_enc.h"
121 #include "q_plsf.h"
122 #include "typedef.h"
123 #include "mode.h"
124 #include "basic_op.h"
125 #include "log2.h"
126 #include "lsp_lsf.h"
127 #include "reorder.h"
128 
129 /*----------------------------------------------------------------------------
130 ; MACROS
131 ; Define module specific macros here
132 ----------------------------------------------------------------------------*/
133 extern Word32 L_add(Word32 L_var1, Word32 L_var2, Flag *pOverflow);
134 
135 /*----------------------------------------------------------------------------
136 ; DEFINES
137 ; Include all pre-processor statements here. Include conditional
138 ; compile variables also.
139 ----------------------------------------------------------------------------*/
140 
141 /*----------------------------------------------------------------------------
142 ; LOCAL FUNCTION DEFINITIONS
143 ; Function Prototype declaration
144 ----------------------------------------------------------------------------*/
145 
146 /*----------------------------------------------------------------------------
147 ; LOCAL VARIABLE DEFINITIONS
148 ; Variable declaration - defined here and used outside this module
149 ----------------------------------------------------------------------------*/
150 
151 
152 /*
153 ------------------------------------------------------------------------------
154  FUNCTION NAME: dtx_enc_init
155 ------------------------------------------------------------------------------
156  INPUT AND OUTPUT DEFINITIONS
157 
158  Inputs:
159     st = pointer to an array of pointers to structures of type
160          dtx_encState
161 
162  Outputs:
163     pointer pointed to by st is set to the address of the allocated
164       memory
165 
166  Returns:
167     return_value = 0, if initialization was successful; -1, otherwise (int)
168 
169  Global Variables Used:
170     None
171 
172  Local Variables Needed:
173     None
174 
175 ------------------------------------------------------------------------------
176  FUNCTION DESCRIPTION
177 
178  This function allocates the state memory used by the dtx_enc function.
179 
180 ------------------------------------------------------------------------------
181  REQUIREMENTS
182 
183  None
184 
185 ------------------------------------------------------------------------------
186  REFERENCES
187 
188  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
189 
190 ------------------------------------------------------------------------------
191  PSEUDO-CODE
192 
193 int dtx_enc_init (dtx_encState **st)
194 {
195   dtx_encState* s;
196 
197   if (st == (dtx_encState **) NULL){
198     fprintf(stderr, "dtx_enc_init: invalid parameter\n");
199     return -1;
200   }
201 
202   *st = NULL;
203 
204   // allocate memory
205   if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){
206     fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
207     return -1;
208   }
209 
210   dtx_enc_reset(s);
211   *st = s;
212 
213   return 0;
214 }
215 
216 ------------------------------------------------------------------------------
217  RESOURCES USED [optional]
218 
219  When the code is written for a specific target processor the
220  the resources used should be documented below.
221 
222  HEAP MEMORY USED: x bytes
223 
224  STACK MEMORY USED: x bytes
225 
226  CLOCK CYCLES: (cycle count equation for this function) + (variable
227                 used to represent cycle count for each subroutine
228                 called)
229      where: (cycle count variable) = cycle count for [subroutine
230                                      name]
231 
232 ------------------------------------------------------------------------------
233  CAUTION [optional]
234  [State any special notes, constraints or cautions for users of this function]
235 
236 ------------------------------------------------------------------------------
237 */
238 
dtx_enc_init(dtx_encState ** st)239 Word16 dtx_enc_init(dtx_encState **st)
240 {
241     dtx_encState* s;
242 
243     if (st == (dtx_encState **) NULL)
244     {
245         return(-1);
246     }
247 
248     *st = NULL;
249 
250     /* allocate memory */
251     if ((s = (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL)
252     {
253         return(-1);
254     }
255 
256     dtx_enc_reset(s);
257     *st = s;
258 
259     return(0);
260 }
261 
262 /****************************************************************************/
263 
264 /*
265 ------------------------------------------------------------------------------
266  FUNCTION NAME: dtx_enc_reset
267 ------------------------------------------------------------------------------
268  INPUT AND OUTPUT DEFINITIONS
269 
270  Inputs:
271     st = pointer to structures of type dtx_encState
272 
273  Outputs:
274     structure pointed to by st is initialized to its reset value
275 
276  Returns:
277     return_value = 1, if reset was successful; -1, otherwise (int)
278 
279  Global Variables Used:
280     None
281 
282  Local Variables Needed:
283     lsp_init_data = table containing LSP initialization values;
284             table elements are constants of type Word16;
285             table length is M
286 
287 ------------------------------------------------------------------------------
288  FUNCTION DESCRIPTION
289 
290  This function initializes the fields of the state memory used by dtx_enc
291  to their reset values.
292 
293 ------------------------------------------------------------------------------
294  REQUIREMENTS
295 
296  None
297 
298 ------------------------------------------------------------------------------
299  REFERENCES
300 
301  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
302 
303 ------------------------------------------------------------------------------
304  PSEUDO-CODE
305 
306 int dtx_enc_reset (dtx_encState *st)
307 {
308   Word16 i;
309 
310   if (st == (dtx_encState *) NULL){
311     fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
312     return -1;
313   }
314 
315   st->hist_ptr = 0;
316   st->log_en_index = 0;
317   st->init_lsf_vq_index = 0;
318   st->lsp_index[0] = 0;
319   st->lsp_index[1] = 0;
320   st->lsp_index[2] = 0;
321 
322   // Init lsp_hist[]
323   for(i = 0; i < DTX_HIST_SIZE; i++)
324   {
325     Copy(lsp_init_data, &st->lsp_hist[i * M], M);
326   }
327 
328   // Reset energy history
329   Set_zero(st->log_en_hist, M);
330 
331   st->dtxHangoverCount = DTX_HANG_CONST;
332   st->decAnaElapsedCount = 32767;
333 
334   return 1;
335 }
336 
337 ------------------------------------------------------------------------------
338  RESOURCES USED [optional]
339 
340  When the code is written for a specific target processor the
341  the resources used should be documented below.
342 
343  HEAP MEMORY USED: x bytes
344 
345  STACK MEMORY USED: x bytes
346 
347  CLOCK CYCLES: (cycle count equation for this function) + (variable
348                 used to represent cycle count for each subroutine
349                 called)
350      where: (cycle count variable) = cycle count for [subroutine
351                                      name]
352 
353 ------------------------------------------------------------------------------
354  CAUTION [optional]
355  [State any special notes, constraints or cautions for users of this function]
356 
357 ------------------------------------------------------------------------------
358 */
359 
dtx_enc_reset(dtx_encState * st)360 Word16 dtx_enc_reset(dtx_encState *st)
361 {
362     Word16 i;
363 
364     if (st == (dtx_encState *) NULL)
365     {
366         return(-1);
367     }
368 
369     st->hist_ptr = 0;
370     st->log_en_index = 0;
371     st->init_lsf_vq_index = 0;
372     st->lsp_index[0] = 0;
373     st->lsp_index[1] = 0;
374     st->lsp_index[2] = 0;
375 
376     /* Init lsp_hist[] */
377     for (i = 0; i < DTX_HIST_SIZE; i++)
378     {
379         memcpy(&st->lsp_hist[i * M], lsp_init_data, M*sizeof(Word16));
380     }
381 
382     /* Reset energy history */
383     memset(st->log_en_hist, 0, sizeof(Word16)*M);
384     st->dtxHangoverCount = DTX_HANG_CONST;
385     st->decAnaElapsedCount = 32767;
386 
387     return(1);
388 }
389 
390 /****************************************************************************/
391 
392 /*
393 ------------------------------------------------------------------------------
394  FUNCTION NAME: dtx_enc_exit
395 ------------------------------------------------------------------------------
396  INPUT AND OUTPUT DEFINITIONS
397 
398  Inputs:
399     st = pointer to an array of pointers to structures of type
400          dtx_encState
401 
402  Outputs:
403     st points to the NULL address
404 
405  Returns:
406     None
407 
408  Global Variables Used:
409     None
410 
411  Local Variables Needed:
412     None
413 
414 ------------------------------------------------------------------------------
415  FUNCTION DESCRIPTION
416 
417  This function deallocates the state memory used by dtx_enc function.
418 
419 ------------------------------------------------------------------------------
420  REQUIREMENTS
421 
422  None
423 
424 ------------------------------------------------------------------------------
425  REFERENCES
426 
427  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
428 
429 ------------------------------------------------------------------------------
430  PSEUDO-CODE
431 
432 void dtx_enc_exit (dtx_encState **st)
433 {
434    if (st == NULL || *st == NULL)
435       return;
436 
437    // deallocate memory
438    free(*st);
439    *st = NULL;
440 
441    return;
442 }
443 
444 ------------------------------------------------------------------------------
445  RESOURCES USED [optional]
446 
447  When the code is written for a specific target processor the
448  the resources used should be documented below.
449 
450  HEAP MEMORY USED: x bytes
451 
452  STACK MEMORY USED: x bytes
453 
454  CLOCK CYCLES: (cycle count equation for this function) + (variable
455                 used to represent cycle count for each subroutine
456                 called)
457      where: (cycle count variable) = cycle count for [subroutine
458                                      name]
459 
460 ------------------------------------------------------------------------------
461  CAUTION [optional]
462  [State any special notes, constraints or cautions for users of this function]
463 
464 ------------------------------------------------------------------------------
465 */
466 
dtx_enc_exit(dtx_encState ** st)467 void dtx_enc_exit(dtx_encState **st)
468 {
469     if (st == NULL || *st == NULL)
470     {
471         return;
472     }
473 
474     /* deallocate memory */
475     free(*st);
476     *st = NULL;
477 
478     return;
479 }
480 
481 /****************************************************************************/
482 
483 /*
484 ------------------------------------------------------------------------------
485  FUNCTION NAME: dtx_enc
486 ------------------------------------------------------------------------------
487  INPUT AND OUTPUT DEFINITIONS
488 
489  Inputs:
490     st = pointer to structures of type dtx_encState
491     computeSidFlag = compute SID flag of type Word16
492     qSt = pointer to structures of type Q_plsfState
493     predState = pointer to structures of type gc_predState
494     anap = pointer to an array of pointers to analysis parameters of
495            type Word16
496 
497  Outputs:
498     structure pointed to by st contains the newly calculated SID
499       parameters
500     structure pointed to by predState contains the new logarithmic frame
501       energy
502     pointer pointed to by anap points to the location of the new
503       logarithmic frame energy and new LSPs
504 
505  Returns:
506     return_value = 0 (int)
507 
508  Global Variables Used:
509     None
510 
511  Local Variables Needed:
512     None
513 
514 ------------------------------------------------------------------------------
515  FUNCTION DESCRIPTION
516 
517  This function calculates the SID parameters when in the DTX mode.
518 
519 ------------------------------------------------------------------------------
520  REQUIREMENTS
521 
522  None
523 
524 ------------------------------------------------------------------------------
525  REFERENCES
526 
527  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
528 
529 ------------------------------------------------------------------------------
530  PSEUDO-CODE
531 
532 int dtx_enc(dtx_encState *st,        // i/o : State struct
533             Word16 computeSidFlag,   // i   : compute SID
534             Q_plsfState *qSt,        // i/o : Qunatizer state struct
535             gc_predState* predState, // i/o : State struct
536         Word16 **anap            // o   : analysis parameters
537         )
538 {
539    Word16 i,j;
540    Word16 log_en;
541    Word16 lsf[M];
542    Word16 lsp[M];
543    Word16 lsp_q[M];
544    Word32 L_lsp[M];
545 
546    // VOX mode computation of SID parameters
547    if ((computeSidFlag != 0)  ||
548         (st->log_en_index == 0))
549    {
550       // compute new SID frame if safe i.e don't
551       // compute immediately after a talk spurt
552       log_en = 0;
553       for (i = 0; i < M; i++)
554       {
555          L_lsp[i] = 0;
556       }
557 
558       // average energy and lsp
559       for (i = 0; i < DTX_HIST_SIZE; i++)
560       {
561          log_en = add(log_en,
562                       shr(st->log_en_hist[i],2));
563 
564          for (j = 0; j < M; j++)
565          {
566             L_lsp[j] = L_add(L_lsp[j],
567                              L_deposit_l(st->lsp_hist[i * M + j]));
568          }
569       }
570 
571       log_en = shr(log_en, 1);
572       for (j = 0; j < M; j++)
573       {
574          lsp[j] = extract_l(L_shr(L_lsp[j], 3));   // divide by 8
575       }
576 
577       //  quantize logarithmic energy to 6 bits
578       st->log_en_index = add(log_en, 2560);          // +2.5 in Q10
579       st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10
580       st->log_en_index = shr(st->log_en_index, 8);
581 
582       if (sub(st->log_en_index, 63) > 0)
583       {
584          st->log_en_index = 63;
585       }
586       if (st->log_en_index < 0)
587       {
588          st->log_en_index = 0;
589       }
590 
591       // update gain predictor memory
592       log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4
593       log_en = sub(log_en, 2560);            // add 2.5 in Q11
594 
595       log_en = sub(log_en, 9000);
596       if (log_en > 0)
597       {
598          log_en = 0;
599       }
600       if (sub(log_en, -14436) < 0)
601       {
602          log_en = -14436;
603       }
604 
605       // past_qua_en for other modes than MR122
606       predState->past_qua_en[0] = log_en;
607       predState->past_qua_en[1] = log_en;
608       predState->past_qua_en[2] = log_en;
609       predState->past_qua_en[3] = log_en;
610 
611       // scale down by factor 20*log10(2) in Q15
612       log_en = mult(5443, log_en);
613 
614       // past_qua_en for mode MR122
615       predState->past_qua_en_MR122[0] = log_en;
616       predState->past_qua_en_MR122[1] = log_en;
617       predState->past_qua_en_MR122[2] = log_en;
618       predState->past_qua_en_MR122[3] = log_en;
619 
620       // make sure that LSP's are ordered
621       Lsp_lsf(lsp, lsf, M);
622       Reorder_lsf(lsf, LSF_GAP, M);
623       Lsf_lsp(lsf, lsp, M);
624 
625       // Quantize lsp and put on parameter list
626       Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
627                &st->init_lsf_vq_index);
628    }
629 
630    *(*anap)++ = st->init_lsf_vq_index; // 3 bits
631 
632    *(*anap)++ = st->lsp_index[0];      // 8 bits
633    *(*anap)++ = st->lsp_index[1];      // 9 bits
634    *(*anap)++ = st->lsp_index[2];      // 9 bits
635 
636 
637    *(*anap)++ = st->log_en_index;      // 6 bits
638                                        // = 35 bits
639 
640    return 0;
641 }
642 
643 ------------------------------------------------------------------------------
644  RESOURCES USED [optional]
645 
646  When the code is written for a specific target processor the
647  the resources used should be documented below.
648 
649  HEAP MEMORY USED: x bytes
650 
651  STACK MEMORY USED: x bytes
652 
653  CLOCK CYCLES: (cycle count equation for this function) + (variable
654                 used to represent cycle count for each subroutine
655                 called)
656      where: (cycle count variable) = cycle count for [subroutine
657                                      name]
658 
659 ------------------------------------------------------------------------------
660  CAUTION [optional]
661  [State any special notes, constraints or cautions for users of this function]
662 
663 ------------------------------------------------------------------------------
664 */
665 
dtx_enc(dtx_encState * st,Word16 computeSidFlag,Q_plsfState * qSt,gc_predState * predState,Word16 ** anap,Flag * pOverflow)666 void dtx_enc(dtx_encState *st,        /* i/o : State struct                  */
667              Word16 computeSidFlag,   /* i   : compute SID                   */
668              Q_plsfState *qSt,        /* i/o : Qunatizer state struct        */
669              gc_predState* predState, /* i/o : State struct                  */
670              Word16 **anap,           /* o   : analysis parameters           */
671              Flag   *pOverflow        /* i/o : overflow indicator            */
672             )
673 {
674     Word16 i, j;
675     Word16 temp;
676     Word16 log_en;
677     Word16 lsf[M];
678     Word16 lsp[M];
679     Word16 lsp_q[M];
680     Word32 L_lsp[M];
681 
682     /* VOX mode computation of SID parameters */
683 
684     if ((computeSidFlag != 0)  ||
685             (st->log_en_index == 0))
686     {
687         /* compute new SID frame if safe i.e don't
688          * compute immediately after a talk spurt  */
689         log_en = 0;
690         for (i = M - 1; i >= 0; i--)
691         {
692             L_lsp[i] = 0;
693         }
694 
695         /* average energy and lsp */
696         for (i = DTX_HIST_SIZE - 1; i >= 0; i--)
697         {
698             if (st->log_en_hist[i] < 0)
699             {
700                 temp = ~((~(st->log_en_hist[i])) >> 2);
701             }
702             else
703             {
704                 temp = st->log_en_hist[i] >> 2;
705             }
706             log_en = add(log_en, temp, pOverflow);
707 
708             for (j = M - 1; j >= 0; j--)
709             {
710                 L_lsp[j] = L_add(L_lsp[j],
711                                  (Word32)(st->lsp_hist[i * M + j]),
712                                  pOverflow);
713             }
714         }
715 
716         if (log_en < 0)
717         {
718             log_en = ~((~log_en) >> 1);
719         }
720         else
721         {
722             log_en = log_en >> 1;
723         }
724 
725         for (j = M - 1; j >= 0; j--)
726         {
727             /* divide by 8 */
728             if (L_lsp[j] < 0)
729             {
730                 lsp[j] = (Word16)(~((~L_lsp[j]) >> 3));
731             }
732             else
733             {
734                 lsp[j] = (Word16)(L_lsp[j] >> 3);
735             }
736         }
737 
738         /*  quantize logarithmic energy to 6 bits */
739         /* +2.5 in Q10 */
740         st->log_en_index = add(log_en, 2560, pOverflow);
741         /* add 0.5/4 in Q10 */
742         st->log_en_index = add(st->log_en_index, 128, pOverflow);
743         if (st->log_en_index < 0)
744         {
745             st->log_en_index = ~((~st->log_en_index) >> 8);
746         }
747         else
748         {
749             st->log_en_index = st->log_en_index >> 8;
750         }
751 
752         /*---------------------------------------------*/
753         /* Limit to max and min allowable 6-bit values */
754         /* Note: For assembly implementation, use the  */
755         /*       following:                            */
756         /*       if(st->long_en_index >> 6 != 0)       */
757         /*       {                                     */
758         /*           if(st->long_en_index < 0)         */
759         /*           {                                 */
760         /*               st->long_en_index = 0         */
761         /*           }                                 */
762         /*           else                              */
763         /*           {                                 */
764         /*               st->long_en_index = 63        */
765         /*           }                                 */
766         /*       }                                     */
767         /*---------------------------------------------*/
768         if (st->log_en_index > 63)
769         {
770             st->log_en_index = 63;
771         }
772         else if (st->log_en_index < 0)
773         {
774             st->log_en_index = 0;
775         }
776 
777         /* update gain predictor memory */
778         /* Q11 and divide by 4 */
779         log_en = (Word16)(((Word32) st->log_en_index) << (-2 + 10));
780 
781         log_en = sub(log_en, 11560, pOverflow);
782 
783         if (log_en > 0)
784         {
785             log_en = 0;
786         }
787         else if (log_en < -14436)
788         {
789             log_en = -14436;
790         }
791 
792         /* past_qua_en for other modes than MR122 */
793         predState->past_qua_en[0] = log_en;
794         predState->past_qua_en[1] = log_en;
795         predState->past_qua_en[2] = log_en;
796         predState->past_qua_en[3] = log_en;
797 
798         /* scale down by factor 20*log10(2) in Q15 */
799         log_en = (Word16)(((Word32)(5443 * log_en)) >> 15);
800 
801         /* past_qua_en for mode MR122 */
802         predState->past_qua_en_MR122[0] = log_en;
803         predState->past_qua_en_MR122[1] = log_en;
804         predState->past_qua_en_MR122[2] = log_en;
805         predState->past_qua_en_MR122[3] = log_en;
806 
807         /* make sure that LSP's are ordered */
808         Lsp_lsf(lsp, lsf, M, pOverflow);
809         Reorder_lsf(lsf, LSF_GAP, M, pOverflow);
810         Lsf_lsp(lsf, lsp, M, pOverflow);
811 
812         /* Quantize lsp and put on parameter list */
813         Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
814                  &st->init_lsf_vq_index, pOverflow);
815     }
816 
817     *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */
818     *(*anap)++ = st->lsp_index[0];      /* 8 bits */
819     *(*anap)++ = st->lsp_index[1];      /* 9 bits */
820     *(*anap)++ = st->lsp_index[2];      /* 9 bits */
821     *(*anap)++ = st->log_en_index;      /* 6 bits    */
822     /* = 35 bits */
823 
824 }
825 
826 /****************************************************************************/
827 
828 
829 /*
830 ------------------------------------------------------------------------------
831  FUNCTION NAME: dtx_buffer
832 ------------------------------------------------------------------------------
833  INPUT AND OUTPUT DEFINITIONS
834 
835  Inputs:
836     st = pointer to structures of type dtx_encState
837     lsp_new = LSP vector whose elements are of type Word16; vector
838           length is M
839     speech = vector of speech samples of type Word16; vector length is
840          BFR_SIZE_GSM
841 
842  Outputs:
843     structure pointed to by st contains the new LSPs and logarithmic
844       frame energy
845 
846  Returns:
847     return_value = 0 (int)
848 
849  Global Variables Used:
850     None
851 
852  Local Variables Needed:
853     None
854 
855 ------------------------------------------------------------------------------
856  FUNCTION DESCRIPTION
857 
858  This function handles the DTX buffer.
859 
860 ------------------------------------------------------------------------------
861  REQUIREMENTS
862 
863  None
864 
865 ------------------------------------------------------------------------------
866  REFERENCES
867 
868  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
869 
870 ------------------------------------------------------------------------------
871  PSEUDO-CODE
872 
873 int dtx_buffer(dtx_encState *st,   // i/o : State struct
874                Word16 lsp_new[],   // i   : LSP vector
875                Word16 speech[]     // i   : speech samples
876 )
877 {
878    Word16 i;
879    Word32 L_frame_en;
880    Word16 log_en_e;
881    Word16 log_en_m;
882    Word16 log_en;
883 
884    // update pointer to circular buffer
885    st->hist_ptr = add(st->hist_ptr, 1);
886    if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
887    {
888       st->hist_ptr = 0;
889    }
890 
891    // copy lsp vector into buffer
892    Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
893 
894    // compute log energy based on frame energy
895    L_frame_en = 0;     // Q0
896    for (i=0; i < L_FRAME; i++)
897    {
898       L_frame_en = L_mac(L_frame_en, speech[i], speech[i]);
899    }
900    Log2(L_frame_en, &log_en_e, &log_en_m);
901 
902    // convert exponent and mantissa to Word16 Q10
903    log_en = shl(log_en_e, 10);  // Q10
904    log_en = add(log_en, shr(log_en_m, 15-10));
905 
906    // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193
907    log_en = sub(log_en, 8521);
908 
909    // insert into log energy buffer with division by 2
910    log_en = shr(log_en, 1);
911    st->log_en_hist[st->hist_ptr] = log_en; // Q10
912 
913    return 0;
914 }
915 
916 ------------------------------------------------------------------------------
917  RESOURCES USED [optional]
918 
919  When the code is written for a specific target processor the
920  the resources used should be documented below.
921 
922  HEAP MEMORY USED: x bytes
923 
924  STACK MEMORY USED: x bytes
925 
926  CLOCK CYCLES: (cycle count equation for this function) + (variable
927                 used to represent cycle count for each subroutine
928                 called)
929      where: (cycle count variable) = cycle count for [subroutine
930                                      name]
931 
932 ------------------------------------------------------------------------------
933  CAUTION [optional]
934  [State any special notes, constraints or cautions for users of this function]
935 
936 ------------------------------------------------------------------------------
937 */
938 
dtx_buffer(dtx_encState * st,Word16 lsp_new[],Word16 speech[],Flag * pOverflow)939 void dtx_buffer(dtx_encState *st,   /* i/o : State struct                    */
940                 Word16 lsp_new[],   /* i   : LSP vector                      */
941                 Word16 speech[],    /* i   : speech samples                  */
942                 Flag   *pOverflow   /* i/o : overflow indicator              */
943                )
944 {
945 
946     Word16 i;
947     Word32 L_frame_en;
948     Word32 mul;
949     Word32 L_temp;
950     Word16 log_en_e;
951     Word16 log_en_m;
952     Word16 log_en;
953     Word16 *p_speech = &speech[0];
954 
955     /* update pointer to circular buffer      */
956     st->hist_ptr += 1;
957 
958     if (st->hist_ptr == DTX_HIST_SIZE)
959     {
960         st->hist_ptr = 0;
961     }
962 
963     /* copy lsp vector into buffer */
964     memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16));
965 
966     /* compute log energy based on frame energy */
967     L_frame_en = 0;     /* Q0 */
968 
969     for (i = L_FRAME; i != 0; i--)
970     {
971         __builtin_mul_overflow(*p_speech, *p_speech, &mul);
972         __builtin_add_overflow(L_frame_en, mul << 1, &L_frame_en);
973         p_speech++;
974         if (L_frame_en < 0)
975         {
976             L_frame_en = MAX_32;
977             break;
978         }
979     }
980 
981     Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow);
982 
983     /* convert exponent and mantissa to Word16 Q10 */
984     /* Q10 */
985     L_temp = ((Word32) log_en_e) << 10;
986     if (L_temp != (Word32)((Word16) L_temp))
987     {
988         *pOverflow = 1;
989         log_en = (log_en_e > 0) ? MAX_16 : MIN_16;
990     }
991     else
992     {
993         log_en = (Word16) L_temp;
994     }
995 
996     log_en += log_en_m >> (15 - 10);
997 
998     /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
999     log_en -= 8521;
1000 
1001     /* insert into log energy buffer with division by 2 */
1002 
1003     st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */
1004 
1005 }
1006 
1007 /****************************************************************************/
1008 
1009 /*
1010 ------------------------------------------------------------------------------
1011  FUNCTION NAME: tx_dtx_handler
1012 ------------------------------------------------------------------------------
1013  INPUT AND OUTPUT DEFINITIONS
1014 
1015  Inputs:
1016     st = pointer to structures of type dtx_encState
1017     vad_flag = VAD decision flag of type Word16
1018     usedMode = pointer to the currently used mode of type enum Mode
1019 
1020  Outputs:
1021     structure pointed to by st contains the newly calculated speech
1022       hangover
1023 
1024  Returns:
1025     compute_new_sid_possible = flag to indicate a change in the
1026                    used mode; store type is Word16
1027 
1028  Global Variables Used:
1029     None
1030 
1031  Local Variables Needed:
1032     None
1033 
1034 ------------------------------------------------------------------------------
1035  FUNCTION DESCRIPTION
1036 
1037  This function adds extra speech hangover to analyze speech on the decoding
1038  side.
1039 
1040 ------------------------------------------------------------------------------
1041  REQUIREMENTS
1042 
1043  None
1044 
1045 ------------------------------------------------------------------------------
1046  REFERENCES
1047 
1048  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1049 
1050 ------------------------------------------------------------------------------
1051  PSEUDO-CODE
1052 
1053 Word16 tx_dtx_handler(dtx_encState *st,      // i/o : State struct
1054                       Word16 vad_flag,       // i   : vad decision
1055                       enum Mode *usedMode    // i/o : mode changed or not
1056                       )
1057 {
1058    Word16 compute_new_sid_possible;
1059 
1060    // this state machine is in synch with the GSMEFR txDtx machine
1061    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
1062 
1063    compute_new_sid_possible = 0;
1064 
1065    if (vad_flag != 0)
1066    {
1067       st->dtxHangoverCount = DTX_HANG_CONST;
1068    }
1069    else
1070    {  // non-speech
1071       if (st->dtxHangoverCount == 0)
1072       {  // out of decoder analysis hangover
1073          st->decAnaElapsedCount = 0;
1074          *usedMode = MRDTX;
1075          compute_new_sid_possible = 1;
1076       }
1077       else
1078       { // in possible analysis hangover
1079          st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
1080 
1081          // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH
1082          if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
1083                  DTX_ELAPSED_FRAMES_THRESH) < 0)
1084          {
1085             *usedMode = MRDTX;
1086             // if short time since decoder update, do not add extra HO
1087          }
1088          // else
1089          //   override VAD and stay in
1090          //   speech mode *usedMode
1091          //   and add extra hangover
1092       }
1093    }
1094 
1095    return compute_new_sid_possible;
1096 }
1097 
1098 ------------------------------------------------------------------------------
1099  RESOURCES USED [optional]
1100 
1101  When the code is written for a specific target processor the
1102  the resources used should be documented below.
1103 
1104  HEAP MEMORY USED: x bytes
1105 
1106  STACK MEMORY USED: x bytes
1107 
1108  CLOCK CYCLES: (cycle count equation for this function) + (variable
1109                 used to represent cycle count for each subroutine
1110                 called)
1111      where: (cycle count variable) = cycle count for [subroutine
1112                                      name]
1113 
1114 ------------------------------------------------------------------------------
1115  CAUTION [optional]
1116  [State any special notes, constraints or cautions for users of this function]
1117 
1118 ------------------------------------------------------------------------------
1119 */
1120 
tx_dtx_handler(dtx_encState * st,Word16 vad_flag,enum Mode * usedMode,Flag * pOverflow)1121 Word16 tx_dtx_handler(dtx_encState *st,      /* i/o : State struct           */
1122                       Word16 vad_flag,       /* i   : vad decision           */
1123                       enum Mode *usedMode,   /* i/o : mode changed or not    */
1124                       Flag   *pOverflow      /* i/o : overflow indicator     */
1125                      )
1126 {
1127     Word16 compute_new_sid_possible;
1128     Word16 count;
1129 
1130     /* this state machine is in synch with the GSMEFR txDtx machine */
1131     st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow);
1132 
1133     compute_new_sid_possible = 0;
1134 
1135     if (vad_flag != 0)
1136     {
1137         st->dtxHangoverCount = DTX_HANG_CONST;
1138     }
1139     else
1140     {  /* non-speech */
1141         if (st->dtxHangoverCount == 0)
1142         {  /* out of decoder analysis hangover  */
1143             st->decAnaElapsedCount = 0;
1144             *usedMode = MRDTX;
1145             compute_new_sid_possible = 1;
1146         }
1147         else
1148         { /* in possible analysis hangover */
1149             st->dtxHangoverCount -= 1;
1150 
1151             /* decAnaElapsedCount + dtxHangoverCount < */
1152             /* DTX_ELAPSED_FRAMES_THRESH               */
1153             count = add(st->decAnaElapsedCount, st->dtxHangoverCount,
1154                         pOverflow);
1155             if (count < DTX_ELAPSED_FRAMES_THRESH)
1156             {
1157                 *usedMode = MRDTX;
1158                 /* if short time since decoder update, */
1159                 /* do not add extra HO                 */
1160             }
1161         }
1162     }
1163 
1164     return(compute_new_sid_possible);
1165 }
1166