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  Pathname: ./audio/gsm-amr/c/src/gc_pred.c
     32  Functions:
     33             gc_pred_reset
     34             gc_pred
     35             gc_pred_update
     36             gc_pred_average_limited
     37 
     38 ------------------------------------------------------------------------------
     39  MODULE DESCRIPTION
     40 
     41  This file contains the functions that perform codebook gain MA prediction.
     42 
     43 ------------------------------------------------------------------------------
     44 */
     45 
     46 /*----------------------------------------------------------------------------
     47 ; INCLUDES
     48 ----------------------------------------------------------------------------*/
     49 #include "gc_pred.h"
     50 #include "basicop_malloc.h"
     51 #include "basic_op.h"
     52 #include "cnst.h"
     53 #include "log2.h"
     54 
     55 /*----------------------------------------------------------------------------
     56 ; MACROS
     57 ; Define module specific macros here
     58 ----------------------------------------------------------------------------*/
     59 
     60 /*----------------------------------------------------------------------------
     61 ; DEFINES
     62 ; Include all pre-processor statements here. Include conditional
     63 ; compile variables also.
     64 ----------------------------------------------------------------------------*/
     65 #define NPRED 4  /* number of prediction taps */
     66 
     67 /* average innovation energy.                               */
     68 /* MEAN_ENER  = 36.0/constant, constant = 20*Log10(2)       */
     69 #define MEAN_ENER_MR122  783741L  /* 36/(20*log10(2)) (Q17) */
     70 
     71 /* minimum quantized energy: -14 dB */
     72 #define MIN_ENERGY       (-14336)       /* 14                 Q10 */
     73 #define MIN_ENERGY_MR122  (-2381)       /* 14 / (20*log10(2)) Q10 */
     74 
     75 /*----------------------------------------------------------------------------
     76 ; LOCAL FUNCTION DEFINITIONS
     77 ; Function Prototype declaration
     78 ----------------------------------------------------------------------------*/
     79 
     80 /*----------------------------------------------------------------------------
     81 ; LOCAL VARIABLE DEFINITIONS
     82 ; Variable declaration - defined here and used outside this module
     83 ----------------------------------------------------------------------------*/
     84 
     85 /* MA prediction coefficients (Q13) */
     86 static const Word16 pred[NPRED] = {5571, 4751, 2785, 1556};
     87 
     88 /* MA prediction coefficients (Q6)  */
     89 static const Word16 pred_MR122[NPRED] = {44, 37, 22, 12};
     90 
     91 /*
     92 ------------------------------------------------------------------------------
     93  FUNCTION NAME: gc_pred_reset
     94 ------------------------------------------------------------------------------
     95  INPUT AND OUTPUT DEFINITIONS
     96 
     97  Inputs:
     98     state = pointer to a structure of type gc_predState
     99 
    100  Outputs:
    101     past_qua_en field in the structure pointed to by state is initialized
    102       to MIN_ENERGY
    103     past_qua_en_MR122 field in the structure pointed to by state is
    104       initialized to MIN_ENERGY_MR122
    105 
    106  Returns:
    107     return_value = 0, if reset was successful; -1, otherwise (int)
    108 
    109  Global Variables Used:
    110     None
    111 
    112  Local Variables Needed:
    113     None
    114 
    115 ------------------------------------------------------------------------------
    116  FUNCTION DESCRIPTION
    117 
    118  This function initializes the state memory used by gc_pred to zero.
    119 
    120 ------------------------------------------------------------------------------
    121  REQUIREMENTS
    122 
    123  None
    124 
    125 ------------------------------------------------------------------------------
    126  REFERENCES
    127 
    128  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    129 
    130 ------------------------------------------------------------------------------
    131  PSEUDO-CODE
    132 
    133 int gc_pred_reset (gc_predState *state)
    134 {
    135    Word16 i;
    136 
    137    if (state == (gc_predState *) NULL){
    138       fprintf(stderr, "gc_pred_reset: invalid parameter\n");
    139       return -1;
    140    }
    141 
    142    for(i = 0; i < NPRED; i++)
    143    {
    144       state->past_qua_en[i] = MIN_ENERGY;
    145       state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
    146    }
    147   return 0;
    148 }
    149 
    150 ------------------------------------------------------------------------------
    151  RESOURCES USED [optional]
    152 
    153  When the code is written for a specific target processor the
    154  the resources used should be documented below.
    155 
    156  HEAP MEMORY USED: x bytes
    157 
    158  STACK MEMORY USED: x bytes
    159 
    160  CLOCK CYCLES: (cycle count equation for this function) + (variable
    161                 used to represent cycle count for each subroutine
    162                 called)
    163      where: (cycle count variable) = cycle count for [subroutine
    164                                      name]
    165 
    166 ------------------------------------------------------------------------------
    167  CAUTION [optional]
    168  [State any special notes, constraints or cautions for users of this function]
    169 
    170 ------------------------------------------------------------------------------
    171 */
    172 
    173 Word16 gc_pred_reset(gc_predState *state)
    174 {
    175     Word16 i;
    176 
    177     if (state == (gc_predState *) NULL)
    178     {
    179         /* fprintf(stderr, "gc_pred_reset: invalid parameter\n"); */
    180         return -1;
    181     }
    182 
    183     for (i = 0; i < NPRED; i++)
    184     {
    185         state->past_qua_en[i] = MIN_ENERGY;
    186         state->past_qua_en_MR122[i] = MIN_ENERGY_MR122;
    187     }
    188 
    189     return(0);
    190 }
    191 
    192 /****************************************************************************/
    193 
    194 /*
    195 ------------------------------------------------------------------------------
    196  FUNCTION NAME: gc_pred
    197 ------------------------------------------------------------------------------
    198  INPUT AND OUTPUT DEFINITIONS
    199 
    200  Inputs:
    201     st = pointer to a structure of type gc_predState
    202     mode = AMR mode (enum Mode)
    203     code = pointer to the innovative codebook vector; Q12 in MR122 mode,
    204            otherwise, Q13 (Word16)
    205     exp_gcode0 = pointer to the exponent part of predicted gain factor
    206              (Q0) (Word16)
    207     frac_gcode0 = pointer to the fractional part of predicted gain factor
    208               (Q15) (Word16)
    209     exp_en = pointer to the exponent part of the innovation energy; this
    210          is calculated for MR795 mode, Q0 (Word16)
    211     frac_en = pointer to the fractional part of the innovation energy;
    212           this is calculated for MR795 mode, Q15 (Word16)
    213     pOverflow = pointer to overflow (Flag)
    214 
    215  Outputs:
    216     store pointed to by exp_gcode0 contains the exponent part of the
    217       recently calculated predicted gain factor
    218     store pointed to by frac_gcode0 contains the fractional part of the
    219       recently calculated predicted gain factor
    220     store pointed to by exp_en contains the exponent part of the
    221       recently calculated innovation energy
    222     store pointed to by frac_en contains the fractional part of the
    223       recently calculated innovation energy
    224     pOverflow = 1 if the math functions called by gc_pred
    225                 results in overflow else zero.
    226 
    227  Returns:
    228     None
    229 
    230  Global Variables Used:
    231     None
    232 
    233  Local Variables Needed:
    234     pred = table of MA prediction coefficients (Q13) (Word16)
    235     pred_MR122 = table of MA prediction coefficients (Q6) (Word16)
    236 
    237 ------------------------------------------------------------------------------
    238  FUNCTION DESCRIPTION
    239 
    240  This function performs the MA prediction of the innovation energy (in
    241  dB/(20*log10(2))), with the mean removed.
    242 
    243 ------------------------------------------------------------------------------
    244  REQUIREMENTS
    245 
    246  None
    247 
    248 ------------------------------------------------------------------------------
    249  REFERENCES
    250 
    251  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    252 
    253 ------------------------------------------------------------------------------
    254  PSEUDO-CODE
    255 
    256 The original etsi reference code uses a global flag Overflow. However, in the
    257 actual implementation a pointer to a the overflow flag is passed in.
    258 
    259 void
    260 gc_pred(
    261     gc_predState *st,   // i/o: State struct
    262     enum Mode mode,     // i  : AMR mode
    263     Word16 *code,       // i  : innovative codebook vector (L_SUBFR)
    264                         //      MR122: Q12, other modes: Q13
    265     Word16 *exp_gcode0, // o  : exponent of predicted gain factor, Q0
    266     Word16 *frac_gcode0,// o  : fraction of predicted gain factor  Q15
    267     Word16 *exp_en,     // o  : exponent of innovation energy,     Q0
    268                         //      (only calculated for MR795)
    269     Word16 *frac_en     // o  : fraction of innovation energy,     Q15
    270                         //      (only calculated for MR795)
    271 )
    272 {
    273     Word16 i;
    274     Word32 ener_code;
    275     Word16 exp, frac;
    276 
    277      *-------------------------------------------------------------------*
    278      *  energy of code:                                                  *
    279      *  ~~~~~~~~~~~~~~~                                                  *
    280      *  ener_code = sum(code[i]^2)                                       *
    281      *-------------------------------------------------------------------*
    282     ener_code = L_mac((Word32) 0, code[0], code[0]);
    283                                                  // MR122:  Q12*Q12 -> Q25
    284                                                  // others: Q13*Q13 -> Q27
    285     for (i = 1; i < L_SUBFR; i++)
    286         ener_code = L_mac(ener_code, code[i], code[i]);
    287 
    288     if (sub (mode, MR122) == 0)
    289     {
    290         Word32 ener;
    291 
    292         // ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20
    293         ener_code = L_mult (pv_round (ener_code), 26214);   // Q9  * Q20 -> Q30
    294 
    295          *-------------------------------------------------------------------*
    296          *  energy of code:                                                  *
    297          *  ~~~~~~~~~~~~~~~                                                  *
    298          *  ener_code(Q17) = 10 * Log10(energy) / constant                   *
    299          *                 = 1/2 * Log2(energy)                              *
    300          *                                           constant = 20*Log10(2)  *
    301          *-------------------------------------------------------------------*
    302         // ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30
    303         Log2(ener_code, &exp, &frac);
    304         ener_code = L_Comp (sub (exp, 30), frac);     // Q16 for log()
    305                                                     // ->Q17 for 1/2 log()
    306 
    307          *-------------------------------------------------------------------*
    308          *  predicted energy:                                                *
    309          *  ~~~~~~~~~~~~~~~~~                                                *
    310          *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant           *
    311          *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])              *
    312          *                                           constant = 20*Log10(2)  *
    313          *-------------------------------------------------------------------*
    314 
    315         ener = MEAN_ENER_MR122;                      // Q24 (Q17)
    316         for (i = 0; i < NPRED; i++)
    317         {
    318             ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
    319                                                      // Q10 * Q13 -> Q24
    320                                                      // Q10 * Q6  -> Q17
    321         }
    322 
    323          *-------------------------------------------------------------------*
    324          *  predicted codebook gain                                          *
    325          *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
    326          *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 )     *
    327          *          = Pow2(ener-ener_code)                                   *
    328          *          = Pow2(int(d)+frac(d))                                   *
    329          *                                                                   *
    330          *  (store exp and frac for pow2())                                  *
    331          *-------------------------------------------------------------------*
    332 
    333         ener = L_shr (L_sub (ener, ener_code), 1);                // Q16
    334         L_Extract(ener, exp_gcode0, frac_gcode0);
    335     }
    336     else // all modes except 12.2
    337     {
    338         Word32 L_tmp;
    339         Word16 exp_code, gcode0;
    340 
    341          *-----------------------------------------------------------------*
    342          *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
    343          *-----------------------------------------------------------------*
    344 
    345         exp_code = norm_l (ener_code);
    346         ener_code = L_shl (ener_code, exp_code);
    347 
    348         // Log2 = log2 + 27
    349         Log2_norm (ener_code, exp_code, &exp, &frac);
    350 
    351         // fact = 10/log2(10) = 3.01 = 24660 Q13
    352         L_tmp = Mpy_32_16(exp, frac, -24660); // Q0.Q15 * Q13 -> Q14
    353 
    354          *   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
    355          *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
    356          *         = K - fact * Log2(ener_code)
    357          *         = K - fact * log2(ener_code) - fact*27
    358          *
    359          *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
    360          *
    361          *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)
    362          *   means_ener =       28.75 =  471040    Q14  (MR67)
    363          *   means_ener =       30    =  491520    Q14  (MR74)
    364          *   means_ener =       36    =  589824    Q14  (MR795)
    365          *   means_ener =       33    =  540672    Q14  (MR102)
    366          *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14
    367          *   fact * 27                = 1331640    Q14
    368          *   -----------------------------------------
    369          *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2
    370          *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2
    371          *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2
    372          *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2
    373          *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2
    374 
    375 
    376         if (sub (mode, MR102) == 0)
    377         {
    378             // mean = 33 dB
    379             L_tmp = L_mac(L_tmp, 16678, 64);     // Q14
    380         }
    381         else if (sub (mode, MR795) == 0)
    382         {
    383             // ener_code  = <xn xn> * 2^27*2^exp_code
    384             // frac_en    = ener_code / 2^16
    385             //            = <xn xn> * 2^11*2^exp_code
    386             // <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en
    387             //           := frac_en            * 2^exp_en
    388 
    389             // ==> exp_en = -11-exp_code;
    390 
    391             *frac_en = extract_h (ener_code);
    392             *exp_en = sub (-11, exp_code);
    393 
    394             // mean = 36 dB
    395             L_tmp = L_mac(L_tmp, 17062, 64);     // Q14
    396         }
    397         else if (sub (mode, MR74) == 0)
    398         {
    399             // mean = 30 dB
    400             L_tmp = L_mac(L_tmp, 32588, 32);     // Q14
    401         }
    402         else if (sub (mode, MR67) == 0)
    403         {
    404             // mean = 28.75 dB
    405             L_tmp = L_mac(L_tmp, 32268, 32);     // Q14
    406         }
    407         else // MR59, MR515, MR475
    408         {
    409             // mean = 33 dB
    410             L_tmp = L_mac(L_tmp, 16678, 64);     // Q14
    411         }
    412 
    413          *-----------------------------------------------------------------*
    414          * Compute gcode0.                                                 *
    415          *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *
    416          *-----------------------------------------------------------------*
    417 
    418         L_tmp = L_shl(L_tmp, 10);                // Q24
    419         for (i = 0; i < 4; i++)
    420             L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);
    421                                                  // Q13 * Q10 -> Q24
    422 
    423         gcode0 = extract_h(L_tmp);               // Q8
    424 
    425          *-----------------------------------------------------------------*
    426          * gcode0 = pow(10.0, gcode0/20)                                   *
    427          *        = pow(2, 3.3219*gcode0/20)                               *
    428          *        = pow(2, 0.166*gcode0)                                   *
    429          *-----------------------------------------------------------------*
    430 
    431         // 5439 Q15 = 0.165985
    432         // (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)
    433         if (sub (mode, MR74) == 0) // For IS641 bitexactness
    434             L_tmp = L_mult(gcode0, 5439);  // Q8 * Q15 -> Q24
    435         else
    436             L_tmp = L_mult(gcode0, 5443);  // Q8 * Q15 -> Q24
    437 
    438         L_tmp = L_shr(L_tmp, 8);                   //          -> Q16
    439         L_Extract(L_tmp, exp_gcode0, frac_gcode0); //       -> Q0.Q15
    440     }
    441 }
    442 
    443 ------------------------------------------------------------------------------
    444  RESOURCES USED [optional]
    445 
    446  When the code is written for a specific target processor the
    447  the resources used should be documented below.
    448 
    449  HEAP MEMORY USED: x bytes
    450 
    451  STACK MEMORY USED: x bytes
    452 
    453  CLOCK CYCLES: (cycle count equation for this function) + (variable
    454                 used to represent cycle count for each subroutine
    455                 called)
    456      where: (cycle count variable) = cycle count for [subroutine
    457                                      name]
    458 
    459 ------------------------------------------------------------------------------
    460  CAUTION [optional]
    461  [State any special notes, constraints or cautions for users of this function]
    462 
    463 ------------------------------------------------------------------------------
    464 */
    465 
    466 void gc_pred(
    467     gc_predState *st,   /* i/o: State struct                           */
    468     enum Mode mode,     /* i  : AMR mode                               */
    469     Word16 *code,       /* i  : innovative codebook vector (L_SUBFR)   */
    470     /*      MR122: Q12, other modes: Q13           */
    471     Word16 *exp_gcode0, /* o  : exponent of predicted gain factor, Q0  */
    472     Word16 *frac_gcode0,/* o  : fraction of predicted gain factor  Q15 */
    473     Word16 *exp_en,     /* o  : exponent of innovation energy,     Q0  */
    474     /*      (only calculated for MR795)            */
    475     Word16 *frac_en,    /* o  : fraction of innovation energy,     Q15 */
    476     /*      (only calculated for MR795)            */
    477     Flag   *pOverflow
    478 )
    479 {
    480     Word16 i;
    481     Word32 L_temp1, L_temp2;
    482     Word32 L_tmp;
    483     Word32 ener_code;
    484     Word32 ener;
    485     Word16 exp, frac;
    486     Word16 exp_code, gcode0;
    487     Word16 tmp;
    488     Word16 *p_code = &code[0];
    489 
    490     /*-------------------------------------------------------------------*
    491      *  energy of code:                                                  *
    492      *  ~~~~~~~~~~~~~~~                                                  *
    493      *  ener_code = sum(code[i]^2)                                       *
    494      *-------------------------------------------------------------------*/
    495     ener_code = 0;
    496 
    497     /* MR122:  Q12*Q12 -> Q25 */
    498     /* others: Q13*Q13 -> Q27 */
    499 
    500     for (i = L_SUBFR >> 2; i != 0; i--)
    501     {
    502         tmp = *(p_code++);
    503         ener_code += ((Word32) tmp * tmp) >> 3;
    504         tmp = *(p_code++);
    505         ener_code += ((Word32) tmp * tmp) >> 3;
    506         tmp = *(p_code++);
    507         ener_code += ((Word32) tmp * tmp) >> 3;
    508         tmp = *(p_code++);
    509         ener_code += ((Word32) tmp * tmp) >> 3;
    510     }
    511 
    512     ener_code <<= 4;
    513 
    514     if (ener_code < 0)      /*  Check for saturation */
    515     {
    516         ener_code = MAX_32;
    517     }
    518 
    519     if (mode == MR122)
    520     {
    521         /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20 */
    522         /* Q9  * Q20 -> Q30 */
    523 
    524         ener_code = ((Word32)(pv_round(ener_code, pOverflow) * 26214)) << 1;
    525 
    526         /*-------------------------------------------------------------*
    527          *  energy of code:                                            *
    528          *  ~~~~~~~~~~~~~~~                                            *
    529          *  ener_code(Q17) = 10 * Log10(energy) / constant             *
    530          *                 = 1/2 * Log2(energy)                        *
    531          *  constant = 20*Log10(2)                                     *
    532          *-------------------------------------------------------------*/
    533         /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
    534         Log2(ener_code, &exp, &frac, pOverflow);
    535 
    536         /* Q16 for log()    */
    537         /* ->Q17 for 1/2 log()*/
    538 
    539         L_temp1 = (Word32)(exp - 30) << 16;
    540         ener_code = L_temp1 + ((Word32)frac << 1);
    541 
    542         /*-------------------------------------------------------------*
    543          *  predicted energy:                                          *
    544          *  ~~~~~~~~~~~~~~~~~                                          *
    545          *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant     *
    546          *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])        *
    547          *  constant = 20*Log10(2)                                     *
    548          *-------------------------------------------------------------*/
    549 
    550         ener = MEAN_ENER_MR122;                   /* Q24 (Q17) */
    551         for (i = 0; i < NPRED; i++)
    552         {
    553             L_temp1 = (((Word32) st->past_qua_en_MR122[i]) *
    554                        pred_MR122[i]) << 1;
    555             ener = L_add(ener, L_temp1, pOverflow);
    556 
    557             /* Q10 * Q13 -> Q24 */
    558             /* Q10 * Q6  -> Q17 */
    559         }
    560 
    561         /*---------------------------------------------------------------*
    562          *  predicted codebook gain                                      *
    563          *  ~~~~~~~~~~~~~~~~~~~~~~~                                      *
    564          *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 ) *
    565          *          = Pow2(ener-ener_code)                               *
    566          *          = Pow2(int(d)+frac(d))                               *
    567          *                                                               *
    568          *  (store exp and frac for pow2())                              *
    569          *---------------------------------------------------------------*/
    570         /* Q16 */
    571 
    572         L_temp1 = L_sub(ener, ener_code, pOverflow);
    573 
    574 
    575         *exp_gcode0 = (Word16)(L_temp1 >> 17);
    576 
    577         L_temp2 = (Word32) * exp_gcode0 << 15;
    578         L_temp1 >>= 2;
    579 
    580         *frac_gcode0 = (Word16)(L_temp1 - L_temp2);
    581 
    582     }
    583     else /* all modes except 12.2 */
    584     {
    585         /*-----------------------------------------------------------------*
    586          *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
    587          *-----------------------------------------------------------------*/
    588 
    589         exp_code = norm_l(ener_code);
    590         ener_code = L_shl(ener_code, exp_code, pOverflow);
    591 
    592         /* Log2 = log2 + 27 */
    593         Log2_norm(ener_code, exp_code, &exp, &frac);
    594 
    595         /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
    596         /* Q0.Q15 * Q13 -> Q14 */
    597 
    598         L_temp2 = (((Word32) exp) * -24660) << 1;
    599         L_tmp = (((Word32) frac) * -24660) >> 15;
    600 
    601         /* Sign-extend resulting product */
    602         if (L_tmp & (Word32) 0x00010000L)
    603         {
    604             L_tmp = L_tmp | (Word32) 0xffff0000L;
    605         }
    606 
    607         L_tmp = L_tmp << 1;
    608         L_tmp = L_add(L_tmp, L_temp2, pOverflow);
    609 
    610 
    611         /*   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
    612          *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
    613          *         = K - fact * Log2(ener_code)
    614          *         = K - fact * log2(ener_code) - fact*27
    615          *
    616          *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
    617          *
    618          *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)
    619          *   means_ener =       28.75 =  471040    Q14  (MR67)
    620          *   means_ener =       30    =  491520    Q14  (MR74)
    621          *   means_ener =       36    =  589824    Q14  (MR795)
    622          *   means_ener =       33    =  540672    Q14  (MR102)
    623          *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14
    624          *   fact * 27                = 1331640    Q14
    625          *   -----------------------------------------
    626          *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2
    627          *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2
    628          *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2
    629          *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2
    630          *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2
    631          */
    632 
    633         if (mode == MR102)
    634         {
    635             /* mean = 33 dB */
    636             L_temp2 = (Word32) 16678 << 7;
    637             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
    638         }
    639         else if (mode == MR795)
    640         {
    641             /* ener_code  = <xn xn> * 2^27*2^exp_code
    642                frac_en    = ener_code / 2^16
    643                           = <xn xn> * 2^11*2^exp_code
    644                <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en
    645             :                 = frac_en            * 2^exp_en
    646                           ==> exp_en = -11-exp_code;      */
    647             *frac_en = (Word16)(ener_code >> 16);
    648             *exp_en = sub(-11, exp_code, pOverflow);
    649 
    650             /* mean = 36 dB */
    651             L_temp2 = (Word32) 17062 << 7;
    652             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
    653         }
    654         else if (mode == MR74)
    655         {
    656             /* mean = 30 dB */
    657             L_temp2 = (Word32) 32588 << 6;
    658             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
    659         }
    660         else if (mode == MR67)
    661         {
    662             /* mean = 28.75 dB */
    663             L_temp2 = (Word32) 32268 << 6;
    664             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
    665         }
    666         else /* MR59, MR515, MR475 */
    667         {
    668             /* mean = 33 dB */
    669             L_temp2 = (Word32) 16678 << 7;
    670             L_tmp = L_add(L_tmp, L_temp2, pOverflow);     /* Q14 */
    671         }
    672 
    673         /*-------------------------------------------------------------*
    674          * Compute gcode0.                                              *
    675          *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener *
    676          *--------------------------------------------------------------*/
    677         /* Q24 */
    678         if (L_tmp > (Word32) 0X001fffffL)
    679         {
    680             *pOverflow = 1;
    681             L_tmp = MAX_32;
    682         }
    683         else if (L_tmp < (Word32) 0xffe00000L)
    684         {
    685             *pOverflow = 1;
    686             L_tmp = MIN_32;
    687         }
    688         else
    689         {
    690             L_tmp = L_tmp << 10;
    691         }
    692 
    693         for (i = 0; i < 4; i++)
    694         {
    695             L_temp2 = ((((Word32) pred[i]) * st->past_qua_en[i]) << 1);
    696             L_tmp = L_add(L_tmp, L_temp2, pOverflow);  /* Q13 * Q10 -> Q24 */
    697         }
    698 
    699         gcode0 = (Word16)(L_tmp >> 16);               /* Q8  */
    700 
    701         /*-----------------------------------------------------------*
    702          * gcode0 = pow(10.0, gcode0/20)                             *
    703          *        = pow(2, 3.3219*gcode0/20)                         *
    704          *        = pow(2, 0.166*gcode0)                             *
    705          *-----------------------------------------------------------*/
    706 
    707         /* 5439 Q15 = 0.165985                                       */
    708         /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)            */
    709 
    710         if (mode == MR74) /* For IS641 bitexactness */
    711         {
    712             L_tmp = (((Word32) gcode0) * 5439) << 1;  /* Q8 * Q15 -> Q24 */
    713         }
    714         else
    715         {
    716             L_tmp = (((Word32) gcode0) * 5443) << 1;  /* Q8 * Q15 -> Q24 */
    717         }
    718 
    719         if (L_tmp < 0)
    720         {
    721             L_tmp = ~((~L_tmp) >> 8);
    722         }
    723         else
    724         {
    725             L_tmp = L_tmp >> 8;     /* -> Q16 */
    726         }
    727 
    728         *exp_gcode0 = (Word16)(L_tmp >> 16);
    729         if (L_tmp < 0)
    730         {
    731             L_temp1 = ~((~L_tmp) >> 1);
    732         }
    733         else
    734         {
    735             L_temp1 = L_tmp >> 1;
    736         }
    737         L_temp2 = (Word32) * exp_gcode0 << 15;
    738         *frac_gcode0 = (Word16)(L_sub(L_temp1, L_temp2, pOverflow));
    739         /* -> Q0.Q15 */
    740     }
    741 
    742     return;
    743 }
    744 
    745 /****************************************************************************/
    746 
    747 /*
    748 ------------------------------------------------------------------------------
    749  FUNCTION NAME: gc_pred_update
    750 ------------------------------------------------------------------------------
    751  INPUT AND OUTPUT DEFINITIONS
    752 
    753  Inputs:
    754     st = pointer to a structure of type gc_predState
    755     qua_ener_MR122 = quantized energy for update (Q10); calculated as
    756              (log2(qua_err)) (Word16)
    757     qua_ener = quantized energy for update (Q10); calculated as
    758            (20*log10(qua_err)) (Word16)
    759 
    760  Outputs:
    761     structure pointed to by st contains the calculated quantized energy
    762       for update
    763 
    764  Returns:
    765     None
    766 
    767  Global Variables Used:
    768     None
    769 
    770  Local Variables Needed:
    771     None
    772 
    773 ------------------------------------------------------------------------------
    774  FUNCTION DESCRIPTION
    775 
    776  This function updates the MA predictor with the last quantized energy.
    777 
    778 ------------------------------------------------------------------------------
    779  REQUIREMENTS
    780 
    781  None
    782 
    783 ------------------------------------------------------------------------------
    784  REFERENCES
    785 
    786  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    787 
    788 ------------------------------------------------------------------------------
    789  PSEUDO-CODE
    790 
    791 void gc_pred_update(
    792     gc_predState *st,      // i/o: State struct
    793     Word16 qua_ener_MR122, // i  : quantized energy for update, Q10
    794                            //      (log2(qua_err))
    795     Word16 qua_ener        // i  : quantized energy for update, Q10
    796                            //      (20*log10(qua_err))
    797 )
    798 {
    799     Word16 i;
    800 
    801     for (i = 3; i > 0; i--)
    802     {
    803         st->past_qua_en[i] = st->past_qua_en[i - 1];
    804         st->past_qua_en_MR122[i] = st->past_qua_en_MR122[i - 1];
    805     }
    806 
    807     st->past_qua_en_MR122[0] = qua_ener_MR122;  //    log2 (qua_err), Q10
    808 
    809     st->past_qua_en[0] = qua_ener;              // 20*log10(qua_err), Q10
    810 
    811 }
    812 
    813 ------------------------------------------------------------------------------
    814  RESOURCES USED [optional]
    815 
    816  When the code is written for a specific target processor the
    817  the resources used should be documented below.
    818 
    819  HEAP MEMORY USED: x bytes
    820 
    821  STACK MEMORY USED: x bytes
    822 
    823  CLOCK CYCLES: (cycle count equation for this function) + (variable
    824                 used to represent cycle count for each subroutine
    825                 called)
    826      where: (cycle count variable) = cycle count for [subroutine
    827                                      name]
    828 
    829 ------------------------------------------------------------------------------
    830  CAUTION [optional]
    831  [State any special notes, constraints or cautions for users of this function]
    832 
    833 ------------------------------------------------------------------------------
    834 */
    835 
    836 void gc_pred_update(
    837     gc_predState *st,      /* i/o: State struct                     */
    838     Word16 qua_ener_MR122, /* i  : quantized energy for update, Q10 */
    839     /*      (log2(qua_err))                  */
    840     Word16 qua_ener        /* i  : quantized energy for update, Q10 */
    841     /*      (20*log10(qua_err))              */
    842 )
    843 {
    844     st->past_qua_en[3] = st->past_qua_en[2];
    845     st->past_qua_en_MR122[3] = st->past_qua_en_MR122[2];
    846 
    847     st->past_qua_en[2] = st->past_qua_en[1];
    848     st->past_qua_en_MR122[2] = st->past_qua_en_MR122[1];
    849 
    850     st->past_qua_en[1] = st->past_qua_en[0];
    851     st->past_qua_en_MR122[1] = st->past_qua_en_MR122[0];
    852 
    853     st->past_qua_en_MR122[0] = qua_ener_MR122; /*    log2 (qua_err), Q10 */
    854 
    855     st->past_qua_en[0] = qua_ener;            /* 20*log10(qua_err), Q10 */
    856 
    857     return;
    858 }
    859 
    860 /****************************************************************************/
    861 
    862 /*
    863 ------------------------------------------------------------------------------
    864  FUNCTION NAME: gc_pred_average_limited
    865 ------------------------------------------------------------------------------
    866  INPUT AND OUTPUT DEFINITIONS
    867 
    868  Inputs:
    869     st = pointer to a structure of type gc_predState
    870     ener_avg_MR122 = pointer to the averaged quantized energy (Q10);
    871              calculated as (log2(qua_err)) (Word16)
    872     ener_avg = pointer to the averaged quantized energy (Q10); calculated
    873            as (20*log10(qua_err)) (Word16)
    874     pOverflow = pointer to overflow (Flag)
    875 
    876  Outputs:
    877     store pointed to by ener_avg_MR122 contains the new averaged quantized
    878       energy
    879     store pointed to by ener_avg contains the new averaged quantized
    880       energy
    881     pOverflow = 1 if the math functions called by gc_pred_average_limited
    882             results in overflow else zero.
    883 
    884  Returns:
    885     None
    886 
    887  Global Variables Used:
    888     None
    889 
    890  Local Variables Needed:
    891     None
    892 
    893 ------------------------------------------------------------------------------
    894  FUNCTION DESCRIPTION
    895 
    896  This function calculates the average of MA predictor state values (with a
    897  lower limit) used in error concealment.
    898 
    899 ------------------------------------------------------------------------------
    900  REQUIREMENTS
    901 
    902  None
    903 
    904 ------------------------------------------------------------------------------
    905  REFERENCES
    906 
    907  gc_pred.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    908 
    909 ------------------------------------------------------------------------------
    910  PSEUDO-CODE
    911 
    912 The original etsi reference code uses a global flag Overflow. However, in the
    913 actual implementation a pointer to a the overflow flag is passed in.
    914 
    915 void gc_pred_average_limited(
    916     gc_predState *st,       // i: State struct
    917     Word16 *ener_avg_MR122, // o: everaged quantized energy,  Q10
    918                             //    (log2(qua_err))
    919     Word16 *ener_avg        // o: averaged quantized energy,  Q10
    920                             //    (20*log10(qua_err))
    921 )
    922 {
    923     Word16 av_pred_en;
    924     Word16 i;
    925 
    926     // do average in MR122 mode (log2() domain)
    927     av_pred_en = 0;
    928     for (i = 0; i < NPRED; i++)
    929     {
    930         av_pred_en = add (av_pred_en, st->past_qua_en_MR122[i]);
    931     }
    932 
    933     // av_pred_en = 0.25*av_pred_en
    934     av_pred_en = mult (av_pred_en, 8192);
    935 
    936     // if (av_pred_en < -14/(20Log10(2))) av_pred_en = ..
    937 
    938     if (sub (av_pred_en, MIN_ENERGY_MR122) < 0)
    939     {
    940         av_pred_en = MIN_ENERGY_MR122;
    941     }
    942     *ener_avg_MR122 = av_pred_en;
    943 
    944     // do average for other modes (20*log10() domain)
    945     av_pred_en = 0;
    946     for (i = 0; i < NPRED; i++)
    947     {
    948         av_pred_en = add (av_pred_en, st->past_qua_en[i]);
    949     }
    950 
    951     // av_pred_en = 0.25*av_pred_en
    952     av_pred_en = mult (av_pred_en, 8192);
    953 
    954     // if (av_pred_en < -14) av_pred_en = ..
    955 
    956     if (sub (av_pred_en, MIN_ENERGY) < 0)
    957     {
    958         av_pred_en = MIN_ENERGY;
    959     }
    960     *ener_avg = av_pred_en;
    961 }
    962 
    963 ------------------------------------------------------------------------------
    964  RESOURCES USED [optional]
    965 
    966  When the code is written for a specific target processor the
    967  the resources used should be documented below.
    968 
    969  HEAP MEMORY USED: x bytes
    970 
    971  STACK MEMORY USED: x bytes
    972 
    973  CLOCK CYCLES: (cycle count equation for this function) + (variable
    974                 used to represent cycle count for each subroutine
    975                 called)
    976      where: (cycle count variable) = cycle count for [subroutine
    977                                      name]
    978 
    979 ------------------------------------------------------------------------------
    980  CAUTION [optional]
    981  [State any special notes, constraints or cautions for users of this function]
    982 
    983 ------------------------------------------------------------------------------
    984 */
    985 
    986 void gc_pred_average_limited(
    987     gc_predState *st,       /* i: State struct                    */
    988     Word16 *ener_avg_MR122, /* o: everaged quantized energy,  Q10 */
    989     /*    (log2(qua_err))                 */
    990     Word16 *ener_avg,       /* o: averaged quantized energy,  Q10 */
    991     /*    (20*log10(qua_err))             */
    992     Flag *pOverflow
    993 )
    994 {
    995     Word16 av_pred_en;
    996     Word16 i;
    997 
    998     /* do average in MR122 mode (log2() domain) */
    999     av_pred_en = 0;
   1000     for (i = 0; i < NPRED; i++)
   1001     {
   1002         av_pred_en =
   1003             add(av_pred_en, st->past_qua_en_MR122[i], pOverflow);
   1004     }
   1005 
   1006     /* av_pred_en = 0.25*av_pred_en  (with sign-extension)*/
   1007     if (av_pred_en < 0)
   1008     {
   1009         av_pred_en = (av_pred_en >> 2) | 0xc000;
   1010     }
   1011     else
   1012     {
   1013         av_pred_en >>= 2;
   1014     }
   1015 
   1016     /* if (av_pred_en < -14/(20Log10(2))) av_pred_en = .. */
   1017     if (av_pred_en < MIN_ENERGY_MR122)
   1018     {
   1019         av_pred_en = MIN_ENERGY_MR122;
   1020     }
   1021     *ener_avg_MR122 = av_pred_en;
   1022 
   1023     /* do average for other modes (20*log10() domain) */
   1024     av_pred_en = 0;
   1025     for (i = 0; i < NPRED; i++)
   1026     {
   1027         av_pred_en = add(av_pred_en, st->past_qua_en[i], pOverflow);
   1028     }
   1029 
   1030     /* av_pred_en = 0.25*av_pred_en  (with sign-extension)*/
   1031     if (av_pred_en < 0)
   1032     {
   1033         av_pred_en = (av_pred_en >> 2) | 0xc000;
   1034     }
   1035     else
   1036     {
   1037         av_pred_en >>= 2;
   1038     }
   1039 
   1040     /* if (av_pred_en < -14) av_pred_en = .. */
   1041     if (av_pred_en < MIN_ENERGY)
   1042     {
   1043         av_pred_en = MIN_ENERGY;
   1044     }
   1045     *ener_avg = av_pred_en;
   1046 }
   1047