1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
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 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: qgain795.cpp
35 Functions: MR795_gain_code_quant3
36 MR795_gain_code_quant_mod
39 ------------------------------------------------------------------------------
43 ------------------------------------------------------------------------------
46 /*----------------------------------------------------------------------------
48 ----------------------------------------------------------------------------*/
61 /*--------------------------------------------------------------------------*/
67 /*----------------------------------------------------------------------------
69 ; Define module specific macros here
70 ----------------------------------------------------------------------------*/
72 /*----------------------------------------------------------------------------
74 ; Include all pre-processor statements here. Include conditional
75 ; compile variables also.
76 ----------------------------------------------------------------------------*/
77 #define NB_QUA_CODE 32
79 /*----------------------------------------------------------------------------
80 ; LOCAL FUNCTION DEFINITIONS
81 ; Function Prototype declaration
82 ----------------------------------------------------------------------------*/
84 /*----------------------------------------------------------------------------
85 ; LOCAL VARIABLE DEFINITIONS
86 ; Variable declaration - defined here and used outside this module
87 ----------------------------------------------------------------------------*/
89 /*----------------------------------------------------------------------------
90 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
91 ; Declare variables used in this module but defined elsewhere
92 ----------------------------------------------------------------------------*/
94 /*--------------------------------------------------------------------------*/
100 ------------------------------------------------------------------------------
101 FUNCTION NAME: MR795_gain_code_quant3
102 ------------------------------------------------------------------------------
103 INPUT AND OUTPUT DEFINITIONS
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()
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)
122 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
123 (for other MA predictor update)
125 pOverflow -- Pointer to Flag -- overflow indicator
130 Global Variables Used:
133 Local Variables Needed:
136 ------------------------------------------------------------------------------
139 PURPOSE: Pre-quantization of codebook gains, given three possible
140 LTP gains (using predicted codebook gain)
141 ------------------------------------------------------------------------------
146 ------------------------------------------------------------------------------
149 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
151 ------------------------------------------------------------------------------
155 ------------------------------------------------------------------------------
157 [State any special notes, constraints or cautions for users of this function]
159 ------------------------------------------------------------------------------
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 */
205 * The error energy (sum) to be minimized consists of five terms, t[0..4].
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>
215 /* determine the scaling exponent for g_code: ec = ec0 - 10 */
216 exp_code = exp_gcode0 - 10;
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);
226 /*-------------------------------------------------------------------*
227 * Find maximum exponent: *
228 * ~~~~~~~~~~~~~~~~~~~~~~ *
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 *
235 * e_max = max(exp_max[i]) + 1; *
236 * e = exp_max[i]-e_max; e <= 0! *
238 *-------------------------------------------------------------------*/
241 for (i = 1; i < 5; i++) /* implemented flattened */
243 if (exp_max[i] > e_max)
249 e_max = add_16(e_max, 1, pOverflow); /* To avoid overflow */
251 for (i = 0; i < 5; i++)
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);
260 /*-------------------------------------------------------------------*
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 *
270 *-------------------------------------------------------------------*/
272 /* start with "infinite" MSE */
277 /* loop through LTP gain candidates */
278 for (j = 0; j < 3; j++)
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);
286 p = &qua_gain_code_ptr[0];
287 for (i = 0; i < NB_QUA_CODE; i++)
289 g_code = *p++; /* this is g_fac Q11 */
290 p++; /* skip log2(g_fac) */
291 p++; /* skip 20*log10(g_fac) */
293 g_code = mult(g_code, gcode0, pOverflow);
295 L_tmp = L_mult(g_code, g_code, pOverflow);
296 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
298 L_tmp = L_mult(g_code, g_pitch, pOverflow);
299 L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow);
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],
305 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4],
306 g_pit_cod_h, g_pit_cod_l, pOverflow);
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)
320 /*------------------------------------------------------------------*
321 * read quantized gains and new values for MA predictor memories *
322 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
323 *------------------------------------------------------------------*/
325 /* Read the quantized gains */
326 p = &qua_gain_code_ptr[(cod_ind<<2) - cod_ind];
329 *qua_ener_MR122 = *p++;
332 /*------------------------------------------------------------------*
333 * calculate final fixed codebook gain: *
334 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
337 *------------------------------------------------------------------*/
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];
349 ------------------------------------------------------------------------------
350 FUNCTION NAME: MR795_gain_code_quant_mod
351 ------------------------------------------------------------------------------
352 INPUT AND OUTPUT DEFINITIONS
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
362 gain_cod_unq -- Word16 -- Code gain (unquantized)
363 (scaling: Q10 - exp_gcode0)
365 gain_cod -- Pointer to Word16 -- Code gain (pre-/quantized), Q1
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
375 index of quantization (Word16)
377 Global Variables Used:
380 Local Variables Needed:
383 ------------------------------------------------------------------------------
386 PURPOSE: Modified quantization of the MR795 codebook gain
388 Uses pre-computed energy coefficients in frac_en[]/exp_en[]
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 ------------------------------------------------------------------------------
399 ------------------------------------------------------------------------------
402 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
404 ------------------------------------------------------------------------------
408 ------------------------------------------------------------------------------
410 [State any special notes, constraints or cautions for users of this function]
412 ------------------------------------------------------------------------------
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),
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 */
460 Steps in calculation of the error criterion (dist):
461 ---------------------------------------------------
463 underlined = constant; alp = FLP value of alpha, alpha = FIP
467 ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
468 ------------ ------ -- -----
471 = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
472 -------------- ------------- ---------
478 d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
479 ------------------- ---
481 d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
484 = alp * (sqrt(ExEn) - sqrt(ResEn))^2
487 = (sqrt(aExEn) - sqrt(alp*ResEn))^2
490 = (sqrt(aExEn) - t[0] )^2
496 * calculate scalings of the constant terms
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 */
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);
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;
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);
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);
526 coeff[4] = mult(one_alpha, frac_en[3], pOverflow);
527 exp_coeff[4] = add_16(exp_coeff[3], 1, pOverflow);
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 */
537 exp_coeff[0] = exp_en[0] - exp;
540 * Determine the maximum exponent occuring in the distance calculation
541 * and adjust all fractions accordingly (including a safety margin)
545 /* find max(e[1..4],e[0]+31) */
546 e_max = exp_coeff[0] + 31;
547 for (i = 1; i <= 4; i++)
549 if (exp_coeff[i] > e_max)
551 e_max = exp_coeff[i];
555 /* scale c[1] (requires no further multiplication) */
556 tmp = e_max - exp_coeff[1];
557 L_t1 = L_shr(L_t1, tmp, pOverflow);
559 /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
560 for (i = 2; i <= 4; i++)
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);
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)
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)*/
580 /* search the quantizer table for the lowest value
581 of the search criterion */
584 p = &qua_gain_code_ptr[0];
586 for (i = 0; i < NB_QUA_CODE; i++)
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);
593 /* only continue if gc[i] < 2.0*gc
594 which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */
596 if (g_code >= gain_code)
601 L_tmp = L_mult(g_code, g_code, pOverflow);
602 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
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);
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);
612 L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow);
613 L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow);
616 tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow);
617 L_tmp = L_mult(tmp, tmp, pOverflow);
620 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow);
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)
631 /*------------------------------------------------------------------*
632 * read quantized gains and new values for MA predictor memories *
633 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
634 *------------------------------------------------------------------*/
636 /* Read the quantized gains */
637 p = &qua_gain_code_ptr[(index<<2) - index];
639 *qua_ener_MR122 = *p++;
642 /*------------------------------------------------------------------*
643 * calculate final fixed codebook gain: *
644 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
647 *------------------------------------------------------------------*/
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);
657 ------------------------------------------------------------------------------
658 FUNCTION NAME: MR795_gain_quant
659 ------------------------------------------------------------------------------
660 INPUT AND OUTPUT DEFINITIONS
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
683 adapt_st -- Pointer to GainAdaptState -- gain adapter state structure
684 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
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)
691 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
692 (for other MA predictor update)
694 anap -- Double Pointer to Word16 -- Index of quantization
695 (first gain pitch, then code pitch)
697 pOverflow -- Pointer to Flag -- overflow indicator
702 Global Variables Used:
705 Local Variables Needed:
708 ------------------------------------------------------------------------------
711 pitch and codebook quantization for MR795
712 ------------------------------------------------------------------------------
717 ------------------------------------------------------------------------------
720 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
722 ------------------------------------------------------------------------------
726 ------------------------------------------------------------------------------
728 [State any special notes, constraints or cautions for users of this function]
730 ------------------------------------------------------------------------------
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 */
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;
770 Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */
773 /* get list of candidate quantized pitch gain values
774 * and corresponding quantization indices
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);
779 /*-------------------------------------------------------------------*
780 * predicted codebook gain *
781 * ~~~~~~~~~~~~~~~~~~~~~~~ *
782 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
784 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
785 *-------------------------------------------------------------------*/
786 gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */
788 /* pre-quantization of codebook gain
789 * (using three pitch gain candidates);
790 * result: best guess of pitch gain and code gain
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);
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);
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
806 gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow);
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
811 if (frac_en[0] != 0 && alpha > 0)
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;
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);
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 */
830 *(*anap)++ = gain_pit_index;
831 *(*anap)++ = gain_cod_index;