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/qgain475.c
     35  Funtions: MR475_quant_store_results
     36            MR475_update_unq_pred
     37            MR475_gain_quant
     38 
     39 ------------------------------------------------------------------------------
     40  MODULE DESCRIPTION
     41 
     42  These modules handle the quantization of pitch and codebook gains for MR475.
     43 
     44 ------------------------------------------------------------------------------
     45 */
     46 
     47 
     48 /*----------------------------------------------------------------------------
     49 ; INCLUDES
     50 ----------------------------------------------------------------------------*/
     51 #include "qgain475.h"
     52 #include "typedef.h"
     53 #include "basic_op.h"
     54 #include "mode.h"
     55 #include "cnst.h"
     56 #include "pow2.h"
     57 #include "log2.h"
     58 
     59 /*----------------------------------------------------------------------------
     60 ; MACROS
     61 ; Define module specific macros here
     62 ----------------------------------------------------------------------------*/
     63 
     64 
     65 /*----------------------------------------------------------------------------
     66 ; DEFINES
     67 ; Include all pre-processor statements here. Include conditional
     68 ; compile variables also.
     69 ----------------------------------------------------------------------------*/
     70 #define MR475_VQ_SIZE 256
     71 
     72 /*----------------------------------------------------------------------------
     73 ; LOCAL FUNCTION DEFINITIONS
     74 ; Function Prototype declaration
     75 ----------------------------------------------------------------------------*/
     76 
     77 /*----------------------------------------------------------------------------
     78 ; LOCAL VARIABLE DEFINITIONS
     79 ; Variable declaration - defined here and used outside this module
     80 ----------------------------------------------------------------------------*/
     81 
     82 /* The table contains the following data:
     83  *
     84  *    g_pitch(0)        (Q14) // for sub-
     85  *    g_fac(0)          (Q12) // frame 0 and 2
     86  *    g_pitch(1)        (Q14) // for sub-
     87  *    g_fac(2)          (Q12) // frame 1 and 3
     88  *
     89  */
     90 static const Word16 table_gain_MR475[MR475_VQ_SIZE*4] =
     91 {
     92     /*g_pit(0), g_fac(0),      g_pit(1), g_fac(1) */
     93     812,          128,           542,      140,
     94     2873,         1135,          2266,     3402,
     95     2067,          563,         12677,      647,
     96     4132,         1798,          5601,     5285,
     97     7689,          374,          3735,      441,
     98     10912,         2638,         11807,     2494,
     99     20490,          797,          5218,      675,
    100     6724,         8354,          5282,     1696,
    101     1488,          428,          5882,      452,
    102     5332,         4072,          3583,     1268,
    103     2469,          901,         15894,     1005,
    104     14982,         3271,         10331,     4858,
    105     3635,         2021,          2596,      835,
    106     12360,         4892,         12206,     1704,
    107     13432,         1604,          9118,     2341,
    108     3968,         1538,          5479,     9936,
    109     3795,          417,          1359,      414,
    110     3640,         1569,          7995,     3541,
    111     11405,          645,          8552,      635,
    112     4056,         1377,         16608,     6124,
    113     11420,          700,          2007,      607,
    114     12415,         1578,         11119,     4654,
    115     13680,         1708,         11990,     1229,
    116     7996,         7297,         13231,     5715,
    117     2428,         1159,          2073,     1941,
    118     6218,         6121,          3546,     1804,
    119     8925,         1802,          8679,     1580,
    120     13935,         3576,         13313,     6237,
    121     6142,         1130,          5994,     1734,
    122     14141,         4662,         11271,     3321,
    123     12226,         1551,         13931,     3015,
    124     5081,        10464,          9444,     6706,
    125     1689,          683,          1436,     1306,
    126     7212,         3933,          4082,     2713,
    127     7793,          704,         15070,      802,
    128     6299,         5212,          4337,     5357,
    129     6676,          541,          6062,      626,
    130     13651,         3700,         11498,     2408,
    131     16156,          716,         12177,      751,
    132     8065,        11489,          6314,     2256,
    133     4466,          496,          7293,      523,
    134     10213,         3833,          8394,     3037,
    135     8403,          966,         14228,     1880,
    136     8703,         5409,         16395,     4863,
    137     7420,         1979,          6089,     1230,
    138     9371,         4398,         14558,     3363,
    139     13559,         2873,         13163,     1465,
    140     5534,         1678,         13138,    14771,
    141     7338,          600,          1318,      548,
    142     4252,         3539,         10044,     2364,
    143     10587,          622,         13088,      669,
    144     14126,         3526,          5039,     9784,
    145     15338,          619,          3115,      590,
    146     16442,         3013,         15542,     4168,
    147     15537,         1611,         15405,     1228,
    148     16023,         9299,          7534,     4976,
    149     1990,         1213,         11447,     1157,
    150     12512,         5519,          9475,     2644,
    151     7716,         2034,         13280,     2239,
    152     16011,         5093,          8066,     6761,
    153     10083,         1413,          5002,     2347,
    154     12523,         5975,         15126,     2899,
    155     18264,         2289,         15827,     2527,
    156     16265,        10254,         14651,    11319,
    157     1797,          337,          3115,      397,
    158     3510,         2928,          4592,     2670,
    159     7519,          628,         11415,      656,
    160     5946,         2435,          6544,     7367,
    161     8238,          829,          4000,      863,
    162     10032,         2492,         16057,     3551,
    163     18204,         1054,          6103,     1454,
    164     5884,         7900,         18752,     3468,
    165     1864,          544,          9198,      683,
    166     11623,         4160,          4594,     1644,
    167     3158,         1157,         15953,     2560,
    168     12349,         3733,         17420,     5260,
    169     6106,         2004,          2917,     1742,
    170     16467,         5257,         16787,     1680,
    171     17205,         1759,          4773,     3231,
    172     7386,         6035,         14342,    10012,
    173     4035,          442,          4194,      458,
    174     9214,         2242,          7427,     4217,
    175     12860,          801,         11186,      825,
    176     12648,         2084,         12956,     6554,
    177     9505,          996,          6629,      985,
    178     10537,         2502,         15289,     5006,
    179     12602,         2055,         15484,     1653,
    180     16194,         6921,         14231,     5790,
    181     2626,          828,          5615,     1686,
    182     13663,         5778,          3668,     1554,
    183     11313,         2633,          9770,     1459,
    184     14003,         4733,         15897,     6291,
    185     6278,         1870,          7910,     2285,
    186     16978,         4571,         16576,     3849,
    187     15248,         2311,         16023,     3244,
    188     14459,        17808,         11847,     2763,
    189     1981,         1407,          1400,      876,
    190     4335,         3547,          4391,     4210,
    191     5405,          680,         17461,      781,
    192     6501,         5118,          8091,     7677,
    193     7355,          794,          8333,     1182,
    194     15041,         3160,         14928,     3039,
    195     20421,          880,         14545,      852,
    196     12337,        14708,          6904,     1920,
    197     4225,          933,          8218,     1087,
    198     10659,         4084,         10082,     4533,
    199     2735,          840,         20657,     1081,
    200     16711,         5966,         15873,     4578,
    201     10871,         2574,          3773,     1166,
    202     14519,         4044,         20699,     2627,
    203     15219,         2734,         15274,     2186,
    204     6257,         3226,         13125,    19480,
    205     7196,          930,          2462,     1618,
    206     4515,         3092,         13852,     4277,
    207     10460,          833,         17339,      810,
    208     16891,         2289,         15546,     8217,
    209     13603,         1684,          3197,     1834,
    210     15948,         2820,         15812,     5327,
    211     17006,         2438,         16788,     1326,
    212     15671,         8156,         11726,     8556,
    213     3762,         2053,          9563,     1317,
    214     13561,         6790,         12227,     1936,
    215     8180,         3550,         13287,     1778,
    216     16299,         6599,         16291,     7758,
    217     8521,         2551,          7225,     2645,
    218     18269,         7489,         16885,     2248,
    219     17882,         2884,         17265,     3328,
    220     9417,        20162,         11042,     8320,
    221     1286,          620,          1431,      583,
    222     5993,         2289,          3978,     3626,
    223     5144,          752,         13409,      830,
    224     5553,         2860,         11764,     5908,
    225     10737,          560,          5446,      564,
    226     13321,         3008,         11946,     3683,
    227     19887,          798,          9825,      728,
    228     13663,         8748,          7391,     3053,
    229     2515,          778,          6050,      833,
    230     6469,         5074,          8305,     2463,
    231     6141,         1865,         15308,     1262,
    232     14408,         4547,         13663,     4515,
    233     3137,         2983,          2479,     1259,
    234     15088,         4647,         15382,     2607,
    235     14492,         2392,         12462,     2537,
    236     7539,         2949,         12909,    12060,
    237     5468,          684,          3141,      722,
    238     5081,         1274,         12732,     4200,
    239     15302,          681,          7819,      592,
    240     6534,         2021,         16478,     8737,
    241     13364,          882,          5397,      899,
    242     14656,         2178,         14741,     4227,
    243     14270,         1298,         13929,     2029,
    244     15477,         7482,         15815,     4572,
    245     2521,         2013,          5062,     1804,
    246     5159,         6582,          7130,     3597,
    247     10920,         1611,         11729,     1708,
    248     16903,         3455,         16268,     6640,
    249     9306,         1007,          9369,     2106,
    250     19182,         5037,         12441,     4269,
    251     15919,         1332,         15357,     3512,
    252     11898,        14141,         16101,     6854,
    253     2010,          737,          3779,      861,
    254     11454,         2880,          3564,     3540,
    255     9057,         1241,         12391,      896,
    256     8546,         4629,         11561,     5776,
    257     8129,          589,          8218,      588,
    258     18728,         3755,         12973,     3149,
    259     15729,          758,         16634,      754,
    260     15222,        11138,         15871,     2208,
    261     4673,          610,         10218,      678,
    262     15257,         4146,          5729,     3327,
    263     8377,         1670,         19862,     2321,
    264     15450,         5511,         14054,     5481,
    265     5728,         2888,          7580,     1346,
    266     14384,         5325,         16236,     3950,
    267     15118,         3744,         15306,     1435,
    268     14597,         4070,         12301,    15696,
    269     7617,         1699,          2170,      884,
    270     4459,         4567,         18094,     3306,
    271     12742,          815,         14926,      907,
    272     15016,         4281,         15518,     8368,
    273     17994,         1087,          2358,      865,
    274     16281,         3787,         15679,     4596,
    275     16356,         1534,         16584,     2210,
    276     16833,         9697,         15929,     4513,
    277     3277,         1085,          9643,     2187,
    278     11973,         6068,          9199,     4462,
    279     8955,         1629,         10289,     3062,
    280     16481,         5155,         15466,     7066,
    281     13678,         2543,          5273,     2277,
    282     16746,         6213,         16655,     3408,
    283     20304,         3363,         18688,     1985,
    284     14172,        12867,         15154,    15703,
    285     4473,         1020,          1681,      886,
    286     4311,         4301,          8952,     3657,
    287     5893,         1147,         11647,     1452,
    288     15886,         2227,          4582,     6644,
    289     6929,         1205,          6220,      799,
    290     12415,         3409,         15968,     3877,
    291     19859,         2109,          9689,     2141,
    292     14742,         8830,         14480,     2599,
    293     1817,         1238,          7771,      813,
    294     19079,         4410,          5554,     2064,
    295     3687,         2844,         17435,     2256,
    296     16697,         4486,         16199,     5388,
    297     8028,         2763,          3405,     2119,
    298     17426,         5477,         13698,     2786,
    299     19879,         2720,          9098,     3880,
    300     18172,         4833,         17336,    12207,
    301     5116,          996,          4935,      988,
    302     9888,         3081,          6014,     5371,
    303     15881,         1667,          8405,     1183,
    304     15087,         2366,         19777,     7002,
    305     11963,         1562,          7279,     1128,
    306     16859,         1532,         15762,     5381,
    307     14708,         2065,         20105,     2155,
    308     17158,         8245,         17911,     6318,
    309     5467,         1504,          4100,     2574,
    310     17421,         6810,          5673,     2888,
    311     16636,         3382,          8975,     1831,
    312     20159,         4737,         19550,     7294,
    313     6658,         2781,         11472,     3321,
    314     19397,         5054,         18878,     4722,
    315     16439,         2373,         20430,     4386,
    316     11353,        26526,         11593,     3068,
    317     2866,         1566,          5108,     1070,
    318     9614,         4915,          4939,     3536,
    319     7541,          878,         20717,      851,
    320     6938,         4395,         16799,     7733,
    321     10137,         1019,          9845,      964,
    322     15494,         3955,         15459,     3430,
    323     18863,          982,         20120,      963,
    324     16876,        12887,         14334,     4200,
    325     6599,         1220,          9222,      814,
    326     16942,         5134,          5661,     4898,
    327     5488,         1798,         20258,     3962,
    328     17005,         6178,         17929,     5929,
    329     9365,         3420,          7474,     1971,
    330     19537,         5177,         19003,     3006,
    331     16454,         3788,         16070,     2367,
    332     8664,         2743,          9445,    26358,
    333     10856,         1287,          3555,     1009,
    334     5606,         3622,         19453,     5512,
    335     12453,          797,         20634,      911,
    336     15427,         3066,         17037,    10275,
    337     18883,         2633,          3913,     1268,
    338     19519,         3371,         18052,     5230,
    339     19291,         1678,         19508,     3172,
    340     18072,        10754,         16625,     6845,
    341     3134,         2298,         10869,     2437,
    342     15580,         6913,         12597,     3381,
    343     11116,         3297,         16762,     2424,
    344     18853,         6715,         17171,     9887,
    345     12743,         2605,          8937,     3140,
    346     19033,         7764,         18347,     3880,
    347     20475,         3682,         19602,     3380,
    348     13044,        19373,         10526,    23124
    349 };
    350 
    351 /*
    352 ------------------------------------------------------------------------------
    353  FUNCTION NAME: MR475_quant_store_results
    354 ------------------------------------------------------------------------------
    355  INPUT AND OUTPUT DEFINITIONS
    356 
    357  Inputs:
    358     pred_st = pointer to structure of type gc_predState
    359     p = pointer to selected quantizer table entry (const Word16)
    360     gcode0 = predicted CB gain (Word16)
    361     exp_gcode0 = exponent of predicted CB gain (Word16)
    362     gain_pit = pointer to Pitch gain (Word16)
    363     gain_cod = pointer to Code gain (Word16)
    364 
    365  Outputs:
    366     pred_st points to the updated structure of type gc_predState
    367     gain_pit points to Pitch gain
    368     gain_cod points to Code gain
    369     pOverflow points to overflow indicator (Flag)
    370 
    371  Returns:
    372     None.
    373 
    374  Global Variables Used:
    375     None.
    376 
    377  Local Variables Needed:
    378     None.
    379 
    380 ------------------------------------------------------------------------------
    381  FUNCTION DESCRIPTION
    382 
    383  This function calculates the final fixed codebook gain and the predictor
    384  update values, and updates the gain predictor.
    385 
    386 ------------------------------------------------------------------------------
    387  REQUIREMENTS
    388 
    389  None.
    390 
    391 ------------------------------------------------------------------------------
    392  REFERENCES
    393 
    394  qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    395 
    396 ------------------------------------------------------------------------------
    397  PSEUDO-CODE
    398 
    399 static void MR475_quant_store_results(
    400 
    401     gc_predState *pred_st, // i/o: gain predictor state struct
    402     const Word16 *p,       // i  : pointer to selected quantizer table entry
    403     Word16 gcode0,         // i  : predicted CB gain,     Q(14 - exp_gcode0)
    404     Word16 exp_gcode0,     // i  : exponent of predicted CB gain,        Q0
    405     Word16 *gain_pit,      // o  : Pitch gain,                           Q14
    406     Word16 *gain_cod       // o  : Code gain,                            Q1
    407 )
    408 {
    409 
    410     Word16 g_code, exp, frac, tmp;
    411     Word32 L_tmp;
    412 
    413     Word16 qua_ener_MR122; // o  : quantized energy error, MR122 version Q10
    414     Word16 qua_ener;       // o  : quantized energy error,               Q10
    415 
    416     // Read the quantized gains
    417     *gain_pit = *p++;
    418     g_code = *p++;
    419 
    420     //------------------------------------------------------------------*
    421      *  calculate final fixed codebook gain:                            *
    422      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
    423      *                                                                  *
    424      *   gc = gc0 * g                                                   *
    425      *------------------------------------------------------------------
    426 
    427     L_tmp = L_mult(g_code, gcode0);
    428     L_tmp = L_shr(L_tmp, sub(10, exp_gcode0));
    429     *gain_cod = extract_h(L_tmp);
    430 
    431     //------------------------------------------------------------------*
    432      *  calculate predictor update values and update gain predictor:    *
    433      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    *
    434      *                                                                  *
    435      *   qua_ener       = log2(g)                                       *
    436      *   qua_ener_MR122 = 20*log10(g)                                   *
    437      *------------------------------------------------------------------
    438 
    439     Log2 (L_deposit_l (g_code), &exp, &frac); // Log2(x Q12) = log2(x) + 12
    440     exp = sub(exp, 12);
    441 
    442     tmp = shr_r (frac, 5);
    443     qua_ener_MR122 = add (tmp, shl (exp, 10));
    444 
    445     L_tmp = Mpy_32_16(exp, frac, 24660); // 24660 Q12 ~= 6.0206 = 20*log10(2)
    446     qua_ener = pv_round (L_shl (L_tmp, 13)); // Q12 * Q0 = Q13 -> Q10
    447 
    448     gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
    449 }
    450 
    451 ------------------------------------------------------------------------------
    452  RESOURCES USED [optional]
    453 
    454  When the code is written for a specific target processor the
    455  the resources used should be documented below.
    456 
    457  HEAP MEMORY USED: x bytes
    458 
    459  STACK MEMORY USED: x bytes
    460 
    461  CLOCK CYCLES: (cycle count equation for this function) + (variable
    462                 used to represent cycle count for each subroutine
    463                 called)
    464      where: (cycle count variable) = cycle count for [subroutine
    465                                      name]
    466 
    467 ------------------------------------------------------------------------------
    468  CAUTION [optional]
    469  [State any special notes, constraints or cautions for users of this function]
    470 
    471 ------------------------------------------------------------------------------
    472 */
    473 
    474 static void MR475_quant_store_results(
    475     gc_predState *pred_st, /* i/o: gain predictor state struct               */
    476     const Word16 *p,       /* i  : pointer to selected quantizer table entry */
    477     Word16 gcode0,         /* i  : predicted CB gain,     Q(14 - exp_gcode0) */
    478     Word16 exp_gcode0,     /* i  : exponent of predicted CB gain,        Q0  */
    479     Word16 *gain_pit,      /* o  : Pitch gain,                           Q14 */
    480     Word16 *gain_cod,      /* o  : Code gain,                            Q1  */
    481     Flag   *pOverflow      /* o  : overflow indicator                        */
    482 )
    483 {
    484     Word16 g_code;
    485     Word16 exp;
    486     Word16 frac;
    487     Word16 tmp;
    488     Word32 L_tmp;
    489 
    490     Word16 qua_ener_MR122; /* o  : quantized energy error, MR122 version Q10 */
    491     Word16 qua_ener;       /* o  : quantized energy error,               Q10 */
    492 
    493 
    494     /* Read the quantized gains */
    495     *gain_pit = *p++;
    496     g_code = *p++;
    497 
    498     /*------------------------------------------------------------------*
    499      *  calculate final fixed codebook gain:                            *
    500      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *
    501      *                                                                  *
    502      *   gc = gc0 * g                                                   *
    503      *------------------------------------------------------------------*/
    504 
    505     L_tmp = ((Word32) g_code * gcode0) << 1;
    506     tmp   = 10 - exp_gcode0;
    507     L_tmp = L_shr(L_tmp, tmp, pOverflow);
    508     *gain_cod = (Word16)(L_tmp >> 16);
    509 
    510     /*------------------------------------------------------------------*
    511      *  calculate predictor update values and update gain predictor:    *
    512      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    *
    513      *                                                                  *
    514      *   qua_ener       = log2(g)                                       *
    515      *   qua_ener_MR122 = 20*log10(g)                                   *
    516      *------------------------------------------------------------------*/
    517 
    518     /* Log2(x Q12) = log2(x) + 12 */
    519     Log2((Word32) g_code, &exp, &frac, pOverflow);
    520     exp -= 12;
    521 
    522     tmp = shr_r(frac, 5, pOverflow);
    523     qua_ener_MR122 = exp << 10;
    524     qua_ener_MR122 = tmp + qua_ener_MR122;
    525 
    526     /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
    527     L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
    528     L_tmp = L_tmp << 13;
    529 
    530     /* Q12 * Q0 = Q13 -> Q10 */
    531     qua_ener = (Word16)((L_tmp + (Word32) 0x00008000L) >> 16);
    532 
    533     gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
    534 
    535     return;
    536 }
    537 
    538 /****************************************************************************/
    539 
    540 
    541 /*
    542 ------------------------------------------------------------------------------
    543  FUNCTION NAME: MR475_update_unq_pred
    544 ------------------------------------------------------------------------------
    545  INPUT AND OUTPUT DEFINITIONS
    546 
    547  Inputs:
    548     pred_st = pointer to structure of type gc_predState
    549     exp_gcode0 = predicted CB gain (exponent MSW) (Word16)
    550     frac_gcode0 = predicted CB gain (exponent LSW) (Word16)
    551     cod_gain_exp = optimum codebook gain (exponent)(Word16)
    552     cod_gain_frac = optimum codebook gain (fraction) (Word16)
    553 
    554  Outputs:
    555     pred_st points to the updated structure of type gc_predState
    556     pOverflow points to overflow indicator (Flag)
    557 
    558  Returns:
    559     None.
    560 
    561  Global Variables Used:
    562     None.
    563 
    564  Local Variables Needed:
    565     None.
    566 
    567 ------------------------------------------------------------------------------
    568  FUNCTION DESCRIPTION
    569 
    570  This module uses the optimum codebook gain and updates the "unquantized"
    571  gain predictor with the (bounded) prediction error.
    572 
    573 ------------------------------------------------------------------------------
    574  REQUIREMENTS
    575 
    576  None.
    577 
    578 ------------------------------------------------------------------------------
    579  REFERENCES
    580 
    581  qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    582 
    583 ------------------------------------------------------------------------------
    584  PSEUDO-CODE
    585 
    586 void
    587 MR475_update_unq_pred(
    588     gc_predState *pred_st, // i/o: gain predictor state struct
    589     Word16 exp_gcode0,     // i  : predicted CB gain (exponent MSW),  Q0
    590     Word16 frac_gcode0,    // i  : predicted CB gain (exponent LSW),  Q15
    591     Word16 cod_gain_exp,   // i  : optimum codebook gain (exponent),  Q0
    592     Word16 cod_gain_frac   // i  : optimum codebook gain (fraction),  Q15
    593 )
    594 {
    595     Word16 tmp, exp, frac;
    596     Word16 qua_ener, qua_ener_MR122;
    597     Word32 L_tmp;
    598 
    599     // calculate prediction error factor (given optimum CB gain gcu):
    600     //   predErrFact = gcu / gcode0
    601     //   (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT
    602     //    -> limit qua_ener*)
    603     //
    604     // calculate prediction error (log):
    605     //
    606     //   qua_ener_MR122 = log2(predErrFact)
    607     //   qua_ener       = 20*log10(predErrFact)
    608 
    609     if (cod_gain_frac <= 0)
    610     {
    611         // if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT
    612         // -> set qua_ener(_MR122) directly
    613         qua_ener = MIN_QUA_ENER;
    614         qua_ener_MR122 = MIN_QUA_ENER_MR122;
    615     }
    616     else
    617     {
    618         // convert gcode0 from DPF to standard fraction/exponent format
    619         // with normalized frac, i.e. 16384 <= frac <= 32767
    620         // Note: exponent correction (exp=exp-14) is done after div_s
    621         frac_gcode0 = extract_l (Pow2 (14, frac_gcode0));
    622 
    623         // make sure cod_gain_frac < frac_gcode0  for div_s
    624         if (sub(cod_gain_frac, frac_gcode0) >= 0)
    625         {
    626             cod_gain_frac = shr (cod_gain_frac, 1);
    627             cod_gain_exp = add (cod_gain_exp, 1);
    628         }
    629 
    630         // predErrFact
    631         //   = gcu / gcode0
    632         //   = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14))
    633         //   = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14)
    634         //   = div_s * 2^(cod_gain_exp-exp_gcode0 - 1)
    635 
    636         frac = div_s (cod_gain_frac, frac_gcode0);
    637         tmp = sub (sub (cod_gain_exp, exp_gcode0), 1);
    638 
    639         Log2 (L_deposit_l (frac), &exp, &frac);
    640         exp = add (exp, tmp);
    641 
    642         // calculate prediction error (log2, Q10)
    643         qua_ener_MR122 = shr_r (frac, 5);
    644         qua_ener_MR122 = add (qua_ener_MR122, shl (exp, 10));
    645 
    646         if (sub(qua_ener_MR122, MIN_QUA_ENER_MR122) < 0)
    647         {
    648             qua_ener = MIN_QUA_ENER;
    649             qua_ener_MR122 = MIN_QUA_ENER_MR122;
    650         }
    651         else if (sub(qua_ener_MR122, MAX_QUA_ENER_MR122) > 0)
    652         {
    653             qua_ener = MAX_QUA_ENER;
    654             qua_ener_MR122 = MAX_QUA_ENER_MR122;
    655         }
    656         else
    657         {
    658             // calculate prediction error (20*log10, Q10)
    659             L_tmp = Mpy_32_16(exp, frac, 24660);
    660             // 24660 Q12 ~= 6.0206 = 20*log10(2)
    661             qua_ener = pv_round (L_shl (L_tmp, 13));
    662             // Q12 * Q0 = Q13 -> Q26 -> Q10
    663         }
    664     }
    665 
    666     // update MA predictor memory
    667     gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
    668 }
    669 
    670 ------------------------------------------------------------------------------
    671  RESOURCES USED [optional]
    672 
    673  When the code is written for a specific target processor the
    674  the resources used should be documented below.
    675 
    676  HEAP MEMORY USED: x bytes
    677 
    678  STACK MEMORY USED: x bytes
    679 
    680  CLOCK CYCLES: (cycle count equation for this function) + (variable
    681                 used to represent cycle count for each subroutine
    682                 called)
    683      where: (cycle count variable) = cycle count for [subroutine
    684                                      name]
    685 
    686 ------------------------------------------------------------------------------
    687  CAUTION [optional]
    688  [State any special notes, constraints or cautions for users of this function]
    689 
    690 ------------------------------------------------------------------------------
    691 */
    692 
    693 void MR475_update_unq_pred(
    694     gc_predState *pred_st, /* i/o: gain predictor state struct            */
    695     Word16 exp_gcode0,     /* i  : predicted CB gain (exponent MSW),  Q0  */
    696     Word16 frac_gcode0,    /* i  : predicted CB gain (exponent LSW),  Q15 */
    697     Word16 cod_gain_exp,   /* i  : optimum codebook gain (exponent),  Q0  */
    698     Word16 cod_gain_frac,  /* i  : optimum codebook gain (fraction),  Q15 */
    699     Flag   *pOverflow      /* o  : overflow indicator                     */
    700 )
    701 {
    702     Word16 tmp;
    703     Word16 exp;
    704     Word16 frac;
    705     Word16 qua_ener;
    706     Word16 qua_ener_MR122;
    707     Word32 L_tmp;
    708 
    709     /* calculate prediction error factor (given optimum CB gain gcu):
    710      *
    711      *   predErrFact = gcu / gcode0
    712      *   (limit to MIN_PRED_ERR_FACT <= predErrFact <= MAX_PRED_ERR_FACT
    713      *    -> limit qua_ener*)
    714      *
    715      * calculate prediction error (log):
    716      *
    717      *   qua_ener_MR122 = log2(predErrFact)
    718      *   qua_ener       = 20*log10(predErrFact)
    719      *
    720      */
    721 
    722     if (cod_gain_frac <= 0)
    723     {
    724         /* if gcu <= 0 -> predErrFact = 0 < MIN_PRED_ERR_FACT */
    725         /* -> set qua_ener(_MR122) directly                   */
    726         qua_ener = MIN_QUA_ENER;
    727         qua_ener_MR122 = MIN_QUA_ENER_MR122;
    728     }
    729     else
    730     {
    731         /* convert gcode0 from DPF to standard fraction/exponent format */
    732         /* with normalized frac, i.e. 16384 <= frac <= 32767            */
    733         /* Note: exponent correction (exp=exp-14) is done after div_s   */
    734         frac_gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow));
    735 
    736         /* make sure cod_gain_frac < frac_gcode0  for div_s */
    737         if (cod_gain_frac >= frac_gcode0)
    738         {
    739             cod_gain_frac >>= 1;
    740             cod_gain_exp += 1;
    741         }
    742 
    743         /*
    744           predErrFact
    745              = gcu / gcode0
    746              = cod_gain_frac/frac_gcode0 * 2^(cod_gain_exp-(exp_gcode0-14))
    747              = div_s (c_g_f, frac_gcode0)*2^-15 * 2^(c_g_e-exp_gcode0+14)
    748              = div_s * 2^(cod_gain_exp-exp_gcode0 - 1)
    749         */
    750         frac = div_s(cod_gain_frac, frac_gcode0);
    751         tmp = cod_gain_exp - exp_gcode0;
    752         tmp -= 1;
    753 
    754         Log2((Word32) frac, &exp, &frac, pOverflow);
    755         exp += tmp;
    756 
    757         /* calculate prediction error (log2, Q10) */
    758         qua_ener_MR122 = shr_r(frac, 5, pOverflow);
    759         tmp = exp << 10;
    760         qua_ener_MR122 += tmp;
    761 
    762         if (qua_ener_MR122 > MAX_QUA_ENER_MR122)
    763         {
    764             qua_ener = MAX_QUA_ENER;
    765             qua_ener_MR122 = MAX_QUA_ENER_MR122;
    766         }
    767         else
    768         {
    769             /* calculate prediction error (20*log10, Q10) */
    770             L_tmp = Mpy_32_16(exp, frac, 24660, pOverflow);
    771             /* 24660 Q12 ~= 6.0206 = 20*log10(2) */
    772             L_tmp =  L_shl(L_tmp, 13, pOverflow);
    773             qua_ener = pv_round(L_tmp, pOverflow);
    774 
    775             /* Q12 * Q0 = Q13 -> Q26 -> Q10     */
    776         }
    777     }
    778 
    779     /* update MA predictor memory */
    780     gc_pred_update(pred_st, qua_ener_MR122, qua_ener);
    781 
    782 
    783     return;
    784 }
    785 
    786 /****************************************************************************/
    787 
    788 
    789 /*
    790 ------------------------------------------------------------------------------
    791  FUNCTION NAME: MR475_gain_quant
    792 ------------------------------------------------------------------------------
    793  INPUT AND OUTPUT DEFINITIONS
    794 
    795  Inputs:
    796     pred_st = pointer to structure of type gc_predState
    797     sf0_exp_gcode0 = predicted CB gain (exponent) (Word16)
    798     f0_frac_gcode0 = predicted CB gain (fraction) (Word16)
    799     sf0_exp_coeff = energy coeff. (exponent part) (Word16)
    800     sf0_frac_coeff = energy coeff. ((fraction part) (Word16)
    801     sf0_exp_target_en = exponent of target energy (Word16)
    802     sf0_frac_target_en = fraction of target energy (Word16)
    803     sf1_code_nosharp = innovative codebook vector  (Word16)
    804     sf1_exp_gcode0 = predicted CB gain (exponent) (Word16)
    805     sf1_frac_gcode0 = predicted CB gain (fraction) (Word16)
    806     sf1_exp_coeff = energy coeff. (exponent part) (Word16)
    807     sf1_frac_coeff = energy coeff. (fraction part) (Word16)
    808     sf1_exp_target_en = exponent of target energy (Word16)
    809     sf1_frac_target_en = fraction of target energy (Word16)
    810     gp_limit = pitch gain limit (Word16)
    811     sf0_gain_pit = pointer to Pitch gain (Word16)
    812     sf0_gain_cod = pointer to Code gain (Word16)
    813     sf1_gain_pit = pointer to Pitch gain (Word16)
    814     sf1_gain_cod = pointer to Code gain (Word16)
    815 
    816  Outputs:
    817     pred_st points to the updated structure of type gc_predState
    818     sf0_gain_pit points to Pitch gain
    819     sf0_gain_cod points to Code gain
    820     sf1_gain_pit points to Pitch gain
    821     sf1_gain_cod points to Code gain
    822 
    823  Returns:
    824     index = index of quantization
    825 
    826  Global Variables Used:
    827     None.
    828 
    829  Local Variables Needed:
    830     None.
    831 
    832 ------------------------------------------------------------------------------
    833  FUNCTION DESCRIPTION
    834 
    835  This module provides quantization of pitch and codebook gains for two
    836  subframes using the predicted codebook gain.
    837 
    838 ------------------------------------------------------------------------------
    839  REQUIREMENTS
    840 
    841  None.
    842 
    843 ------------------------------------------------------------------------------
    844  REFERENCES
    845 
    846  qgain475.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
    847 
    848 ------------------------------------------------------------------------------
    849  PSEUDO-CODE
    850 
    851 Word16
    852 MR475_gain_quant(              // o  : index of quantization.
    853     gc_predState *pred_st,     // i/o: gain predictor state struct
    854 
    855                                // data from subframe 0 (or 2)
    856     Word16 sf0_exp_gcode0,     // i  : predicted CB gain (exponent),      Q0
    857     Word16 sf0_frac_gcode0,    // i  : predicted CB gain (fraction),      Q15
    858     Word16 sf0_exp_coeff[],    // i  : energy coeff. (5), exponent part,  Q0
    859     Word16 sf0_frac_coeff[],   // i  : energy coeff. (5), fraction part,  Q15
    860                                //      (frac_coeff and exp_coeff computed in
    861                                //       calc_filt_energies())
    862     Word16 sf0_exp_target_en,  // i  : exponent of target energy,         Q0
    863     Word16 sf0_frac_target_en, // i  : fraction of target energy,         Q15
    864 
    865                                // data from subframe 1 (or 3)
    866     Word16 sf1_code_nosharp[], // i  : innovative codebook vector (L_SUBFR)
    867                                //      (whithout pitch sharpening)
    868     Word16 sf1_exp_gcode0,     // i  : predicted CB gain (exponent),      Q0
    869     Word16 sf1_frac_gcode0,    // i  : predicted CB gain (fraction),      Q15
    870     Word16 sf1_exp_coeff[],    // i  : energy coeff. (5), exponent part,  Q0
    871     Word16 sf1_frac_coeff[],   // i  : energy coeff. (5), fraction part,  Q15
    872                                //      (frac_coeff and exp_coeff computed in
    873                                //       calc_filt_energies())
    874     Word16 sf1_exp_target_en,  // i  : exponent of target energy,         Q0
    875     Word16 sf1_frac_target_en, // i  : fraction of target energy,         Q15
    876 
    877     Word16 gp_limit,           // i  : pitch gain limit
    878 
    879     Word16 *sf0_gain_pit,      // o  : Pitch gain,                        Q14
    880     Word16 *sf0_gain_cod,      // o  : Code gain,                         Q1
    881 
    882     Word16 *sf1_gain_pit,      // o  : Pitch gain,                        Q14
    883     Word16 *sf1_gain_cod       // o  : Code gain,                         Q1
    884 )
    885 {
    886     const Word16 *p;
    887     Word16 i, index = 0;
    888     Word16 tmp;
    889     Word16 exp;
    890     Word16 sf0_gcode0, sf1_gcode0;
    891     Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
    892     Word16 coeff[10], coeff_lo[10], exp_max[10];  // 0..4: sf0; 5..9: sf1
    893     Word32 L_tmp, dist_min;
    894 
    895      *-------------------------------------------------------------------*
    896      *  predicted codebook gain                                          *
    897      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
    898      *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *
    899      *                                                                   *
    900      *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *
    901      *-------------------------------------------------------------------*
    902 
    903     sf0_gcode0 = extract_l(Pow2(14, sf0_frac_gcode0));
    904     sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
    905 
    906      * For each subframe, the error energy (sum) to be minimized consists
    907      * of five terms, t[0..4].
    908      *
    909      *                      t[0] =    gp^2  * <y1 y1>
    910      *                      t[1] = -2*gp    * <xn y1>
    911      *                      t[2] =    gc^2  * <y2 y2>
    912      *                      t[3] = -2*gc    * <xn y2>
    913      *                      t[4] =  2*gp*gc * <y1 y2>
    914      *
    915 
    916     // sf 0
    917     // determine the scaling exponent for g_code: ec = ec0 - 11
    918     exp = sub(sf0_exp_gcode0, 11);
    919 
    920     // calculate exp_max[i] = s[i]-1
    921     exp_max[0] = sub(sf0_exp_coeff[0], 13);
    922     exp_max[1] = sub(sf0_exp_coeff[1], 14);
    923     exp_max[2] = add(sf0_exp_coeff[2], add(15, shl(exp, 1)));
    924     exp_max[3] = add(sf0_exp_coeff[3], exp);
    925     exp_max[4] = add(sf0_exp_coeff[4], add(1, exp));
    926 
    927     // sf 1
    928     // determine the scaling exponent for g_code: ec = ec0 - 11
    929     exp = sub(sf1_exp_gcode0, 11);
    930 
    931     // calculate exp_max[i] = s[i]-1
    932     exp_max[5] = sub(sf1_exp_coeff[0], 13);
    933     exp_max[6] = sub(sf1_exp_coeff[1], 14);
    934     exp_max[7] = add(sf1_exp_coeff[2], add(15, shl(exp, 1)));
    935     exp_max[8] = add(sf1_exp_coeff[3], exp);
    936     exp_max[9] = add(sf1_exp_coeff[4], add(1, exp));
    937 
    938      *-------------------------------------------------------------------*
    939      *  Gain search equalisation:                                        *
    940      *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                        *
    941      *  The MSE for the two subframes is weighted differently if there   *
    942      *  is a big difference in the corresponding target energies         *
    943      *-------------------------------------------------------------------*
    944 
    945     // make the target energy exponents the same by de-normalizing the
    946     // fraction of the smaller one. This is necessary to be able to compare
    947     // them
    948 
    949     exp = sf0_exp_target_en - sf1_exp_target_en;
    950     if (exp > 0)
    951     {
    952         sf1_frac_target_en = shr (sf1_frac_target_en, exp);
    953     }
    954     else
    955     {
    956         sf0_frac_target_en = shl (sf0_frac_target_en, exp);
    957     }
    958 
    959     // assume no change of exponents
    960     exp = 0;
    961 
    962     // test for target energy difference; set exp to +1 or -1 to scale
    963     // up/down coefficients for sf 1
    964 
    965     tmp = shr_r (sf1_frac_target_en, 1);   // tmp = ceil(0.5*en(sf1))
    966     if (sub (tmp, sf0_frac_target_en) > 0) // tmp > en(sf0)?
    967     {
    968         // target_energy(sf1) > 2*target_energy(sf0)
    969         //   -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4
    970         exp = 1;
    971     }
    972     else
    973     {
    974         tmp = shr (add (sf0_frac_target_en, 3), 2); // tmp=ceil(0.25*en(sf0))
    975         if (sub (tmp, sf1_frac_target_en) > 0)      // tmp > en(sf1)?
    976         {
    977             // target_energy(sf1) < 0.25*target_energy(sf0)
    978             //   -> scale down MSE(sf0) by 0.5 by subtracting 1 from
    979             //      coefficients 0..4
    980             exp = -1;
    981         }
    982     }
    983 
    984     for (i = 0; i < 5; i++)
    985     {
    986         exp_max[i] = add (exp_max[i], exp);
    987     }
    988 
    989      *-------------------------------------------------------------------*
    990      *  Find maximum exponent:                                           *
    991      *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
    992      *                                                                   *
    993      *  For the sum operation, all terms must have the same scaling;     *
    994      *  that scaling should be low enough to prevent overflow. There-    *
    995      *  fore, the maximum scale is determined and all coefficients are   *
    996      *  re-scaled:                                                       *
    997      *                                                                   *
    998      *    exp = max(exp_max[i]) + 1;                                     *
    999      *    e = exp_max[i]-exp;         e <= 0!                            *
   1000      *    c[i] = c[i]*2^e                                                *
   1001      *-------------------------------------------------------------------*
   1002 
   1003     exp = exp_max[0];
   1004     for (i = 1; i < 10; i++)
   1005     {
   1006         if (sub(exp_max[i], exp) > 0)
   1007         {
   1008             exp = exp_max[i];
   1009         }
   1010     }
   1011     exp = add(exp, 1);      // To avoid overflow
   1012 
   1013     p = &sf0_frac_coeff[0];
   1014     for (i = 0; i < 5; i++) {
   1015         tmp = sub(exp, exp_max[i]);
   1016         L_tmp = L_deposit_h(*p++);
   1017         L_tmp = L_shr(L_tmp, tmp);
   1018         L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
   1019     }
   1020     p = &sf1_frac_coeff[0];
   1021     for (; i < 10; i++) {
   1022         tmp = sub(exp, exp_max[i]);
   1023         L_tmp = L_deposit_h(*p++);
   1024         L_tmp = L_shr(L_tmp, tmp);
   1025         L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
   1026     }
   1027 
   1028     //-------------------------------------------------------------------*
   1029      *  Codebook search:                                                 *
   1030      *  ~~~~~~~~~~~~~~~~                                                 *
   1031      *                                                                   *
   1032      *  For each pair (g_pitch, g_fac) in the table calculate the        *
   1033      *  terms t[0..4] and sum them up; the result is the mean squared    *
   1034      *  error for the quantized gains from the table. The index for the  *
   1035      *  minimum MSE is stored and finally used to retrieve the quantized *
   1036      *  gains                                                            *
   1037      *-------------------------------------------------------------------
   1038 
   1039     // start with "infinite" MSE
   1040     dist_min = MAX_32;
   1041 
   1042     p = &table_gain_MR475[0];
   1043 
   1044     for (i = 0; i < MR475_VQ_SIZE; i++)
   1045     {
   1046         // subframe 0 (and 2) calculations
   1047         g_pitch = *p++;
   1048         g_code = *p++;
   1049 
   1050         g_code = mult(g_code, sf0_gcode0);
   1051         g2_pitch = mult(g_pitch, g_pitch);
   1052         g2_code = mult(g_code, g_code);
   1053         g_pit_cod = mult(g_code, g_pitch);
   1054 
   1055         L_tmp = Mpy_32_16(       coeff[0], coeff_lo[0], g2_pitch);
   1056         L_tmp = Mac_32_16(L_tmp, coeff[1], coeff_lo[1], g_pitch);
   1057         L_tmp = Mac_32_16(L_tmp, coeff[2], coeff_lo[2], g2_code);
   1058         L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], g_code);
   1059         L_tmp = Mac_32_16(L_tmp, coeff[4], coeff_lo[4], g_pit_cod);
   1060 
   1061         tmp = sub (g_pitch, gp_limit);
   1062 
   1063         // subframe 1 (and 3) calculations
   1064         g_pitch = *p++;
   1065         g_code = *p++;
   1066 
   1067         if (tmp <= 0 && sub(g_pitch, gp_limit) <= 0)
   1068         {
   1069             g_code = mult(g_code, sf1_gcode0);
   1070             g2_pitch = mult(g_pitch, g_pitch);
   1071             g2_code = mult(g_code, g_code);
   1072             g_pit_cod = mult(g_code, g_pitch);
   1073 
   1074             L_tmp = Mac_32_16(L_tmp, coeff[5], coeff_lo[5], g2_pitch);
   1075             L_tmp = Mac_32_16(L_tmp, coeff[6], coeff_lo[6], g_pitch);
   1076             L_tmp = Mac_32_16(L_tmp, coeff[7], coeff_lo[7], g2_code);
   1077             L_tmp = Mac_32_16(L_tmp, coeff[8], coeff_lo[8], g_code);
   1078             L_tmp = Mac_32_16(L_tmp, coeff[9], coeff_lo[9], g_pit_cod);
   1079 
   1080             // store table index if MSE for this index is lower
   1081                than the minimum MSE seen so far
   1082             if (L_sub(L_tmp, dist_min) < (Word32) 0)
   1083             {
   1084                 dist_min = L_tmp;
   1085                 index = i;
   1086             }
   1087         }
   1088     }
   1089 
   1090      *------------------------------------------------------------------*
   1091      *  read quantized gains and update MA predictor memories           *
   1092      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           *
   1093      *------------------------------------------------------------------*
   1094 
   1095     // for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same
   1096     // as those calculated from the "real" predictor using quantized gains
   1097     tmp = shl(index, 2);
   1098     MR475_quant_store_results(pred_st,
   1099                               &table_gain_MR475[tmp],
   1100                               sf0_gcode0,
   1101                               sf0_exp_gcode0,
   1102                               sf0_gain_pit,
   1103                               sf0_gain_cod);
   1104 
   1105     // calculate new predicted gain for subframe 1 (this time using
   1106     // the real, quantized gains)
   1107     gc_pred(pred_st, MR475, sf1_code_nosharp,
   1108             &sf1_exp_gcode0, &sf1_frac_gcode0,
   1109             &sf0_exp_gcode0, &sf0_gcode0); // last two args are dummy
   1110     sf1_gcode0 = extract_l(Pow2(14, sf1_frac_gcode0));
   1111 
   1112     tmp = add (tmp, 2);
   1113     MR475_quant_store_results(pred_st,
   1114                               &table_gain_MR475[tmp],
   1115                               sf1_gcode0,
   1116                               sf1_exp_gcode0,
   1117                               sf1_gain_pit,
   1118                               sf1_gain_cod);
   1119 
   1120     return index;
   1121 }
   1122 
   1123 ------------------------------------------------------------------------------
   1124  RESOURCES USED [optional]
   1125 
   1126  When the code is written for a specific target processor the
   1127  the resources used should be documented below.
   1128 
   1129  HEAP MEMORY USED: x bytes
   1130 
   1131  STACK MEMORY USED: x bytes
   1132 
   1133  CLOCK CYCLES: (cycle count equation for this function) + (variable
   1134                 used to represent cycle count for each subroutine
   1135                 called)
   1136      where: (cycle count variable) = cycle count for [subroutine
   1137                                      name]
   1138 
   1139 ------------------------------------------------------------------------------
   1140  CAUTION [optional]
   1141  [State any special notes, constraints or cautions for users of this function]
   1142 
   1143 ------------------------------------------------------------------------------
   1144 */
   1145 
   1146 Word16 MR475_gain_quant(       /* o  : index of quantization.                 */
   1147     gc_predState *pred_st,     /* i/o: gain predictor state struct            */
   1148 
   1149     /* data from subframe 0 (or 2) */
   1150     Word16 sf0_exp_gcode0,     /* i  : predicted CB gain (exponent),      Q0  */
   1151     Word16 sf0_frac_gcode0,    /* i  : predicted CB gain (fraction),      Q15 */
   1152     Word16 sf0_exp_coeff[],    /* i  : energy coeff. (5), exponent part,  Q0  */
   1153     Word16 sf0_frac_coeff[],   /* i  : energy coeff. (5), fraction part,  Q15 */
   1154     /*      (frac_coeff and exp_coeff computed in  */
   1155     /*       calc_filt_energies())                 */
   1156     Word16 sf0_exp_target_en,  /* i  : exponent of target energy,         Q0  */
   1157     Word16 sf0_frac_target_en, /* i  : fraction of target energy,         Q15 */
   1158 
   1159     /* data from subframe 1 (or 3) */
   1160     Word16 sf1_code_nosharp[], /* i  : innovative codebook vector (L_SUBFR)   */
   1161     /*      (whithout pitch sharpening)            */
   1162     Word16 sf1_exp_gcode0,     /* i  : predicted CB gain (exponent),      Q0  */
   1163     Word16 sf1_frac_gcode0,    /* i  : predicted CB gain (fraction),      Q15 */
   1164     Word16 sf1_exp_coeff[],    /* i  : energy coeff. (5), exponent part,  Q0  */
   1165     Word16 sf1_frac_coeff[],   /* i  : energy coeff. (5), fraction part,  Q15 */
   1166     /*      (frac_coeff and exp_coeff computed in  */
   1167     /*       calc_filt_energies())                 */
   1168     Word16 sf1_exp_target_en,  /* i  : exponent of target energy,         Q0  */
   1169     Word16 sf1_frac_target_en, /* i  : fraction of target energy,         Q15 */
   1170 
   1171     Word16 gp_limit,           /* i  : pitch gain limit                       */
   1172 
   1173     Word16 *sf0_gain_pit,      /* o  : Pitch gain,                        Q14 */
   1174     Word16 *sf0_gain_cod,      /* o  : Code gain,                         Q1  */
   1175 
   1176     Word16 *sf1_gain_pit,      /* o  : Pitch gain,                        Q14 */
   1177     Word16 *sf1_gain_cod,      /* o  : Code gain,                         Q1  */
   1178     Flag   *pOverflow          /* o  : overflow indicator                     */
   1179 )
   1180 {
   1181     const Word16 *p;
   1182     Word16 i;
   1183     Word16 index = 0;
   1184     Word16 tmp;
   1185     Word16 exp;
   1186     Word16 sf0_gcode0;
   1187     Word16 sf1_gcode0;
   1188     Word16 g_pitch;
   1189     Word16 g2_pitch;
   1190     Word16 g_code;
   1191     Word16 g2_code;
   1192     Word16 g_pit_cod;
   1193     Word16 coeff[10];
   1194     Word16 coeff_lo[10];
   1195     Word16 exp_max[10];  /* 0..4: sf0; 5..9: sf1 */
   1196     Word32 L_tmp;
   1197     Word32 dist_min;
   1198 
   1199     /*-------------------------------------------------------------------*
   1200      *  predicted codebook gain                                          *
   1201      *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
   1202      *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *
   1203      *                                                                   *
   1204      *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *
   1205      *-------------------------------------------------------------------*/
   1206 
   1207     sf0_gcode0 = (Word16)(Pow2(14, sf0_frac_gcode0, pOverflow));
   1208     sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));
   1209 
   1210     /*
   1211      * For each subframe, the error energy (sum) to be minimized consists
   1212      * of five terms, t[0..4].
   1213      *
   1214      *                      t[0] =    gp^2  * <y1 y1>
   1215      *                      t[1] = -2*gp    * <xn y1>
   1216      *                      t[2] =    gc^2  * <y2 y2>
   1217      *                      t[3] = -2*gc    * <xn y2>
   1218      *                      t[4] =  2*gp*gc * <y1 y2>
   1219      *
   1220      */
   1221 
   1222     /* sf 0 */
   1223     /* determine the scaling exponent for g_code: ec = ec0 - 11 */
   1224     exp = sf0_exp_gcode0 - 11;
   1225 
   1226     /* calculate exp_max[i] = s[i]-1 */
   1227     exp_max[0] = (sf0_exp_coeff[0] - 13);
   1228     exp_max[1] = (sf0_exp_coeff[1] - 14);
   1229     exp_max[2] = (sf0_exp_coeff[2] + (15 + (exp << 1)));
   1230     exp_max[3] = (sf0_exp_coeff[3] + exp);
   1231     exp_max[4] = (sf0_exp_coeff[4] + (1 + exp));
   1232 
   1233     /* sf 1 */
   1234     /* determine the scaling exponent for g_code: ec = ec0 - 11 */
   1235     exp = sf1_exp_gcode0 - 11;
   1236 
   1237     /* calculate exp_max[i] = s[i]-1 */
   1238     exp_max[5] = (sf1_exp_coeff[0] - 13);
   1239     exp_max[6] = (sf1_exp_coeff[1] - 14);
   1240     exp_max[7] = (sf1_exp_coeff[2] + (15 + (exp << 1)));
   1241     exp_max[8] = (sf1_exp_coeff[3] + exp);
   1242     exp_max[9] = (sf1_exp_coeff[4] + (1 + exp));
   1243 
   1244     /*-------------------------------------------------------------------*
   1245      *  Gain search equalisation:                                        *
   1246      *  ~~~~~~~~~~~~~~~~~~~~~~~~~                                        *
   1247      *  The MSE for the two subframes is weighted differently if there   *
   1248      *  is a big difference in the corresponding target energies         *
   1249      *-------------------------------------------------------------------*/
   1250 
   1251     /* make the target energy exponents the same by de-normalizing the
   1252        fraction of the smaller one. This is necessary to be able to compare
   1253        them
   1254      */
   1255     exp = sf0_exp_target_en - sf1_exp_target_en;
   1256     if (exp > 0)
   1257     {
   1258         sf1_frac_target_en >>= exp;
   1259     }
   1260     else
   1261     {
   1262         sf0_frac_target_en >>= (-exp);
   1263     }
   1264 
   1265     /* assume no change of exponents */
   1266     exp = 0;
   1267 
   1268     /* test for target energy difference; set exp to +1 or -1 to scale
   1269      * up/down coefficients for sf 1
   1270      */
   1271     tmp = shr_r(sf1_frac_target_en, 1, pOverflow);  /* tmp = ceil(0.5*en(sf1)) */
   1272 
   1273     if (tmp > sf0_frac_target_en)          /* tmp > en(sf0)? */
   1274     {
   1275         /*
   1276          * target_energy(sf1) > 2*target_energy(sf0)
   1277          *   -> scale up MSE(sf0) by 2 by adding 1 to exponents 0..4
   1278          */
   1279         exp = 1;
   1280     }
   1281     else
   1282     {
   1283         tmp = ((sf0_frac_target_en + 3) >> 2); /* tmp=ceil(0.25*en(sf0)) */
   1284 
   1285         if (tmp > sf1_frac_target_en)      /* tmp > en(sf1)? */
   1286         {
   1287             /*
   1288              * target_energy(sf1) < 0.25*target_energy(sf0)
   1289              *   -> scale down MSE(sf0) by 0.5 by subtracting 1 from
   1290              *      coefficients 0..4
   1291              */
   1292             exp = -1;
   1293         }
   1294     }
   1295 
   1296     for (i = 0; i < 5; i++)
   1297     {
   1298         exp_max[i] += exp;
   1299     }
   1300 
   1301     /*-------------------------------------------------------------------*
   1302      *  Find maximum exponent:                                           *
   1303      *  ~~~~~~~~~~~~~~~~~~~~~~                                           *
   1304      *                                                                   *
   1305      *  For the sum operation, all terms must have the same scaling;     *
   1306      *  that scaling should be low enough to prevent overflow. There-    *
   1307      *  fore, the maximum scale is determined and all coefficients are   *
   1308      *  re-scaled:                                                       *
   1309      *                                                                   *
   1310      *    exp = max(exp_max[i]) + 1;                                     *
   1311      *    e = exp_max[i]-exp;         e <= 0!                            *
   1312      *    c[i] = c[i]*2^e                                                *
   1313      *-------------------------------------------------------------------*/
   1314 
   1315     exp = exp_max[0];
   1316     for (i = 9; i > 0; i--)
   1317     {
   1318         if (exp_max[i] > exp)
   1319         {
   1320             exp = exp_max[i];
   1321         }
   1322     }
   1323     exp++;      /* To avoid overflow */
   1324 
   1325     p = &sf0_frac_coeff[0];
   1326     for (i = 0; i < 5; i++)
   1327     {
   1328         tmp = (exp - exp_max[i]);
   1329         L_tmp = ((Word32)(*p++) << 16);
   1330         L_tmp = L_shr(L_tmp, tmp, pOverflow);
   1331         coeff[i] = (Word16)(L_tmp >> 16);
   1332         coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15));
   1333     }
   1334     p = &sf1_frac_coeff[0];
   1335     for (; i < 10; i++)
   1336     {
   1337         tmp = exp - exp_max[i];
   1338         L_tmp = ((Word32)(*p++) << 16);
   1339         L_tmp = L_shr(L_tmp, tmp, pOverflow);
   1340         coeff[i] = (Word16)(L_tmp >> 16);
   1341         coeff_lo[i] = (Word16)((L_tmp >> 1) - ((L_tmp >> 16) << 15));
   1342     }
   1343 
   1344 
   1345     /*-------------------------------------------------------------------*
   1346      *  Codebook search:                                                 *
   1347      *  ~~~~~~~~~~~~~~~~                                                 *
   1348      *                                                                   *
   1349      *  For each pair (g_pitch, g_fac) in the table calculate the        *
   1350      *  terms t[0..4] and sum them up; the result is the mean squared    *
   1351      *  error for the quantized gains from the table. The index for the  *
   1352      *  minimum MSE is stored and finally used to retrieve the quantized *
   1353      *  gains                                                            *
   1354      *-------------------------------------------------------------------*/
   1355 
   1356     /* start with "infinite" MSE */
   1357     dist_min = MAX_32;
   1358 
   1359     p = &table_gain_MR475[0];
   1360 
   1361     for (i = 0; i < MR475_VQ_SIZE; i++)
   1362     {
   1363         /* subframe 0 (and 2) calculations */
   1364         g_pitch = *p++;
   1365         g_code = *p++;
   1366 
   1367         /* Need to be there OKA */
   1368         g_code    = (Word16)(((Word32) g_code * sf0_gcode0) >> 15);
   1369         g2_pitch  = (Word16)(((Word32) g_pitch * g_pitch) >> 15);
   1370         g2_code   = (Word16)(((Word32) g_code * g_code) >> 15);
   1371         g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15);
   1372 
   1373 
   1374         L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow) +
   1375                 Mpy_32_16(coeff[1], coeff_lo[1], g_pitch, pOverflow) +
   1376                 Mpy_32_16(coeff[2], coeff_lo[2], g2_code, pOverflow) +
   1377                 Mpy_32_16(coeff[3], coeff_lo[3], g_code, pOverflow) +
   1378                 Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod, pOverflow);
   1379 
   1380         tmp = (g_pitch - gp_limit);
   1381 
   1382         /* subframe 1 (and 3) calculations */
   1383         g_pitch = *p++;
   1384         g_code = *p++;
   1385 
   1386         if ((tmp <= 0) && (g_pitch <= gp_limit))
   1387         {
   1388             g_code = (Word16)(((Word32) g_code * sf1_gcode0) >> 15);
   1389             g2_pitch  = (Word16)(((Word32) g_pitch * g_pitch) >> 15);
   1390             g2_code   = (Word16)(((Word32) g_code * g_code) >> 15);
   1391             g_pit_cod = (Word16)(((Word32) g_code * g_pitch) >> 15);
   1392 
   1393             L_tmp += (Mpy_32_16(coeff[5], coeff_lo[5], g2_pitch, pOverflow) +
   1394                       Mpy_32_16(coeff[6], coeff_lo[6], g_pitch, pOverflow) +
   1395                       Mpy_32_16(coeff[7], coeff_lo[7], g2_code, pOverflow) +
   1396                       Mpy_32_16(coeff[8], coeff_lo[8], g_code, pOverflow) +
   1397                       Mpy_32_16(coeff[9], coeff_lo[9], g_pit_cod, pOverflow));
   1398 
   1399             /* store table index if MSE for this index is lower
   1400                than the minimum MSE seen so far */
   1401             if (L_tmp < dist_min)
   1402             {
   1403                 dist_min = L_tmp;
   1404                 index = i;
   1405             }
   1406         }
   1407     }
   1408 
   1409     /*------------------------------------------------------------------*
   1410      *  read quantized gains and update MA predictor memories           *
   1411      *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           *
   1412      *------------------------------------------------------------------*/
   1413 
   1414     /* for subframe 0, the pre-calculated gcode0/exp_gcode0 are the same
   1415        as those calculated from the "real" predictor using quantized gains */
   1416     tmp = index << 2;
   1417     MR475_quant_store_results(pred_st,
   1418                               &table_gain_MR475[tmp],
   1419                               sf0_gcode0,
   1420                               sf0_exp_gcode0,
   1421                               sf0_gain_pit,
   1422                               sf0_gain_cod,
   1423                               pOverflow);
   1424 
   1425     /* calculate new predicted gain for subframe 1 (this time using
   1426        the real, quantized gains)                                   */
   1427     gc_pred(pred_st, MR475, sf1_code_nosharp,
   1428             &sf1_exp_gcode0, &sf1_frac_gcode0,
   1429             &sf0_exp_gcode0, &sf0_gcode0, /* dummy args */
   1430             pOverflow);
   1431 
   1432     sf1_gcode0 = (Word16)(Pow2(14, sf1_frac_gcode0, pOverflow));
   1433 
   1434     tmp += 2;
   1435     MR475_quant_store_results(
   1436         pred_st,
   1437         &table_gain_MR475[tmp],
   1438         sf1_gcode0,
   1439         sf1_exp_gcode0,
   1440         sf1_gain_pit,
   1441         sf1_gain_cod,
   1442         pOverflow);
   1443 
   1444     return(index);
   1445 }
   1446