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.
LcdInitialize(IN EFI_PHYSICAL_ADDRESS VramBaseAddress)28 ****************************************************************************************/
29 /*
30 ------------------------------------------------------------------------------
31
32
33
34 Filename: qgain795.cpp
35 Functions: MR795_gain_code_quant3
36 MR795_gain_code_quant_mod
37 MR795_gain_quant
38
39 ------------------------------------------------------------------------------
40 MODULE DESCRIPTION
41
42
43 ------------------------------------------------------------------------------
44 */
45
46 /*----------------------------------------------------------------------------
47 ; INCLUDES
48 ----------------------------------------------------------------------------*/
49 #include "qgain795.h"
50 #include "typedef.h"
51 #include "basic_op.h"
52 #include "cnst.h"
53 #include "log2.h"
54 #include "pow2.h"
55 #include "sqrt_l.h"
56 #include "g_adapt.h"
57 #include "calc_en.h"
58 #include "q_gain_p.h"
59
60
61 /*--------------------------------------------------------------------------*/
62 #ifdef __cplusplus
63 extern "C"
64 {
65 #endif
66
67 /*----------------------------------------------------------------------------
68 ; MACROS
69 ; Define module specific macros here
70 ----------------------------------------------------------------------------*/
71
72 /*----------------------------------------------------------------------------
73 ; DEFINES
74 ; Include all pre-processor statements here. Include conditional
75 ; compile variables also.
76 ----------------------------------------------------------------------------*/
77 #define NB_QUA_CODE 32
78
79 /*----------------------------------------------------------------------------
80 ; LOCAL FUNCTION DEFINITIONS
81 ; Function Prototype declaration
82 ----------------------------------------------------------------------------*/
83
84 /*----------------------------------------------------------------------------
85 ; LOCAL VARIABLE DEFINITIONS
86 ; Variable declaration - defined here and used outside this module
87 ----------------------------------------------------------------------------*/
88
89 /*----------------------------------------------------------------------------
90 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
91 ; Declare variables used in this module but defined elsewhere
92 ----------------------------------------------------------------------------*/
93
94 /*--------------------------------------------------------------------------*/
95 #ifdef __cplusplus
96 }
97 #endif
98
99 /*
100 ------------------------------------------------------------------------------
101 FUNCTION NAME: MR795_gain_code_quant3
102 ------------------------------------------------------------------------------
103 INPUT AND OUTPUT DEFINITIONS
104
105 Inputs:
106 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
107 gcode0 -- Word16 -- predicted CB gain (norm.)
108 g_pitch_cand[] -- Word16 array -- Pitch gain candidates (3), Q14
109 g_pitch_cind[] -- Word16 array -- Pitch gain cand. indices (3), Q0
110 frac_coeff[] -- Word16 array -- coefficients (5), Q15
111 exp_coeff[] -- Word16 array -- energy coefficients (5), Q0
112 coefficients from calc_filt_ener()
113
114 Outputs:
115 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
116 gain_pit_ind -- Pointer to Word16 -- Pitch gain index, Q0
117 gain_cod -- Pointer to Word16 -- Code gain, Q1
118 gain_cod_ind -- Pointer to Word16 -- Code gain index, Q0
119 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
120 (for MR122 MA predictor update)
121
122 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
123 (for other MA predictor update)
124
125 pOverflow -- Pointer to Flag -- overflow indicator
126
127 Returns:
128 None
129
130 Global Variables Used:
131 None
132
133 Local Variables Needed:
134 None
135
136 ------------------------------------------------------------------------------
137 FUNCTION DESCRIPTION
138
139 PURPOSE: Pre-quantization of codebook gains, given three possible
140 LTP gains (using predicted codebook gain)
141 ------------------------------------------------------------------------------
142 REQUIREMENTS
143
144 None
145
146 ------------------------------------------------------------------------------
147 REFERENCES
148
LcdShutdown(VOID)149 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
150
151 ------------------------------------------------------------------------------
152 PSEUDO-CODE
153
154
155 ------------------------------------------------------------------------------
156 CAUTION [optional]
157 [State any special notes, constraints or cautions for users of this function]
158
159 ------------------------------------------------------------------------------
160 */
161
162 static void
163 MR795_gain_code_quant3(
164 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
165 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
166 Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */
167 Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */
168 Word16 frac_coeff[], /* i : coefficients (5), Q15 */
169 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
170 /* coefficients from calc_filt_ener()*/
171 Word16 *gain_pit, /* o : Pitch gain, Q14 */
172 Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */
173 Word16 *gain_cod, /* o : Code gain, Q1 */
174 Word16 *gain_cod_ind, /* o : Code gain index, Q0 */
175 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
176 /* (for MR122 MA predictor update) */
177 Word16 *qua_ener, /* o : quantized energy error, Q10 */
178 /* (for other MA predictor update) */
179 const Word16* qua_gain_code_ptr, /* i : ptr to read-only table */
180 Flag *pOverflow /* o : overflow indicator */
181 )
182 {
183 const Word16 *p;
184 Word16 i;
185 Word16 j;
186 Word16 cod_ind;
187 Word16 pit_ind;
188 Word16 e_max;
189 Word16 exp_code;
190 Word16 g_pitch;
191 Word16 g2_pitch;
192 Word16 g_code;
193 Word16 g2_code_h;
194 Word16 g2_code_l;
195 Word16 g_pit_cod_h;
196 Word16 g_pit_cod_l;
197 Word16 coeff[5];
198 Word16 coeff_lo[5];
199 Word16 exp_max[5];
200 Word32 L_tmp;
201 Word32 L_tmp0;
202 Word32 dist_min;
203
204 /*
205 * The error energy (sum) to be minimized consists of five terms, t[0..4].
206 *
207 * t[0] = gp^2 * <y1 y1>
208 * t[1] = -2*gp * <xn y1>
209 * t[2] = gc^2 * <y2 y2>
210 * t[3] = -2*gc * <xn y2>
211 * t[4] = 2*gp*gc * <y1 y2>
212 *
213 */
214
215 /* determine the scaling exponent for g_code: ec = ec0 - 10 */
216 exp_code = exp_gcode0 - 10;
217
218 /* calculate exp_max[i] = s[i]-1 */
219 exp_max[0] = exp_coeff[0] - 13;
220 exp_max[1] = exp_coeff[1] - 14;
221 exp_max[2] = exp_coeff[2] + shl(exp_code, 1, pOverflow) + 15;
222 exp_max[3] = exp_coeff[3] + exp_code;
223 exp_max[4] = exp_coeff[4] + (exp_code + 1);
224
225
226 /*-------------------------------------------------------------------*
227 * Find maximum exponent: *
228 * ~~~~~~~~~~~~~~~~~~~~~~ *
229 * *
230 * For the sum operation, all terms must have the same scaling; *
231 * that scaling should be low enough to prevent overflow. There- *
232 * fore, the maximum scale is determined and all coefficients are *
233 * re-scaled: *
234 * *
235 * e_max = max(exp_max[i]) + 1; *
236 * e = exp_max[i]-e_max; e <= 0! *
237 * c[i] = c[i]*2^e *
238 *-------------------------------------------------------------------*/
239
240 e_max = exp_max[0];
241 for (i = 1; i < 5; i++) /* implemented flattened */
242 {
243 if (exp_max[i] > e_max)
244 {
245 e_max = exp_max[i];
246 }
247 }
248
249 e_max = add_16(e_max, 1, pOverflow); /* To avoid overflow */
250
251 for (i = 0; i < 5; i++)
252 {
253 j = e_max - exp_max[i];
254 L_tmp = ((Word32)frac_coeff[i] << 16);
255 L_tmp = L_shr(L_tmp, j, pOverflow);
256 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
257 }
258
259
260 /*-------------------------------------------------------------------*
261 * Codebook search: *
262 * ~~~~~~~~~~~~~~~~ *
263 * *
264 * For each of the candiates LTP gains in g_pitch_cand[], the terms *
265 * t[0..4] are calculated from the values in the table (and the *
266 * pitch gain candidate) and summed up; the result is the mean *
267 * squared error for the LPT/CB gain pair. The index for the mini- *
268 * mum MSE is stored and finally used to retrieve the quantized CB *
269 * gain *
270 *-------------------------------------------------------------------*/
271
272 /* start with "infinite" MSE */
273 dist_min = MAX_32;
274 cod_ind = 0;
275 pit_ind = 0;
276
277 /* loop through LTP gain candidates */
278 for (j = 0; j < 3; j++)
279 {
280 /* pre-calculate terms only dependent on pitch gain */
281 g_pitch = g_pitch_cand[j];
282 g2_pitch = mult(g_pitch, g_pitch, pOverflow);
283 L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
284 L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow);
285
286 p = &qua_gain_code_ptr[0];
287 for (i = 0; i < NB_QUA_CODE; i++)
288 {
289 g_code = *p++; /* this is g_fac Q11 */
290 p++; /* skip log2(g_fac) */
291 p++; /* skip 20*log10(g_fac) */
292
293 g_code = mult(g_code, gcode0, pOverflow);
294
295 L_tmp = L_mult(g_code, g_code, pOverflow);
296 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
297
298 L_tmp = L_mult(g_code, g_pitch, pOverflow);
299 L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow);
300
301 L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2],
302 g2_code_h, g2_code_l, pOverflow);
303 L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3],
304 g_code, pOverflow);
305 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4],
306 g_pit_cod_h, g_pit_cod_l, pOverflow);
307
308 /* store table index if MSE for this index is lower
309 than the minimum MSE seen so far; also store the
310 pitch gain for this (so far) lowest MSE */
311 if (L_tmp < dist_min)
312 {
313 dist_min = L_tmp;
314 cod_ind = i;
315 pit_ind = j;
316 }
317 }
318 }
319
320 /*------------------------------------------------------------------*
321 * read quantized gains and new values for MA predictor memories *
322 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
323 *------------------------------------------------------------------*/
324
325 /* Read the quantized gains */
326 p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind];
327
328 g_code = *p++;
329 *qua_ener_MR122 = *p++;
330 *qua_ener = *p;
331
332 /*------------------------------------------------------------------*
333 * calculate final fixed codebook gain: *
334 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
335 * *
336 * gc = gc0 * g *
337 *------------------------------------------------------------------*/
338
339 L_tmp = L_mult(g_code, gcode0, pOverflow);
340 L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
341 *gain_cod = (Word16)(L_tmp >> 16);
342 *gain_cod_ind = cod_ind;
343 *gain_pit = g_pitch_cand[pit_ind];
344 *gain_pit_ind = g_pitch_cind[pit_ind];
345 }
346
347
348 /*
349 ------------------------------------------------------------------------------
350 FUNCTION NAME: MR795_gain_code_quant_mod
351 ------------------------------------------------------------------------------
352 INPUT AND OUTPUT DEFINITIONS
353
354 Inputs:
355 gain_pit -- Word16 -- pitch gain, Q14
356 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
357 gcode0 -- Word16 -- predicted CB gain (norm.), Q14
358 frac_en[] -- Word16 array -- energy coefficients (4), fraction part, Q15
359 exp_en[] -- Word16 array -- energy coefficients (4), exponent part, Q0
360 alpha -- Word16 -- gain adaptor factor (>0), Q15
361
362 gain_cod_unq -- Word16 -- Code gain (unquantized)
363 (scaling: Q10 - exp_gcode0)
364
365 gain_cod -- Pointer to Word16 -- Code gain (pre-/quantized), Q1
366
367 Outputs:
368 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
369 (for MR122 MA predictor update)
370 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
371 (for other MA predictor update)
372 pOverflow -- Pointer to Flag -- overflow indicator
373
374 Returns:
375 index of quantization (Word16)
376
377 Global Variables Used:
378 None
379
380 Local Variables Needed:
381 None
382
383 ------------------------------------------------------------------------------
384 FUNCTION DESCRIPTION
385
386 PURPOSE: Modified quantization of the MR795 codebook gain
387
388 Uses pre-computed energy coefficients in frac_en[]/exp_en[]
389
390 frac_en[0]*2^exp_en[0] = <res res> // LP residual energy
391 frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy
392 frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product
393 frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy
394 ------------------------------------------------------------------------------
395 REQUIREMENTS
396
397 None
398
399 ------------------------------------------------------------------------------
400 REFERENCES
401
402 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
403
404 ------------------------------------------------------------------------------
405 PSEUDO-CODE
406
407
408 ------------------------------------------------------------------------------
409 CAUTION [optional]
410 [State any special notes, constraints or cautions for users of this function]
411
412 ------------------------------------------------------------------------------
413 */
414
415 static Word16
416 MR795_gain_code_quant_mod( /* o : index of quantization. */
417 Word16 gain_pit, /* i : pitch gain, Q14 */
418 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
419 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
420 Word16 frac_en[], /* i : energy coefficients (4),
421 fraction part, Q15 */
422 Word16 exp_en[], /* i : energy coefficients (4),
423 eponent part, Q0 */
424 Word16 alpha, /* i : gain adaptor factor (>0), Q15 */
425 Word16 gain_cod_unq, /* i : Code gain (unquantized) */
426 /* (scaling: Q10 - exp_gcode0) */
427 Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */
428 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
429 /* (for MR122 MA predictor update) */
430 Word16 *qua_ener, /* o : quantized energy error, Q10 */
431 /* (for other MA predictor update) */
432 const Word16* qua_gain_code_ptr, /* i : ptr to read-only ptr */
433 Flag *pOverflow /* o : overflow indicator */
434 )
435 {
436 const Word16 *p;
437 Word16 i;
438 Word16 index;
439 Word16 tmp;
440 Word16 one_alpha;
441 Word16 exp;
442 Word16 e_max;
443
444 Word16 g2_pitch;
445 Word16 g_code;
446 Word16 g2_code_h;
447 Word16 g2_code_l;
448 Word16 d2_code_h;
449 Word16 d2_code_l;
450 Word16 coeff[5];
451 Word16 coeff_lo[5];
452 Word16 exp_coeff[5];
453 Word32 L_tmp;
454 Word32 L_t0;
455 Word32 L_t1;
456 Word32 dist_min;
457 Word16 gain_code;
458
459 /*
460 Steps in calculation of the error criterion (dist):
461 ---------------------------------------------------
462
463 underlined = constant; alp = FLP value of alpha, alpha = FIP
464 ----------
465
466
467 ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
468 ------------ ------ -- -----
469
470 aExEn= alp * ExEn
471 = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
472 -------------- ------------- ---------
473
474 = t[1] + t[2] + t[3]
475
476 dist = d1 + d2;
477
478 d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
479 ------------------- ---
480
481 d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
482 --- ----- --- -----
483
484 = alp * (sqrt(ExEn) - sqrt(ResEn))^2
485 --- -----------
486
487 = (sqrt(aExEn) - sqrt(alp*ResEn))^2
488 ---------------
489
490 = (sqrt(aExEn) - t[0] )^2
491 ----
492
493 */
494
495 /*
496 * calculate scalings of the constant terms
497 */
498 gain_code = shl(*gain_cod, (10 - exp_gcode0), pOverflow); /* Q1 -> Q11 (-ec0) */
499 g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */
500 /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */
501 one_alpha = add_16((32767 - alpha), 1, pOverflow); /* 32768 - alpha */
502
503
504 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
505 L_t1 = L_mult(alpha, frac_en[1], pOverflow);
506 L_t1 = L_shl(L_t1, 1, pOverflow);
507 tmp = (Word16)(L_t1 >> 16);
508
509 /* directly store in 32 bit variable because no further mult. required */
510 L_t1 = L_mult(tmp, g2_pitch, pOverflow);
511 exp_coeff[1] = exp_en[1] - 15;
512
513
514 tmp = (Word16)(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow) >> 16);
515 coeff[2] = mult(tmp, gain_pit, pOverflow);
516 exp = exp_gcode0 - 10;
517 exp_coeff[2] = add_16(exp_en[2], exp, pOverflow);
518
519
520 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
521 coeff[3] = (Word16)(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow) >> 16);
522 exp = shl(exp_gcode0, 1, pOverflow) - 7;
523 exp_coeff[3] = add_16(exp_en[3], exp, pOverflow);
524
525
526 coeff[4] = mult(one_alpha, frac_en[3], pOverflow);
527 exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow);
528
529
530 L_tmp = L_mult(alpha, frac_en[0], pOverflow);
531 /* sqrt_l returns normalized value and 2*exponent
532 -> result = val >> (exp/2)
533 exp_coeff holds 2*exponent for c[0] */
534 /* directly store in 32 bit variable because no further mult. required */
535 L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */
536 exp += 47;
537 exp_coeff[0] = exp_en[0] - exp;
538
539 /*
540 * Determine the maximum exponent occuring in the distance calculation
541 * and adjust all fractions accordingly (including a safety margin)
542 *
543 */
544
545 /* find max(e[1..4],e[0]+31) */
546 e_max = exp_coeff[0] + 31;
547 for (i = 1; i <= 4; i++)
548 {
549 if (exp_coeff[i] > e_max)
550 {
551 e_max = exp_coeff[i];
552 }
553 }
554
555 /* scale c[1] (requires no further multiplication) */
556 tmp = e_max - exp_coeff[1];
557 L_t1 = L_shr(L_t1, tmp, pOverflow);
558
559 /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
560 for (i = 2; i <= 4; i++)
561 {
562 tmp = e_max - exp_coeff[i];
563 L_tmp = ((Word32)coeff[i] << 16);
564 L_tmp = L_shr(L_tmp, tmp, pOverflow);
565 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
566 }
567
568 /* scale c[0] (requires no further multiplication) */
569 exp = e_max - 31; /* new exponent */
570 tmp = exp - exp_coeff[0];
571 L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow);
572 /* perform correction by 1/sqrt(2) if exponent difference is odd */
573 if ((tmp & 0x1) != 0)
574 {
575 L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow);
576 L_t0 = Mpy_32_16(coeff[0], coeff_lo[0],
577 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/
578 }
579
580 /* search the quantizer table for the lowest value
581 of the search criterion */
582 dist_min = MAX_32;
583 index = 0;
584 p = &qua_gain_code_ptr[0];
585
586 for (i = 0; i < NB_QUA_CODE; i++)
587 {
588 g_code = *p++; /* this is g_fac (Q11) */
589 p++; /* skip log2(g_fac) */
590 p++; /* skip 20*log10(g_fac) */
591 g_code = mult(g_code, gcode0, pOverflow);
592
593 /* only continue if gc[i] < 2.0*gc
594 which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */
595
596 if (g_code >= gain_code)
597 {
598 break;
599 }
600
601 L_tmp = L_mult(g_code, g_code, pOverflow);
602 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
603
604 tmp = sub(g_code, gain_cod_unq, pOverflow);
605 L_tmp = L_mult(tmp, tmp, pOverflow);
606 L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow);
607
608 /* t2, t3, t4 */
609 L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow);
610 L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow);
611
612 L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow);
613 L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow);
614
615 /* d2 */
616 tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow);
617 L_tmp = L_mult(tmp, tmp, pOverflow);
618
619 /* dist */
620 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow);
621
622 /* store table index if distance measure for this
623 index is lower than the minimum seen so far */
624 if (L_tmp < dist_min)
625 {
626 dist_min = L_tmp;
627 index = i;
628 }
629 }
630
631 /*------------------------------------------------------------------*
632 * read quantized gains and new values for MA predictor memories *
633 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
634 *------------------------------------------------------------------*/
635
636 /* Read the quantized gains */
637 p = &qua_gain_code_ptr[(index<<2) - index];
638 g_code = *p++;
639 *qua_ener_MR122 = *p++;
640 *qua_ener = *p;
641
642 /*------------------------------------------------------------------*
643 * calculate final fixed codebook gain: *
644 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
645 * *
646 * gc = gc0 * g *
647 *------------------------------------------------------------------*/
648
649 L_tmp = L_mult(g_code, gcode0, pOverflow);
650 L_tmp = L_shr(L_tmp, 9 - exp_gcode0, pOverflow);
651 *gain_cod = (Word16)(L_tmp >> 16);
652
653 return index;
654 }
655
656 /*
657 ------------------------------------------------------------------------------
658 FUNCTION NAME: MR795_gain_quant
659 ------------------------------------------------------------------------------
660 INPUT AND OUTPUT DEFINITIONS
661 MR795_gain_quant(
662
663
664 Inputs:
665 adapt_st -- Pointer to GainAdaptState -- gain adapter state structure
666 res -- Word16 array -- LP residual, Q0
667 exc -- Word16 array -- LTP excitation (unfiltered), Q0
668 code -- Word16 array -- CB innovation (unfiltered), Q13
669 frac_coeff -- Word16 array -- coefficients (5), Q15
670 exp_coeff -- Word16 array -- energy coefficients (5), Q0
671 coefficients from calc_filt_ener()
672 exp_code_en -- Word16 -- innovation energy (exponent), Q0
673 frac_code_en -- Word16 -- innovation energy (fraction), Q15
674 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
675 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15
676 L_subfr -- Word16 -- Subframe length
677 cod_gain_frac -- Word16 -- opt. codebook gain (fraction),Q15
678 cod_gain_exp -- Word16 -- opt. codebook gain (exponent), Q0
679 gp_limit -- Word16 -- pitch gain limit
680 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
681
682 Output
683 adapt_st -- Pointer to GainAdaptState -- gain adapter state structure
684 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
685
686 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
687 gain_cod -- Pointer to Word16 -- Code gain, Q1
688 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
689 (for MR122 MA predictor update)
690
691 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
692 (for other MA predictor update)
693
694 anap -- Double Pointer to Word16 -- Index of quantization
695 (first gain pitch, then code pitch)
696
697 pOverflow -- Pointer to Flag -- overflow indicator
698
699 Returns:
700 None
701
702 Global Variables Used:
703 None
704
705 Local Variables Needed:
706 None
707
708 ------------------------------------------------------------------------------
709 FUNCTION DESCRIPTION
710
711 pitch and codebook quantization for MR795
712 ------------------------------------------------------------------------------
713 REQUIREMENTS
714
715 None
716
717 ------------------------------------------------------------------------------
718 REFERENCES
719
720 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
721
722 ------------------------------------------------------------------------------
723 PSEUDO-CODE
724
725
726 ------------------------------------------------------------------------------
727 CAUTION [optional]
728 [State any special notes, constraints or cautions for users of this function]
729
730 ------------------------------------------------------------------------------
731 */
732
733 void
734 MR795_gain_quant(
735 GainAdaptState *adapt_st, /* i/o: gain adapter state structure */
736 Word16 res[], /* i : LP residual, Q0 */
737 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */
738 Word16 code[], /* i : CB innovation (unfiltered), Q13 */
739 Word16 frac_coeff[], /* i : coefficients (5), Q15 */
740 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
741 /* coefficients from calc_filt_ener() */
742 Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */
743 Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */
744 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
745 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
746 Word16 L_subfr, /* i : Subframe length */
747 Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */
748 Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */
749 Word16 gp_limit, /* i : pitch gain limit */
750 Word16 *gain_pit, /* i/o: Pitch gain, Q14 */
751 Word16 *gain_cod, /* o : Code gain, Q1 */
752 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
753 /* (for MR122 MA predictor update) */
754 Word16 *qua_ener, /* o : quantized energy error, Q10 */
755 /* (for other MA predictor update) */
756 Word16 **anap, /* o : Index of quantization */
757 /* (first gain pitch, then code pitch)*/
758 CommonAmrTbls* common_amr_tbls, /* i : ptr to struct of table ptrs */
759 Flag *pOverflow /* o : overflow indicator */
760 )
761 {
762 Word16 frac_en[4];
763 Word16 exp_en[4];
764 Word16 ltpg, alpha, gcode0;
765 Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */
766 Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */
767 Word16 gain_pit_index;
768 Word16 gain_cod_index;
769 Word16 exp;
770 Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */
771
772
773 /* get list of candidate quantized pitch gain values
774 * and corresponding quantization indices
775 */
776 gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit,
777 g_pitch_cand, g_pitch_cind, common_amr_tbls->qua_gain_pitch_ptr, pOverflow);
778
779 /*-------------------------------------------------------------------*
780 * predicted codebook gain *
781 * ~~~~~~~~~~~~~~~~~~~~~~~ *
782 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
783 * *
784 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
785 *-------------------------------------------------------------------*/
786 gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */
787
788 /* pre-quantization of codebook gain
789 * (using three pitch gain candidates);
790 * result: best guess of pitch gain and code gain
791 */
792 MR795_gain_code_quant3(
793 exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind,
794 frac_coeff, exp_coeff,
795 gain_pit, &gain_pit_index, gain_cod, &gain_cod_index,
796 qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr, pOverflow);
797
798 /* calculation of energy coefficients and LTP coding gain */
799 calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr,
800 frac_en, exp_en, <pg, pOverflow);
801
802 /* run gain adaptor, calculate alpha factor to balance LTP/CB gain
803 * (this includes the gain adaptor update)
804 * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case
805 */
806 gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow);
807
808 /* if this is a very low energy signal (threshold: see
809 * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer
810 */
811 if (frac_en[0] != 0 && alpha > 0)
812 {
813 /* innovation energy <cod cod> was already computed in gc_pred() */
814 /* (this overwrites the LtpResEn which is no longer needed) */
815 frac_en[3] = frac_code_en;
816 exp_en[3] = exp_code_en;
817
818 /* store optimum codebook gain in Q(10-exp_gcode0) */
819 exp = sub(cod_gain_exp, exp_gcode0, pOverflow) + 10;
820 gain_cod_unq = shl(cod_gain_frac, exp, pOverflow);
821
822 /* run quantization with modified criterion */
823 gain_cod_index = MR795_gain_code_quant_mod(
824 *gain_pit, exp_gcode0, gcode0,
825 frac_en, exp_en, alpha, gain_cod_unq,
826 gain_cod, qua_ener_MR122, qua_ener, common_amr_tbls->qua_gain_code_ptr,
827 pOverflow); /* function result */
828 }
829
830 *(*anap)++ = gain_pit_index;
831 *(*anap)++ = gain_cod_index;
832 }
833