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
MR475_quant_store_results(gc_predState * pred_st,const Word16 * p,Word16 gcode0,Word16 exp_gcode0,Word16 * gain_pit,Word16 * gain_cod,Flag * pOverflow)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
MR475_update_unq_pred(gc_predState * pred_st,Word16 exp_gcode0,Word16 frac_gcode0,Word16 cod_gain_exp,Word16 cod_gain_frac,Flag * pOverflow)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 unused
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
MR475_gain_quant(gc_predState * pred_st,Word16 sf0_exp_gcode0,Word16 sf0_frac_gcode0,Word16 sf0_exp_coeff[],Word16 sf0_frac_coeff[],Word16 sf0_exp_target_en,Word16 sf0_frac_target_en,Word16 sf1_code_nosharp[],Word16 sf1_exp_gcode0,Word16 sf1_frac_gcode0,Word16 sf1_exp_coeff[],Word16 sf1_frac_coeff[],Word16 sf1_exp_target_en,Word16 sf1_frac_target_en,Word16 gp_limit,Word16 * sf0_gain_pit,Word16 * sf0_gain_cod,Word16 * sf1_gain_pit,Word16 * sf1_gain_cod,Flag * pOverflow)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, /* unused 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