• 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.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 L_temp;
949     Word16 log_en_e;
950     Word16 log_en_m;
951     Word16 log_en;
952     Word16 *p_speech = &speech[0];
953 
954     /* update pointer to circular buffer      */
955     st->hist_ptr += 1;
956 
957     if (st->hist_ptr == DTX_HIST_SIZE)
958     {
959         st->hist_ptr = 0;
960     }
961 
962     /* copy lsp vector into buffer */
963     memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16));
964 
965     /* compute log energy based on frame energy */
966     L_frame_en = 0;     /* Q0 */
967 
968     for (i = L_FRAME; i != 0; i--)
969     {
970         L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1;
971         p_speech++;
972         if (L_frame_en < 0)
973         {
974             L_frame_en = MAX_32;
975             break;
976         }
977     }
978 
979     Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow);
980 
981     /* convert exponent and mantissa to Word16 Q10 */
982     /* Q10 */
983     L_temp = ((Word32) log_en_e) << 10;
984     if (L_temp != (Word32)((Word16) L_temp))
985     {
986         *pOverflow = 1;
987         log_en = (log_en_e > 0) ? MAX_16 : MIN_16;
988     }
989     else
990     {
991         log_en = (Word16) L_temp;
992     }
993 
994     log_en += log_en_m >> (15 - 10);
995 
996     /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
997     log_en -= 8521;
998 
999     /* insert into log energy buffer with division by 2 */
1000 
1001     st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */
1002 
1003 }
1004 
1005 /****************************************************************************/
1006 
1007 /*
1008 ------------------------------------------------------------------------------
1009  FUNCTION NAME: tx_dtx_handler
1010 ------------------------------------------------------------------------------
1011  INPUT AND OUTPUT DEFINITIONS
1012 
1013  Inputs:
1014     st = pointer to structures of type dtx_encState
1015     vad_flag = VAD decision flag of type Word16
1016     usedMode = pointer to the currently used mode of type enum Mode
1017 
1018  Outputs:
1019     structure pointed to by st contains the newly calculated speech
1020       hangover
1021 
1022  Returns:
1023     compute_new_sid_possible = flag to indicate a change in the
1024                    used mode; store type is Word16
1025 
1026  Global Variables Used:
1027     None
1028 
1029  Local Variables Needed:
1030     None
1031 
1032 ------------------------------------------------------------------------------
1033  FUNCTION DESCRIPTION
1034 
1035  This function adds extra speech hangover to analyze speech on the decoding
1036  side.
1037 
1038 ------------------------------------------------------------------------------
1039  REQUIREMENTS
1040 
1041  None
1042 
1043 ------------------------------------------------------------------------------
1044  REFERENCES
1045 
1046  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1047 
1048 ------------------------------------------------------------------------------
1049  PSEUDO-CODE
1050 
1051 Word16 tx_dtx_handler(dtx_encState *st,      // i/o : State struct
1052                       Word16 vad_flag,       // i   : vad decision
1053                       enum Mode *usedMode    // i/o : mode changed or not
1054                       )
1055 {
1056    Word16 compute_new_sid_possible;
1057 
1058    // this state machine is in synch with the GSMEFR txDtx machine
1059    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
1060 
1061    compute_new_sid_possible = 0;
1062 
1063    if (vad_flag != 0)
1064    {
1065       st->dtxHangoverCount = DTX_HANG_CONST;
1066    }
1067    else
1068    {  // non-speech
1069       if (st->dtxHangoverCount == 0)
1070       {  // out of decoder analysis hangover
1071          st->decAnaElapsedCount = 0;
1072          *usedMode = MRDTX;
1073          compute_new_sid_possible = 1;
1074       }
1075       else
1076       { // in possible analysis hangover
1077          st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
1078 
1079          // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH
1080          if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
1081                  DTX_ELAPSED_FRAMES_THRESH) < 0)
1082          {
1083             *usedMode = MRDTX;
1084             // if short time since decoder update, do not add extra HO
1085          }
1086          // else
1087          //   override VAD and stay in
1088          //   speech mode *usedMode
1089          //   and add extra hangover
1090       }
1091    }
1092 
1093    return compute_new_sid_possible;
1094 }
1095 
1096 ------------------------------------------------------------------------------
1097  RESOURCES USED [optional]
1098 
1099  When the code is written for a specific target processor the
1100  the resources used should be documented below.
1101 
1102  HEAP MEMORY USED: x bytes
1103 
1104  STACK MEMORY USED: x bytes
1105 
1106  CLOCK CYCLES: (cycle count equation for this function) + (variable
1107                 used to represent cycle count for each subroutine
1108                 called)
1109      where: (cycle count variable) = cycle count for [subroutine
1110                                      name]
1111 
1112 ------------------------------------------------------------------------------
1113  CAUTION [optional]
1114  [State any special notes, constraints or cautions for users of this function]
1115 
1116 ------------------------------------------------------------------------------
1117 */
1118 
tx_dtx_handler(dtx_encState * st,Word16 vad_flag,enum Mode * usedMode,Flag * pOverflow)1119 Word16 tx_dtx_handler(dtx_encState *st,      /* i/o : State struct           */
1120                       Word16 vad_flag,       /* i   : vad decision           */
1121                       enum Mode *usedMode,   /* i/o : mode changed or not    */
1122                       Flag   *pOverflow      /* i/o : overflow indicator     */
1123                      )
1124 {
1125     Word16 compute_new_sid_possible;
1126     Word16 count;
1127 
1128     /* this state machine is in synch with the GSMEFR txDtx machine */
1129     st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow);
1130 
1131     compute_new_sid_possible = 0;
1132 
1133     if (vad_flag != 0)
1134     {
1135         st->dtxHangoverCount = DTX_HANG_CONST;
1136     }
1137     else
1138     {  /* non-speech */
1139         if (st->dtxHangoverCount == 0)
1140         {  /* out of decoder analysis hangover  */
1141             st->decAnaElapsedCount = 0;
1142             *usedMode = MRDTX;
1143             compute_new_sid_possible = 1;
1144         }
1145         else
1146         { /* in possible analysis hangover */
1147             st->dtxHangoverCount -= 1;
1148 
1149             /* decAnaElapsedCount + dtxHangoverCount < */
1150             /* DTX_ELAPSED_FRAMES_THRESH               */
1151             count = add(st->decAnaElapsedCount, st->dtxHangoverCount,
1152                         pOverflow);
1153             if (count < DTX_ELAPSED_FRAMES_THRESH)
1154             {
1155                 *usedMode = MRDTX;
1156                 /* if short time since decoder update, */
1157                 /* do not add extra HO                 */
1158             }
1159         }
1160     }
1161 
1162     return(compute_new_sid_possible);
1163 }
1164