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