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/****************************************************************************************
19Portions 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)
26Permission to distribute, modify and use this file under the standard license
27terms 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----------------------------------------------------------------------------*/
133extern Word32 L_add(register Word32 L_var1, register 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
193int 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
239Word16 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
306int 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
360Word16 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
432void 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
467void 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
532int 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
666void 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    register 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
873int 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
939void 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    register 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
1051Word16 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
1119Word16 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