annotate libtwamr/qua_gain.c @ 581:e2d5cad04cbf

libgsmhr1 RxFE: store CN R0+LPC separately from speech In the original GSM 06.06 code the ECU for speech mode is entirely separate from the CN generator, maintaining separate state. (The main intertie between them is the speech vs CN state variable, distinguishing between speech and CN BFIs, in addition to the CN-specific function of distinguishing between initial and update SIDs.) In the present RxFE implementation I initially thought that we could use the same saved_frame buffer for both ECU and CN, overwriting just the first 4 params (R0 and LPC) when a valid SID comes in. However, I now realize it was a bad idea: the original code has a corner case (long sequence of speech-mode BFIs to put the ECU in state 6, then SID and CN-mode BFIs, then a good speech frame) that would be broken by that buffer reuse approach. We could eliminate this corner case by resetting the ECU state when passing through a CN insertion period, but doing so would needlessly increase the behavioral diffs between GSM 06.06 and our version. Solution: use a separate CN-specific buffer for CN R0+LPC parameters, and match the behavior of GSM 06.06 code in this regard.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Feb 2025 10:02:45 +0000
parents b02e043dcba0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
377
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 * R99 Version 3.3.0
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 * REL-4 Version 4.1.0
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 * File : qua_gain.c
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 * Purpose : Quantization of pitch and codebook gains.
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 /*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 * MODULE INCLUDE FILE AND VERSION ID
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 #include "namespace.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 #include "qua_gain.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 /*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 * INCLUDE FILES
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 #include "tw_amr.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 #include "typedef.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 #include "basic_op.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 #include "oper_32b.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 #include "no_count.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 #include "cnst.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 #include "pow2.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 #include "gc_pred.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 #include "qua_gain_tab.h"
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 /*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 * PUBLIC PROGRAM CODE
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 ********************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 /*************************************************************************
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 * FUNCTION: Qua_gain()
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 * PURPOSE: Quantization of pitch and codebook gains.
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 * (using predicted codebook gain)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 *************************************************************************/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 Word16
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 Qua_gain( /* o : index of quantization. */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 enum Mode mode, /* i : AMR mode */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 Word16 frac_coeff[], /* i : energy coeff. (5), fraction part, Q15 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 Word16 exp_coeff[], /* i : energy coeff. (5), exponent part, Q0 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 /* (frac_coeff and exp_coeff computed in */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 /* calc_filt_energies()) */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 Word16 gp_limit, /* i : pitch gain limit */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 Word16 *gain_pit, /* o : Pitch gain, Q14 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 Word16 *gain_cod, /* o : Code gain, Q1 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 /* (for MR122 MA predictor update) */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 Word16 *qua_ener /* o : quantized energy error, Q10 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 /* (for other MA predictor update) */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 )
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 const Word16 *p;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 Word16 i, j, index = 0;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 Word16 gcode0, e_max, exp_code;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 Word16 coeff[5], coeff_lo[5];
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 Word16 exp_max[5];
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 Word32 L_tmp, dist_min;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 const Word16 *table_gain;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 Word16 table_len;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 test(); test(); test();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 if ( sub (mode, MR102) == 0 || sub (mode, MR74) == 0 || sub (mode, MR67) == 0)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 table_len = VQ_SIZE_HIGHRATES; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 table_gain = table_gain_highrates; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 else
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 table_len = VQ_SIZE_LOWRATES; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 table_gain = table_gain_lowrates; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 /*-------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 * predicted codebook gain *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 * ~~~~~~~~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 * *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 *-------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 gcode0 = extract_l(Pow2(14, frac_gcode0));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 /*-------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 * Scaling considerations: *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 * ~~~~~~~~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 *-------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 /*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 * The error energy (sum) to be minimized consists of five terms, t[0..4].
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 * t[0] = gp^2 * <y1 y1>
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 * t[1] = -2*gp * <xn y1>
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 * t[2] = gc^2 * <y2 y2>
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 * t[3] = -2*gc * <xn y2>
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 * t[4] = 2*gp*gc * <y1 y2>
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 /* determine the scaling exponent for g_code: ec = ec0 - 11 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 exp_code = sub(exp_gcode0, 11);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
121
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
122 /* calculate exp_max[i] = s[i]-1 */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
123 exp_max[0] = sub(exp_coeff[0], 13); move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
124 exp_max[1] = sub(exp_coeff[1], 14); move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
125 exp_max[2] = add(exp_coeff[2], add(15, shl(exp_code, 1))); move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
126 exp_max[3] = add(exp_coeff[3], exp_code); move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
127 exp_max[4] = add(exp_coeff[4], add(1, exp_code)); move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
128
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
129
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
130 /*-------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
131 * Find maximum exponent: *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
132 * ~~~~~~~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
133 * *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
134 * For the sum operation, all terms must have the same scaling; *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
135 * that scaling should be low enough to prevent overflow. There- *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
136 * fore, the maximum scale is determined and all coefficients are *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
137 * re-scaled: *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
138 * *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
139 * e_max = max(exp_max[i]) + 1; *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
140 * e = exp_max[i]-e_max; e <= 0! *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
141 * c[i] = c[i]*2^e *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
142 *-------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
143
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
144 e_max = exp_max[0]; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
145 for (i = 1; i < 5; i++)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
146 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
147 move16(); test();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
148 if (sub(exp_max[i], e_max) > 0)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
149 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
150 e_max = exp_max[i]; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
151 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
152 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
153
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
154 e_max = add(e_max, 1); /* To avoid overflow */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
155
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
156 for (i = 0; i < 5; i++) {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
157 j = sub(e_max, exp_max[i]);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
158 L_tmp = L_deposit_h(frac_coeff[i]);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
159 L_tmp = L_shr(L_tmp, j);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
160 L_Extract(L_tmp, &coeff[i], &coeff_lo[i]);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
161 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
162
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
163
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
164 /*-------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
165 * Codebook search: *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
166 * ~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
167 * *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
168 * For each pair (g_pitch, g_fac) in the table calculate the *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
169 * terms t[0..4] and sum them up; the result is the mean squared *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
170 * error for the quantized gains from the table. The index for the *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
171 * minimum MSE is stored and finally used to retrieve the quantized *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
172 * gains *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
173 *-------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
174
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
175 /* start with "infinite" MSE */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
176 dist_min = MAX_32; move32();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
177
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
178 p = &table_gain[0]; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
179
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
180 for (i = 0; i < table_len; i++)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
181 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
182 g_pitch = *p++; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
183 g_code = *p++; move16 (); /* this is g_fac */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
184 p++; /* skip log2(g_fac) */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
185 p++; /* skip 20*log10(g_fac) */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
186
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
187 test ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
188 if (sub(g_pitch, gp_limit) <= 0)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
189 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
190 g_code = mult(g_code, gcode0);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
191 g2_pitch = mult(g_pitch, g_pitch);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
192 g2_code = mult(g_code, g_code);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
193 g_pit_cod = mult(g_code, g_pitch);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
194
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
195 L_tmp = Mpy_32_16(coeff[0], coeff_lo[0], g2_pitch);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
196 L_tmp = L_add(L_tmp, Mpy_32_16(coeff[1], coeff_lo[1], g_pitch));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
197 L_tmp = L_add(L_tmp, Mpy_32_16(coeff[2], coeff_lo[2], g2_code));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
198 L_tmp = L_add(L_tmp, Mpy_32_16(coeff[3], coeff_lo[3], g_code));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
199 L_tmp = L_add(L_tmp, Mpy_32_16(coeff[4], coeff_lo[4], g_pit_cod));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
200
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
201 /* store table index if MSE for this index is lower
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
202 than the minimum MSE seen so far */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
203 test ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
204 if (L_sub(L_tmp, dist_min) < (Word32) 0)
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
205 {
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
206 dist_min = L_tmp; move32 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
207 index = i; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
208 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
209 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
210 }
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
211
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
212 /*------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
213 * read quantized gains and new values for MA predictor memories *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
214 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
215 *------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
216
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
217 /* Read the quantized gains */
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
218 p = &table_gain[shl (index, 2)]; move16 ();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
219 *gain_pit = *p++; move16();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
220 g_code = *p++; move16();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
221 *qua_ener_MR122 = *p++; move16();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
222 *qua_ener = *p; move16();
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
223
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
224 /*------------------------------------------------------------------*
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
225 * calculate final fixed codebook gain: *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
226 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
227 * *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
228 * gc = gc0 * g *
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
229 *------------------------------------------------------------------*/
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
230
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
231 L_tmp = L_mult(g_code, gcode0);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
232 L_tmp = L_shr(L_tmp, sub(10, exp_gcode0));
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
233 *gain_cod = extract_h(L_tmp);
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
234
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
235 return index;
b02e043dcba0 libtwamr: integrate qua_gain.c
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
236 }