Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_com.h" /* Static table prototypes */
8 : #include "prot_fx.h" /* Function prototypes */
9 :
10 :
11 : /*===========================================================================*/
12 : /* FUNCTION : Es_pred_dec_fx() */
13 : /*---------------------------------------------------------------------------*/
14 : /* PURPOSE : Decoding of scaled predicted innovation energy to be */
15 : /* used in all subframes */
16 : /*---------------------------------------------------------------------------*/
17 : /* INPUT ARGUMENTS : */
18 : /* _ (Word16) coder_type : coder type */
19 : /* _ (Word32) core_brate : core bitrate */
20 : /* _ (Word16*) Es_pred_qua_nb_fx : Gain quantization - quantization table */
21 : /* for scaled innovation energy prediciton Q8*/
22 : /*---------------------------------------------------------------------------*/
23 : /* OUTPUT ARGUMENTS : */
24 : /* _ (Word16*) Es_pred : predicited scaled innovation energy Q8 */
25 : /*---------------------------------------------------------------------------*/
26 :
27 : /*---------------------------------------------------------------------------*/
28 : /* RETURN ARGUMENTS : */
29 : /* _ None */
30 : /*===========================================================================*/
31 117061 : void Es_pred_dec_fx(
32 : Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/
33 : const Word16 enr_idx, /* i : indice */
34 : const Word16 nb_bits, /* i : number of bits */
35 : const Word16 no_ltp /* i : no LTP flag */
36 : )
37 : {
38 : #ifdef IVAS_GAIN_MOD
39 : PMT( "Verify if Es_pred_dec_fx should use noltp parameters" )
40 : #endif
41 117061 : IF( no_ltp == 0 )
42 : {
43 115686 : SWITCH( nb_bits )
44 : {
45 100403 : case 5:
46 100403 : *Es_pred = Es_pred_qua_5b_fx[enr_idx]; /*Q8*/
47 100403 : move16();
48 100403 : BREAK;
49 15283 : case 4:
50 15283 : *Es_pred = Es_pred_qua_4b_fx[enr_idx]; /*Q8*/
51 15283 : move16();
52 15283 : BREAK;
53 0 : case 3:
54 0 : *Es_pred = Es_pred_qua_3b_fx[enr_idx]; /*Q8*/
55 0 : break;
56 0 : default:
57 0 : *Es_pred = Es_pred_qua_5b_fx[enr_idx]; /*Q8*/
58 0 : move16();
59 0 : BREAK;
60 : }
61 : }
62 : ELSE
63 : {
64 1375 : *Es_pred = Es_pred_qua_4b_no_ltp_fx[enr_idx]; /*Q8*/
65 1375 : move16();
66 : }
67 117061 : }
68 : /*======================================================================================*/
69 : /* FUNCTION : void gain_dec_tc_fx () */
70 : /*--------------------------------------------------------------------------------------*/
71 : /* PURPOSE : Decoding of pitch and codebook gains and updating long term energies */
72 : /*--------------------------------------------------------------------------------------*/
73 : /* INPUT ARGUMENTS : */
74 : /* Word32 core_brate_fx i : core bitrate */
75 : /* Word16 *code_fx i : algebraic code excitation */
76 : /* Word16 L_frame_fx i : length of the frame */
77 : /* Word16 i_subfr_fx i : subframe number */
78 : /* Word16 tc_subfr_fx i : TC subframe index */
79 : /* Word16 Es_pred_fx i : predicted scaled innov. energy Q8 */
80 : /*--------------------------------------------------------------------------------------*/
81 : /* OUTPUT ARGUMENTS : */
82 : /* Word16 *gain_pit_fx o : pitch gain Q14 */
83 : /* Word32 *gain_code_fx o : Quantized codeebook gain Q16 */
84 : /* Word16 *gain_inov_fx o : unscaled innovation gain Q12 */
85 : /* Word32 *norm_gain_code_fx o : norm. gain of the codebook excit. Q16 */
86 : /*--------------------------------------------------------------------------------------*/
87 : /* INPUT/OUTPUT ARGUMENTS : */
88 : /*--------------------------------------------------------------------------------------*/
89 : /* RETURN ARGUMENTS : */
90 : /* _ None */
91 : /*--------------------------------------------------------------------------------------*/
92 : /* CALLED FROM : */
93 : /*======================================================================================*/
94 :
95 94 : void gain_dec_tc_fx(
96 : Decoder_State *st_fx, /* i/o: decoder state structure */
97 : const Word16 *code_fx, /* i : algebraic code excitation */
98 : const Word16 i_subfr_fx, /* i : subframe number */
99 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */
100 : Word16 *gain_pit_fx, /* o : pitch gain */
101 : Word32 *gain_code_fx, /* o : Quantized codeebook gain */
102 : Word16 *gain_inov_fx, /* o : unscaled innovation gain */
103 : Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excit. */
104 : )
105 : {
106 : Word16 index, nBits;
107 : Word16 gcode0_fx;
108 : Word16 Ei_fx;
109 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac;
110 : Word32 L_tmp, L_tmp1;
111 94 : Word16 wgain_code = 0;
112 94 : move16();
113 94 : *gain_pit_fx = 0;
114 94 : move16();
115 :
116 : /*----------------------------------------------------------------*
117 : * find number of bits for gain dequantization
118 : *----------------------------------------------------------------*/
119 94 : nBits = st_fx->acelp_cfg.gains_mode[( i_subfr_fx / 64 )];
120 94 : move16();
121 : /*-----------------------------------------------------------------*
122 : * calculate the predicted gain code
123 : *-----------------------------------------------------------------*/
124 :
125 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
126 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
127 94 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); /*Q31 - expg*/
128 94 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
129 94 : expg2 = expg;
130 94 : move16();
131 94 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
132 94 : move32();
133 94 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
134 :
135 94 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
136 94 : move16(); /* gain_inov in Q12 */
137 :
138 :
139 : /* Ei = 10 * (float)log10( Ecode );*/
140 94 : e_tmp = norm_l( L_tmp1 );
141 94 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/
142 94 : e_tmp = sub( expg2, add( 1, e_tmp ) );
143 94 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
144 94 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
145 : /* gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
146 94 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
147 :
148 : /*-----------------------------------------------------------------*
149 : * gcode0 = pow(10.0, gcode0/20)
150 : * = pow(2, 3.321928*gcode0/20)
151 : * = pow(2, 0.166096*gcode0)
152 : *-----------------------------------------------------------------*/
153 94 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
154 94 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
155 94 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
156 94 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
157 : /* output of Pow2() will be: */
158 : /* 16384 < Pow2() <= 32767 */
159 94 : exp_gcode0 = sub( exp_gcode0, 14 );
160 : /*------------------------------------------------------------------------------------------*
161 : * Select the gain quantization table and dequantize the gain
162 : *------------------------------------------------------------------------------------------*/
163 :
164 : /* index = (Word16)get_indice( st_fx,"gain_code", i_subfr_fx, ACELP_CORE);move16();*/
165 94 : index = (Word16) get_next_indice_fx( st_fx, nBits );
166 94 : move16();
167 :
168 :
169 94 : IF( GT_16( nBits, 3 ) )
170 : {
171 14 : wgain_code = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, nBits, &expg );
172 14 : wgain_code = shl_sat( wgain_code, add( expg, 13 ) ); /* wgain_code in Q13*/
173 : }
174 : ELSE /* nBits == 3 */
175 : {
176 80 : wgain_code = tbl_gain_code_tc_fx[index]; /*Q13*/
177 80 : move16();
178 : }
179 :
180 : /*-----------------------------------------------------------------*
181 : * decode normalized codebook gain
182 : *-----------------------------------------------------------------*/
183 :
184 : /* *gain_code *= gcode0;*/
185 94 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
186 94 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); /*Q16*/
187 94 : move32();
188 :
189 : /**norm_gain_code = *gain_code / *gain_inov;*/
190 94 : expg = sub( norm_s( *gain_inov_fx ), 1 );
191 94 : expg = s_max( expg, 0 );
192 :
193 94 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
194 94 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q16*/
195 94 : move32();
196 :
197 94 : return;
198 : }
199 :
200 : /*======================================================================================*/
201 : /* FUNCTION : void gain_dec_tc_ivas_fx () */
202 : /*--------------------------------------------------------------------------------------*/
203 : /* PURPOSE : Decoding of pitch and codebook gains and updating long term energies */
204 : /*--------------------------------------------------------------------------------------*/
205 : /* INPUT ARGUMENTS : */
206 : /* Word32 core_brate_fx i : core bitrate */
207 : /* Word16 *code_fx i : algebraic code excitation */
208 : /* Word16 L_frame_fx i : length of the frame */
209 : /* Word16 i_subfr_fx i : subframe number */
210 : /* Word16 tc_subfr_fx i : TC subframe index */
211 : /* Word16 Es_pred_fx i : predicted scaled innov. energy Q8 */
212 : /*--------------------------------------------------------------------------------------*/
213 : /* OUTPUT ARGUMENTS : */
214 : /* Word16 *gain_pit_fx o : pitch gain Q14 */
215 : /* Word32 *gain_code_fx o : Quantized codeebook gain Q16 */
216 : /* Word16 *gain_inov_fx o : unscaled innovation gain Q12 */
217 : /* Word32 *norm_gain_code_fx o : norm. gain of the codebook excit. Q16 */
218 : /*--------------------------------------------------------------------------------------*/
219 : /* INPUT/OUTPUT ARGUMENTS : */
220 : /*--------------------------------------------------------------------------------------*/
221 : /* RETURN ARGUMENTS : */
222 : /* _ None */
223 : /*--------------------------------------------------------------------------------------*/
224 : /* CALLED FROM : */
225 : /*======================================================================================*/
226 :
227 17498 : void gain_dec_tc_ivas_fx(
228 : Decoder_State *st_fx, /* i/o: decoder state structure */
229 : const Word16 *code_fx, /* i : algebraic code excitation */
230 : const Word16 i_subfr_fx, /* i : subframe number */
231 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */
232 : Word16 *gain_pit_fx, /* o : pitch gain */
233 : Word32 *gain_code_fx, /* o : Quantized codeebook gain */
234 : Word16 *gain_inov_fx, /* o : unscaled innovation gain */
235 : Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excit. */
236 : )
237 : {
238 : Word16 index, nBits;
239 : Word16 gcode0_fx;
240 : Word16 Ei_fx;
241 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac;
242 : Word32 L_tmp, L_tmp1;
243 17498 : Word16 wgain_code = 0;
244 17498 : move16();
245 17498 : *gain_pit_fx = 0;
246 17498 : move16();
247 :
248 : /*----------------------------------------------------------------*
249 : * find number of bits for gain dequantization
250 : *----------------------------------------------------------------*/
251 17498 : nBits = st_fx->acelp_cfg.gains_mode[( i_subfr_fx / 64 )];
252 17498 : move16();
253 : /*-----------------------------------------------------------------*
254 : * calculate the predicted gain code
255 : *-----------------------------------------------------------------*/
256 :
257 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
258 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
259 17498 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); /*Q31 - expg*/
260 17498 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
261 17498 : expg2 = expg;
262 17498 : move16();
263 17498 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
264 17498 : move32();
265 17498 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
266 :
267 17498 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
268 17498 : move16(); /* gain_inov in Q12 */
269 :
270 :
271 : /* Ei = 10 * (float)log10( Ecode );*/
272 17498 : e_tmp = norm_l( L_tmp1 );
273 17498 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/
274 17498 : e_tmp = sub( expg2, add( 1, e_tmp ) );
275 17498 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
276 17498 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
277 : /* gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
278 17498 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
279 :
280 : /*-----------------------------------------------------------------*
281 : * gcode0 = pow(10.0, gcode0/20)
282 : * = pow(2, 3.321928*gcode0/20)
283 : * = pow(2, 0.166096*gcode0)
284 : *-----------------------------------------------------------------*/
285 17498 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
286 17498 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
287 17498 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
288 17498 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
289 : /* output of Pow2() will be: */
290 : /* 16384 < Pow2() <= 32767 */
291 17498 : exp_gcode0 = sub( exp_gcode0, 14 );
292 : /*------------------------------------------------------------------------------------------*
293 : * Select the gain quantization table and dequantize the gain
294 : *------------------------------------------------------------------------------------------*/
295 :
296 : /* index = (Word16)get_indice( st_fx,"gain_code", i_subfr_fx, ACELP_CORE);move16();*/
297 17498 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
298 :
299 :
300 17498 : IF( GT_16( nBits, 3 ) )
301 : {
302 1218 : wgain_code = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, nBits, &expg );
303 1218 : wgain_code = shl( wgain_code, add( expg, 12 ) ); /* wgain_code in Q12*/
304 : }
305 : ELSE /* nBits == 3 */
306 : {
307 16280 : wgain_code = shr( tbl_gain_code_tc_fx[index], 1 ); // Q12
308 16280 : move16();
309 : }
310 :
311 : /*-----------------------------------------------------------------*
312 : * decode normalized codebook gain
313 : *-----------------------------------------------------------------*/
314 :
315 : /* *gain_code *= gcode0;*/
316 17498 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q12*Q0 -> Q13 */
317 17498 : *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 3 ) ); /* Q13 -> Q16 */
318 17498 : move32();
319 :
320 : /**norm_gain_code = *gain_code / *gain_inov;*/
321 17498 : expg = sub( norm_s( *gain_inov_fx ), 1 );
322 17498 : expg = s_max( expg, 0 );
323 :
324 17498 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
325 17498 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q16*/
326 17498 : move32();
327 :
328 17498 : return;
329 : }
330 :
331 : /*======================================================================================*/
332 : /* FUNCTION : gain_dec_mless_fx() */
333 : /*--------------------------------------------------------------------------------------*/
334 : /* PURPOSE : Decoding of pitch and codebook gains without updating long term energies */
335 : /*--------------------------------------------------------------------------------------*/
336 : /* INPUT ARGUMENTS : */
337 : /* _ (Word32) core_brate_fx : core bitrate */
338 : /* _ (Word16) L_frame_fx : length of the frame */
339 : /* _ (Word16) coder_type : coding type */
340 : /* _ (Word16) i_subfr_fx : subframe index */
341 : /* _ (Word16) tc_subfr_fx : TC subframe index */
342 : /* _ (Word16*[]) code_fx : algebraic code excitation (Q12) */
343 : /* _ (Word16) Es_pred_fx : predicted scaled innov. energy (Q8) */
344 : /*--------------------------------------------------------------------------------------*/
345 : /* OUTPUT ARGUMENTS : */
346 : /* _ (Word16*) gain_pit_fx : quantized pitch gain (Q14) */
347 : /* _ (Word32*) gain_code_fx : quantized codebook gain (Q16) */
348 : /* _ (Word16*) gain_inov_fx : gain of the innovation (used for normalization) (Q12) */
349 : /* _ (Word32*) norm_gain_code_fx : norm. gain of the codebook excitation (Q16) */
350 : /*--------------------------------------------------------------------------------------*/
351 : /* INPUT/OUTPUT ARGUMENTS : */
352 : /* _ None */
353 : /*--------------------------------------------------------------------------------------*/
354 :
355 : /* _ None */
356 : /*--------------------------------------------------------------------------------------*/
357 : /* RETURN ARGUMENTS : */
358 : /* _ None */
359 : /*======================================================================================*/
360 468875 : void gain_dec_mless_fx(
361 : Decoder_State *st_fx, /* i/o: decoder state structure */
362 : const Word16 L_frame_fx, /* i : length of the frame */
363 : const Word16 coder_type, /* i : coding type */
364 : const Word16 i_subfr_fx, /* i : subframe number */
365 : const Word16 tc_subfr_fx, /* i : TC subframe index */
366 : const Word16 *code_fx, /* i : algebraic code excitation */
367 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */
368 : Word16 *gain_pit_fx, /* o : Quantized pitch gain Q14*/
369 : Word32 *gain_code_fx, /* o : Quantized codeebook gain Q16*/
370 : Word16 *gain_inov_fx, /* o : unscaled innovation gain Q12*/
371 : Word32 *norm_gain_code_fx /* o : norm. gain of the codebook excitation Q16*/
372 : )
373 : {
374 : Word16 index, nBits;
375 : Word16 gcode0_fx, Ei_fx, gain_code16;
376 : const Word16 *qua_table_fx;
377 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac;
378 : Word32 L_tmp, L_tmp1;
379 :
380 : /*-----------------------------------------------------------------*
381 : * decode pitch gain
382 : *-----------------------------------------------------------------*/
383 468875 : nBits = st_fx->acelp_cfg.gains_mode[( i_subfr_fx / 64 )];
384 468875 : move16();
385 :
386 468875 : test();
387 468875 : test();
388 468875 : test();
389 468875 : test();
390 468875 : test();
391 468875 : IF( ( EQ_16( tc_subfr_fx, 3 * L_SUBFR ) && EQ_16( i_subfr_fx, 3 * L_SUBFR ) && EQ_16( L_frame_fx, L_FRAME ) ) ||
392 : ( EQ_16( tc_subfr_fx, 4 * L_SUBFR ) && EQ_16( i_subfr_fx, 4 * L_SUBFR ) && EQ_16( L_frame_fx, L_FRAME16k ) ) )
393 : {
394 : /* decode pitch gain */
395 3125 : index = (Word16) get_next_indice_fx( st_fx, shr( nBits, 1 ) ); /*Q0*/
396 :
397 : /*Ei = (G_PITCH_MAX_TC192 - G_PITCH_MIN_TC192) / ((1 << (nBits>>1)) - 1);*/ /* set quantization step */
398 3125 : tmp_fx = div_s( 1, sub( shl( 1, shr( nBits, 1 ) ), 1 ) ); /*Q15*/
399 3125 : Ei_fx = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, tmp_fx ); /*Q13*/
400 :
401 : /**gain_pit = usdequant( index, G_PITCH_MIN_TC192, Ei );*/
402 3125 : *gain_pit_fx = usdequant_fx( index, G_PITCH_MIN_TC192_Q14, Ei_fx );
403 3125 : move16(); /*Q14*/
404 :
405 : /* calculate the predicted gain code */
406 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
407 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
408 3125 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); /*Q31 - expg*/
409 3125 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q12), -6 (/L_SUBFR) */
410 3125 : expg2 = expg;
411 3125 : move16();
412 3125 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
413 3125 : move32();
414 3125 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
415 :
416 3125 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
417 3125 : move16();
418 :
419 : /*Ei = 10 * (float)log10( Ecode );*/
420 3125 : e_tmp = norm_l( L_tmp1 );
421 3125 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/
422 3125 : e_tmp = sub( expg2, add( 1, e_tmp ) );
423 3125 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
424 3125 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
425 :
426 : /*-----------------------------------------------------------------*
427 : * calculate the predicted gain code
428 : *-----------------------------------------------------------------*/
429 :
430 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
431 3125 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
432 :
433 : /*-----------------------------------------------------------------*
434 : * gcode0 = pow(10.0, gcode0/20)
435 : * = pow(2, 3.321928*gcode0/20)
436 : * = pow(2, 0.166096*gcode0)
437 : *-----------------------------------------------------------------*/
438 3125 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
439 3125 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
440 3125 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
441 :
442 3125 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
443 : /* output of Pow2() will be: */
444 : /* 16384 < Pow2() <= 32767 */
445 3125 : exp_gcode0 = sub( exp_gcode0, 14 );
446 :
447 : /* decode normalized codebook gain */
448 : /*index = (short)get_indice( st_fx, "gain_code", i_subfr_fx, ACELP_CORE );move16();*/
449 3125 : index = (Word16) get_next_indice_fx( st_fx, shr( add( nBits, 1 ), 1 ) ); /*Q0*/
450 3125 : move16();
451 :
452 : /**gain_code = gain_dequant( index, G_CODE_MIN_TC192, G_CODE_MAX_TC192, (nBits+1)>>1 );*/
453 3125 : gain_code16 = gain_dequant_fx( index, G_CODE_MIN_TC192_Q15, G_CODE_MAX_TC192_Q0, shr( add( nBits, 1 ), 1 ), &expg );
454 :
455 : /**gain_code *= gcode0;*/
456 3125 : L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/
457 3125 : *gain_code_fx = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
458 3125 : move32();
459 : }
460 : ELSE
461 : {
462 465750 : SWITCH( nBits )
463 : {
464 748 : case 7:
465 : {
466 748 : qua_table_fx = gain_qua_mless_7b_fx; /*Q14*/
467 748 : BREAK;
468 : }
469 464510 : case 6:
470 : {
471 464510 : qua_table_fx = gain_qua_mless_6b_fx; /*Q14*/
472 464510 : if ( st_fx->element_mode > EVS_MONO )
473 : {
474 : // PMT("gain_qua_mless_6b_stereo to fixed point")
475 461594 : qua_table_fx = gain_qua_mless_6b_stereo_fx; /*Q14*/
476 : }
477 464510 : BREAK;
478 : }
479 492 : case 5:
480 : {
481 492 : qua_table_fx = gain_qua_mless_5b_fx; /*Q14*/
482 492 : BREAK;
483 : }
484 0 : default:
485 : {
486 0 : qua_table_fx = gain_qua_mless_6b_fx; /*Q14*/
487 0 : BREAK;
488 : }
489 : }
490 :
491 465750 : test();
492 465750 : if ( coder_type == INACTIVE && EQ_16( nBits, 6 ) )
493 : {
494 3135 : nBits = sub( nBits, 1 );
495 : }
496 :
497 465750 : index = (Word16) get_next_indice_fx( st_fx, nBits );
498 465750 : move16();
499 :
500 465750 : *gain_pit_fx = qua_table_fx[index * 2]; /*Q14*/
501 465750 : move16();
502 :
503 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
504 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
505 :
506 465750 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); /*Q31 - expg*/
507 465750 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
508 :
509 : // To avoid crash in case code value is 0
510 465750 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, expg, 21474836, 0 ), -1 ) )
511 : {
512 : // setting values to avoid extra computation
513 0 : *gain_inov_fx = 32767; /*8(max value gain_inov can hold) in Q12*/
514 0 : Ei_fx = -9743; /* -38 in Q8*/
515 0 : move16();
516 0 : move16();
517 : }
518 : ELSE
519 : {
520 465750 : expg2 = expg;
521 465750 : move16();
522 465750 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
523 465750 : move32();
524 465750 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
525 :
526 465750 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
527 465750 : move16();
528 :
529 : /*Ei = 10 * (float)log10( Ecode );*/
530 465750 : e_tmp = norm_l( L_tmp1 );
531 465750 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); /*Q15*/
532 465750 : e_tmp = sub( expg2, add( 1, e_tmp ) );
533 465750 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
534 465750 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
535 : }
536 : /*-----------------------------------------------------------------*
537 : * calculate the predicted gain code
538 : *-----------------------------------------------------------------*/
539 :
540 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
541 465750 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
542 :
543 : /*-----------------------------------------------------------------*
544 : * gcode0 = pow(10.0, gcode0/20)
545 : * = pow(2, 3.321928*gcode0/20)
546 : * = pow(2, 0.166096*gcode0)
547 : *-----------------------------------------------------------------*/
548 465750 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
549 465750 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
550 465750 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
551 :
552 465750 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
553 : /* output of Pow2() will be: */
554 : /* 16384 < Pow2() <= 32767 */
555 465750 : exp_gcode0 = sub( exp_gcode0, 14 );
556 :
557 : /*-----------------------------------------------------------------*
558 : * decode normalized codebook gain
559 : *-----------------------------------------------------------------*/
560 :
561 : /**gain_code = qua_table[index * 2 + 1] * gcode0;*/
562 465750 : L_tmp = L_mult( qua_table_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
563 465750 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
564 465750 : move32();
565 : }
566 :
567 : /**norm_gain_code = *gain_code / *gain_inov;*/
568 468875 : expg = sub( norm_s( *gain_inov_fx ), 1 );
569 468875 : expg = s_max( expg, 0 );
570 :
571 468875 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
572 468875 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q16*/
573 468875 : move32();
574 :
575 468875 : return;
576 : }
577 :
578 : /*==================================================================================*/
579 : /* FUNCTION : gain_dec_lbr_fx() */
580 : /*----------------------------------------------------------------------------------*/
581 : /* PURPOSE : Decoding of pitch and codebook gains in ACELP at 6.6 and 7.5 kbps */
582 : /*----------------------------------------------------------------------------------*/
583 : /* INPUT ARGUMENTS : */
584 : /* _ (Word32) core_brate : core bitrate */
585 : /* _ (Word16) coder_type : coding type */
586 : /* _ (Word16) i_subfr : subframe index */
587 : /* _ (Word16*[]) code_fx : algebraic excitation (Q12) */
588 : /*----------------------------------------------------------------------------------*/
589 : /* OUTPUT ARGUMENTS : */
590 : /* _ (Word16*) gain_pit_fx : quantized pitch gain (Q14) */
591 : /* _ (Word32*) gain_code_fx : quantized codebook gain (Q16) */
592 : /* _ (Word16*) gain_inov_fx : gain of the innovation (used for normalization) (Q12) */
593 : /* _ (Word32*) norm_gain_code_fx : norm. gain of the codebook excitation (Q12) */
594 : /*----------------------------------------------------------------------------------*/
595 : /* INPUT/OUTPUT ARGUMENTS : */
596 : /* _ None */
597 : /*----------------------------------------------------------------------------------*/
598 :
599 : /* _ None */
600 : /*----------------------------------------------------------------------------------*/
601 : /* RETURN ARGUMENTS : */
602 : /* _ None */
603 : /*==================================================================================*/
604 :
605 16448 : void gain_dec_lbr_fx(
606 : Decoder_State *st_fx, /* i/o: decoder state structure */
607 : const Word16 coder_type, /* i : coding type */
608 : const Word16 i_subfr, /* i : subframe index */
609 : const Word16 *code_fx, /* i : algebraic excitation Q9 */
610 : Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/
611 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
612 : Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/
613 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/
614 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
615 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
616 : const Word16 L_subfr /* i : subfr lenght */
617 : )
618 : {
619 : Word16 index, nBits, n_pred, ctype;
620 : Word16 gcode0_fx, aux_fx[10];
621 : Word32 L_tmp, L_tmp1, L_tmp2;
622 : Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx;
623 16448 : const Word16 *b_fx, *cdbk_fx = 0;
624 : /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
625 : *gain_inov = 1.0f / (float)sqrt(Ecode); */
626 : Word16 shift_L_subfr;
627 16448 : shift_L_subfr = 6;
628 16448 : move16(); // for *cdbk_fx
629 16448 : move16();
630 16448 : if ( GT_16( L_subfr, L_SUBFR ) )
631 : {
632 3644 : shift_L_subfr = add( shift_L_subfr, 1 );
633 : }
634 16448 : L_tmp = Dot_product12( code_fx, code_fx, L_subfr, &expg ); /*Q31 - expg*/
635 16448 : expg = sub( expg, add( 18, shift_L_subfr ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
636 :
637 16448 : expg2 = expg;
638 16448 : move16();
639 16448 : L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */
640 16448 : move32();
641 16448 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
642 :
643 16448 : *gain_inov_fx = extract_h( L_shl_sat( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
644 16448 : move16();
645 :
646 : /*-----------------------------------------------------------------*
647 : * select the codebook, size and number of bits
648 : * set the gains searching range
649 : *-----------------------------------------------------------------*/
650 16448 : nBits = st_fx->acelp_cfg.gains_mode[shr( i_subfr, shift_L_subfr )];
651 16448 : move16();
652 :
653 16448 : ctype = shl( sub( coder_type, 1 ), 1 );
654 :
655 : /*-----------------------------------------------------------------*
656 : * calculate prediction of gcode
657 : * search for the best codeword
658 : *-----------------------------------------------------------------*/
659 16448 : test();
660 16448 : IF( i_subfr == 0 )
661 : {
662 5023 : b_fx = b_1sfr_fx; /*Q12*/
663 5023 : move16();
664 5023 : n_pred = 2;
665 5023 : move16();
666 5023 : cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14*/
667 5023 : SWITCH( nBits )
668 : {
669 2027 : case 8:
670 : {
671 2027 : cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/
672 2027 : BREAK;
673 : }
674 430 : case 7:
675 : {
676 430 : cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/
677 430 : BREAK;
678 : }
679 2566 : case 6:
680 : {
681 2566 : cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/
682 2566 : BREAK;
683 : }
684 : }
685 :
686 : /* calculate predicted gain */
687 5023 : aux_fx[0] = 4096; /*Q12*/
688 5023 : move16();
689 5023 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
690 5023 : move16();
691 :
692 : /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
693 : gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
694 : gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
695 :
696 5023 : e_tmp = norm_l( L_tmp2 );
697 5023 : f_tmp = Log2_norm_lc( L_shl( L_tmp2, e_tmp ) ); /*Q15*/
698 5023 : e_tmp = sub( expg2, add( 1, e_tmp ) );
699 5023 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
700 :
701 5023 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
702 5023 : L_tmp = Mult_32_16( L_tmp, 160 ); /*Q13, 20 in Q3*/
703 5023 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q13*/
704 :
705 5023 : gcode0_fx = round_fx( L_shl( L_tmp, 11 ) ); /* Q8 */
706 :
707 :
708 : /*-----------------------------------------------------------------*
709 : * gcode0 = pow(10.0, gcode0/20)
710 : * = pow(2, 3.321928*gcode0/20)
711 : * = pow(2, 0.166096*gcode0)
712 : *-----------------------------------------------------------------*/
713 :
714 5023 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
715 5023 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
716 5023 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
717 :
718 5023 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
719 : /* output of Pow2() will be: */
720 : /* 16384 < Pow2() <= 32767 */
721 5023 : exp_gcode0 = sub( exp_gcode0, 14 );
722 :
723 : /* retrieve the codebook index and calculate both gains */
724 : /*index = (Word16)get_indice( st_fx,"gain", i_subfr, ACELP_CORE);move16();*/
725 5023 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
726 5023 : move16();
727 :
728 5023 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
729 5023 : move16();
730 :
731 5023 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
732 5023 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
733 5023 : move16();
734 :
735 5023 : gc_mem[0] = *gain_code_fx; /*Q16*/
736 5023 : move32();
737 5023 : gp_mem[0] = *gain_pit_fx; /*Q14*/
738 5023 : move16();
739 : }
740 11425 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
741 : {
742 5023 : b_fx = b_2sfr_fx; /*Q12*/
743 5023 : move16();
744 5023 : n_pred = 4;
745 5023 : move16();
746 :
747 5023 : cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14*/
748 5023 : SWITCH( nBits )
749 : {
750 2026 : case 7:
751 : {
752 2026 : cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/
753 2026 : BREAK;
754 : }
755 2997 : case 6:
756 : {
757 2997 : cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/
758 2997 : BREAK;
759 : }
760 : }
761 :
762 : /* calculate predicted gain */
763 5023 : aux_fx[0] = 4096; /*Q12*/
764 5023 : move16();
765 5023 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
766 5023 : move16();
767 :
768 : /*aux_fx[2] = (float)log10(gc_mem[0]);
769 : = log2(gc_mem[0])*log10(2);*/
770 5023 : e_tmp = norm_l( gc_mem[0] );
771 5023 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
772 5023 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
773 5023 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
774 5023 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
775 5023 : move16();
776 :
777 5023 : aux_fx[3] = shr( gp_mem[0], 2 ); /*Q12*/
778 5023 : move16();
779 :
780 : /*-----------------------------------------------------------------*
781 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
782 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
783 : *-----------------------------------------------------------------*/
784 5023 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
785 5023 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
786 5023 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
787 5023 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
788 :
789 5023 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
790 : /* output of Pow2() will be: */
791 : /* 16384 < Pow2() <= 32767 */
792 5023 : exp_gcode0 = sub( exp_gcode0, 14 );
793 :
794 : /* retrieve the codebook index and calculate both gains */
795 5023 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
796 5023 : move16();
797 :
798 5023 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
799 5023 : move16();
800 :
801 5023 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
802 5023 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
803 5023 : move16();
804 :
805 5023 : gc_mem[1] = *gain_code_fx; /*Q16*/
806 5023 : move32();
807 5023 : gp_mem[1] = *gain_pit_fx; /*Q14*/
808 5023 : move16();
809 : }
810 6402 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
811 : {
812 3201 : b_fx = b_3sfr_fx; /*Q12*/
813 3201 : move16();
814 3201 : n_pred = 6;
815 3201 : move16();
816 :
817 3201 : cdbk_fx = gp_gamma_3sfr_6b_fx; /*Q14/Q9 */
818 :
819 3201 : if ( EQ_16( nBits, 7 ) )
820 : {
821 2 : cdbk_fx = gp_gamma_3sfr_7b_fx; /*Q14*/
822 : // PMT("verify if gp_gamma_3sfr_7b_fx is correct")
823 : }
824 :
825 : /* calculate predicted gain */
826 3201 : aux_fx[0] = 4096; /*Q12*/
827 3201 : move16();
828 3201 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
829 3201 : move16();
830 :
831 : /*aux_fx[2] = (float)log10(gc_mem[0]);
832 : = log2(gc_mem[0])*log10(2);*/
833 3201 : e_tmp = norm_l( gc_mem[0] );
834 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
835 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
836 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
837 3201 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
838 3201 : move16();
839 :
840 : /*aux[3] = (float)log10(gc_mem[1]);
841 : = log2(gc_mem[1])*log10(2);*/
842 3201 : e_tmp = norm_l( gc_mem[1] );
843 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
844 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
845 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
846 3201 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
847 3201 : move16();
848 :
849 3201 : aux_fx[4] = shr( gp_mem[0], 2 ); /*Q12*/
850 3201 : move16();
851 3201 : aux_fx[5] = shr( gp_mem[1], 2 ); /*Q12*/
852 3201 : move16();
853 :
854 : /*-----------------------------------------------------------------*
855 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
856 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
857 : *-----------------------------------------------------------------*/
858 3201 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
859 3201 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
860 3201 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
861 3201 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
862 :
863 3201 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
864 : /* output of Pow2() will be: */
865 : /* 16384 < Pow2() <= 32767 */
866 3201 : exp_gcode0 = sub( exp_gcode0, 14 );
867 :
868 : /* retrieve the codebook index and calculate both gains */
869 3201 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
870 3201 : move16();
871 :
872 3201 : *gain_pit_fx = cdbk_fx[( index * 2 )];
873 3201 : move16();
874 :
875 3201 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
876 3201 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/
877 3201 : move32();
878 3201 : gc_mem[2] = *gain_code_fx; /*Q16*/
879 3201 : move32();
880 3201 : gp_mem[2] = *gain_pit_fx; /*Q14*/
881 3201 : move16();
882 : }
883 3201 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
884 : {
885 3201 : b_fx = b_4sfr_fx; /*Q12*/
886 3201 : n_pred = 8;
887 3201 : move16();
888 :
889 :
890 3201 : cdbk_fx = gp_gamma_4sfr_6b_fx; /*Q14*/
891 :
892 3201 : IF( EQ_16( nBits, 7 ) )
893 : {
894 0 : cdbk_fx = gp_gamma_4sfr_7b_fx; /*Q14*/
895 : // PMT( "verify if gp_gamma_4sfr_7b_fx is correct" )
896 : }
897 :
898 : /* calculate predicted gain */
899 3201 : aux_fx[0] = 4096; /*Q12*/
900 3201 : move16();
901 3201 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
902 3201 : move16();
903 :
904 : /*aux[2] = (float)log10(gc_mem[0]);
905 : = log2(gc_mem[0])*log10(2);*/
906 3201 : e_tmp = norm_l( gc_mem[0] );
907 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
908 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
909 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
910 3201 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
911 3201 : move16();
912 :
913 : /*aux[3] = (float)log10(gc_mem[1]);
914 : = log2(gc_mem[1])*log10(2);*/
915 3201 : e_tmp = norm_l( gc_mem[1] );
916 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
917 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
918 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
919 3201 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
920 3201 : move16();
921 :
922 : /*aux[4] = (float)log10(gc_mem[2]);
923 : = log2(gc_mem[2])*log10(2);*/
924 3201 : e_tmp = norm_l( gc_mem[2] );
925 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[2], e_tmp ) ); /*Q15*/
926 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[2])=16*/
927 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
928 3201 : aux_fx[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
929 3201 : move16();
930 :
931 3201 : aux_fx[5] = shr( gp_mem[0], 2 ); /*Q12*/
932 3201 : move16();
933 3201 : aux_fx[6] = shr( gp_mem[1], 2 ); /*Q12*/
934 3201 : move16();
935 3201 : aux_fx[7] = shr( gp_mem[2], 2 ); /*Q12*/
936 3201 : move16();
937 :
938 : /*-----------------------------------------------------------------*
939 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
940 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
941 : *-----------------------------------------------------------------*/
942 3201 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
943 3201 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
944 3201 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
945 3201 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
946 :
947 3201 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
948 : /* output of Pow2() will be: */
949 : /* 16384 < Pow2() <= 32767 */
950 3201 : exp_gcode0 = sub( exp_gcode0, 14 );
951 :
952 : /* retrieve the codebook index and calculate both gains */
953 3201 : index = (Word16) get_next_indice_fx( st_fx, nBits );
954 3201 : move16();
955 3201 : *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/
956 3201 : move16();
957 :
958 3201 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
959 3201 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
960 3201 : move32();
961 : }
962 :
963 : /* *norm_gain_code = *gain_code / *gain_inov; */
964 16448 : expg = sub( norm_s( *gain_inov_fx ), 1 );
965 16448 : expg = s_max( expg, 0 );
966 :
967 16448 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); /*Q15*/
968 16448 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q15*/
969 16448 : move32();
970 :
971 16448 : return;
972 : }
973 :
974 : /*====================================================================== */
975 : /* FUNCTION : lp_gain_updt_fx() */
976 : /*-----------------------------------------------------------------------*/
977 : /* PURPOSE : Update of LP pitch and code gains (FEC) */
978 : /* */
979 : /*-----------------------------------------------------------------------*/
980 : /* INPUT ARGUMENTS : */
981 : /* _ (Word16) i_subfr : subframe number Q0 */
982 : /* _ (Word16) gain_pit : Decoded gain pitch Q14 */
983 : /* _ (Word32) norm_gain_code : Normalised gain code Q16 */
984 : /* _ (Word16) L_frame : length of the frame Q0 */
985 : /*-----------------------------------------------------------------------*/
986 : /* OUTPUT ARGUMENTS : */
987 : /* _ (Word16 *) T0 : close loop integer pitch */
988 : /* _ (Word16 *) T0_frac : close loop fractional part of the pitch */
989 : /* _ (Word16 ) pitch : pitch value Q6 */
990 : /*-----------------------------------------------------------------------*/
991 : /* INPUT OUTPUT ARGUMENTS */
992 : /* _ (Word16 *) lp_gainp : LP-filtered pitch gain(FEC) Q14 */
993 : /* _ (Word16 *) lp_gainc : LP-filtered code gain (FEC) Q3 */
994 : /*-----------------------------------------------------------------------*/
995 :
996 : /*-----------------------------------------------------------------------*/
997 : /* RETURN ARGUMENTS : */
998 : /* _ None */
999 : /*=======================================================================*/
1000 :
1001 :
1002 6337 : void lp_gain_updt_fx(
1003 : const Word16 i_subfr, /* i : subframe number Q0 */
1004 : const Word16 gain_pit, /* i : Decoded gain pitch Q14 */
1005 : const Word32 norm_gain_code, /* i : Normalised gain code Q16 */
1006 : Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */
1007 : Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */
1008 : const Word16 L_frame /* i : length of the frame */
1009 : )
1010 : {
1011 : Word16 tmp;
1012 :
1013 6337 : tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/
1014 6337 : IF( EQ_16( L_frame, L_FRAME ) )
1015 : {
1016 2992 : IF( EQ_16( i_subfr, 0 ) )
1017 : {
1018 748 : *lp_gainp = mult( 3277, gain_pit );
1019 748 : move16(); /*0.1 in Q15 = 3277 , (15+14)-15 -> Q14*/
1020 748 : *lp_gainc = mult_r( 3277, tmp );
1021 748 : move16(); /* (15+3)-15 -> Q3*/
1022 : }
1023 2244 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1024 : {
1025 748 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1026 748 : move16(); /*Q14 (0.2 in Q15 = 6554)*/
1027 748 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1028 748 : move16(); /*Q3*/
1029 : }
1030 1496 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1031 : {
1032 748 : *lp_gainp = add( *lp_gainp, mult( 9830, gain_pit ) );
1033 748 : move16(); /*Q14 (0.3 in Q15 = 9830)*/
1034 748 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 9830, tmp );
1035 748 : move16(); /*Q3*/
1036 : }
1037 : ELSE /* i_subfr == 3*L_SUBFR */
1038 : {
1039 748 : *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) );
1040 748 : move16(); /*Q14 (0.4 in Q15 = 13107)*/
1041 748 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp );
1042 748 : move16(); /*Q3*/
1043 : }
1044 : }
1045 : ELSE
1046 : {
1047 3345 : IF( i_subfr == 0 )
1048 : {
1049 669 : *lp_gainp = mult( 2185, gain_pit );
1050 669 : move16(); /*(1.0/15.0) in Q15 = 2185 , (15+14)-15 -> Q14*/
1051 669 : *lp_gainc = mult_r( 2185, tmp );
1052 669 : move16(); /* (15+3)-15 -> Q3*/
1053 : }
1054 2676 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1055 : {
1056 669 : *lp_gainp = add( *lp_gainp, mult( 4369, gain_pit ) );
1057 669 : move16(); /*Q14 (2.0/15.0 in Q15 = 4369)*/
1058 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 4369, tmp );
1059 669 : move16(); /*Q3*/
1060 : }
1061 2007 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1062 : {
1063 669 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1064 669 : move16(); /*Q14 (3.0/15.0 in Q15 = 6554)*/
1065 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1066 669 : move16(); /*Q3*/
1067 : }
1068 1338 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1069 : {
1070 669 : *lp_gainp = add( *lp_gainp, mult( 8738, gain_pit ) );
1071 669 : move16(); /*Q14 (4.0/15.0 in Q15 = 8738)*/
1072 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 8738, tmp );
1073 669 : move16(); /*Q3*/
1074 : }
1075 : ELSE /* i_subfr == 4*L_SUBFR */
1076 : {
1077 669 : *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) );
1078 669 : move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/
1079 669 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp );
1080 669 : move16(); /*Q3*/
1081 : }
1082 : }
1083 6337 : return;
1084 : }
1085 :
1086 : /*====================================================================== */
1087 : /* FUNCTION : lp_gain_updt_ivas_fx() */
1088 : /*-----------------------------------------------------------------------*/
1089 : /* PURPOSE : Update of LP pitch and code gains (FEC) */
1090 : /* */
1091 : /*-----------------------------------------------------------------------*/
1092 : /* INPUT ARGUMENTS : */
1093 : /* _ (Word16) i_subfr : subframe number Q0 */
1094 : /* _ (Word16) gain_pit : Decoded gain pitch Q14 */
1095 : /* _ (Word32) norm_gain_code : Normalised gain code Q16 */
1096 : /* _ (Word16) L_frame : length of the frame Q0 */
1097 : /*-----------------------------------------------------------------------*/
1098 : /* OUTPUT ARGUMENTS : */
1099 : /* _ (Word16 *) T0 : close loop integer pitch */
1100 : /* _ (Word16 *) T0_frac : close loop fractional part of the pitch */
1101 : /* _ (Word16 ) pitch : pitch value Q6 */
1102 : /*-----------------------------------------------------------------------*/
1103 : /* INPUT OUTPUT ARGUMENTS */
1104 : /* _ (Word16 *) lp_gainp : LP-filtered pitch gain(FEC) Q14 */
1105 : /* _ (Word16 *) lp_gainc : LP-filtered code gain (FEC) Q3 */
1106 : /*-----------------------------------------------------------------------*/
1107 :
1108 : /*-----------------------------------------------------------------------*/
1109 : /* RETURN ARGUMENTS : */
1110 : /* _ None */
1111 : /*=======================================================================*/
1112 :
1113 :
1114 548208 : void lp_gain_updt_ivas_fx(
1115 : const Word16 i_subfr, /* i : subframe number Q0 */
1116 : const Word16 gain_pit, /* i : Decoded gain pitch Q14 */
1117 : const Word32 norm_gain_code, /* i : Normalised gain code Q16 */
1118 : Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */
1119 : Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */
1120 : const Word16 L_frame /* i : length of the frame */
1121 : )
1122 : {
1123 : Word16 tmp;
1124 :
1125 548208 : tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/
1126 : /* To handle extremely low values */
1127 548208 : test();
1128 548208 : if ( norm_gain_code != 0 && tmp == 0 )
1129 : {
1130 940 : tmp = 1;
1131 940 : move16();
1132 : }
1133 :
1134 548208 : IF( EQ_16( L_frame, L_FRAME ) )
1135 : {
1136 230168 : IF( EQ_16( i_subfr, 0 ) )
1137 : {
1138 57542 : *lp_gainp = mult( 3277, gain_pit );
1139 57542 : move16(); /*0.1 in Q15 = 3277 , (15+14)-15 -> Q14*/
1140 57542 : *lp_gainc = mult_r( 3277, tmp );
1141 57542 : move16(); /* (15+3)-15 -> Q3*/
1142 : }
1143 172626 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1144 : {
1145 57542 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1146 57542 : move16(); /*Q14 (0.2 in Q15 = 6554)*/
1147 57542 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1148 57542 : move16(); /*Q3*/
1149 : }
1150 115084 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1151 : {
1152 57542 : *lp_gainp = add( *lp_gainp, mult( 9830, gain_pit ) );
1153 57542 : move16(); /*Q14 (0.3 in Q15 = 9830)*/
1154 57542 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 9830, tmp );
1155 57542 : move16(); /*Q3*/
1156 : }
1157 : ELSE /* i_subfr == 3*L_SUBFR */
1158 : {
1159 57542 : *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) );
1160 57542 : move16(); /*Q14 (0.4 in Q15 = 13107)*/
1161 57542 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp );
1162 57542 : move16(); /*Q3*/
1163 : }
1164 : }
1165 : ELSE
1166 : {
1167 318040 : IF( i_subfr == 0 )
1168 : {
1169 63608 : *lp_gainp = mult( 2185, gain_pit );
1170 63608 : move16(); /*(1.0/15.0) in Q15 = 2185 , (15+14)-15 -> Q14*/
1171 63608 : *lp_gainc = mult_r( 2185, tmp );
1172 63608 : move16(); /* (15+3)-15 -> Q3*/
1173 : }
1174 254432 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1175 : {
1176 63608 : *lp_gainp = add( *lp_gainp, mult( 4369, gain_pit ) );
1177 63608 : move16(); /*Q14 (2.0/15.0 in Q15 = 4369)*/
1178 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 4369, tmp );
1179 63608 : move16(); /*Q3*/
1180 : }
1181 190824 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1182 : {
1183 63608 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1184 63608 : move16(); /*Q14 (3.0/15.0 in Q15 = 6554)*/
1185 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1186 63608 : move16(); /*Q3*/
1187 : }
1188 127216 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1189 : {
1190 63608 : *lp_gainp = add( *lp_gainp, mult( 8738, gain_pit ) );
1191 63608 : move16(); /*Q14 (4.0/15.0 in Q15 = 8738)*/
1192 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 8738, tmp );
1193 63608 : move16(); /*Q3*/
1194 : }
1195 : ELSE /* i_subfr == 4*L_SUBFR */
1196 : {
1197 63608 : *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) );
1198 63608 : move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/
1199 63608 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp );
1200 63608 : move16(); /*Q3*/
1201 : }
1202 : }
1203 :
1204 : /* To handle extremely low values */
1205 548208 : test();
1206 548208 : if ( tmp != 0 && *lp_gainc == 0 )
1207 : {
1208 2270 : *lp_gainc = 1;
1209 2270 : move16();
1210 : }
1211 :
1212 548208 : return;
1213 : }
1214 :
1215 : /*-------------------------------------------------*
1216 : * gain_dec_gaus_fx()
1217 : *
1218 : * Decode gains of purely unvoiced sounds
1219 : *-------------------------------------------------*/
1220 :
1221 : /*! r: quantized codebook gain Q16 */
1222 0 : Word32 gain_dec_gaus_fx(
1223 : Word16 index, /* i : quantization index */
1224 : const Word16 bits, /* i : number of bits to quantize */
1225 : const Word16 lowBound, /* i : lower bound of quantizer (dB) */
1226 : const Word16 topBound, /* i : upper bound of quantizer (dB) */
1227 : const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */
1228 : Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */
1229 : )
1230 : {
1231 : Word16 stepSize, gain, expg, frac, expi, tmp_igi;
1232 : Word32 L_tmp, L_enr_q, L_gain;
1233 : Word16 stepSize_Exp;
1234 :
1235 0 : stepSize_Exp = 14;
1236 0 : move16();
1237 :
1238 : /*------------------------------------------------------------------------------------------*
1239 : * Quantize linearly the log E
1240 : *------------------------------------------------------------------------------------------*/
1241 :
1242 0 : if ( EQ_16( bits, 6 ) )
1243 : {
1244 0 : stepSize_Exp = sub( stepSize_Exp, 1 );
1245 : }
1246 0 : stepSize = shl( sub( topBound, lowBound ), sub( stepSize_Exp, bits ) ); /* QstepSize_Exp */
1247 :
1248 : /*------------------------------------------------------------------------------------------*
1249 : * Gaussian codebook gain
1250 : *------------------------------------------------------------------------------------------*/
1251 :
1252 : /* enr_q = (float)index*stepSize ,lowBound); */
1253 0 : L_enr_q = L_mult( index, stepSize ); /* Q0 * QstepSize_Exp -> QstepSize_Exp+1 */
1254 0 : L_enr_q = L_shl( L_enr_q, sub( 24 - 1, stepSize_Exp ) ); /* QstepSize_Exp+1 -> Q24 */
1255 0 : L_enr_q = L_add( L_enr_q, L_shl( L_deposit_h( lowBound ), 8 ) ); /* Q24 */
1256 : /*------------------------------------------------------------*
1257 : * gain = pow(10.0, enr/20)
1258 : * = pow(2, 3.321928*enr/20)
1259 : * = pow(2, 0.166096*enr)
1260 : *------------------------------------------------------------*/
1261 :
1262 : /* gain = (float)pow( 10.0f, enr/20.0f ); quantized codebook gain */
1263 0 : L_tmp = Mult_32_16( L_enr_q, 21771 ); /* *0.166096 in Q17 -> Q26 */
1264 0 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1265 0 : frac = L_Extract_lc( L_tmp, &expg ); /* Extract exponent of enr */
1266 0 : L_gain = Pow2( 30, frac ); /* Put 30 as exponent so that the */
1267 0 : expg = add( expg, 16 - 30 ); /* output of Pow2() will be */
1268 : /* Normalized, set result in Q16 */
1269 0 : gain = round_fx( L_gain );
1270 0 : L_gain = L_shl_sat( L_gain, expg ); /* In Q16*/
1271 : /* *norm_gain_code = gain / *inv_gain_inov;*/
1272 0 : expi = norm_s( inv_gain_inov );
1273 0 : tmp_igi = shl( inv_gain_inov, expi );
1274 0 : L_tmp = div_s( shr( gain, 1 ), tmp_igi );
1275 0 : L_tmp = L_shl_sat( L_tmp, add( 1, expi ) );
1276 0 : *L_norm_gain_code = L_shl_sat( L_tmp, add( expg, 13 ) ); /* Q16 */
1277 0 : move32();
1278 :
1279 0 : return L_gain;
1280 : }
1281 :
1282 : /*--------------------------------------------------------------------------*
1283 : * gain_dec_SQ()
1284 : *
1285 : * Decoding of pitch and codebook gains using scalar quantizers
1286 : *-------------------------------------------------------------------------*/
1287 :
1288 40578 : void gain_dec_SQ_fx(
1289 : Decoder_State *st_fx, /* i/o: decoder state structure */
1290 : const Word16 i_subfr, /* i : subframe number */
1291 : const Word16 *code, /* i : algebraic code excitation Q9*/
1292 : const Word16 Es_pred, /* i : predicted scaled innov. energy Q8 */
1293 : Word16 *gain_pit, /* o : Quantized pitch gain Q14*/
1294 : Word32 *gain_code, /* o : Quantized codeebook gain Q16*/
1295 : Word16 *gain_inov, /* o : unscaled innovation gain Q12*/
1296 : Word32 *norm_gain_code /* o : norm. gain of the codebook excitation Q16*/
1297 : )
1298 : {
1299 : Word16 index, nBits;
1300 : Word16 gcode0, Ei;
1301 : Word16 tmp16, expg, expg2, e_tmp, f_tmp, exp_gcode0, frac;
1302 : Word32 L_tmp, L_tmp1;
1303 :
1304 : /*-----------------------------------------------------------------*
1305 : * get number of bits
1306 : *-----------------------------------------------------------------*/
1307 :
1308 40578 : nBits = st_fx->acelp_cfg.gains_mode[( i_subfr / 64 )];
1309 40578 : move16();
1310 :
1311 : /*-----------------------------------------------------------------*
1312 : * decode pitch gain
1313 : *-----------------------------------------------------------------*/
1314 :
1315 40578 : index = (Word16) get_next_indice_fx( st_fx, shr( nBits, 1 ) );
1316 40578 : move16();
1317 :
1318 : /*Ei = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << (nBits>>1)) - 1); set quantization step */
1319 40578 : tmp16 = div_s( 1, sub( shl( 1, shr( nBits, 1 ) ), 1 ) ); /* Q15*/
1320 40578 : Ei = mult_r( G_PITCH_MAX_MINUS_MIN_Q13, tmp16 ); /* Q13*/
1321 :
1322 : /**gain_pit = usdequant( index, G_PITCH_MIN, Ei );*/
1323 40578 : *gain_pit = usdequant_fx( index, G_PITCH_MIN_Q14, Ei );
1324 40578 : move16(); /*Q14 */
1325 :
1326 : /*-----------------------------------------------------------------*
1327 : * calculate the predicted gain code
1328 : *-----------------------------------------------------------------*/
1329 :
1330 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
1331 : /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
1332 :
1333 40578 : L_tmp = Dot_product12( code, code, L_SUBFR, &expg );
1334 40578 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1335 40578 : expg2 = expg;
1336 40578 : move16();
1337 40578 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1338 40578 : move32();
1339 40578 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
1340 :
1341 40578 : *gain_inov = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
1342 40578 : move16();
1343 :
1344 : /*Ei = 10 * (float)log10( Ecode );*/
1345 40578 : e_tmp = norm_l( L_tmp1 );
1346 40578 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1347 40578 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1348 40578 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1349 40578 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1350 :
1351 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1352 40578 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
1353 :
1354 : /* gcode0 = pow(10.0, gcode0/20) = pow(2, 3.321928*gcode0/20) = pow(2, 0.166096*gcode0) */
1355 40578 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
1356 40578 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1357 40578 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1358 :
1359 40578 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that output of Pow2() will be: 16384 < Pow2() <= 32767 */
1360 40578 : exp_gcode0 = sub( exp_gcode0, 14 );
1361 :
1362 : /*-----------------------------------------------------------------*
1363 : * decode normalized codebook gain
1364 : *-----------------------------------------------------------------*/
1365 :
1366 40578 : index = (Word16) get_next_indice_fx( st_fx, shr( add( nBits, 1 ), 1 ) );
1367 40578 : move16();
1368 :
1369 40578 : tmp16 = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, shr( add( nBits, 1 ), 1 ), &expg );
1370 :
1371 : /**gain_code *= gcode0;*/
1372 40578 : L_tmp = L_mult( tmp16, gcode0 ); /* Q0*Q0 -> Q1*/
1373 : /**gain_code = L_shl(L_tmp,add(expg,15)); Q16*/
1374 40578 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1375 40578 : move32();
1376 :
1377 : /**norm_gain_code = *gain_code / *gain_inov;*/
1378 40578 : expg = sub( norm_s( *gain_inov ), 1 );
1379 40578 : expg = s_max( expg, 0 );
1380 :
1381 40578 : tmp16 = div_s( shr( 8192, expg ), *gain_inov ); /*Q15*/
1382 40578 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp16 ), sub( 1, expg ) ); /*Q16*/
1383 40578 : move32();
1384 :
1385 40578 : return;
1386 : }
1387 :
1388 : /*---------------------------------------------------------------------*
1389 : * gain_dec_amr_wb()
1390 : *
1391 : * Decoding of pitch and fixed codebook gains (used also in AMR-WB IO mode)
1392 : *---------------------------------------------------------------------*/
1393 :
1394 0 : void gain_dec_amr_wb_fx(
1395 : Decoder_State *st_fx, /* i/o: decoder state structure */
1396 : const Word32 core_brate, /* i : core bitrate */
1397 : Word16 *gain_pit, /* o : Quantized pitch gain Q14*/
1398 : Word32 *gain_code, /* o : Quantized codeebook gain Q16*/
1399 : Word16 *past_qua_en, /* i/o: gain quantization memory (4 words) Q10*/
1400 : Word16 *gain_inov, /* o : unscaled innovation gain Q12*/
1401 : const Word16 *code, /* i : algebraic code excitation Q9*/
1402 : Word32 *norm_gain_code /* o : norm. gain of the codebook excitation Q16*/
1403 : )
1404 : {
1405 : Word16 i, index, index2;
1406 : Word16 nbits;
1407 : Word16 gcode0, qua_en;
1408 : const Word16 *t_qua_gain;
1409 : Word16 tmp;
1410 : Word32 L_tmp;
1411 : Word16 expg, exp_gcode0, fracg;
1412 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1413 0 : Flag Overflow = 0;
1414 0 : move32();
1415 : #endif
1416 :
1417 :
1418 : /**gain_inov = 1.0f/ (float)sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR );*/
1419 :
1420 0 : L_tmp = Dot_product12( code, code, L_SUBFR, &expg ); /*Q31 - expg*/
1421 0 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1422 0 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
1423 :
1424 0 : *gain_inov = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
1425 0 : move16();
1426 :
1427 : /*-----------------------------------------------------------------*
1428 : * Select the gain quantization table
1429 : *-----------------------------------------------------------------*/
1430 0 : nbits = 7;
1431 0 : move16();
1432 0 : t_qua_gain = t_qua_gain7b_fx;
1433 :
1434 0 : if ( LT_32( core_brate, ACELP_12k65 ) )
1435 : {
1436 0 : nbits = 6;
1437 0 : move16();
1438 0 : t_qua_gain = t_qua_gain6b_fx;
1439 : }
1440 :
1441 : /*-----------------------------------------------------------------*
1442 : * predicted code gain
1443 : *-----------------------------------------------------------------*/
1444 :
1445 : /* start with predicting code energy in dB */
1446 : /**for (i=0; i<GAIN_PRED_ORDER; i++) {gcode0 += pred_gain[i] * past_qua_en[i];}*/
1447 : /*gcode0 += (float)(20.0 * log10( *gain_inov ) );*/
1448 : /* predicted energy */
1449 0 : L_tmp = L_deposit_h( MEAN_ENER ); /* MEAN_ENER in Q16 */
1450 0 : L_tmp = L_shl( L_tmp, 9 ); /* From Q16 to Q25 */
1451 :
1452 0 : FOR( i = 0; i < GAIN_PRED_ORDER; i++ )
1453 : {
1454 : /* pred_code += pred[i]*past_qua_en[i]; */
1455 0 : L_tmp = L_mac( L_tmp, pred_gain_fx[i], past_qua_en[i] ); /* Q14*Q10 -> Q25 */
1456 : }
1457 :
1458 : /* predicted codebook gain */
1459 0 : gcode0 = extract_h( L_tmp ); /* From Q25 to Q9 */
1460 :
1461 : /*-----------------------------------------------------------------*
1462 : * gcode0 = pow(10.0, gcode0/20)
1463 : * = pow(2, 3.321928*gcode0/20)
1464 : * = pow(2, 0.166096*gcode0)
1465 : *-----------------------------------------------------------------*/
1466 0 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q27 */
1467 0 : L_tmp = L_shr( L_tmp, 9 + 2 ); /* From Q27 to Q16 */
1468 0 : L_Extract( L_tmp, &exp_gcode0, &fracg ); /* Extract exponent of gcode0 */
1469 :
1470 0 : gcode0 = extract_l( Pow2( 14, fracg ) ); /* Put 14 as exponent so that */
1471 : /* output of Pow2() will be: */
1472 : /* 16384 < Pow2() <= 32767 */
1473 0 : exp_gcode0 = sub( exp_gcode0, 14 );
1474 :
1475 : /*-----------------------------------------------------------------*
1476 : * Decode pitch gain
1477 : *-----------------------------------------------------------------*/
1478 :
1479 0 : index = (Word16) get_next_indice_fx( st_fx, nbits );
1480 0 : move16();
1481 0 : index2 = shl( index, 1 );
1482 0 : *gain_pit = t_qua_gain[index2];
1483 0 : move16();
1484 :
1485 : /*-----------------------------------------------------------------*
1486 : * Decode code gain
1487 : *-----------------------------------------------------------------*/
1488 0 : qua_en = t_qua_gain[( index2 + 1 )];
1489 0 : move16();
1490 :
1491 : /* *gain_code = t_qua_gain[indice*2+1] * gcode0; */
1492 0 : L_tmp = L_mult( qua_en, gcode0 ); /* Q11*Q0 -> Q12 */
1493 0 : tmp = round_fx( L_tmp ); /* Q-4 */
1494 0 : *gain_code = L_shl( L_tmp, add( exp_gcode0, 4 ) ); /* Q12 -> Q16 */
1495 0 : move32();
1496 :
1497 : /* adjust gain according to energy of code */
1498 0 : L_tmp = Mult_32_16( *gain_code, *gain_inov );
1499 0 : *gain_code = L_shl_o( L_tmp, 3, &Overflow ); /* gcode_inov in Q12*/
1500 0 : move32();
1501 :
1502 : /*-----------------------------------------------------------------*
1503 : * update table of past quantized energies
1504 : *-----------------------------------------------------------------*/
1505 :
1506 0 : FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
1507 : {
1508 0 : past_qua_en[i] = past_qua_en[i - 1];
1509 0 : move16();
1510 : }
1511 : /*past_qua_en[0] = (float)(20.0*log10(qua_en));*/
1512 : /*----------------------------------------------------------*
1513 : * past_qua_en[0] = 20*log10(t_qua_gain[indice*2+1])
1514 : * = 6.0206*log2(t_qua_gain[indice*2+1])
1515 : * = 6.0206*(log2(t_qua_gain[indice*2+1]Q11 -11)
1516 : *----------------------------------------------------------*/
1517 0 : tmp = norm_l( qua_en );
1518 0 : fracg = Log2_norm_lc( L_shl( qua_en, tmp ) );
1519 0 : expg = sub( 30, tmp );
1520 0 : expg = sub( expg, 11 );
1521 0 : L_tmp = Mpy_32_16( expg, fracg, 24660 ); /* x 6.0206 in Q12 */
1522 0 : qua_en = extract_h( L_shl( L_tmp, 13 ) ); /* result in Q10 */
1523 :
1524 0 : past_qua_en[0] = qua_en;
1525 0 : move16(); /* in Q10 */
1526 :
1527 : /*-----------------------------------------------------------------*
1528 : * Normalized code gain
1529 : *-----------------------------------------------------------------*/
1530 : /**norm_gain_code = *gain_code / *gain_inov;*/
1531 0 : expg = sub( norm_s( *gain_inov ), 1 );
1532 0 : expg = s_max( expg, 0 );
1533 :
1534 0 : tmp = div_s( shr( 8192, expg ), *gain_inov ); /*Q15*/
1535 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, expg ) ); /*Q16*/
1536 0 : move32();
1537 :
1538 0 : return;
1539 : }
|