1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/****************************************************************************************
19Portions of this file are derived from the following 3GPP standard:
20
21    3GPP TS 26.073
22    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23    Available from http://www.3gpp.org
24
25(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26Permission to distribute, modify and use this file under the standard license
27terms listed above has been obtained from the copyright holder.
28****************************************************************************************/
29/*
30------------------------------------------------------------------------------
31
32
33
34 Pathname: ./audio/gsm-amr/c/src/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 */
90static 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
399static 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
474static 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
586void
587MR475_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
693void 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
851Word16
852MR475_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
1146Word16 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