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 Pathname: ./audio/gsm-amr/c/src/qgain795.c
35 Functions: MR795_gain_code_quant3
36 MR795_gain_code_quant_mod
41 ------------------------------------------------------------------------------
44 Description: Updated template used to PV coding template.
45 Changed to accept the pOverflow flag for EPOC compatibility.
48 (1) Removed optimization -- mult(i, 3, pOverflow) is NOT the same as adding
49 i to itself 3 times. The reason is because the mult function does a
50 right shift by 15, which will obliterate smaller numbers.
52 Description: Replaced OSCL mem type functions and eliminated include
53 files that now are chosen by OSCL definitions
55 Description: Replaced "int" and/or "char" with OSCL defined types.
57 Description: Changed round function name to pv_round to avoid conflict with
58 round function in C standard library.
60 Description: Added #ifdef __cplusplus around extern'ed table.
64 ------------------------------------------------------------------------------
68 ------------------------------------------------------------------------------
71 /*----------------------------------------------------------------------------
73 ----------------------------------------------------------------------------*/
86 /*--------------------------------------------------------------------------*/
92 /*----------------------------------------------------------------------------
94 ; Define module specific macros here
95 ----------------------------------------------------------------------------*/
97 /*----------------------------------------------------------------------------
99 ; Include all pre-processor statements here. Include conditional
100 ; compile variables also.
101 ----------------------------------------------------------------------------*/
102 #define NB_QUA_CODE 32
104 /*----------------------------------------------------------------------------
105 ; LOCAL FUNCTION DEFINITIONS
106 ; Function Prototype declaration
107 ----------------------------------------------------------------------------*/
109 /*----------------------------------------------------------------------------
110 ; LOCAL VARIABLE DEFINITIONS
111 ; Variable declaration - defined here and used outside this module
112 ----------------------------------------------------------------------------*/
114 /*----------------------------------------------------------------------------
115 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
116 ; Declare variables used in this module but defined elsewhere
117 ----------------------------------------------------------------------------*/
118 extern const Word16 qua_gain_code[NB_QUA_CODE*3];
121 /*--------------------------------------------------------------------------*/
127 ------------------------------------------------------------------------------
128 FUNCTION NAME: MR795_gain_code_quant3
129 ------------------------------------------------------------------------------
130 INPUT AND OUTPUT DEFINITIONS
133 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
134 gcode0 -- Word16 -- predicted CB gain (norm.)
135 g_pitch_cand[] -- Word16 array -- Pitch gain candidates (3), Q14
136 g_pitch_cind[] -- Word16 array -- Pitch gain cand. indices (3), Q0
137 frac_coeff[] -- Word16 array -- coefficients (5), Q15
138 exp_coeff[] -- Word16 array -- energy coefficients (5), Q0
139 coefficients from calc_filt_ener()
142 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
143 gain_pit_ind -- Pointer to Word16 -- Pitch gain index, Q0
144 gain_cod -- Pointer to Word16 -- Code gain, Q1
145 gain_cod_ind -- Pointer to Word16 -- Code gain index, Q0
146 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
147 (for MR122 MA predictor update)
149 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
150 (for other MA predictor update)
152 pOverflow -- Pointer to Flag -- overflow indicator
157 Global Variables Used:
160 Local Variables Needed:
163 ------------------------------------------------------------------------------
166 PURPOSE: Pre-quantization of codebook gains, given three possible
167 LTP gains (using predicted codebook gain)
168 ------------------------------------------------------------------------------
173 ------------------------------------------------------------------------------
176 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
178 ------------------------------------------------------------------------------
182 ------------------------------------------------------------------------------
183 RESOURCES USED [optional]
185 When the code is written for a specific target processor the
186 the resources used should be documented below.
188 HEAP MEMORY USED: x bytes
190 STACK MEMORY USED: x bytes
192 CLOCK CYCLES: (cycle count equation for this function) + (variable
193 used to represent cycle count for each subroutine
195 where: (cycle count variable) = cycle count for [subroutine
198 ------------------------------------------------------------------------------
200 [State any special notes, constraints or cautions for users of this function]
202 ------------------------------------------------------------------------------
206 MR795_gain_code_quant3(
207 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
208 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
209 Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */
210 Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */
211 Word16 frac_coeff[], /* i : coefficients (5), Q15 */
212 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
213 /* coefficients from calc_filt_ener()*/
214 Word16 *gain_pit, /* o : Pitch gain, Q14 */
215 Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */
216 Word16 *gain_cod, /* o : Code gain, Q1 */
217 Word16 *gain_cod_ind, /* o : Code gain index, Q0 */
218 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
219 /* (for MR122 MA predictor update) */
220 Word16 *qua_ener, /* o : quantized energy error, Q10 */
221 /* (for other MA predictor update) */
222 Flag *pOverflow /* o : overflow indicator */
247 * The error energy (sum) to be minimized consists of five terms, t[0..4].
249 * t[0] = gp^2 * <y1 y1>
250 * t[1] = -2*gp * <xn y1>
251 * t[2] = gc^2 * <y2 y2>
252 * t[3] = -2*gc * <xn y2>
253 * t[4] = 2*gp*gc * <y1 y2>
257 /* determine the scaling exponent for g_code: ec = ec0 - 10 */
258 exp_code = sub(exp_gcode0, 10, pOverflow);
260 /* calculate exp_max[i] = s[i]-1 */
261 exp_max[0] = sub(exp_coeff[0], 13, pOverflow);
262 exp_max[1] = sub(exp_coeff[1], 14, pOverflow);
263 exp_max[2] = add(exp_coeff[2], add(15, shl(exp_code, 1, pOverflow), pOverflow), pOverflow);
264 exp_max[3] = add(exp_coeff[3], exp_code, pOverflow);
265 exp_max[4] = add(exp_coeff[4], add(exp_code, 1, pOverflow), pOverflow);
268 /*-------------------------------------------------------------------*
269 * Find maximum exponent: *
270 * ~~~~~~~~~~~~~~~~~~~~~~ *
272 * For the sum operation, all terms must have the same scaling; *
273 * that scaling should be low enough to prevent overflow. There- *
274 * fore, the maximum scale is determined and all coefficients are *
277 * e_max = max(exp_max[i]) + 1; *
278 * e = exp_max[i]-e_max; e <= 0! *
280 *-------------------------------------------------------------------*/
283 for (i = 1; i < 5; i++) /* implemented flattened */
285 if (exp_max[i] > e_max)
291 e_max = add(e_max, 1, pOverflow); /* To avoid overflow */
293 for (i = 0; i < 5; i++)
295 j = sub(e_max, exp_max[i], pOverflow);
296 L_tmp = L_deposit_h(frac_coeff[i]);
297 L_tmp = L_shr(L_tmp, j, pOverflow);
298 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
302 /*-------------------------------------------------------------------*
306 * For each of the candiates LTP gains in g_pitch_cand[], the terms *
307 * t[0..4] are calculated from the values in the table (and the *
308 * pitch gain candidate) and summed up; the result is the mean *
309 * squared error for the LPT/CB gain pair. The index for the mini- *
310 * mum MSE is stored and finally used to retrieve the quantized CB *
312 *-------------------------------------------------------------------*/
314 /* start with "infinite" MSE */
319 /* loop through LTP gain candidates */
320 for (j = 0; j < 3; j++)
322 /* pre-calculate terms only dependent on pitch gain */
323 g_pitch = g_pitch_cand[j];
324 g2_pitch = mult(g_pitch, g_pitch, pOverflow);
325 L_tmp0 = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch, pOverflow);
326 L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch, pOverflow);
328 p = &qua_gain_code[0];
329 for (i = 0; i < NB_QUA_CODE; i++)
331 g_code = *p++; /* this is g_fac Q11 */
332 p++; /* skip log2(g_fac) */
333 p++; /* skip 20*log10(g_fac) */
335 g_code = mult(g_code, gcode0, pOverflow);
337 L_tmp = L_mult(g_code, g_code, pOverflow);
338 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
340 L_tmp = L_mult(g_code, g_pitch, pOverflow);
341 L_Extract(L_tmp, &g_pit_cod_h, &g_pit_cod_l, pOverflow);
343 L_tmp = Mac_32(L_tmp0, coeff[2], coeff_lo[2],
344 g2_code_h, g2_code_l, pOverflow);
345 L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3],
347 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4],
348 g_pit_cod_h, g_pit_cod_l, pOverflow);
350 /* store table index if MSE for this index is lower
351 than the minimum MSE seen so far; also store the
352 pitch gain for this (so far) lowest MSE */
353 if (L_tmp < dist_min)
362 /*------------------------------------------------------------------*
363 * read quantized gains and new values for MA predictor memories *
364 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
365 *------------------------------------------------------------------*/
367 /* Read the quantized gains */
369 add(add(cod_ind, cod_ind, pOverflow), cod_ind, pOverflow)];
372 *qua_ener_MR122 = *p++;
375 /*------------------------------------------------------------------*
376 * calculate final fixed codebook gain: *
377 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
380 *------------------------------------------------------------------*/
382 L_tmp = L_mult(g_code, gcode0, pOverflow);
383 L_tmp = L_shr(L_tmp, sub(9, exp_gcode0, pOverflow), pOverflow);
384 *gain_cod = extract_h(L_tmp);
385 *gain_cod_ind = cod_ind;
386 *gain_pit = g_pitch_cand[pit_ind];
387 *gain_pit_ind = g_pitch_cind[pit_ind];
392 ------------------------------------------------------------------------------
393 FUNCTION NAME: MR795_gain_code_quant_mod
394 ------------------------------------------------------------------------------
395 INPUT AND OUTPUT DEFINITIONS
398 gain_pit -- Word16 -- pitch gain, Q14
399 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
400 gcode0 -- Word16 -- predicted CB gain (norm.), Q14
401 frac_en[] -- Word16 array -- energy coefficients (4), fraction part, Q15
402 exp_en[] -- Word16 array -- energy coefficients (4), exponent part, Q0
403 alpha -- Word16 -- gain adaptor factor (>0), Q15
405 gain_cod_unq -- Word16 -- Code gain (unquantized)
406 (scaling: Q10 - exp_gcode0)
408 gain_cod -- Pointer to Word16 -- Code gain (pre-/quantized), Q1
411 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
412 (for MR122 MA predictor update)
413 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
414 (for other MA predictor update)
415 pOverflow -- Pointer to Flag -- overflow indicator
418 index of quantization (Word16)
420 Global Variables Used:
423 Local Variables Needed:
426 ------------------------------------------------------------------------------
429 PURPOSE: Modified quantization of the MR795 codebook gain
431 Uses pre-computed energy coefficients in frac_en[]/exp_en[]
433 frac_en[0]*2^exp_en[0] = <res res> // LP residual energy
434 frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy
435 frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product
436 frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy
437 ------------------------------------------------------------------------------
442 ------------------------------------------------------------------------------
445 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
447 ------------------------------------------------------------------------------
451 ------------------------------------------------------------------------------
452 RESOURCES USED [optional]
454 When the code is written for a specific target processor the
455 the resources used should be documented below.
457 HEAP MEMORY USED: x bytes
459 STACK MEMORY USED: x bytes
461 CLOCK CYCLES: (cycle count equation for this function) + (variable
462 used to represent cycle count for each subroutine
464 where: (cycle count variable) = cycle count for [subroutine
467 ------------------------------------------------------------------------------
469 [State any special notes, constraints or cautions for users of this function]
471 ------------------------------------------------------------------------------
475 MR795_gain_code_quant_mod( /* o : index of quantization. */
476 Word16 gain_pit, /* i : pitch gain, Q14 */
477 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
478 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */
479 Word16 frac_en[], /* i : energy coefficients (4),
480 fraction part, Q15 */
481 Word16 exp_en[], /* i : energy coefficients (4),
483 Word16 alpha, /* i : gain adaptor factor (>0), Q15 */
484 Word16 gain_cod_unq, /* i : Code gain (unquantized) */
485 /* (scaling: Q10 - exp_gcode0) */
486 Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */
487 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
488 /* (for MR122 MA predictor update) */
489 Word16 *qua_ener, /* o : quantized energy error, Q10 */
490 /* (for other MA predictor update) */
491 Flag *pOverflow /* o : overflow indicator */
518 Steps in calculation of the error criterion (dist):
519 ---------------------------------------------------
521 underlined = constant; alp = FLP value of alpha, alpha = FIP
525 ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn;
526 ------------ ------ -- -----
529 = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2
530 -------------- ------------- ---------
536 d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4]
537 ------------------- ---
539 d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn);
542 = alp * (sqrt(ExEn) - sqrt(ResEn))^2
545 = (sqrt(aExEn) - sqrt(alp*ResEn))^2
548 = (sqrt(aExEn) - t[0] )^2
554 * calculate scalings of the constant terms
556 gain_code = shl(*gain_cod, sub(10, exp_gcode0, pOverflow), pOverflow); /* Q1 -> Q11 (-ec0) */
557 g2_pitch = mult(gain_pit, gain_pit, pOverflow); /* Q14 -> Q13 */
558 /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */
559 one_alpha = add(sub(32767, alpha, pOverflow), 1, pOverflow); /* 32768 - alpha */
562 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
563 L_t1 = L_mult(alpha, frac_en[1], pOverflow);
564 L_t1 = L_shl(L_t1, 1, pOverflow);
565 tmp = extract_h(L_t1);
567 /* directly store in 32 bit variable because no further mult. required */
568 L_t1 = L_mult(tmp, g2_pitch, pOverflow);
569 exp_coeff[1] = sub(exp_en[1], 15, pOverflow);
572 tmp = extract_h(L_shl(L_mult(alpha, frac_en[2], pOverflow), 1, pOverflow));
573 coeff[2] = mult(tmp, gain_pit, pOverflow);
574 exp = sub(exp_gcode0, 10, pOverflow);
575 exp_coeff[2] = add(exp_en[2], exp, pOverflow);
578 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
579 coeff[3] = extract_h(L_shl(L_mult(alpha, frac_en[3], pOverflow), 1, pOverflow));
580 exp = sub(shl(exp_gcode0, 1, pOverflow), 7, pOverflow);
581 exp_coeff[3] = add(exp_en[3], exp, pOverflow);
584 coeff[4] = mult(one_alpha, frac_en[3], pOverflow);
585 exp_coeff[4] = add(exp_coeff[3], 1, pOverflow);
588 L_tmp = L_mult(alpha, frac_en[0], pOverflow);
589 /* sqrt_l returns normalized value and 2*exponent
590 -> result = val >> (exp/2)
591 exp_coeff holds 2*exponent for c[0] */
592 /* directly store in 32 bit variable because no further mult. required */
593 L_t0 = sqrt_l_exp(L_tmp, &exp, pOverflow); /* normalization included in sqrt_l_exp */
594 exp = add(exp, 47, pOverflow);
595 exp_coeff[0] = sub(exp_en[0], exp, pOverflow);
598 * Determine the maximum exponent occuring in the distance calculation
599 * and adjust all fractions accordingly (including a safety margin)
603 /* find max(e[1..4],e[0]+31) */
604 e_max = add(exp_coeff[0], 31, pOverflow);
605 for (i = 1; i <= 4; i++)
607 if (exp_coeff[i] > e_max)
609 e_max = exp_coeff[i];
613 /* scale c[1] (requires no further multiplication) */
614 tmp = sub(e_max, exp_coeff[1], pOverflow);
615 L_t1 = L_shr(L_t1, tmp, pOverflow);
617 /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */
618 for (i = 2; i <= 4; i++)
620 tmp = sub(e_max, exp_coeff[i], pOverflow);
621 L_tmp = L_deposit_h(coeff[i]);
622 L_tmp = L_shr(L_tmp, tmp, pOverflow);
623 L_Extract(L_tmp, &coeff[i], &coeff_lo[i], pOverflow);
626 /* scale c[0] (requires no further multiplication) */
627 exp = sub(e_max, 31, pOverflow); /* new exponent */
628 tmp = sub(exp, exp_coeff[0], pOverflow);
629 L_t0 = L_shr(L_t0, shr(tmp, 1, pOverflow), pOverflow);
630 /* perform correction by 1/sqrt(2) if exponent difference is odd */
631 if ((tmp & 0x1) != 0)
633 L_Extract(L_t0, &coeff[0], &coeff_lo[0], pOverflow);
634 L_t0 = Mpy_32_16(coeff[0], coeff_lo[0],
635 23170, pOverflow); /* 23170 Q15 = 1/sqrt(2)*/
638 /* search the quantizer table for the lowest value
639 of the search criterion */
642 p = &qua_gain_code[0];
644 for (i = 0; i < NB_QUA_CODE; i++)
646 g_code = *p++; /* this is g_fac (Q11) */
647 p++; /* skip log2(g_fac) */
648 p++; /* skip 20*log10(g_fac) */
649 g_code = mult(g_code, gcode0, pOverflow);
651 /* only continue if gc[i] < 2.0*gc
652 which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */
654 if (g_code >= gain_code)
659 L_tmp = L_mult(g_code, g_code, pOverflow);
660 L_Extract(L_tmp, &g2_code_h, &g2_code_l, pOverflow);
662 tmp = sub(g_code, gain_cod_unq, pOverflow);
663 L_tmp = L_mult(tmp, tmp, pOverflow);
664 L_Extract(L_tmp, &d2_code_h, &d2_code_l, pOverflow);
667 L_tmp = Mac_32_16(L_t1, coeff[2], coeff_lo[2], g_code, pOverflow);
668 L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l, pOverflow);
670 L_tmp = sqrt_l_exp(L_tmp, &exp, pOverflow);
671 L_tmp = L_shr(L_tmp, shr(exp, 1, pOverflow), pOverflow);
674 tmp = pv_round(L_sub(L_tmp, L_t0, pOverflow), pOverflow);
675 L_tmp = L_mult(tmp, tmp, pOverflow);
678 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l, pOverflow);
680 /* store table index if distance measure for this
681 index is lower than the minimum seen so far */
682 if (L_tmp < dist_min)
689 /*------------------------------------------------------------------*
690 * read quantized gains and new values for MA predictor memories *
691 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
692 *------------------------------------------------------------------*/
694 /* Read the quantized gains */
695 p = &qua_gain_code[add(add(index, index, pOverflow), index, pOverflow)];
697 *qua_ener_MR122 = *p++;
700 /*------------------------------------------------------------------*
701 * calculate final fixed codebook gain: *
702 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
705 *------------------------------------------------------------------*/
707 L_tmp = L_mult(g_code, gcode0, pOverflow);
708 L_tmp = L_shr(L_tmp, sub(9, exp_gcode0, pOverflow), pOverflow);
709 *gain_cod = extract_h(L_tmp);
715 ------------------------------------------------------------------------------
716 FUNCTION NAME: MR795_gain_quant
717 ------------------------------------------------------------------------------
718 INPUT AND OUTPUT DEFINITIONS
723 adapt_st -- Pointer to GainAdaptState -- gain adapter state structure
724 res -- Word16 array -- LP residual, Q0
725 exc -- Word16 array -- LTP excitation (unfiltered), Q0
726 code -- Word16 array -- CB innovation (unfiltered), Q13
727 frac_coeff -- Word16 array -- coefficients (5), Q15
728 exp_coeff -- Word16 array -- energy coefficients (5), Q0
729 coefficients from calc_filt_ener()
730 exp_code_en -- Word16 -- innovation energy (exponent), Q0
731 frac_code_en -- Word16 -- innovation energy (fraction), Q15
732 exp_gcode0 -- Word16 -- predicted CB gain (exponent), Q0
733 frac_gcode0 -- Word16 -- predicted CB gain (fraction), Q15
734 L_subfr -- Word16 -- Subframe length
735 cod_gain_frac -- Word16 -- opt. codebook gain (fraction),Q15
736 cod_gain_exp -- Word16 -- opt. codebook gain (exponent), Q0
737 gp_limit -- Word16 -- pitch gain limit
738 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
741 adapt_st -- Pointer to GainAdaptState -- gain adapter state structure
742 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
744 gain_pit -- Pointer to Word16 -- Pitch gain, Q14
745 gain_cod -- Pointer to Word16 -- Code gain, Q1
746 qua_ener_MR122 -- Pointer to Word16 -- quantized energy error, Q10
747 (for MR122 MA predictor update)
749 qua_ener -- Pointer to Word16 -- quantized energy error, Q10
750 (for other MA predictor update)
752 anap -- Double Pointer to Word16 -- Index of quantization
753 (first gain pitch, then code pitch)
755 pOverflow -- Pointer to Flag -- overflow indicator
760 Global Variables Used:
763 Local Variables Needed:
766 ------------------------------------------------------------------------------
769 pitch and codebook quantization for MR795
770 ------------------------------------------------------------------------------
775 ------------------------------------------------------------------------------
778 qgain795.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
780 ------------------------------------------------------------------------------
784 ------------------------------------------------------------------------------
785 RESOURCES USED [optional]
787 When the code is written for a specific target processor the
788 the resources used should be documented below.
790 HEAP MEMORY USED: x bytes
792 STACK MEMORY USED: x bytes
794 CLOCK CYCLES: (cycle count equation for this function) + (variable
795 used to represent cycle count for each subroutine
797 where: (cycle count variable) = cycle count for [subroutine
800 ------------------------------------------------------------------------------
802 [State any special notes, constraints or cautions for users of this function]
804 ------------------------------------------------------------------------------
809 GainAdaptState *adapt_st, /* i/o: gain adapter state structure */
810 Word16 res[], /* i : LP residual, Q0 */
811 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */
812 Word16 code[], /* i : CB innovation (unfiltered), Q13 */
813 Word16 frac_coeff[], /* i : coefficients (5), Q15 */
814 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */
815 /* coefficients from calc_filt_ener() */
816 Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */
817 Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */
818 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
819 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
820 Word16 L_subfr, /* i : Subframe length */
821 Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */
822 Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */
823 Word16 gp_limit, /* i : pitch gain limit */
824 Word16 *gain_pit, /* i/o: Pitch gain, Q14 */
825 Word16 *gain_cod, /* o : Code gain, Q1 */
826 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
827 /* (for MR122 MA predictor update) */
828 Word16 *qua_ener, /* o : quantized energy error, Q10 */
829 /* (for other MA predictor update) */
830 Word16 **anap, /* o : Index of quantization */
831 /* (first gain pitch, then code pitch)*/
832 Flag *pOverflow /* o : overflow indicator */
837 Word16 ltpg, alpha, gcode0;
838 Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */
839 Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */
840 Word16 gain_pit_index;
841 Word16 gain_cod_index;
843 Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */
846 /* get list of candidate quantized pitch gain values
847 * and corresponding quantization indices
849 gain_pit_index = q_gain_pitch(MR795, gp_limit, gain_pit,
850 g_pitch_cand, g_pitch_cind, pOverflow);
852 /*-------------------------------------------------------------------*
853 * predicted codebook gain *
854 * ~~~~~~~~~~~~~~~~~~~~~~~ *
855 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
857 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
858 *-------------------------------------------------------------------*/
859 gcode0 = (Word16)(Pow2(14, frac_gcode0, pOverflow)); /* Q14 */
861 /* pre-quantization of codebook gain
862 * (using three pitch gain candidates);
863 * result: best guess of pitch gain and code gain
865 MR795_gain_code_quant3(
866 exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind,
867 frac_coeff, exp_coeff,
868 gain_pit, &gain_pit_index, gain_cod, &gain_cod_index,
869 qua_ener_MR122, qua_ener, pOverflow);
871 /* calculation of energy coefficients and LTP coding gain */
872 calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr,
873 frac_en, exp_en, <pg, pOverflow);
875 /* run gain adaptor, calculate alpha factor to balance LTP/CB gain
876 * (this includes the gain adaptor update)
877 * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case
879 gain_adapt(adapt_st, ltpg, *gain_cod, &alpha, pOverflow);
881 /* if this is a very low energy signal (threshold: see
882 * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer
884 if (frac_en[0] != 0 && alpha > 0)
886 /* innovation energy <cod cod> was already computed in gc_pred() */
887 /* (this overwrites the LtpResEn which is no longer needed) */
888 frac_en[3] = frac_code_en;
889 exp_en[3] = exp_code_en;
891 /* store optimum codebook gain in Q(10-exp_gcode0) */
892 exp = add(sub(cod_gain_exp, exp_gcode0, pOverflow), 10, pOverflow);
893 gain_cod_unq = shl(cod_gain_frac, exp, pOverflow);
895 /* run quantization with modified criterion */
896 gain_cod_index = MR795_gain_code_quant_mod(
897 *gain_pit, exp_gcode0, gcode0,
898 frac_en, exp_en, alpha, gain_cod_unq,
899 gain_cod, qua_ener_MR122, qua_ener, pOverflow); /* function result */
902 *(*anap)++ = gain_pit_index;
903 *(*anap)++ = gain_cod_index;