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