Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /****************************************************************************************
     19 Portions of this file are derived from the following 3GPP standard:
     20 
     21     3GPP TS 26.073
     22     ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
     23     Available from http://www.3gpp.org
     24 
     25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
     26 Permission to distribute, modify and use this file under the standard license
     27 terms listed above has been obtained from the copyright holder.
     28 ****************************************************************************************/
     29 /*
     30 ------------------------------------------------------------------------------
     31 
     32 
     33 
     34  Pathname: ./audio/gsm-amr/c/src/dtx_enc.c
     35  Funtions: dtx_enc_init
     36            dtx_enc_reset
     37            dtx_enc_exit
     38            dtx_enc
     39            dtx_buffer
     40            tx_dtx_handler
     41 
     42      Date: 06/08/2000
     43 
     44 ------------------------------------------------------------------------------
     45  REVISION HISTORY
     46 
     47  Description: Updated template used to PV coding template. First attempt at
     48           optimizing C code.
     49 
     50  Description: Updated file per comments gathered from Phase 2/3 review.
     51           Synched up with new template (Inputs/Outputs section). Deleted
     52           lines leftover from original code prior to the code section of
     53           dtx_enc_exit function. Deleted confusing comment in the log_en
     54           calculation in dtx_enc function. Restructured IF statement in
     55           the calculation of the sum of squares of speech signals in
     56           dtx_buffer.
     57 
     58  Description: Added setting of Overflow flag in inlined code.
     59 
     60  Description: Synchronized file with UTMS version 3.2.0. Updated coding
     61               template. Removed unnecessary include files.
     62 
     63  Description: Made the following changes per comments from Phase 2/3 review:
     64               1. Modified FOR loops to count down.
     65               2. Fixed typecasting issue with TI C compiler.
     66               3. Fixed comment in dtx_enc pseudo-code.
     67               4. Added dtx_enc code comment pertaining to possible assembly
     68                  implementation.
     69 
     70  Description: Added calls to add() in tx_dtx_handler. Updated copyright year.
     71 
     72  Description: Pass in pointer to overflow flag to all functions requiring this
     73               flag. This is to make the library EPOC compatible.
     74 
     75  Description:  For dtx_enc_reset() only
     76               1. Replaced copy() with memcpy.
     77               2. Eliminated include file copy.h
     78               3. Eliminated printf statement
     79               For dtx_buffer()
     80               1. Replaced copy() with memcpy.
     81               2. Eliminated math operations that unnecessary checked for
     82                  saturation, in some cases this by shifting before adding and
     83                  in other cases by evaluating the operands
     84               3. Unrolled loop to speed up execution
     85 
     86  Description:  For dtx_buffer()
     87               1. Modified scaling and added check for saturation. Previous
     88                  scaling was correct but altered precision, this cause bit
     89                  exactness test failure.
     90 
     91  Description:  For dtx_buffer()
     92               1. Modified scaling and saturation checks. Previous
     93                  scaling was correct but altered precision, this cause bit
     94                  exactness test failure for dtx vad2.
     95 
     96  Description:  Replaced OSCL mem type functions and eliminated include
     97                files that now are chosen by OSCL definitions
     98 
     99  Description:  Replaced "int" and/or "char" with OSCL defined types.
    100 
    101  Description:
    102 
    103 ------------------------------------------------------------------------------
    104  MODULE DESCRIPTION
    105 
    106  This file contains the various functions that perform the computation of the
    107  Silence Indicator (SID) parameters when in Discontinuous Transmission (DTX)
    108  mode.
    109 
    110 ------------------------------------------------------------------------------
    111 */
    112 
    113 
    114 /*----------------------------------------------------------------------------
    115 ; INCLUDES
    116 ----------------------------------------------------------------------------*/
    117 #include <stdlib.h>
    118 #include <string.h>
    119 
    120 #include "dtx_enc.h"
    121 #include "q_plsf.h"
    122 #include "typedef.h"
    123 #include "mode.h"
    124 #include "basic_op.h"
    125 #include "log2.h"
    126 #include "lsp_lsf.h"
    127 #include "reorder.h"
    128 
    129 /*----------------------------------------------------------------------------
    130 ; MACROS
    131 ; Define module specific macros here
    132 ----------------------------------------------------------------------------*/
    133 extern Word32 L_add(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 
    193 int dtx_enc_init (dtx_encState **st)
    194 {
    195   dtx_encState* s;
    196 
    197   if (st == (dtx_encState **) NULL){
    198     fprintf(stderr, "dtx_enc_init: invalid parameter\n");
    199     return -1;
    200   }
    201 
    202   *st = NULL;
    203 
    204   // allocate memory
    205   if ((s= (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL){
    206     fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
    207     return -1;
    208   }
    209 
    210   dtx_enc_reset(s);
    211   *st = s;
    212 
    213   return 0;
    214 }
    215 
    216 ------------------------------------------------------------------------------
    217  RESOURCES USED [optional]
    218 
    219  When the code is written for a specific target processor the
    220  the resources used should be documented below.
    221 
    222  HEAP MEMORY USED: x bytes
    223 
    224  STACK MEMORY USED: x bytes
    225 
    226  CLOCK CYCLES: (cycle count equation for this function) + (variable
    227                 used to represent cycle count for each subroutine
    228                 called)
    229      where: (cycle count variable) = cycle count for [subroutine
    230                                      name]
    231 
    232 ------------------------------------------------------------------------------
    233  CAUTION [optional]
    234  [State any special notes, constraints or cautions for users of this function]
    235 
    236 ------------------------------------------------------------------------------
    237 */
    238 
    239 Word16 dtx_enc_init(dtx_encState **st)
    240 {
    241     dtx_encState* s;
    242 
    243     if (st == (dtx_encState **) NULL)
    244     {
    245         return(-1);
    246     }
    247 
    248     *st = NULL;
    249 
    250     /* allocate memory */
    251     if ((s = (dtx_encState *) malloc(sizeof(dtx_encState))) == NULL)
    252     {
    253         return(-1);
    254     }
    255 
    256     dtx_enc_reset(s);
    257     *st = s;
    258 
    259     return(0);
    260 }
    261 
    262 /****************************************************************************/
    263 
    264 /*
    265 ------------------------------------------------------------------------------
    266  FUNCTION NAME: dtx_enc_reset
    267 ------------------------------------------------------------------------------
    268  INPUT AND OUTPUT DEFINITIONS
    269 
    270  Inputs:
    271     st = pointer to structures of type dtx_encState
    272 
    273  Outputs:
    274     structure pointed to by st is initialized to its reset value
    275 
    276  Returns:
    277     return_value = 1, if reset was successful; -1, otherwise (int)
    278 
    279  Global Variables Used:
    280     None
    281 
    282  Local Variables Needed:
    283     lsp_init_data = table containing LSP initialization values;
    284             table elements are constants of type Word16;
    285             table length is M
    286 
    287 ------------------------------------------------------------------------------
    288  FUNCTION DESCRIPTION
    289 
    290  This function initializes the fields of the state memory used by dtx_enc
    291  to their reset values.
    292 
    293 ------------------------------------------------------------------------------
    294  REQUIREMENTS
    295 
    296  None
    297 
    298 ------------------------------------------------------------------------------
    299  REFERENCES
    300 
    301  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    302 
    303 ------------------------------------------------------------------------------
    304  PSEUDO-CODE
    305 
    306 int dtx_enc_reset (dtx_encState *st)
    307 {
    308   Word16 i;
    309 
    310   if (st == (dtx_encState *) NULL){
    311     fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
    312     return -1;
    313   }
    314 
    315   st->hist_ptr = 0;
    316   st->log_en_index = 0;
    317   st->init_lsf_vq_index = 0;
    318   st->lsp_index[0] = 0;
    319   st->lsp_index[1] = 0;
    320   st->lsp_index[2] = 0;
    321 
    322   // Init lsp_hist[]
    323   for(i = 0; i < DTX_HIST_SIZE; i++)
    324   {
    325     Copy(lsp_init_data, &st->lsp_hist[i * M], M);
    326   }
    327 
    328   // Reset energy history
    329   Set_zero(st->log_en_hist, M);
    330 
    331   st->dtxHangoverCount = DTX_HANG_CONST;
    332   st->decAnaElapsedCount = 32767;
    333 
    334   return 1;
    335 }
    336 
    337 ------------------------------------------------------------------------------
    338  RESOURCES USED [optional]
    339 
    340  When the code is written for a specific target processor the
    341  the resources used should be documented below.
    342 
    343  HEAP MEMORY USED: x bytes
    344 
    345  STACK MEMORY USED: x bytes
    346 
    347  CLOCK CYCLES: (cycle count equation for this function) + (variable
    348                 used to represent cycle count for each subroutine
    349                 called)
    350      where: (cycle count variable) = cycle count for [subroutine
    351                                      name]
    352 
    353 ------------------------------------------------------------------------------
    354  CAUTION [optional]
    355  [State any special notes, constraints or cautions for users of this function]
    356 
    357 ------------------------------------------------------------------------------
    358 */
    359 
    360 Word16 dtx_enc_reset(dtx_encState *st)
    361 {
    362     Word16 i;
    363 
    364     if (st == (dtx_encState *) NULL)
    365     {
    366         return(-1);
    367     }
    368 
    369     st->hist_ptr = 0;
    370     st->log_en_index = 0;
    371     st->init_lsf_vq_index = 0;
    372     st->lsp_index[0] = 0;
    373     st->lsp_index[1] = 0;
    374     st->lsp_index[2] = 0;
    375 
    376     /* Init lsp_hist[] */
    377     for (i = 0; i < DTX_HIST_SIZE; i++)
    378     {
    379         memcpy(&st->lsp_hist[i * M], lsp_init_data, M*sizeof(Word16));
    380     }
    381 
    382     /* Reset energy history */
    383     memset(st->log_en_hist, 0, sizeof(Word16)*M);
    384     st->dtxHangoverCount = DTX_HANG_CONST;
    385     st->decAnaElapsedCount = 32767;
    386 
    387     return(1);
    388 }
    389 
    390 /****************************************************************************/
    391 
    392 /*
    393 ------------------------------------------------------------------------------
    394  FUNCTION NAME: dtx_enc_exit
    395 ------------------------------------------------------------------------------
    396  INPUT AND OUTPUT DEFINITIONS
    397 
    398  Inputs:
    399     st = pointer to an array of pointers to structures of type
    400          dtx_encState
    401 
    402  Outputs:
    403     st points to the NULL address
    404 
    405  Returns:
    406     None
    407 
    408  Global Variables Used:
    409     None
    410 
    411  Local Variables Needed:
    412     None
    413 
    414 ------------------------------------------------------------------------------
    415  FUNCTION DESCRIPTION
    416 
    417  This function deallocates the state memory used by dtx_enc function.
    418 
    419 ------------------------------------------------------------------------------
    420  REQUIREMENTS
    421 
    422  None
    423 
    424 ------------------------------------------------------------------------------
    425  REFERENCES
    426 
    427  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    428 
    429 ------------------------------------------------------------------------------
    430  PSEUDO-CODE
    431 
    432 void dtx_enc_exit (dtx_encState **st)
    433 {
    434    if (st == NULL || *st == NULL)
    435       return;
    436 
    437    // deallocate memory
    438    free(*st);
    439    *st = NULL;
    440 
    441    return;
    442 }
    443 
    444 ------------------------------------------------------------------------------
    445  RESOURCES USED [optional]
    446 
    447  When the code is written for a specific target processor the
    448  the resources used should be documented below.
    449 
    450  HEAP MEMORY USED: x bytes
    451 
    452  STACK MEMORY USED: x bytes
    453 
    454  CLOCK CYCLES: (cycle count equation for this function) + (variable
    455                 used to represent cycle count for each subroutine
    456                 called)
    457      where: (cycle count variable) = cycle count for [subroutine
    458                                      name]
    459 
    460 ------------------------------------------------------------------------------
    461  CAUTION [optional]
    462  [State any special notes, constraints or cautions for users of this function]
    463 
    464 ------------------------------------------------------------------------------
    465 */
    466 
    467 void dtx_enc_exit(dtx_encState **st)
    468 {
    469     if (st == NULL || *st == NULL)
    470     {
    471         return;
    472     }
    473 
    474     /* deallocate memory */
    475     free(*st);
    476     *st = NULL;
    477 
    478     return;
    479 }
    480 
    481 /****************************************************************************/
    482 
    483 /*
    484 ------------------------------------------------------------------------------
    485  FUNCTION NAME: dtx_enc
    486 ------------------------------------------------------------------------------
    487  INPUT AND OUTPUT DEFINITIONS
    488 
    489  Inputs:
    490     st = pointer to structures of type dtx_encState
    491     computeSidFlag = compute SID flag of type Word16
    492     qSt = pointer to structures of type Q_plsfState
    493     predState = pointer to structures of type gc_predState
    494     anap = pointer to an array of pointers to analysis parameters of
    495            type Word16
    496 
    497  Outputs:
    498     structure pointed to by st contains the newly calculated SID
    499       parameters
    500     structure pointed to by predState contains the new logarithmic frame
    501       energy
    502     pointer pointed to by anap points to the location of the new
    503       logarithmic frame energy and new LSPs
    504 
    505  Returns:
    506     return_value = 0 (int)
    507 
    508  Global Variables Used:
    509     None
    510 
    511  Local Variables Needed:
    512     None
    513 
    514 ------------------------------------------------------------------------------
    515  FUNCTION DESCRIPTION
    516 
    517  This function calculates the SID parameters when in the DTX mode.
    518 
    519 ------------------------------------------------------------------------------
    520  REQUIREMENTS
    521 
    522  None
    523 
    524 ------------------------------------------------------------------------------
    525  REFERENCES
    526 
    527  dtx_enc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    528 
    529 ------------------------------------------------------------------------------
    530  PSEUDO-CODE
    531 
    532 int dtx_enc(dtx_encState *st,        // i/o : State struct
    533             Word16 computeSidFlag,   // i   : compute SID
    534             Q_plsfState *qSt,        // i/o : Qunatizer state struct
    535             gc_predState* predState, // i/o : State struct
    536         Word16 **anap            // o   : analysis parameters
    537         )
    538 {
    539    Word16 i,j;
    540    Word16 log_en;
    541    Word16 lsf[M];
    542    Word16 lsp[M];
    543    Word16 lsp_q[M];
    544    Word32 L_lsp[M];
    545 
    546    // VOX mode computation of SID parameters
    547    if ((computeSidFlag != 0)  ||
    548         (st->log_en_index == 0))
    549    {
    550       // compute new SID frame if safe i.e don't
    551       // compute immediately after a talk spurt
    552       log_en = 0;
    553       for (i = 0; i < M; i++)
    554       {
    555          L_lsp[i] = 0;
    556       }
    557 
    558       // average energy and lsp
    559       for (i = 0; i < DTX_HIST_SIZE; i++)
    560       {
    561          log_en = add(log_en,
    562                       shr(st->log_en_hist[i],2));
    563 
    564          for (j = 0; j < M; j++)
    565          {
    566             L_lsp[j] = L_add(L_lsp[j],
    567                              L_deposit_l(st->lsp_hist[i * M + j]));
    568          }
    569       }
    570 
    571       log_en = shr(log_en, 1);
    572       for (j = 0; j < M; j++)
    573       {
    574          lsp[j] = extract_l(L_shr(L_lsp[j], 3));   // divide by 8
    575       }
    576 
    577       //  quantize logarithmic energy to 6 bits
    578       st->log_en_index = add(log_en, 2560);          // +2.5 in Q10
    579       st->log_en_index = add(st->log_en_index, 128); // add 0.5/4 in Q10
    580       st->log_en_index = shr(st->log_en_index, 8);
    581 
    582       if (sub(st->log_en_index, 63) > 0)
    583       {
    584          st->log_en_index = 63;
    585       }
    586       if (st->log_en_index < 0)
    587       {
    588          st->log_en_index = 0;
    589       }
    590 
    591       // update gain predictor memory
    592       log_en = shl(st->log_en_index, -2+10); // Q11 and divide by 4
    593       log_en = sub(log_en, 2560);            // add 2.5 in Q11
    594 
    595       log_en = sub(log_en, 9000);
    596       if (log_en > 0)
    597       {
    598          log_en = 0;
    599       }
    600       if (sub(log_en, -14436) < 0)
    601       {
    602          log_en = -14436;
    603       }
    604 
    605       // past_qua_en for other modes than MR122
    606       predState->past_qua_en[0] = log_en;
    607       predState->past_qua_en[1] = log_en;
    608       predState->past_qua_en[2] = log_en;
    609       predState->past_qua_en[3] = log_en;
    610 
    611       // scale down by factor 20*log10(2) in Q15
    612       log_en = mult(5443, log_en);
    613 
    614       // past_qua_en for mode MR122
    615       predState->past_qua_en_MR122[0] = log_en;
    616       predState->past_qua_en_MR122[1] = log_en;
    617       predState->past_qua_en_MR122[2] = log_en;
    618       predState->past_qua_en_MR122[3] = log_en;
    619 
    620       // make sure that LSP's are ordered
    621       Lsp_lsf(lsp, lsf, M);
    622       Reorder_lsf(lsf, LSF_GAP, M);
    623       Lsf_lsp(lsf, lsp, M);
    624 
    625       // Quantize lsp and put on parameter list
    626       Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
    627                &st->init_lsf_vq_index);
    628    }
    629 
    630    *(*anap)++ = st->init_lsf_vq_index; // 3 bits
    631 
    632    *(*anap)++ = st->lsp_index[0];      // 8 bits
    633    *(*anap)++ = st->lsp_index[1];      // 9 bits
    634    *(*anap)++ = st->lsp_index[2];      // 9 bits
    635 
    636 
    637    *(*anap)++ = st->log_en_index;      // 6 bits
    638                                        // = 35 bits
    639 
    640    return 0;
    641 }
    642 
    643 ------------------------------------------------------------------------------
    644  RESOURCES USED [optional]
    645 
    646  When the code is written for a specific target processor the
    647  the resources used should be documented below.
    648 
    649  HEAP MEMORY USED: x bytes
    650 
    651  STACK MEMORY USED: x bytes
    652 
    653  CLOCK CYCLES: (cycle count equation for this function) + (variable
    654                 used to represent cycle count for each subroutine
    655                 called)
    656      where: (cycle count variable) = cycle count for [subroutine
    657                                      name]
    658 
    659 ------------------------------------------------------------------------------
    660  CAUTION [optional]
    661  [State any special notes, constraints or cautions for users of this function]
    662 
    663 ------------------------------------------------------------------------------
    664 */
    665 
    666 void dtx_enc(dtx_encState *st,        /* i/o : State struct                  */
    667              Word16 computeSidFlag,   /* i   : compute SID                   */
    668              Q_plsfState *qSt,        /* i/o : Qunatizer state struct        */
    669              gc_predState* predState, /* i/o : State struct                  */
    670              Word16 **anap,           /* o   : analysis parameters           */
    671              Flag   *pOverflow        /* i/o : overflow indicator            */
    672             )
    673 {
    674     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 
    873 int dtx_buffer(dtx_encState *st,   // i/o : State struct
    874                Word16 lsp_new[],   // i   : LSP vector
    875                Word16 speech[]     // i   : speech samples
    876 )
    877 {
    878    Word16 i;
    879    Word32 L_frame_en;
    880    Word16 log_en_e;
    881    Word16 log_en_m;
    882    Word16 log_en;
    883 
    884    // update pointer to circular buffer
    885    st->hist_ptr = add(st->hist_ptr, 1);
    886    if (sub(st->hist_ptr, DTX_HIST_SIZE) == 0)
    887    {
    888       st->hist_ptr = 0;
    889    }
    890 
    891    // copy lsp vector into buffer
    892    Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
    893 
    894    // compute log energy based on frame energy
    895    L_frame_en = 0;     // Q0
    896    for (i=0; i < L_FRAME; i++)
    897    {
    898       L_frame_en = L_mac(L_frame_en, speech[i], speech[i]);
    899    }
    900    Log2(L_frame_en, &log_en_e, &log_en_m);
    901 
    902    // convert exponent and mantissa to Word16 Q10
    903    log_en = shl(log_en_e, 10);  // Q10
    904    log_en = add(log_en, shr(log_en_m, 15-10));
    905 
    906    // divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193
    907    log_en = sub(log_en, 8521);
    908 
    909    // insert into log energy buffer with division by 2
    910    log_en = shr(log_en, 1);
    911    st->log_en_hist[st->hist_ptr] = log_en; // Q10
    912 
    913    return 0;
    914 }
    915 
    916 ------------------------------------------------------------------------------
    917  RESOURCES USED [optional]
    918 
    919  When the code is written for a specific target processor the
    920  the resources used should be documented below.
    921 
    922  HEAP MEMORY USED: x bytes
    923 
    924  STACK MEMORY USED: x bytes
    925 
    926  CLOCK CYCLES: (cycle count equation for this function) + (variable
    927                 used to represent cycle count for each subroutine
    928                 called)
    929      where: (cycle count variable) = cycle count for [subroutine
    930                                      name]
    931 
    932 ------------------------------------------------------------------------------
    933  CAUTION [optional]
    934  [State any special notes, constraints or cautions for users of this function]
    935 
    936 ------------------------------------------------------------------------------
    937 */
    938 
    939 void dtx_buffer(dtx_encState *st,   /* i/o : State struct                    */
    940                 Word16 lsp_new[],   /* i   : LSP vector                      */
    941                 Word16 speech[],    /* i   : speech samples                  */
    942                 Flag   *pOverflow   /* i/o : overflow indicator              */
    943                )
    944 {
    945 
    946     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 
   1051 Word16 tx_dtx_handler(dtx_encState *st,      // i/o : State struct
   1052                       Word16 vad_flag,       // i   : vad decision
   1053                       enum Mode *usedMode    // i/o : mode changed or not
   1054                       )
   1055 {
   1056    Word16 compute_new_sid_possible;
   1057 
   1058    // this state machine is in synch with the GSMEFR txDtx machine
   1059    st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
   1060 
   1061    compute_new_sid_possible = 0;
   1062 
   1063    if (vad_flag != 0)
   1064    {
   1065       st->dtxHangoverCount = DTX_HANG_CONST;
   1066    }
   1067    else
   1068    {  // non-speech
   1069       if (st->dtxHangoverCount == 0)
   1070       {  // out of decoder analysis hangover
   1071          st->decAnaElapsedCount = 0;
   1072          *usedMode = MRDTX;
   1073          compute_new_sid_possible = 1;
   1074       }
   1075       else
   1076       { // in possible analysis hangover
   1077          st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
   1078 
   1079          // decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH
   1080          if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
   1081                  DTX_ELAPSED_FRAMES_THRESH) < 0)
   1082          {
   1083             *usedMode = MRDTX;
   1084             // if short time since decoder update, do not add extra HO
   1085          }
   1086          // else
   1087          //   override VAD and stay in
   1088          //   speech mode *usedMode
   1089          //   and add extra hangover
   1090       }
   1091    }
   1092 
   1093    return compute_new_sid_possible;
   1094 }
   1095 
   1096 ------------------------------------------------------------------------------
   1097  RESOURCES USED [optional]
   1098 
   1099  When the code is written for a specific target processor the
   1100  the resources used should be documented below.
   1101 
   1102  HEAP MEMORY USED: x bytes
   1103 
   1104  STACK MEMORY USED: x bytes
   1105 
   1106  CLOCK CYCLES: (cycle count equation for this function) + (variable
   1107                 used to represent cycle count for each subroutine
   1108                 called)
   1109      where: (cycle count variable) = cycle count for [subroutine
   1110                                      name]
   1111 
   1112 ------------------------------------------------------------------------------
   1113  CAUTION [optional]
   1114  [State any special notes, constraints or cautions for users of this function]
   1115 
   1116 ------------------------------------------------------------------------------
   1117 */
   1118 
   1119 Word16 tx_dtx_handler(dtx_encState *st,      /* i/o : State struct           */
   1120                       Word16 vad_flag,       /* i   : vad decision           */
   1121                       enum Mode *usedMode,   /* i/o : mode changed or not    */
   1122                       Flag   *pOverflow      /* i/o : overflow indicator     */
   1123                      )
   1124 {
   1125     Word16 compute_new_sid_possible;
   1126     Word16 count;
   1127 
   1128     /* this state machine is in synch with the GSMEFR txDtx machine */
   1129     st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1, pOverflow);
   1130 
   1131     compute_new_sid_possible = 0;
   1132 
   1133     if (vad_flag != 0)
   1134     {
   1135         st->dtxHangoverCount = DTX_HANG_CONST;
   1136     }
   1137     else
   1138     {  /* non-speech */
   1139         if (st->dtxHangoverCount == 0)
   1140         {  /* out of decoder analysis hangover  */
   1141             st->decAnaElapsedCount = 0;
   1142             *usedMode = MRDTX;
   1143             compute_new_sid_possible = 1;
   1144         }
   1145         else
   1146         { /* in possible analysis hangover */
   1147             st->dtxHangoverCount -= 1;
   1148 
   1149             /* decAnaElapsedCount + dtxHangoverCount < */
   1150             /* DTX_ELAPSED_FRAMES_THRESH               */
   1151             count = add(st->decAnaElapsedCount, st->dtxHangoverCount,
   1152                         pOverflow);
   1153             if (count < DTX_ELAPSED_FRAMES_THRESH)
   1154             {
   1155                 *usedMode = MRDTX;
   1156                 /* if short time since decoder update, */
   1157                 /* do not add extra HO                 */
   1158             }
   1159         }
   1160     }
   1161 
   1162     return(compute_new_sid_possible);
   1163 }
   1164