FreeCalypso > hg > gsm-codec-lib
comparison libtwamr/qgain795.c @ 376:2aa98051d445
libtwamr: integrate qgain795.c
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 06 May 2024 04:20:11 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
375:1d2b39027b70 | 376:2aa98051d445 |
---|---|
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 : qgain795.c | |
11 * Purpose : pitch and codebook gain quantization for MR795 | |
12 * | |
13 ******************************************************************************** | |
14 */ | |
15 | |
16 /* | |
17 ******************************************************************************** | |
18 * MODULE INCLUDE FILE AND VERSION ID | |
19 ******************************************************************************** | |
20 */ | |
21 #include "namespace.h" | |
22 #include "qgain795.h" | |
23 | |
24 /* | |
25 ******************************************************************************** | |
26 * INCLUDE FILES | |
27 ******************************************************************************** | |
28 */ | |
29 #include "typedef.h" | |
30 #include "basic_op.h" | |
31 #include "oper_32b.h" | |
32 #include "no_count.h" | |
33 #include "cnst.h" | |
34 #include "log2.h" | |
35 #include "pow2.h" | |
36 #include "sqrt_l.h" | |
37 #include "g_adapt.h" | |
38 #include "calc_en.h" | |
39 #include "q_gain_p.h" | |
40 #include "mac_32.h" | |
41 #include "gains_tab.h" | |
42 | |
43 /* | |
44 ******************************************************************************** | |
45 * LOCAL PROGRAM CODE | |
46 ******************************************************************************** | |
47 */ | |
48 | |
49 /************************************************************************* | |
50 * | |
51 * FUNCTION: MR795_gain_code_quant3 | |
52 * | |
53 * PURPOSE: Pre-quantization of codebook gains, given three possible | |
54 * LTP gains (using predicted codebook gain) | |
55 * | |
56 *************************************************************************/ | |
57 static void | |
58 MR795_gain_code_quant3( | |
59 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ | |
60 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ | |
61 Word16 g_pitch_cand[], /* i : Pitch gain candidates (3), Q14 */ | |
62 Word16 g_pitch_cind[], /* i : Pitch gain cand. indices (3), Q0 */ | |
63 Word16 frac_coeff[], /* i : coefficients (5), Q15 */ | |
64 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ | |
65 /* coefficients from calc_filt_ener()*/ | |
66 Word16 *gain_pit, /* o : Pitch gain, Q14 */ | |
67 Word16 *gain_pit_ind, /* o : Pitch gain index, Q0 */ | |
68 Word16 *gain_cod, /* o : Code gain, Q1 */ | |
69 Word16 *gain_cod_ind, /* o : Code gain index, Q0 */ | |
70 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ | |
71 /* (for MR122 MA predictor update) */ | |
72 Word16 *qua_ener /* o : quantized energy error, Q10 */ | |
73 /* (for other MA predictor update) */ | |
74 ) | |
75 { | |
76 const Word16 *p; | |
77 Word16 i, j, cod_ind, pit_ind; | |
78 Word16 e_max, exp_code; | |
79 Word16 g_pitch, g2_pitch, g_code, g2_code_h, g2_code_l; | |
80 Word16 g_pit_cod_h, g_pit_cod_l; | |
81 Word16 coeff[5], coeff_lo[5]; | |
82 Word16 exp_max[5]; | |
83 Word32 L_tmp, L_tmp0, dist_min; | |
84 | |
85 /* | |
86 * The error energy (sum) to be minimized consists of five terms, t[0..4]. | |
87 * | |
88 * t[0] = gp^2 * <y1 y1> | |
89 * t[1] = -2*gp * <xn y1> | |
90 * t[2] = gc^2 * <y2 y2> | |
91 * t[3] = -2*gc * <xn y2> | |
92 * t[4] = 2*gp*gc * <y1 y2> | |
93 * | |
94 */ | |
95 | |
96 /* determine the scaling exponent for g_code: ec = ec0 - 10 */ | |
97 exp_code = sub(exp_gcode0, 10); | |
98 | |
99 /* calculate exp_max[i] = s[i]-1 */ | |
100 exp_max[0] = sub(exp_coeff[0], 13); move16 (); | |
101 exp_max[1] = sub(exp_coeff[1], 14); move16 (); | |
102 exp_max[2] = add(exp_coeff[2], add(15, shl(exp_code, 1))); move16 (); | |
103 exp_max[3] = add(exp_coeff[3], exp_code); move16 (); | |
104 exp_max[4] = add(exp_coeff[4], add(exp_code,1)); move16 (); | |
105 | |
106 | |
107 /*-------------------------------------------------------------------* | |
108 * Find maximum exponent: * | |
109 * ~~~~~~~~~~~~~~~~~~~~~~ * | |
110 * * | |
111 * For the sum operation, all terms must have the same scaling; * | |
112 * that scaling should be low enough to prevent overflow. There- * | |
113 * fore, the maximum scale is determined and all coefficients are * | |
114 * re-scaled: * | |
115 * * | |
116 * e_max = max(exp_max[i]) + 1; * | |
117 * e = exp_max[i]-e_max; e <= 0! * | |
118 * c[i] = c[i]*2^e * | |
119 *-------------------------------------------------------------------*/ | |
120 | |
121 e_max = exp_max[0]; move16 (); | |
122 for (i = 1; i < 5; i++) /* implemented flattened */ | |
123 { | |
124 move16(); test(); | |
125 if (sub(exp_max[i], e_max) > 0) | |
126 { | |
127 e_max = exp_max[i]; move16 (); | |
128 } | |
129 } | |
130 | |
131 e_max = add(e_max, 1); /* To avoid overflow */ | |
132 | |
133 for (i = 0; i < 5; i++) { | |
134 j = sub(e_max, exp_max[i]); | |
135 L_tmp = L_deposit_h(frac_coeff[i]); | |
136 L_tmp = L_shr(L_tmp, j); | |
137 L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); | |
138 } | |
139 | |
140 | |
141 /*-------------------------------------------------------------------* | |
142 * Codebook search: * | |
143 * ~~~~~~~~~~~~~~~~ * | |
144 * * | |
145 * For each of the candiates LTP gains in g_pitch_cand[], the terms * | |
146 * t[0..4] are calculated from the values in the table (and the * | |
147 * pitch gain candidate) and summed up; the result is the mean * | |
148 * squared error for the LPT/CB gain pair. The index for the mini- * | |
149 * mum MSE is stored and finally used to retrieve the quantized CB * | |
150 * gain * | |
151 *-------------------------------------------------------------------*/ | |
152 | |
153 /* start with "infinite" MSE */ | |
154 dist_min = MAX_32; move16 (); | |
155 cod_ind = 0; move16 (); | |
156 pit_ind = 0; move16 (); | |
157 | |
158 /* loop through LTP gain candidates */ | |
159 for (j = 0; j < 3; j++) | |
160 { | |
161 /* pre-calculate terms only dependent on pitch gain */ | |
162 g_pitch = g_pitch_cand[j]; move16 (); | |
163 g2_pitch = mult(g_pitch, g_pitch); | |
164 L_tmp0 = Mpy_32_16( coeff[0], coeff_lo[0], g2_pitch); | |
165 L_tmp0 = Mac_32_16(L_tmp0, coeff[1], coeff_lo[1], g_pitch); | |
166 | |
167 p = &qua_gain_code[0]; | |
168 for (i = 0; i < NB_QUA_CODE; i++) | |
169 { | |
170 g_code = *p++; move16 (); /* this is g_fac Q11 */ | |
171 p++; /* skip log2(g_fac) */ | |
172 p++; /* skip 20*log10(g_fac) */ | |
173 | |
174 g_code = mult(g_code, gcode0); | |
175 | |
176 L_tmp = L_mult (g_code, g_code); | |
177 L_Extract (L_tmp, &g2_code_h, &g2_code_l); | |
178 | |
179 L_tmp = L_mult(g_code, g_pitch); | |
180 L_Extract (L_tmp, &g_pit_cod_h, &g_pit_cod_l); | |
181 | |
182 L_tmp = Mac_32 (L_tmp0, coeff[2], coeff_lo[2], | |
183 g2_code_h, g2_code_l); | |
184 L_tmp = Mac_32_16(L_tmp, coeff[3], coeff_lo[3], | |
185 g_code); | |
186 L_tmp = Mac_32 (L_tmp, coeff[4], coeff_lo[4], | |
187 g_pit_cod_h, g_pit_cod_l); | |
188 | |
189 /* store table index if MSE for this index is lower | |
190 than the minimum MSE seen so far; also store the | |
191 pitch gain for this (so far) lowest MSE */ | |
192 test (); | |
193 if (L_sub(L_tmp, dist_min) < (Word32) 0) | |
194 { | |
195 dist_min = L_tmp; move32 (); | |
196 cod_ind = i; move16 (); | |
197 pit_ind = j; move16 (); | |
198 } | |
199 } | |
200 } | |
201 | |
202 /*------------------------------------------------------------------* | |
203 * read quantized gains and new values for MA predictor memories * | |
204 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
205 *------------------------------------------------------------------*/ | |
206 | |
207 /* Read the quantized gains */ | |
208 p = &qua_gain_code[add (add (cod_ind, cod_ind), cod_ind)]; move16 (); | |
209 g_code = *p++; move16(); | |
210 *qua_ener_MR122 = *p++; move16(); | |
211 *qua_ener = *p; move16(); | |
212 | |
213 /*------------------------------------------------------------------* | |
214 * calculate final fixed codebook gain: * | |
215 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
216 * * | |
217 * gc = gc0 * g * | |
218 *------------------------------------------------------------------*/ | |
219 | |
220 L_tmp = L_mult(g_code, gcode0); | |
221 L_tmp = L_shr(L_tmp, sub(9, exp_gcode0)); | |
222 *gain_cod = extract_h(L_tmp); | |
223 *gain_cod_ind = cod_ind; move16 (); | |
224 *gain_pit = g_pitch_cand[pit_ind]; move16 (); | |
225 *gain_pit_ind = g_pitch_cind[pit_ind]; move16 (); | |
226 } | |
227 | |
228 | |
229 /************************************************************************* | |
230 * | |
231 * FUNCTION: MR795_gain_code_quant_mod | |
232 * | |
233 * PURPOSE: Modified quantization of the MR795 codebook gain | |
234 * | |
235 * Uses pre-computed energy coefficients in frac_en[]/exp_en[] | |
236 * | |
237 * frac_en[0]*2^exp_en[0] = <res res> // LP residual energy | |
238 * frac_en[1]*2^exp_en[1] = <exc exc> // LTP residual energy | |
239 * frac_en[2]*2^exp_en[2] = <exc code> // LTP/CB innovation dot product | |
240 * frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy | |
241 * | |
242 *************************************************************************/ | |
243 static Word16 | |
244 MR795_gain_code_quant_mod( /* o : index of quantization. */ | |
245 Word16 gain_pit, /* i : pitch gain, Q14 */ | |
246 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ | |
247 Word16 gcode0, /* i : predicted CB gain (norm.), Q14 */ | |
248 Word16 frac_en[], /* i : energy coefficients (4), | |
249 fraction part, Q15 */ | |
250 Word16 exp_en[], /* i : energy coefficients (4), | |
251 eponent part, Q0 */ | |
252 Word16 alpha, /* i : gain adaptor factor (>0), Q15 */ | |
253 Word16 gain_cod_unq, /* i : Code gain (unquantized) */ | |
254 /* (scaling: Q10 - exp_gcode0) */ | |
255 Word16 *gain_cod, /* i/o: Code gain (pre-/quantized), Q1 */ | |
256 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ | |
257 /* (for MR122 MA predictor update) */ | |
258 Word16 *qua_ener /* o : quantized energy error, Q10 */ | |
259 /* (for other MA predictor update) */ | |
260 ) | |
261 { | |
262 const Word16 *p; | |
263 Word16 i, index, tmp; | |
264 Word16 one_alpha; | |
265 Word16 exp, e_max; | |
266 Word16 g2_pitch, g_code; | |
267 Word16 g2_code_h, g2_code_l; | |
268 Word16 d2_code_h, d2_code_l; | |
269 Word16 coeff[5], coeff_lo[5], exp_coeff[5]; | |
270 Word32 L_tmp, L_t0, L_t1, dist_min; | |
271 Word16 gain_code; | |
272 | |
273 /* | |
274 Steps in calculation of the error criterion (dist): | |
275 --------------------------------------------------- | |
276 | |
277 underlined = constant; alp = FLP value of alpha, alpha = FIP | |
278 ---------- | |
279 | |
280 | |
281 ExEn = gp^2 * LtpEn + 2.0*gp*gc[i] * XC + gc[i]^2 * InnEn; | |
282 ------------ ------ -- ----- | |
283 | |
284 aExEn= alp * ExEn | |
285 = alp*gp^2*LtpEn + 2.0*alp*gp*XC* gc[i] + alp*InnEn* gc[i]^2 | |
286 -------------- ------------- --------- | |
287 | |
288 = t[1] + t[2] + t[3] | |
289 | |
290 dist = d1 + d2; | |
291 | |
292 d1 = (1.0 - alp) * InnEn * (gcu - gc[i])^2 = t[4] | |
293 ------------------- --- | |
294 | |
295 d2 = alp * (ResEn - 2.0 * sqrt(ResEn*ExEn) + ExEn); | |
296 --- ----- --- ----- | |
297 | |
298 = alp * (sqrt(ExEn) - sqrt(ResEn))^2 | |
299 --- ----------- | |
300 | |
301 = (sqrt(aExEn) - sqrt(alp*ResEn))^2 | |
302 --------------- | |
303 | |
304 = (sqrt(aExEn) - t[0] )^2 | |
305 ---- | |
306 | |
307 */ | |
308 | |
309 /* | |
310 * calculate scalings of the constant terms | |
311 */ | |
312 gain_code = shl (*gain_cod, sub (10, exp_gcode0)); /* Q1 -> Q11 (-ec0) */ | |
313 g2_pitch = mult (gain_pit, gain_pit); /* Q14 -> Q13 */ | |
314 /* 0 < alpha <= 0.5 => 0.5 <= 1-alpha < 1, i.e one_alpha is normalized */ | |
315 one_alpha = add (sub (32767, alpha), 1); /* 32768 - alpha */ | |
316 | |
317 | |
318 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ | |
319 tmp = extract_h (L_shl (L_mult (alpha, frac_en[1]), 1)); | |
320 /* directly store in 32 bit variable because no further mult. required */ | |
321 L_t1 = L_mult (tmp, g2_pitch); move16 (); | |
322 exp_coeff[1] = sub (exp_en[1], 15); move16 (); | |
323 | |
324 | |
325 tmp = extract_h (L_shl (L_mult (alpha, frac_en[2]), 1)); | |
326 coeff[2] = mult (tmp, gain_pit); move16 (); | |
327 exp = sub (exp_gcode0, 10); | |
328 exp_coeff[2] = add (exp_en[2], exp); move16 (); | |
329 | |
330 | |
331 /* alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */ | |
332 coeff[3] = extract_h (L_shl (L_mult (alpha, frac_en[3]), 1)); | |
333 exp = sub (shl (exp_gcode0, 1), 7); | |
334 exp_coeff[3] = add (exp_en[3], exp); move16 (); | |
335 | |
336 | |
337 coeff[4] = mult (one_alpha, frac_en[3]); move16 (); | |
338 exp_coeff[4] = add (exp_coeff[3], 1); move16 (); | |
339 | |
340 | |
341 L_tmp = L_mult (alpha, frac_en[0]); | |
342 /* sqrt_l returns normalized value and 2*exponent | |
343 -> result = val >> (exp/2) | |
344 exp_coeff holds 2*exponent for c[0] */ | |
345 /* directly store in 32 bit variable because no further mult. required */ | |
346 L_t0 = sqrt_l_exp (L_tmp, &exp); /* normalization included in sqrt_l_exp */ | |
347 move32 (); /* function result */ | |
348 exp = add (exp, 47); | |
349 exp_coeff[0] = sub (exp_en[0], exp); move16 (); | |
350 | |
351 /* | |
352 * Determine the maximum exponent occuring in the distance calculation | |
353 * and adjust all fractions accordingly (including a safety margin) | |
354 * | |
355 */ | |
356 | |
357 /* find max(e[1..4],e[0]+31) */ | |
358 e_max = add (exp_coeff[0], 31); | |
359 for (i = 1; i <= 4; i++) | |
360 { | |
361 test (); | |
362 if (sub (exp_coeff[i], e_max) > 0) | |
363 { | |
364 e_max = exp_coeff[i]; move16 (); | |
365 } | |
366 } | |
367 | |
368 /* scale c[1] (requires no further multiplication) */ | |
369 tmp = sub (e_max, exp_coeff[1]); | |
370 L_t1 = L_shr(L_t1, tmp); | |
371 | |
372 /* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */ | |
373 for (i = 2; i <= 4; i++) | |
374 { | |
375 tmp = sub (e_max, exp_coeff[i]); | |
376 L_tmp = L_deposit_h(coeff[i]); | |
377 L_tmp = L_shr(L_tmp, tmp); | |
378 L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); | |
379 } | |
380 | |
381 /* scale c[0] (requires no further multiplication) */ | |
382 exp = sub (e_max, 31); /* new exponent */ | |
383 tmp = sub (exp, exp_coeff[0]); | |
384 L_t0 = L_shr (L_t0, shr (tmp, 1)); | |
385 /* perform correction by 1/sqrt(2) if exponent difference is odd */ | |
386 test (); logic16 (); | |
387 if ((tmp & 0x1) != 0) | |
388 { | |
389 L_Extract(L_t0, &coeff[0], &coeff_lo[0]); | |
390 L_t0 = Mpy_32_16(coeff[0], coeff_lo[0], | |
391 23170); /* 23170 Q15 = 1/sqrt(2)*/ | |
392 } | |
393 | |
394 /* search the quantizer table for the lowest value | |
395 of the search criterion */ | |
396 dist_min = MAX_32; move32 (); | |
397 index = 0; move16 (); | |
398 p = &qua_gain_code[0]; move16 (); | |
399 | |
400 for (i = 0; i < NB_QUA_CODE; i++) | |
401 { | |
402 g_code = *p++; move16 (); /* this is g_fac (Q11) */ | |
403 p++; /* skip log2(g_fac) */ | |
404 p++; /* skip 20*log10(g_fac) */ | |
405 g_code = mult (g_code, gcode0); | |
406 | |
407 /* only continue if gc[i] < 2.0*gc | |
408 which is equiv. to g_code (Q10-ec0) < gain_code (Q11-ec0) */ | |
409 test (); | |
410 if (sub (g_code, gain_code) >= 0) | |
411 break; | |
412 | |
413 L_tmp = L_mult (g_code, g_code); | |
414 L_Extract (L_tmp, &g2_code_h, &g2_code_l); | |
415 | |
416 tmp = sub (g_code, gain_cod_unq); | |
417 L_tmp = L_mult (tmp, tmp); | |
418 L_Extract (L_tmp, &d2_code_h, &d2_code_l); | |
419 | |
420 /* t2, t3, t4 */ | |
421 L_tmp = Mac_32_16 (L_t1, coeff[2], coeff_lo[2], g_code); | |
422 L_tmp = Mac_32(L_tmp, coeff[3], coeff_lo[3], g2_code_h, g2_code_l); | |
423 | |
424 L_tmp = sqrt_l_exp (L_tmp, &exp); | |
425 L_tmp = L_shr (L_tmp, shr (exp, 1)); | |
426 | |
427 /* d2 */ | |
428 tmp = round (L_sub (L_tmp, L_t0)); | |
429 L_tmp = L_mult (tmp, tmp); | |
430 | |
431 /* dist */ | |
432 L_tmp = Mac_32(L_tmp, coeff[4], coeff_lo[4], d2_code_h, d2_code_l); | |
433 | |
434 /* store table index if distance measure for this | |
435 index is lower than the minimum seen so far */ | |
436 test (); | |
437 if (L_sub (L_tmp, dist_min) < (Word32) 0) | |
438 { | |
439 dist_min = L_tmp; move16 (); | |
440 index = i; move16 (); | |
441 } | |
442 } | |
443 | |
444 /*------------------------------------------------------------------* | |
445 * read quantized gains and new values for MA predictor memories * | |
446 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
447 *------------------------------------------------------------------*/ | |
448 | |
449 /* Read the quantized gains */ | |
450 p = &qua_gain_code[add (add (index, index), index)]; move16 (); | |
451 g_code = *p++; move16(); | |
452 *qua_ener_MR122 = *p++; move16(); | |
453 *qua_ener = *p; move16(); | |
454 | |
455 /*------------------------------------------------------------------* | |
456 * calculate final fixed codebook gain: * | |
457 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * | |
458 * * | |
459 * gc = gc0 * g * | |
460 *------------------------------------------------------------------*/ | |
461 | |
462 L_tmp = L_mult(g_code, gcode0); | |
463 L_tmp = L_shr(L_tmp, sub(9, exp_gcode0)); | |
464 *gain_cod = extract_h(L_tmp); | |
465 | |
466 return index; | |
467 } | |
468 | |
469 /* | |
470 ******************************************************************************** | |
471 * PUBLIC PROGRAM CODE | |
472 ******************************************************************************** | |
473 */ | |
474 | |
475 /************************************************************************* | |
476 * | |
477 * FUNCTION: MR795_gain_quant | |
478 * | |
479 * PURPOSE: pitch and codebook quantization for MR795 | |
480 * | |
481 *************************************************************************/ | |
482 void | |
483 MR795_gain_quant( | |
484 GainAdaptState *adapt_st, /* i/o: gain adapter state structure */ | |
485 Word16 res[], /* i : LP residual, Q0 */ | |
486 Word16 exc[], /* i : LTP excitation (unfiltered), Q0 */ | |
487 Word16 code[], /* i : CB innovation (unfiltered), Q13 */ | |
488 Word16 frac_coeff[], /* i : coefficients (5), Q15 */ | |
489 Word16 exp_coeff[], /* i : energy coefficients (5), Q0 */ | |
490 /* coefficients from calc_filt_ener() */ | |
491 Word16 exp_code_en, /* i : innovation energy (exponent), Q0 */ | |
492 Word16 frac_code_en, /* i : innovation energy (fraction), Q15 */ | |
493 Word16 exp_gcode0, /* i : predicted CB gain (exponent), Q0 */ | |
494 Word16 frac_gcode0, /* i : predicted CB gain (fraction), Q15 */ | |
495 Word16 L_subfr, /* i : Subframe length */ | |
496 Word16 cod_gain_frac, /* i : opt. codebook gain (fraction),Q15 */ | |
497 Word16 cod_gain_exp, /* i : opt. codebook gain (exponent), Q0 */ | |
498 Word16 gp_limit, /* i : pitch gain limit */ | |
499 Word16 *gain_pit, /* i/o: Pitch gain, Q14 */ | |
500 Word16 *gain_cod, /* o : Code gain, Q1 */ | |
501 Word16 *qua_ener_MR122, /* o : quantized energy error, Q10 */ | |
502 /* (for MR122 MA predictor update) */ | |
503 Word16 *qua_ener, /* o : quantized energy error, Q10 */ | |
504 /* (for other MA predictor update) */ | |
505 Word16 **anap /* o : Index of quantization */ | |
506 /* (first gain pitch, then code pitch)*/ | |
507 ) | |
508 { | |
509 Word16 frac_en[4]; | |
510 Word16 exp_en[4]; | |
511 Word16 ltpg, alpha, gcode0; | |
512 Word16 g_pitch_cand[3]; /* pitch gain candidates Q14 */ | |
513 Word16 g_pitch_cind[3]; /* pitch gain indices Q0 */ | |
514 Word16 gain_pit_index; | |
515 Word16 gain_cod_index; | |
516 Word16 exp; | |
517 Word16 gain_cod_unq; /* code gain (unq.) Q(10-exp_gcode0) */ | |
518 | |
519 | |
520 /* get list of candidate quantized pitch gain values | |
521 * and corresponding quantization indices | |
522 */ | |
523 gain_pit_index = q_gain_pitch (MR795, gp_limit, gain_pit, | |
524 g_pitch_cand, g_pitch_cind); | |
525 move16 (); /* function result */ | |
526 | |
527 /*-------------------------------------------------------------------* | |
528 * predicted codebook gain * | |
529 * ~~~~~~~~~~~~~~~~~~~~~~~ * | |
530 * gc0 = 2^exp_gcode0 + 2^frac_gcode0 * | |
531 * * | |
532 * gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0) * | |
533 *-------------------------------------------------------------------*/ | |
534 gcode0 = extract_l(Pow2(14, frac_gcode0)); /* Q14 */ | |
535 | |
536 /* pre-quantization of codebook gain | |
537 * (using three pitch gain candidates); | |
538 * result: best guess of pitch gain and code gain | |
539 */ | |
540 MR795_gain_code_quant3( | |
541 exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind, | |
542 frac_coeff, exp_coeff, | |
543 gain_pit, &gain_pit_index, gain_cod, &gain_cod_index, | |
544 qua_ener_MR122, qua_ener); | |
545 | |
546 /* calculation of energy coefficients and LTP coding gain */ | |
547 calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr, | |
548 frac_en, exp_en, <pg); | |
549 | |
550 /* run gain adaptor, calculate alpha factor to balance LTP/CB gain | |
551 * (this includes the gain adaptor update) | |
552 * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case | |
553 */ | |
554 gain_adapt(adapt_st, ltpg, *gain_cod, &alpha); | |
555 | |
556 /* if this is a very low energy signal (threshold: see | |
557 * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer | |
558 */ | |
559 test (); move16 (); test (); | |
560 if (frac_en[0] != 0 && alpha > 0) | |
561 { | |
562 /* innovation energy <cod cod> was already computed in gc_pred() */ | |
563 /* (this overwrites the LtpResEn which is no longer needed) */ | |
564 frac_en[3] = frac_code_en; move16 (); | |
565 exp_en[3] = exp_code_en; move16 (); | |
566 | |
567 /* store optimum codebook gain in Q(10-exp_gcode0) */ | |
568 exp = add (sub (cod_gain_exp, exp_gcode0), 10); | |
569 gain_cod_unq = shl (cod_gain_frac, exp); | |
570 | |
571 /* run quantization with modified criterion */ | |
572 gain_cod_index = MR795_gain_code_quant_mod( | |
573 *gain_pit, exp_gcode0, gcode0, | |
574 frac_en, exp_en, alpha, gain_cod_unq, | |
575 gain_cod, qua_ener_MR122, qua_ener); move16 (); /* function result */ | |
576 } | |
577 | |
578 *(*anap)++ = gain_pit_index; move16 (); | |
579 *(*anap)++ = gain_cod_index; move16 (); | |
580 } |