Initialize Tizen 2.3
[external/opencore-amr.git] / opencore / codecs_v2 / audio / gsm_amr / amr_nb / enc / src / dtx_enc.cpp
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  Filename: dtx_enc.cpp
35  Functions: dtx_enc_init
36            dtx_enc_reset
37            dtx_enc_exit
38            dtx_enc
39            dtx_buffer
40            tx_dtx_handler
41
42 ------------------------------------------------------------------------------
43  MODULE DESCRIPTION
44
45  This file contains the various functions that perform the computation of the
46  Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX)
47  mode.
48
49 ------------------------------------------------------------------------------
50 */
51
52
53 /*----------------------------------------------------------------------------
54 ; INCLUDES
55 ----------------------------------------------------------------------------*/
56 #include "dtx_enc.h"
57 #include "q_plsf.h"
58 #include "typedef.h"
59 #include "mode.h"
60 #include "basic_op.h"
61 #include "log2.h"
62 #include "lsp_lsf.h"
63 #include "reorder.h"
64 #include "oscl_mem.h"
65
66 /*----------------------------------------------------------------------------
67 ; MACROS
68 ; Define module specific macros here
69 ----------------------------------------------------------------------------*/
70 extern Word32 L_add(register Word32 L_var1, register Word32 L_var2, Flag *pOverflow);
71
72 /*----------------------------------------------------------------------------
73 ; DEFINES
74 ; Include all pre-processor statements here. Include conditional
75 ; compile variables also.
76 ----------------------------------------------------------------------------*/
77
78 /*----------------------------------------------------------------------------
79 ; LOCAL FUNCTION DEFINITIONS
80 ; Function Prototype declaration
81 ----------------------------------------------------------------------------*/
82
83 /*----------------------------------------------------------------------------
84 ; LOCAL VARIABLE DEFINITIONS
85 ; Variable declaration - defined here and used outside this module
86 ----------------------------------------------------------------------------*/
87
88
89 /*
90 ------------------------------------------------------------------------------
91  FUNCTION NAME: dtx_enc_init
92 ------------------------------------------------------------------------------
93  INPUT AND OUTPUT DEFINITIONS
94
95  Inputs:
96     st = pointer to an array of pointers to structures of type
97          dtx_encState
98
99  Outputs:
100     pointer pointed to by st is set to the address of the allocated
101       memory
102
103  Returns:
104     return_value = 0, if initialization was successful; -1, otherwise (int)
105
106  Global Variables Used:
107     None
108
109  Local Variables Needed:
110     None
111
112 ------------------------------------------------------------------------------
113  FUNCTION DESCRIPTION
114
115  This function allocates the state memory used by the dtx_enc function.
116
117 ------------------------------------------------------------------------------
118  REQUIREMENTS
119
120  None
121
122 ------------------------------------------------------------------------------
123  REFERENCES
124
125  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
126
127 ------------------------------------------------------------------------------
128  PSEUDO-CODE
129
130 int dtx_enc_init (dtx_encState **st)
131 {
132   dtx_encState* s;
133
134   if (st == (dtx_encState **) NULL){
135     fprintf(stderr, "dtx_enc_init: invalid parameter\n");
136     return -1;
137   }
138
139   *st = NULL;
140
141   // allocate memory
142   if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){
143     fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
144     return -1;
145   }
146
147   dtx_enc_reset(s);
148   *st = s;
149
150   return 0;
151 }
152
153 ------------------------------------------------------------------------------
154  CAUTION [optional]
155  [State any special notes, constraints or cautions for users of this function]
156
157 ------------------------------------------------------------------------------
158 */
159
160 Word16 dtx_enc_init(dtx_encState **st, const Word16* lsp_init_data_ptr)
161 {
162     dtx_encState* s;
163
164     if (st == (dtx_encState **) NULL)
165     {
166         return(-1);
167     }
168
169     *st = NULL;
170
171     /* allocate memory */
172     if ((s = (dtx_encState *) oscl_malloc(sizeof(dtx_encState))) == NULL)
173     {
174         return(-1);
175     }
176
177     dtx_enc_reset(s, lsp_init_data_ptr);
178     *st = s;
179
180     return(0);
181 }
182
183 /****************************************************************************/
184
185 /*
186 ------------------------------------------------------------------------------
187  FUNCTION NAME: dtx_enc_reset
188 ------------------------------------------------------------------------------
189  INPUT AND OUTPUT DEFINITIONS
190
191  Inputs:
192     st = pointer to structures of type dtx_encState
193
194  Outputs:
195     structure pointed to by st is initialized to its reset value
196
197  Returns:
198     return_value = 1, if reset was successful; -1, otherwise (int)
199
200  Global Variables Used:
201     None
202
203  Local Variables Needed:
204     lsp_init_data = table containing LSP initialization values;
205             table elements are constants of type Word16;
206             table length is M
207
208 ------------------------------------------------------------------------------
209  FUNCTION DESCRIPTION
210
211  This function initializes the fields of the state memory used by dtx_enc
212  to their reset values.
213
214 ------------------------------------------------------------------------------
215  REQUIREMENTS
216
217  None
218
219 ------------------------------------------------------------------------------
220  REFERENCES
221
222  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
223
224 ------------------------------------------------------------------------------
225  PSEUDO-CODE
226
227 int dtx_enc_reset (dtx_encState *st)
228 {
229   Word16 i;
230
231   if (st == (dtx_encState *) NULL){
232     fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
233     return -1;
234   }
235
236   st->hist_ptr = 0;
237   st->log_en_index = 0;
238   st->init_lsf_vq_index = 0;
239   st->lsp_index[0] = 0;
240   st->lsp_index[1] = 0;
241   st->lsp_index[2] = 0;
242
243   // Init lsp_hist[]
244   for(i = 0; i < DTX_HIST_SIZE; i++)
245   {
246     Copy(lsp_init_data, &st->lsp_hist[i * M], M);
247   }
248
249   // Reset energy history
250   Set_zero(st->log_en_hist, M);
251
252   st->dtxHangoverCount = DTX_HANG_CONST;
253   st->decAnaElapsedCount = 32767;
254
255   return 1;
256 }
257
258 ------------------------------------------------------------------------------
259  CAUTION [optional]
260  [State any special notes, constraints or cautions for users of this function]
261
262 ------------------------------------------------------------------------------
263 */
264
265 Word16 dtx_enc_reset(dtx_encState *st, const Word16* lsp_init_data_ptr)
266 {
267     Word16 i;
268
269     if (st == (dtx_encState *) NULL)
270     {
271         return(-1);
272     }
273
274     st->hist_ptr = 0;
275     st->log_en_index = 0;
276     st->init_lsf_vq_index = 0;
277     st->lsp_index[0] = 0;
278     st->lsp_index[1] = 0;
279     st->lsp_index[2] = 0;
280
281     /* Init lsp_hist[] */
282     for (i = 0; i < DTX_HIST_SIZE; i++)
283     {
284         oscl_memcpy(&st->lsp_hist[i * M], lsp_init_data_ptr, M*sizeof(Word16));
285     }
286
287     /* Reset energy history */
288     oscl_memset(st->log_en_hist, 0, sizeof(Word16)*M);
289     st->dtxHangoverCount = DTX_HANG_CONST;
290     st->decAnaElapsedCount = 32767;
291
292     return(1);
293 }
294
295 /****************************************************************************/
296
297 /*
298 ------------------------------------------------------------------------------
299  FUNCTION NAME: dtx_enc_exit
300 ------------------------------------------------------------------------------
301  INPUT AND OUTPUT DEFINITIONS
302
303  Inputs:
304     st = pointer to an array of pointers to structures of type
305          dtx_encState
306
307  Outputs:
308     st points to the NULL address
309
310  Returns:
311     None
312
313  Global Variables Used:
314     None
315
316  Local Variables Needed:
317     None
318
319 ------------------------------------------------------------------------------
320  FUNCTION DESCRIPTION
321
322  This function deallocates the state memory used by dtx_enc function.
323
324 ------------------------------------------------------------------------------
325  REQUIREMENTS
326
327  None
328
329 ------------------------------------------------------------------------------
330  REFERENCES
331
332  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
333
334 ------------------------------------------------------------------------------
335  PSEUDO-CODE
336
337 void dtx_enc_exit (dtx_encState **st)
338 {
339    if (st == NULL || *st == NULL)
340       return;
341
342    // deallocate memory
343    free(*st);
344    *st = NULL;
345
346    return;
347 }
348
349 ------------------------------------------------------------------------------
350  CAUTION [optional]
351  [State any special notes, constraints or cautions for users of this function]
352
353 ------------------------------------------------------------------------------
354 */
355
356 void dtx_enc_exit(dtx_encState **st)
357 {
358     if (st == NULL || *st == NULL)
359     {
360         return;
361     }
362
363     /* deallocate memory */
364     oscl_free(*st);
365     *st = NULL;
366
367     return;
368 }
369
370 /****************************************************************************/
371
372 /*
373 ------------------------------------------------------------------------------
374  FUNCTION NAME: dtx_enc
375 ------------------------------------------------------------------------------
376  INPUT AND OUTPUT DEFINITIONS
377
378  Inputs:
379     st = pointer to structures of type dtx_encState
380     computeSidFlag = compute SID flag of type Word16
381     qSt = pointer to structures of type Q_plsfState
382     predState = pointer to structures of type gc_predState
383     anap = pointer to an array of pointers to analysis parameters of
384            type Word16
385
386  Outputs:
387     structure pointed to by st contains the newly calculated SID
388       parameters
389     structure pointed to by predState contains the new logarithmic frame
390       energy
391     pointer pointed to by anap points to the location of the new
392       logarithmic frame energy and new LSPs
393
394  Returns:
395     return_value = 0 (int)
396
397  Global Variables Used:
398     None
399
400  Local Variables Needed:
401     None
402
403 ------------------------------------------------------------------------------
404  FUNCTION DESCRIPTION
405
406  This function calculates the SID parameters when in the DTX mode.
407
408 ------------------------------------------------------------------------------
409  REQUIREMENTS
410
411  None
412
413 ------------------------------------------------------------------------------
414  REFERENCES
415
416  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
417
418 ------------------------------------------------------------------------------
419  PSEUDO-CODE
420
421 int dtx_enc(dtx_encState *st,        // i/o : State struct
422             Word16 computeSidFlag,   // i   : compute SID
423             Q_plsfState *qSt,        // i/o : Qunatizer state struct
424             gc_predState* predState, // i/o : State struct
425         Word16 **anap            // o   : analysis parameters
426         )
427 {
428    Word16 i,j;
429    Word16 log_en;
430    Word16 lsf[M];
431    Word16 lsp[M];
432    Word16 lsp_q[M];
433    Word32 L_lsp[M];
434
435    // VOX mode computation of SID parameters
436    if ((computeSidFlag != 0)  ||
437         (st->log_en_index == 0))
438    {
439       // compute new SID frame if safe i.e don't
440       // compute immediately after a talk spurt
441       log_en = 0;
442       for (i = 0; i < M; i++)
443       {
444          L_lsp[i] = 0;
445       }
446
447       // average energy and lsp
448       for (i = 0; i < DTX_HIST_SIZE; i++)
449       {
450          log_en = add(log_en,
451                       shr(st->log_en_hist[i],2));
452
453          for (j = 0; j < M; j++)
454          {
455             L_lsp[j] = L_add(L_lsp[j],
456                              L_deposit_l(st->lsp_hist[i * M + j]));
457          }
458       }
459
460       log_en = shr(log_en, 1);
461       for (j = 0; j < M; j++)
462       {
463          lsp[j] = extract_l(L_shr(L_lsp[j], 3));   // divide by 8
464       }
465
466       //  quantize logarithmic energy to 6 bits
467       st->log_en_index = add(log_en, 2560);          // +2.5 in Q10
468       st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10
469       st->log_en_index = shr(st->log_en_index, 8);
470
471       if (sub(st->log_en_index, 63) > 0)
472       {
473          st->log_en_index = 63;
474       }
475       if (st->log_en_index < 0)
476       {
477          st->log_en_index = 0;
478       }
479
480       // update gain predictor memory
481       log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4
482       log_en = sub(log_en, 2560);            // add 2.5 in Q11
483
484       log_en = sub(log_en, 9000);
485       if (log_en > 0)
486       {
487          log_en = 0;
488       }
489       if (sub(log_en, -14436) < 0)
490       {
491          log_en = -14436;
492       }
493
494       // past_qua_en for other modes than MR122
495       predState->past_qua_en[0] = log_en;
496       predState->past_qua_en[1] = log_en;
497       predState->past_qua_en[2] = log_en;
498       predState->past_qua_en[3] = log_en;
499
500       // scale down by factor 20*log10(2) in Q15
501       log_en = mult(5443, log_en);
502
503       // past_qua_en for mode MR122
504       predState->past_qua_en_MR122[0] = log_en;
505       predState->past_qua_en_MR122[1] = log_en;
506       predState->past_qua_en_MR122[2] = log_en;
507       predState->past_qua_en_MR122[3] = log_en;
508
509       // make sure that LSP's are ordered
510       Lsp_lsf(lsp, lsf, M);
511       Reorder_lsf(lsf, LSF_GAP, M);
512       Lsf_lsp(lsf, lsp, M);
513
514       // Quantize lsp and put on parameter list
515       Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
516                &st->init_lsf_vq_index);
517    }
518
519    *(*anap)++ = st->init_lsf_vq_index; // 3 bits
520
521    *(*anap)++ = st->lsp_index[0];      // 8 bits
522    *(*anap)++ = st->lsp_index[1];      // 9 bits
523    *(*anap)++ = st->lsp_index[2];      // 9 bits
524
525
526    *(*anap)++ = st->log_en_index;      // 6 bits
527                                        // = 35 bits
528
529    return 0;
530 }
531
532 ------------------------------------------------------------------------------
533  CAUTION [optional]
534  [State any special notes, constraints or cautions for users of this function]
535
536 ------------------------------------------------------------------------------
537 */
538
539 void dtx_enc(dtx_encState *st,        /* i/o : State struct                  */
540              Word16 computeSidFlag,   /* i   : compute SID                   */
541              Q_plsfState *qSt,        /* i/o : Qunatizer state struct        */
542              gc_predState* predState, /* i/o : State struct                  */
543              Word16 **anap,           /* o   : analysis parameters           */
544              Flag   *pOverflow        /* i/o : overflow indicator            */
545             )
546 {
547     register Word16 i, j;
548     Word16 temp;
549     Word16 log_en;
550     Word16 lsf[M];
551     Word16 lsp[M];
552     Word16 lsp_q[M];
553     Word32 L_lsp[M];
554
555     /* VOX mode computation of SID parameters */
556
557     if ((computeSidFlag != 0)  ||
558             (st->log_en_index == 0))
559     {
560         /* compute new SID frame if safe i.e don't
561          * compute immediately after a talk spurt  */
562         log_en = 0;
563         for (i = M - 1; i >= 0; i--)
564         {
565             L_lsp[i] = 0;
566         }
567
568         /* average energy and lsp */
569         for (i = DTX_HIST_SIZE - 1; i >= 0; i--)
570         {
571             if (st->log_en_hist[i] < 0)
572             {
573                 temp = ~((~(st->log_en_hist[i])) >> 2);
574             }
575             else
576             {
577                 temp = st->log_en_hist[i] >> 2;
578             }
579             log_en = add_16(log_en, temp, pOverflow);
580
581             for (j = M - 1; j >= 0; j--)
582             {
583                 L_lsp[j] = L_add(L_lsp[j],
584                                  (Word32)(st->lsp_hist[i * M + j]),
585                                  pOverflow);
586             }
587         }
588
589         if (log_en < 0)
590         {
591             log_en = ~((~log_en) >> 1);
592         }
593         else
594         {
595             log_en = log_en >> 1;
596         }
597
598         for (j = M - 1; j >= 0; j--)
599         {
600             /* divide by 8 */
601             if (L_lsp[j] < 0)
602             {
603                 lsp[j] = (Word16)(~((~L_lsp[j]) >> 3));
604             }
605             else
606             {
607                 lsp[j] = (Word16)(L_lsp[j] >> 3);
608             }
609         }
610
611         /*  quantize logarithmic energy to 6 bits */
612         /* +2.5 in Q10 */
613         st->log_en_index = log_en + 2560;
614         /* add 0.5/4 in Q10 */
615         st->log_en_index += 128;
616         if (st->log_en_index < 0)
617         {
618             st->log_en_index = ~((~st->log_en_index) >> 8);
619         }
620         else
621         {
622             st->log_en_index = st->log_en_index >> 8;
623         }
624
625         /*---------------------------------------------*/
626         /* Limit to max and min allowable 6-bit values */
627         /* Note: For assembly implementation, use the  */
628         /*       following:                            */
629         /*       if(st->long_en_index >> 6 != 0)       */
630         /*       {                                     */
631         /*           if(st->long_en_index < 0)         */
632         /*           {                                 */
633         /*               st->long_en_index = 0         */
634         /*           }                                 */
635         /*           else                              */
636         /*           {                                 */
637         /*               st->long_en_index = 63        */
638         /*           }                                 */
639         /*       }                                     */
640         /*---------------------------------------------*/
641         if (st->log_en_index > 63)
642         {
643             st->log_en_index = 63;
644         }
645         else if (st->log_en_index < 0)
646         {
647             st->log_en_index = 0;
648         }
649
650         /* update gain predictor memory */
651         /* Q11 and divide by 4 */
652         log_en = (Word16)(((Word32) st->log_en_index) << (-2 + 10));
653
654         log_en = sub(log_en, 11560, pOverflow);
655
656         if (log_en > 0)
657         {
658             log_en = 0;
659         }
660         else if (log_en < -14436)
661         {
662             log_en = -14436;
663         }
664
665         /* past_qua_en for other modes than MR122 */
666         predState->past_qua_en[0] = log_en;
667         predState->past_qua_en[1] = log_en;
668         predState->past_qua_en[2] = log_en;
669         predState->past_qua_en[3] = log_en;
670
671         /* scale down by factor 20*log10(2) in Q15 */
672         log_en = (Word16)(((Word32)(5443 * log_en)) >> 15);
673
674         /* past_qua_en for mode MR122 */
675         predState->past_qua_en_MR122[0] = log_en;
676         predState->past_qua_en_MR122[1] = log_en;
677         predState->past_qua_en_MR122[2] = log_en;
678         predState->past_qua_en_MR122[3] = log_en;
679
680         /* make sure that LSP's are ordered */
681         Lsp_lsf(lsp, lsf, M, pOverflow);
682         Reorder_lsf(lsf, LSF_GAP, M, pOverflow);
683         Lsf_lsp(lsf, lsp, M, pOverflow);
684
685         /* Quantize lsp and put on parameter list */
686         Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
687                  &st->init_lsf_vq_index, pOverflow);
688     }
689
690     *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */
691     *(*anap)++ = st->lsp_index[0];      /* 8 bits */
692     *(*anap)++ = st->lsp_index[1];      /* 9 bits */
693     *(*anap)++ = st->lsp_index[2];      /* 9 bits */
694     *(*anap)++ = st->log_en_index;      /* 6 bits    */
695     /* = 35 bits */
696
697 }
698
699 /****************************************************************************/
700
701
702 /*
703 ------------------------------------------------------------------------------
704  FUNCTION NAME: dtx_buffer
705 ------------------------------------------------------------------------------
706  INPUT AND OUTPUT DEFINITIONS
707
708  Inputs:
709     st = pointer to structures of type dtx_encState
710     lsp_new = LSP vector whose elements are of type Word16; vector
711           length is M
712     speech = vector of speech samples of type Word16; vector length is
713          BFR_SIZE_GSM
714
715  Outputs:
716     structure pointed to by st contains the new LSPs and logarithmic
717       frame energy
718
719  Returns:
720     return_value = 0 (int)
721
722  Global Variables Used:
723     None
724
725  Local Variables Needed:
726     None
727
728 ------------------------------------------------------------------------------
729  FUNCTION DESCRIPTION
730
731  This function handles the DTX buffer.
732
733 ------------------------------------------------------------------------------
734  REQUIREMENTS
735
736  None
737
738 ------------------------------------------------------------------------------
739  REFERENCES
740
741  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
742
743 ------------------------------------------------------------------------------
744  PSEUDO-CODE
745
746 int dtx_buffer(dtx_encState *st,   // i/o : State struct
747                Word16 lsp_new[],   // i   : LSP vector
748                Word16 speech[]     // i   : speech samples
749 )
750 {
751    Word16 i;
752    Word32 L_frame_en;
753    Word16 log_en_e;
754    Word16 log_en_m;
755    Word16 log_en;
756
757    // update pointer to circular buffer
758    st->hist_ptr = add(st->hist_ptr, 1);
759    if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
760    {
761       st->hist_ptr = 0;
762    }
763
764    // copy lsp vector into buffer
765    Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
766
767    // compute log energy based on frame energy
768    L_frame_en = 0;     // Q0
769    for (i=0; i < L_FRAME; i++)
770    {
771       L_frame_en = L_mac(L_frame_en, speech[i], speech[i]);
772    }
773    Log2(L_frame_en, &log_en_e, &log_en_m);
774
775    // convert exponent and mantissa to Word16 Q10
776    log_en = shl(log_en_e, 10);  // Q10
777    log_en = add(log_en, shr(log_en_m, 15-10));
778
779    // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193
780    log_en = sub(log_en, 8521);
781
782    // insert into log energy buffer with division by 2
783    log_en = shr(log_en, 1);
784    st->log_en_hist[st->hist_ptr] = log_en; // Q10
785
786    return 0;
787 }
788
789 ------------------------------------------------------------------------------
790  CAUTION [optional]
791  [State any special notes, constraints or cautions for users of this function]
792
793 ------------------------------------------------------------------------------
794 */
795
796 void dtx_buffer(dtx_encState *st,   /* i/o : State struct                    */
797                 Word16 lsp_new[],   /* i   : LSP vector                      */
798                 Word16 speech[],    /* i   : speech samples                  */
799                 Flag   *pOverflow   /* i/o : overflow indicator              */
800                )
801 {
802
803     register Word16 i;
804     Word32 L_frame_en;
805     Word32 L_temp;
806     Word16 log_en_e;
807     Word16 log_en_m;
808     Word16 log_en;
809     Word16 *p_speech = &speech[0];
810
811     /* update pointer to circular buffer      */
812     st->hist_ptr += 1;
813
814     if (st->hist_ptr == DTX_HIST_SIZE)
815     {
816         st->hist_ptr = 0;
817     }
818
819     /* copy lsp vector into buffer */
820     oscl_memcpy(&st->lsp_hist[st->hist_ptr * M], lsp_new, M*sizeof(Word16));
821
822     /* compute log energy based on frame energy */
823     L_frame_en = 0;     /* Q0 */
824
825     for (i = L_FRAME; i != 0; i--)
826     {
827         L_frame_en += (((Word32) * p_speech) * *(p_speech)) << 1;
828         p_speech++;
829         if (L_frame_en < 0)
830         {
831             L_frame_en = MAX_32;
832             break;
833         }
834     }
835
836     Log2(L_frame_en, &log_en_e, &log_en_m, pOverflow);
837
838     /* convert exponent and mantissa to Word16 Q10 */
839     /* Q10 */
840     L_temp = ((Word32) log_en_e) << 10;
841     if (L_temp != (Word32)((Word16) L_temp))
842     {
843         *pOverflow = 1;
844         log_en = (log_en_e > 0) ? MAX_16 : MIN_16;
845     }
846     else
847     {
848         log_en = (Word16) L_temp;
849     }
850
851     log_en += log_en_m >> (15 - 10);
852
853     /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
854     log_en -= 8521;
855
856     /* insert into log energy buffer with division by 2 */
857
858     st->log_en_hist[st->hist_ptr] = log_en >> 1; /* Q10 */
859
860 }
861
862 /****************************************************************************/
863
864 /*
865 ------------------------------------------------------------------------------
866  FUNCTION NAME: tx_dtx_handler
867 ------------------------------------------------------------------------------
868  INPUT AND OUTPUT DEFINITIONS
869
870  Inputs:
871     st = pointer to structures of type dtx_encState
872     vad_flag = VAD decision flag of type Word16
873     usedMode = pointer to the currently used mode of type enum Mode
874
875  Outputs:
876     structure pointed to by st contains the newly calculated speech
877       hangover
878
879  Returns:
880     compute_new_sid_possible = flag to indicate a change in the
881                    used mode; store type is Word16
882
883  Global Variables Used:
884     None
885
886  Local Variables Needed:
887     None
888
889 ------------------------------------------------------------------------------
890  FUNCTION DESCRIPTION
891
892  This function adds extra speech hangover to analyze speech on the decoding
893  side.
894
895 ------------------------------------------------------------------------------
896  REQUIREMENTS
897
898  None
899
900 ------------------------------------------------------------------------------
901  REFERENCES
902
903  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
904
905 ------------------------------------------------------------------------------
906  PSEUDO-CODE
907
908 Word16 tx_dtx_handler(dtx_encState *st,      // i/o : State struct
909                       Word16 vad_flag,       // i   : vad decision
910                       enum Mode *usedMode    // i/o : mode changed or not
911                       )
912 {
913    Word16 compute_new_sid_possible;
914
915    // this state machine is in synch with the GSMEFR txDtx machine
916    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
917
918    compute_new_sid_possible = 0;
919
920    if (vad_flag != 0)
921    {
922       st->dtxHangoverCount = DTX_HANG_CONST;
923    }
924    else
925    {  // non-speech
926       if (st->dtxHangoverCount == 0)
927       {  // out of decoder analysis hangover
928          st->decAnaElapsedCount = 0;
929          *usedMode = MRDTX;
930          compute_new_sid_possible = 1;
931       }
932       else
933       { // in possible analysis hangover
934          st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
935
936          // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH
937          if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
938                  DTX_ELAPSED_FRAMES_THRESH) < 0)
939          {
940             *usedMode = MRDTX;
941             // if short time since decoder update, do not add extra HO
942          }
943          // else
944          //   override VAD and stay in
945          //   speech mode *usedMode
946          //   and add extra hangover
947       }
948    }
949
950    return compute_new_sid_possible;
951 }
952
953 ------------------------------------------------------------------------------
954  CAUTION [optional]
955  [State any special notes, constraints or cautions for users of this function]
956
957 ------------------------------------------------------------------------------
958 */
959
960 Word16 tx_dtx_handler(dtx_encState *st,      /* i/o : State struct           */
961                       Word16 vad_flag,       /* i   : vad decision           */
962                       enum Mode *usedMode,   /* i/o : mode changed or not    */
963                       Flag   *pOverflow      /* i/o : overflow indicator     */
964                      )
965 {
966     Word16 compute_new_sid_possible;
967     Word16 count;
968
969     /* this state machine is in synch with the GSMEFR txDtx machine */
970     st->decAnaElapsedCount = add_16(st->decAnaElapsedCount, 1, pOverflow);
971
972     compute_new_sid_possible = 0;
973
974     if (vad_flag != 0)
975     {
976         st->dtxHangoverCount = DTX_HANG_CONST;
977     }
978     else
979     {  /* non-speech */
980         if (st->dtxHangoverCount == 0)
981         {  /* out of decoder analysis hangover  */
982             st->decAnaElapsedCount = 0;
983             *usedMode = MRDTX;
984             compute_new_sid_possible = 1;
985         }
986         else
987         { /* in possible analysis hangover */
988             st->dtxHangoverCount -= 1;
989
990             /* decAnaElapsedCount + dtxHangoverCount < */
991             /* DTX_ELAPSED_FRAMES_THRESH               */
992             count = add_16(st->decAnaElapsedCount, st->dtxHangoverCount,
993                            pOverflow);
994             if (count < DTX_ELAPSED_FRAMES_THRESH)
995             {
996                 *usedMode = MRDTX;
997                 /* if short time since decoder update, */
998                 /* do not add extra HO                 */
999             }
1000         }
1001     }
1002
1003     return(compute_new_sid_possible);
1004 }