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 
     35  Pathname: ./audio/gsm-amr/c/src/ec_gain.c
     36  Funtions:
     37 
     38      Date: 01/28/2002
     39 
     40 ------------------------------------------------------------------------------
     41  REVISION HISTORY
     42 
     43  Description: Removed the functions ec_gain_code_init, ec_gain_pitch_init,
     44  ech_gain_code_exit, and ec_gain_pitch_exit.
     45 
     46  The ec_gains related structures are no longer dynamically allocated.
     47 
     48  Description: Updated include files and input/output sections.
     49 
     50  Description:  Replaced OSCL mem type functions and eliminated include
     51                files that now are chosen by OSCL definitions
     52 
     53  Description:  Replaced "int" and/or "char" with OSCL defined types.
     54 
     55  Description: Added #ifdef __cplusplus around extern'ed table.
     56 
     57  Description:
     58 
     59 ------------------------------------------------------------------------------
     60  MODULE DESCRIPTION
     61 
     62  These modules execute the code book gains for error concealment. This module
     63  contains the init, reset, exit, and "main" functions in this process.
     64 
     65 ------------------------------------------------------------------------------
     66 */
     67 
     68 
     69 /*----------------------------------------------------------------------------
     70 ; INCLUDES
     71 ----------------------------------------------------------------------------*/
     72 #include "ec_gains.h"
     73 #include "typedef.h"
     74 #include "cnst.h"
     75 #include "gmed_n.h"
     76 #include "gc_pred.h"
     77 #include "basic_op.h"
     78 
     79 
     80 /*--------------------------------------------------------------------------*/
     81 #ifdef __cplusplus
     82 extern "C"
     83 {
     84 #endif
     85 
     86     /*----------------------------------------------------------------------------
     87     ; MACROS
     88     ; Define module specific macros here
     89     ----------------------------------------------------------------------------*/
     90 
     91 
     92     /*----------------------------------------------------------------------------
     93     ; DEFINES
     94     ; Include all pre-processor statements here. Include conditional
     95     ; compile variables also.
     96     ----------------------------------------------------------------------------*/
     97 
     98 
     99     /*----------------------------------------------------------------------------
    100     ; LOCAL FUNCTION DEFINITIONS
    101     ; Function Prototype declaration
    102     ----------------------------------------------------------------------------*/
    103 
    104 
    105     /*----------------------------------------------------------------------------
    106     ; LOCAL VARIABLE DEFINITIONS
    107     ; Variable declaration - defined here and used outside this module
    108     ----------------------------------------------------------------------------*/
    109 
    110     extern const Word16 qua_gain_pitch[];
    111     extern const Word16 qua_gain_code[];
    112 
    113 
    114     /*--------------------------------------------------------------------------*/
    115 #ifdef __cplusplus
    116 }
    117 #endif
    118 
    119 /*
    120 ------------------------------------------------------------------------------
    121  FUNCTION NAME: ec_gain_code_reset
    122 ------------------------------------------------------------------------------
    123  INPUT AND OUTPUT DEFINITIONS
    124 
    125  Inputs:
    126   state = pointer to a pointer to a structure containing code state data of
    127           stucture type ec_gain_codeState
    128 
    129  Outputs:
    130     None.
    131 
    132  Returns:
    133     None
    134 
    135  Global Variables Used:
    136     None.
    137 
    138  Local Variables Needed:
    139     None.
    140 
    141 ------------------------------------------------------------------------------
    142  FUNCTION DESCRIPTION
    143 
    144  This function resets the state data for the ec_gain module.
    145 
    146 ------------------------------------------------------------------------------
    147  REQUIREMENTS
    148 
    149  None
    150 
    151 ------------------------------------------------------------------------------
    152  REFERENCES
    153 
    154  None
    155 
    156 ------------------------------------------------------------------------------
    157  PSEUDO-CODE
    158 
    159 int ec_gain_code_reset (ec_gain_codeState *state)
    160 {
    161   Word16 i;
    162 
    163   if (state == (ec_gain_codeState *) NULL){
    164       // fprintf(stderr, "ec_gain_code_reset: invalid parameter\n");
    165       return -1;
    166   }
    167 
    168   for ( i = 0; i < 5; i++)
    169       state->gbuf[i] = 1;
    170   state->past_gain_code = 0;
    171   state->prev_gc = 1;
    172 
    173   return 0;
    174 }
    175 
    176 ------------------------------------------------------------------------------
    177  RESOURCES USED [optional]
    178 
    179  When the code is written for a specific target processor the
    180  the resources used should be documented below.
    181 
    182  HEAP MEMORY USED: x bytes
    183 
    184  STACK MEMORY USED: x bytes
    185 
    186  CLOCK CYCLES: (cycle count equation for this function) + (variable
    187                 used to represent cycle count for each subroutine
    188                 called)
    189      where: (cycle count variable) = cycle count for [subroutine
    190                                      name]
    191 
    192 ------------------------------------------------------------------------------
    193  CAUTION [optional]
    194  [State any special notes, constraints or cautions for users of this function]
    195 
    196 ------------------------------------------------------------------------------
    197 */
    198 
    199 Word16 ec_gain_code_reset(ec_gain_codeState *state)
    200 {
    201     Word16 i;
    202 
    203     if (state == (ec_gain_codeState *) NULL)
    204     {
    205         /* fprintf(stderr, "ec_gain_code_reset: invalid parameter\n"); */
    206         return -1;
    207     }
    208 
    209     for (i = 0; i < 5; i++)
    210         state->gbuf[i] = 1;
    211     state->past_gain_code = 0;
    212     state->prev_gc = 1;
    213 
    214     return 0;
    215 }
    216 
    217 /*
    218 ------------------------------------------------------------------------------
    219  FUNCTION NAME: ec_gain_code
    220 ------------------------------------------------------------------------------
    221  INPUT AND OUTPUT DEFINITIONS
    222 
    223  Inputs:
    224   st = pointer to a pointer to a structure containing code state data of
    225        stucture type ec_gain_codeState
    226   pred_state = pointer to MA predictor state of type gc_predState
    227   state  = state of the state machine of type Word16
    228   gain_code = pointer to decoded innovation gain of type Word16
    229   pOverflow = pointer to overflow indicator of type Flag
    230 
    231  Outputs:
    232   st = pointer to a pointer to a structure containing code state data of
    233        stucture type ec_gain_codeState
    234   pred_state = pointer to MA predictor state of type gc_predState
    235   pOverflow = 1 if there is an overflow else it is zero.
    236 
    237  Returns:
    238     None.
    239 
    240  Global Variables Used:
    241     None.
    242 
    243  Local Variables Needed:
    244     None.
    245 
    246 ------------------------------------------------------------------------------
    247  FUNCTION DESCRIPTION
    248 
    249 This function does error concealment using the codebook. Call this function
    250 only in BFI (instead of normal gain decoding function).
    251 
    252 ------------------------------------------------------------------------------
    253  REQUIREMENTS
    254 
    255  None.
    256 
    257 ------------------------------------------------------------------------------
    258  REFERENCES
    259 
    260  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    261 
    262 ------------------------------------------------------------------------------
    263  PSEUDO-CODE
    264 
    265     static const Word16 cdown[7] =
    266     {
    267         32767, 32112, 32112, 32112,
    268         32112, 32112, 22937
    269     };
    270 
    271     Word16 tmp;
    272     Word16 qua_ener_MR122;
    273     Word16 qua_ener;
    274 
    275     // calculate median of last five gain values
    276     tmp = gmed_n (st->gbuf,5);
    277 
    278     // new gain = minimum(median, past_gain) * cdown[state]
    279     if (sub (tmp, st->past_gain_code) > 0)
    280     {
    281         tmp = st->past_gain_code;
    282     }
    283     tmp = mult (tmp, cdown[state]);
    284     *gain_code = tmp;
    285 
    286     // update table of past quantized energies with average of
    287     // current values
    288 
    289     gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener);
    290     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
    291 }
    292 
    293 ------------------------------------------------------------------------------
    294  RESOURCES USED [optional]
    295 
    296  When the code is written for a specific target processor the
    297  the resources used should be documented below.
    298 
    299  HEAP MEMORY USED: x bytes
    300 
    301  STACK MEMORY USED: x bytes
    302 
    303  CLOCK CYCLES: (cycle count equation for this function) + (variable
    304                 used to represent cycle count for each subroutine
    305                 called)
    306      where: (cycle count variable) = cycle count for [subroutine
    307                                      name]
    308 
    309 ------------------------------------------------------------------------------
    310  CAUTION [optional]
    311  [State any special notes, constraints or cautions for users of this function]
    312 
    313 ------------------------------------------------------------------------------
    314 */
    315 void ec_gain_code(
    316     ec_gain_codeState *st,    /* i/o : State struct                     */
    317     gc_predState *pred_state, /* i/o : MA predictor state               */
    318     Word16 state,             /* i   : state of the state machine       */
    319     Word16 *gain_code,        /* o   : decoded innovation gain          */
    320     Flag   *pOverflow
    321 )
    322 {
    323     static const Word16 cdown[7] =
    324     {
    325         32767, 32112, 32112, 32112,
    326         32112, 32112, 22937
    327     };
    328 
    329     Word16 tmp;
    330     Word16 qua_ener_MR122;
    331     Word16 qua_ener;
    332 
    333     /* calculate median of last five gain values */
    334     tmp = gmed_n(st->gbuf, 5);
    335 
    336     /* new gain = minimum(median, past_gain) * cdown[state] */
    337     if (sub(tmp, st->past_gain_code, pOverflow) > 0)
    338     {
    339         tmp = st->past_gain_code;
    340     }
    341     tmp = mult(tmp, cdown[state], pOverflow);
    342     *gain_code = tmp;
    343 
    344     /* update table of past quantized energies with average of
    345      * current values
    346      */
    347     gc_pred_average_limited(pred_state, &qua_ener_MR122, &qua_ener, pOverflow);
    348     gc_pred_update(pred_state, qua_ener_MR122, qua_ener);
    349 }
    350 
    351 /****************************************************************************/
    352 
    353 /*
    354 ------------------------------------------------------------------------------
    355  FUNCTION NAME: ec_gain_code_update
    356 ------------------------------------------------------------------------------
    357  INPUT AND OUTPUT DEFINITIONS
    358 
    359  Inputs:
    360   st = pointer to a pointer to a structure containing code state data of
    361        stucture type ec_gain_codeState
    362   bfi = a flag that indicates if the frame is bad of type Word16
    363   prev_bf = a flag that indicates if the previous frame was bad of type Word16
    364   gain_code = pointer to decoded innovation gain of type Word16
    365   pOverflow = pointer to overflow indicator of type Flag
    366 
    367  Outputs:
    368   st = pointer to a pointer to a structure containing code state data of
    369        stucture type ec_gain_codeState
    370   gain_code = pointer to decoded innovation gain of type Word16
    371   pOverflow = 1 if there is an overflow else it is zero.
    372 
    373  Returns:
    374     None.
    375 
    376  Global Variables Used:
    377     None.
    378 
    379  Local Variables Needed:
    380     None.
    381 
    382 ------------------------------------------------------------------------------
    383  FUNCTION DESCRIPTION
    384 
    385   Purpose     : update the codebook gain concealment state;
    386                 limit gain_code if the previous frame was bad
    387                 Call this function always after decoding (or concealing)
    388                 the gain
    389 
    390 ------------------------------------------------------------------------------
    391  REQUIREMENTS
    392 
    393  None.
    394 
    395 ------------------------------------------------------------------------------
    396  REFERENCES
    397 
    398  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    399 
    400 ------------------------------------------------------------------------------
    401  PSEUDO-CODE
    402 
    403     Word16 i;
    404 
    405     // limit gain_code by previous good gain if previous frame was bad
    406     if (bfi == 0)
    407     {
    408         if (prev_bf != 0)
    409         {
    410             if (sub (*gain_code, st->prev_gc) > 0)
    411             {
    412                 *gain_code = st->prev_gc;
    413             }
    414         }
    415         st->prev_gc = *gain_code;
    416     }
    417 
    418     // update EC states: previous gain, gain buffer
    419     st->past_gain_code = *gain_code;
    420 
    421     for (i = 1; i < 5; i++)
    422     {
    423         st->gbuf[i - 1] = st->gbuf[i];
    424     }
    425     st->gbuf[4] = *gain_code;
    426 
    427     return;
    428 }
    429 
    430 ------------------------------------------------------------------------------
    431  RESOURCES USED [optional]
    432 
    433  When the code is written for a specific target processor the
    434  the resources used should be documented below.
    435 
    436  HEAP MEMORY USED: x bytes
    437 
    438  STACK MEMORY USED: x bytes
    439 
    440  CLOCK CYCLES: (cycle count equation for this function) + (variable
    441                 used to represent cycle count for each subroutine
    442                 called)
    443      where: (cycle count variable) = cycle count for [subroutine
    444                                      name]
    445 
    446 ------------------------------------------------------------------------------
    447  CAUTION [optional]
    448  [State any special notes, constraints or cautions for users of this function]
    449 
    450 ------------------------------------------------------------------------------
    451 */
    452 void ec_gain_code_update(
    453     ec_gain_codeState *st,    /* i/o : State struct                     */
    454     Word16 bfi,               /* i   : flag: frame is bad               */
    455     Word16 prev_bf,           /* i   : flag: previous frame was bad     */
    456     Word16 *gain_code,        /* i/o : decoded innovation gain          */
    457     Flag   *pOverflow
    458 )
    459 {
    460     Word16 i;
    461 
    462     /* limit gain_code by previous good gain if previous frame was bad */
    463     if (bfi == 0)
    464     {
    465         if (prev_bf != 0)
    466         {
    467             if (sub(*gain_code, st->prev_gc, pOverflow) > 0)
    468             {
    469                 *gain_code = st->prev_gc;
    470             }
    471         }
    472         st->prev_gc = *gain_code;
    473     }
    474 
    475     /* update EC states: previous gain, gain buffer */
    476     st->past_gain_code = *gain_code;
    477 
    478     for (i = 1; i < 5; i++)
    479     {
    480         st->gbuf[i - 1] = st->gbuf[i];
    481     }
    482     st->gbuf[4] = *gain_code;
    483 
    484     return;
    485 }
    486 
    487 /****************************************************************************/
    488 
    489 /*
    490 ------------------------------------------------------------------------------
    491  FUNCTION NAME: ec_gain_pitch
    492 ------------------------------------------------------------------------------
    493  INPUT AND OUTPUT DEFINITIONS
    494 
    495  Inputs:
    496   st = pointer to a pointer to a structure containing code
    497        state data of stucture type ec_gain_pitchState
    498   state = state of the state machine of type Word16
    499   pOverflow = pointer to overflow indicator of type Flag
    500 
    501   Outputs:
    502   state = pointer to a pointer to a structure containing code
    503           state data of stucture type ec_gain_pitchState
    504   gain_pitch = pointer to pitch gain (Q14) of type Word16
    505   pOverflow = 1 if there is an overflow else it is zero.
    506 
    507  Returns:
    508     None.
    509 
    510  Global Variables Used:
    511     None.
    512 
    513  Local Variables Needed:
    514     None.
    515 
    516 ------------------------------------------------------------------------------
    517  FUNCTION DESCRIPTION
    518 
    519  This function conceals the error using code gain implementation in this
    520  function.
    521 
    522 ------------------------------------------------------------------------------
    523  REQUIREMENTS
    524 
    525  None.
    526 
    527 ------------------------------------------------------------------------------
    528  REFERENCES
    529 
    530  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    531 
    532 ------------------------------------------------------------------------------
    533  PSEUDO-CODE
    534 
    535 
    536     static const Word16 pdown[7] =
    537     {
    538         32767, 32112, 32112, 26214,
    539         9830, 6553, 6553
    540     };
    541 
    542     Word16 tmp;
    543 
    544     // calculate median of last five gains
    545     tmp = gmed_n (st->pbuf, 5);
    546 
    547     // new gain = minimum(median, past_gain) * pdown[state]
    548     if (sub (tmp, st->past_gain_pit) > 0)
    549     {
    550         tmp = st->past_gain_pit;
    551     }
    552     *gain_pitch = mult (tmp, pdown[state]);
    553 
    554 
    555 ------------------------------------------------------------------------------
    556  RESOURCES USED [optional]
    557 
    558  When the code is written for a specific target processor the
    559  the resources used should be documented below.
    560 
    561  HEAP MEMORY USED: x bytes
    562 
    563  STACK MEMORY USED: x bytes
    564 
    565  CLOCK CYCLES: (cycle count equation for this function) + (variable
    566                 used to represent cycle count for each subroutine
    567                 called)
    568      where: (cycle count variable) = cycle count for [subroutine
    569                                      name]
    570 
    571 ------------------------------------------------------------------------------
    572  CAUTION [optional]
    573  [State any special notes, constraints or cautions for users of this function]
    574 
    575 ------------------------------------------------------------------------------
    576 */
    577 void ec_gain_pitch(
    578     ec_gain_pitchState *st, /* i/o : state variables                   */
    579     Word16 state,           /* i   : state of the state machine        */
    580     Word16 *gain_pitch,     /* o   : pitch gain (Q14)                  */
    581     Flag   *pOverflow
    582 )
    583 {
    584     static const Word16 pdown[7] =
    585     {
    586         32767, 32112, 32112, 26214,
    587         9830, 6553, 6553
    588     };
    589 
    590     Word16 tmp;
    591 
    592     /* calculate median of last five gains */
    593     tmp = gmed_n(st->pbuf, 5);
    594 
    595     /* new gain = minimum(median, past_gain) * pdown[state] */
    596     if (sub(tmp, st->past_gain_pit, pOverflow) > 0)
    597     {
    598         tmp = st->past_gain_pit;
    599     }
    600     *gain_pitch = mult(tmp, pdown[state], pOverflow);
    601 }
    602 
    603 /****************************************************************************/
    604 /*
    605 ------------------------------------------------------------------------------
    606  FUNCTION NAME: ec_gain_pitch_reset
    607 ------------------------------------------------------------------------------
    608  INPUT AND OUTPUT DEFINITIONS
    609 
    610  Inputs:
    611   state = state of the state machine of type Word16
    612   pOverflow = pointer to overflow indicator of type Flag
    613 
    614   Outputs:
    615   state = pointer to a pointer to a structure containing code
    616           state data of stucture type ec_gain_pitchState
    617   pOverflow = 1 if there is an overflow else it is zero.
    618 
    619  Returns:
    620     None.
    621 
    622  Global Variables Used:
    623     None.
    624 
    625  Local Variables Needed:
    626     None.
    627 
    628 ------------------------------------------------------------------------------
    629  FUNCTION DESCRIPTION
    630 
    631  Function:   ec_gain_pitch_reset
    632  Purpose:    Resets state memory
    633 
    634 ------------------------------------------------------------------------------
    635  REQUIREMENTS
    636 
    637  None.
    638 
    639 ------------------------------------------------------------------------------
    640  REFERENCES
    641 
    642  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    643 
    644 ------------------------------------------------------------------------------
    645  PSEUDO-CODE
    646 
    647 int ec_gain_pitch_reset (ec_gain_pitchState *state)
    648 {
    649   Word16 i;
    650 
    651   if (state == (ec_gain_pitchState *) NULL){
    652       // fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n");
    653       return -1;
    654   }
    655 
    656   for(i = 0; i < 5; i++)
    657       state->pbuf[i] = 1640;
    658   state->past_gain_pit = 0;
    659   state->prev_gp = 16384;
    660 
    661   return 0;
    662 }
    663 
    664 ------------------------------------------------------------------------------
    665  RESOURCES USED [optional]
    666 
    667  When the code is written for a specific target processor the
    668  the resources used should be documented below.
    669 
    670  HEAP MEMORY USED: x bytes
    671 
    672  STACK MEMORY USED: x bytes
    673 
    674  CLOCK CYCLES: (cycle count equation for this function) + (variable
    675                 used to represent cycle count for each subroutine
    676                 called)
    677      where: (cycle count variable) = cycle count for [subroutine
    678                                      name]
    679 
    680 ------------------------------------------------------------------------------
    681  CAUTION [optional]
    682  [State any special notes, constraints or cautions for users of this function]
    683 
    684 ------------------------------------------------------------------------------
    685 */
    686 Word16 ec_gain_pitch_reset(ec_gain_pitchState *state)
    687 {
    688     Word16 i;
    689 
    690     if (state == (ec_gain_pitchState *) NULL)
    691     {
    692         /* fprintf(stderr, "ec_gain_pitch_reset: invalid parameter\n"); */
    693         return -1;
    694     }
    695 
    696     for (i = 0; i < 5; i++)
    697         state->pbuf[i] = 1640;
    698     state->past_gain_pit = 0;
    699     state->prev_gp = 16384;
    700 
    701     return 0;
    702 }
    703 
    704 /****************************************************************************/
    705 
    706 
    707 /*
    708 ------------------------------------------------------------------------------
    709  FUNCTION NAME: ec_gain_pitch_update
    710 ------------------------------------------------------------------------------
    711  INPUT AND OUTPUT DEFINITIONS
    712 
    713  Inputs:
    714   st = pointer to a pointer to a structure containing code
    715        state data of stucture type ec_gain_pitchState
    716   bfi = flag indicating the frame is bad of type Word16
    717   prev_bf = flag indicating the previous frame was bad of type Word16
    718   gain_pitch = pointer to pitch gain of type Word16
    719   pOverflow = pointer to overflow indicator of type Flag
    720 
    721   Outputs:
    722   state = pointer to a pointer to a structure containing code
    723           state data of stucture type ec_gain_pitchState
    724   gain_pitch = pointer to pitch gain of type Word16
    725   pOverflow = 1 if there is an overflow else it is zero.
    726 
    727  Returns:
    728     None.
    729 
    730  Global Variables Used:
    731     None.
    732 
    733  Local Variables Needed:
    734     None.
    735 
    736 ------------------------------------------------------------------------------
    737  FUNCTION DESCRIPTION
    738 
    739   Purpose     : update the pitch gain concealment state;
    740                 limit gain_pitch if the previous frame was bad
    741                 Call this function always after decoding (or concealing)
    742                 the gain
    743 
    744 ------------------------------------------------------------------------------
    745  REQUIREMENTS
    746 
    747  None.
    748 
    749 ------------------------------------------------------------------------------
    750  REFERENCES
    751 
    752  ec_gain.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    753 
    754 ------------------------------------------------------------------------------
    755  PSEUDO-CODE
    756 
    757     Word16 i;
    758 
    759     if (bfi == 0)
    760     {
    761         if (prev_bf != 0)
    762         {
    763             if (sub (*gain_pitch, st->prev_gp) > 0)
    764             {
    765                 *gain_pitch = st->prev_gp;
    766             }
    767         }
    768         st->prev_gp = *gain_pitch;
    769     }
    770 
    771     st->past_gain_pit = *gain_pitch;
    772 
    773     if (sub (st->past_gain_pit, 16384) > 0)  // if (st->past_gain_pit > 1.0)
    774     {
    775         st->past_gain_pit = 16384;
    776     }
    777     for (i = 1; i < 5; i++)
    778     {
    779         st->pbuf[i - 1] = st->pbuf[i];
    780     }
    781     st->pbuf[4] = st->past_gain_pit;
    782 
    783 
    784 ------------------------------------------------------------------------------
    785  RESOURCES USED [optional]
    786 
    787  When the code is written for a specific target processor the
    788  the resources used should be documented below.
    789 
    790  HEAP MEMORY USED: x bytes
    791 
    792  STACK MEMORY USED: x bytes
    793 
    794  CLOCK CYCLES: (cycle count equation for this function) + (variable
    795                 used to represent cycle count for each subroutine
    796                 called)
    797      where: (cycle count variable) = cycle count for [subroutine
    798                                      name]
    799 
    800 ------------------------------------------------------------------------------
    801  CAUTION [optional]
    802  [State any special notes, constraints or cautions for users of this function]
    803 
    804 ------------------------------------------------------------------------------
    805 */
    806 void ec_gain_pitch_update(
    807     ec_gain_pitchState *st, /* i/o : state variables                   */
    808     Word16 bfi,             /* i   : flag: frame is bad                */
    809     Word16 prev_bf,         /* i   : flag: previous frame was bad      */
    810     Word16 *gain_pitch,     /* i/o : pitch gain                        */
    811     Flag   *pOverflow
    812 )
    813 {
    814     Word16 i;
    815 
    816     if (bfi == 0)
    817     {
    818         if (prev_bf != 0)
    819         {
    820             if (sub(*gain_pitch, st->prev_gp, pOverflow) > 0)
    821             {
    822                 *gain_pitch = st->prev_gp;
    823             }
    824         }
    825         st->prev_gp = *gain_pitch;
    826     }
    827 
    828     st->past_gain_pit = *gain_pitch;
    829 
    830     if (sub(st->past_gain_pit, 16384, pOverflow) > 0)
    831         /* if (st->past_gain_pit > 1.0) */
    832     {
    833         st->past_gain_pit = 16384;
    834     }
    835     for (i = 1; i < 5; i++)
    836     {
    837         st->pbuf[i - 1] = st->pbuf[i];
    838     }
    839     st->pbuf[4] = st->past_gain_pit;
    840 }
    841 
    842 
    843