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 : #ifndef REMOVE_EVS_DUPLICATES
606 : void gain_dec_lbr_fx(
607 : Decoder_State *st_fx, /* i/o: decoder state structure */
608 : const Word16 coder_type, /* i : coding type */
609 : const Word16 i_subfr, /* i : subframe index */
610 : const Word16 *code_fx, /* i : algebraic excitation Q9 */
611 : Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/
612 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
613 : Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/
614 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/
615 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
616 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
617 : const Word16 L_subfr /* i : subfr lenght */
618 : )
619 : {
620 : Word16 index, nBits, n_pred, ctype;
621 : Word16 gcode0_fx, aux_fx[10];
622 : Word32 L_tmp, L_tmp1, L_tmp2;
623 : Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx;
624 : const Word16 *b_fx, *cdbk_fx = 0;
625 : /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
626 : *gain_inov = 1.0f / (float)sqrt(Ecode); */
627 : Word16 shift_L_subfr;
628 : shift_L_subfr = 6;
629 : move16(); // for *cdbk_fx
630 : move16();
631 : if ( GT_16( L_subfr, L_SUBFR ) )
632 : {
633 : shift_L_subfr = add( shift_L_subfr, 1 );
634 : }
635 : L_tmp = Dot_product12( code_fx, code_fx, L_subfr, &expg ); /*Q31 - expg*/
636 : expg = sub( expg, add( 18, shift_L_subfr ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
637 :
638 : expg2 = expg;
639 : move16();
640 : L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */
641 : move32();
642 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
643 :
644 : *gain_inov_fx = extract_h( L_shl_sat( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
645 : move16();
646 :
647 : /*-----------------------------------------------------------------*
648 : * select the codebook, size and number of bits
649 : * set the gains searching range
650 : *-----------------------------------------------------------------*/
651 : nBits = st_fx->acelp_cfg.gains_mode[shr( i_subfr, shift_L_subfr )];
652 : move16();
653 :
654 : ctype = shl( sub( coder_type, 1 ), 1 );
655 :
656 : /*-----------------------------------------------------------------*
657 : * calculate prediction of gcode
658 : * search for the best codeword
659 : *-----------------------------------------------------------------*/
660 : IF( i_subfr == 0 )
661 : {
662 : b_fx = b_1sfr_fx;
663 : move16();
664 : n_pred = 2;
665 : move16();
666 : cdbk_fx = gp_gamma_1sfr_6b_fx;
667 : SWITCH( nBits )
668 : {
669 : case 8:
670 : {
671 : cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/
672 : BREAK;
673 : }
674 : case 7:
675 : {
676 : cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/
677 : BREAK;
678 : }
679 : case 6:
680 : {
681 : cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/
682 : BREAK;
683 : }
684 : }
685 :
686 : /* calculate predicted gain */
687 : aux_fx[0] = 4096; /*Q12*/
688 : move16();
689 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
690 : 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 : e_tmp = norm_l( L_tmp2 );
697 : f_tmp = Log2_norm_lc( L_shl( L_tmp2, e_tmp ) ); /*Q15*/
698 : e_tmp = sub( expg2, add( 1, e_tmp ) );
699 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
700 :
701 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
702 : L_tmp = Mult_32_16( L_tmp, 160 ); /*Q13, 20 in Q3*/
703 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q13*/
704 :
705 : 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 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
715 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
716 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
717 :
718 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
719 : /* output of Pow2() will be: */
720 : /* 16384 < Pow2() <= 32767 */
721 : 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 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
726 : move16();
727 :
728 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
729 : move16();
730 :
731 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
732 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/
733 : move16();
734 :
735 : gc_mem[0] = *gain_code_fx; /*Q16*/
736 : move32();
737 : gp_mem[0] = *gain_pit_fx; /*Q14*/
738 : move16();
739 : }
740 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
741 : {
742 : b_fx = b_2sfr_fx; /*Q12*/
743 : move16();
744 : n_pred = 4;
745 : move16();
746 :
747 : cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14/Q9 */
748 : SWITCH( nBits )
749 : {
750 : case 7:
751 : {
752 : cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/
753 : BREAK;
754 : }
755 : case 6:
756 : {
757 : cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/
758 : BREAK;
759 : }
760 : }
761 :
762 : /* calculate predicted gain */
763 : aux_fx[0] = 4096; /*Q12*/
764 : move16();
765 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
766 : move16();
767 :
768 : /*aux_fx[2] = (float)log10(gc_mem[0]);
769 : = log2(gc_mem[0])*log10(2);*/
770 : e_tmp = norm_l( gc_mem[0] );
771 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
772 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
773 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
774 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
775 : move16();
776 :
777 : aux_fx[3] = shr( gp_mem[0], 2 ); /*Q12*/
778 : 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 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
785 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
786 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
787 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
788 :
789 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
790 : /* output of Pow2() will be: */
791 : /* 16384 < Pow2() <= 32767 */
792 : exp_gcode0 = sub( exp_gcode0, 14 );
793 :
794 : /* retrieve the codebook index and calculate both gains */
795 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
796 : move16();
797 :
798 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
799 : move16();
800 :
801 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
802 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
803 : move16();
804 :
805 : gc_mem[1] = *gain_code_fx; /*Q16*/
806 : move32();
807 : gp_mem[1] = *gain_pit_fx; /*Q14*/
808 : move16();
809 : }
810 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
811 : {
812 : b_fx = b_3sfr_fx;
813 : move16();
814 : n_pred = 6;
815 : move16();
816 :
817 : cdbk_fx = gp_gamma_3sfr_6b_fx; /*Q14/Q9 */
818 :
819 : if ( EQ_16( nBits, 7 ) )
820 : {
821 : 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 : aux_fx[0] = 4096; /*Q12*/
827 : move16();
828 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
829 : move16();
830 :
831 : /*aux_fx[2] = (float)log10(gc_mem[0]);
832 : = log2(gc_mem[0])*log10(2);*/
833 : e_tmp = norm_l( gc_mem[0] );
834 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
835 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
836 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
837 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
838 : move16();
839 :
840 : /*aux[3] = (float)log10(gc_mem[1]);
841 : = log2(gc_mem[1])*log10(2);*/
842 : e_tmp = norm_l( gc_mem[1] );
843 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
844 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
845 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
846 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
847 : move16();
848 :
849 : aux_fx[4] = shr( gp_mem[0], 2 ); /*Q12*/
850 : move16();
851 : aux_fx[5] = shr( gp_mem[1], 2 ); /*Q12*/
852 : 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 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
859 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
860 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
861 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
862 :
863 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
864 : /* output of Pow2() will be: */
865 : /* 16384 < Pow2() <= 32767 */
866 : exp_gcode0 = sub( exp_gcode0, 14 );
867 :
868 : /* retrieve the codebook index and calculate both gains */
869 : index = (Word16) get_next_indice_fx( st_fx, nBits );
870 : move16();
871 :
872 : *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/
873 : move16();
874 :
875 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
876 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/
877 : move32();
878 : gc_mem[2] = *gain_code_fx; /*Q16*/
879 : move32();
880 : gp_mem[2] = *gain_pit_fx; /*Q14*/
881 : move16();
882 : }
883 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
884 : {
885 : b_fx = b_4sfr_fx; /*Q12*/
886 : n_pred = 8;
887 : move16();
888 :
889 :
890 : cdbk_fx = gp_gamma_4sfr_6b_fx; /*Q14*/
891 : #ifdef IVAS_GAIN_MOD
892 : IF( EQ_16( nBits, 7 ) )
893 : {
894 : cdbk_fx = gp_gamma_4sfr_7b_fx;
895 : PMT( "verify if gp_gamma_4sfr_7b_fx is correct" )
896 : }
897 : #endif
898 :
899 : /* calculate predicted gain */
900 : aux_fx[0] = 4096; /*Q12*/
901 : move16();
902 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
903 : move16();
904 :
905 : /*aux[2] = (float)log10(gc_mem[0]);
906 : = log2(gc_mem[0])*log10(2);*/
907 : e_tmp = norm_l( gc_mem[0] );
908 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
909 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
910 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
911 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
912 : move16();
913 :
914 : /*aux[3] = (float)log10(gc_mem[1]);
915 : = log2(gc_mem[1])*log10(2);*/
916 : e_tmp = norm_l( gc_mem[1] );
917 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
918 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
919 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
920 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
921 : move16();
922 :
923 : /*aux[4] = (float)log10(gc_mem[2]);
924 : = log2(gc_mem[2])*log10(2);*/
925 : e_tmp = norm_l( gc_mem[2] );
926 : f_tmp = Log2_norm_lc( L_shl( gc_mem[2], e_tmp ) ); /*Q15*/
927 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[2])=16*/
928 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
929 : aux_fx[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
930 : move16();
931 :
932 : aux_fx[5] = shr( gp_mem[0], 2 ); /*Q12*/
933 : move16();
934 : aux_fx[6] = shr( gp_mem[1], 2 ); /*Q12*/
935 : move16();
936 : aux_fx[7] = shr( gp_mem[2], 2 ); /*Q12*/
937 : move16();
938 :
939 : /*-----------------------------------------------------------------*
940 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
941 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
942 : *-----------------------------------------------------------------*/
943 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
944 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
945 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
946 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
947 :
948 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
949 : /* output of Pow2() will be: */
950 : /* 16384 < Pow2() <= 32767 */
951 : exp_gcode0 = sub( exp_gcode0, 14 );
952 :
953 : /* retrieve the codebook index and calculate both gains */
954 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
955 : move16();
956 : *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/
957 : move16();
958 :
959 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
960 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
961 : move32();
962 : }
963 :
964 : /* *norm_gain_code = *gain_code / *gain_inov; */
965 : expg = sub( norm_s( *gain_inov_fx ), 1 );
966 : expg = s_max( expg, 0 );
967 :
968 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); /*Q15*/
969 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q16*/
970 : move32();
971 :
972 : return;
973 : }
974 : #endif
975 16448 : void gain_dec_lbr_ivas_fx(
976 : Decoder_State *st_fx, /* i/o: decoder state structure */
977 : const Word16 coder_type, /* i : coding type */
978 : const Word16 i_subfr, /* i : subframe index */
979 : const Word16 *code_fx, /* i : algebraic excitation Q9 */
980 : Word16 *gain_pit_fx, /* o : quantized pitch gain Q14*/
981 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
982 : Word16 *gain_inov_fx, /* o : gain of the innovation (used for normalization) Q12*/
983 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/
984 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
985 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
986 : const Word16 L_subfr /* i : subfr lenght */
987 : )
988 : {
989 : Word16 index, nBits, n_pred, ctype;
990 : Word16 gcode0_fx, aux_fx[10];
991 : Word32 L_tmp, L_tmp1, L_tmp2;
992 : Word16 expg, expg2, e_tmp, exp_gcode0, f_tmp, frac, tmp_fx;
993 16448 : const Word16 *b_fx, *cdbk_fx = 0;
994 : /* Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
995 : *gain_inov = 1.0f / (float)sqrt(Ecode); */
996 : Word16 shift_L_subfr;
997 16448 : shift_L_subfr = 6;
998 16448 : move16(); // for *cdbk_fx
999 16448 : move16();
1000 16448 : if ( GT_16( L_subfr, L_SUBFR ) )
1001 : {
1002 3644 : shift_L_subfr = add( shift_L_subfr, 1 );
1003 : }
1004 16448 : L_tmp = Dot_product12( code_fx, code_fx, L_subfr, &expg ); /*Q31 - expg*/
1005 16448 : expg = sub( expg, add( 18, shift_L_subfr ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1006 :
1007 16448 : expg2 = expg;
1008 16448 : move16();
1009 16448 : L_tmp2 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1010 16448 : move32();
1011 16448 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
1012 :
1013 16448 : *gain_inov_fx = extract_h( L_shl_sat( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
1014 16448 : move16();
1015 :
1016 : /*-----------------------------------------------------------------*
1017 : * select the codebook, size and number of bits
1018 : * set the gains searching range
1019 : *-----------------------------------------------------------------*/
1020 16448 : nBits = st_fx->acelp_cfg.gains_mode[shr( i_subfr, shift_L_subfr )];
1021 16448 : move16();
1022 :
1023 16448 : ctype = shl( sub( coder_type, 1 ), 1 );
1024 :
1025 : /*-----------------------------------------------------------------*
1026 : * calculate prediction of gcode
1027 : * search for the best codeword
1028 : *-----------------------------------------------------------------*/
1029 16448 : test();
1030 16448 : IF( i_subfr == 0 )
1031 : {
1032 5023 : b_fx = b_1sfr_fx; /*Q12*/
1033 5023 : move16();
1034 5023 : n_pred = 2;
1035 5023 : move16();
1036 5023 : cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14*/
1037 5023 : SWITCH( nBits )
1038 : {
1039 2027 : case 8:
1040 : {
1041 2027 : cdbk_fx = gp_gamma_1sfr_8b_fx; /* Q14/Q9*/
1042 2027 : BREAK;
1043 : }
1044 430 : case 7:
1045 : {
1046 430 : cdbk_fx = gp_gamma_1sfr_7b_fx; /* Q14/Q9*/
1047 430 : BREAK;
1048 : }
1049 2566 : case 6:
1050 : {
1051 2566 : cdbk_fx = gp_gamma_1sfr_6b_fx; /* Q14/Q9*/
1052 2566 : BREAK;
1053 : }
1054 : }
1055 :
1056 : /* calculate predicted gain */
1057 5023 : aux_fx[0] = 4096; /*Q12*/
1058 5023 : move16();
1059 5023 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
1060 5023 : move16();
1061 :
1062 : /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
1063 : gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
1064 : gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
1065 :
1066 5023 : e_tmp = norm_l( L_tmp2 );
1067 5023 : f_tmp = Log2_norm_lc( L_shl( L_tmp2, e_tmp ) ); /*Q15*/
1068 5023 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1069 5023 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1070 :
1071 5023 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
1072 5023 : L_tmp = Mult_32_16( L_tmp, 160 ); /*Q13, 20 in Q3*/
1073 5023 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q13*/
1074 :
1075 5023 : gcode0_fx = round_fx( L_shl( L_tmp, 11 ) ); /* Q8 */
1076 :
1077 :
1078 : /*-----------------------------------------------------------------*
1079 : * gcode0 = pow(10.0, gcode0/20)
1080 : * = pow(2, 3.321928*gcode0/20)
1081 : * = pow(2, 0.166096*gcode0)
1082 : *-----------------------------------------------------------------*/
1083 :
1084 5023 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1085 5023 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1086 5023 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1087 :
1088 5023 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1089 : /* output of Pow2() will be: */
1090 : /* 16384 < Pow2() <= 32767 */
1091 5023 : exp_gcode0 = sub( exp_gcode0, 14 );
1092 :
1093 : /* retrieve the codebook index and calculate both gains */
1094 : /*index = (Word16)get_indice( st_fx,"gain", i_subfr, ACELP_CORE);move16();*/
1095 5023 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
1096 5023 : move16();
1097 :
1098 5023 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
1099 5023 : move16();
1100 :
1101 5023 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
1102 5023 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
1103 5023 : move16();
1104 :
1105 5023 : gc_mem[0] = *gain_code_fx; /*Q16*/
1106 5023 : move32();
1107 5023 : gp_mem[0] = *gain_pit_fx; /*Q14*/
1108 5023 : move16();
1109 : }
1110 11425 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
1111 : {
1112 5023 : b_fx = b_2sfr_fx; /*Q12*/
1113 5023 : move16();
1114 5023 : n_pred = 4;
1115 5023 : move16();
1116 :
1117 5023 : cdbk_fx = gp_gamma_1sfr_6b_fx; /*Q14*/
1118 5023 : SWITCH( nBits )
1119 : {
1120 2026 : case 7:
1121 : {
1122 2026 : cdbk_fx = gp_gamma_2sfr_7b_fx; /* Q14/Q9*/
1123 2026 : BREAK;
1124 : }
1125 2997 : case 6:
1126 : {
1127 2997 : cdbk_fx = gp_gamma_2sfr_6b_fx; /* Q14/Q9*/
1128 2997 : BREAK;
1129 : }
1130 : }
1131 :
1132 : /* calculate predicted gain */
1133 5023 : aux_fx[0] = 4096; /*Q12*/
1134 5023 : move16();
1135 5023 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
1136 5023 : move16();
1137 :
1138 : /*aux_fx[2] = (float)log10(gc_mem[0]);
1139 : = log2(gc_mem[0])*log10(2);*/
1140 5023 : e_tmp = norm_l( gc_mem[0] );
1141 5023 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
1142 5023 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
1143 5023 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1144 5023 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1145 5023 : move16();
1146 :
1147 5023 : aux_fx[3] = shr( gp_mem[0], 2 ); /*Q12*/
1148 5023 : move16();
1149 :
1150 : /*-----------------------------------------------------------------*
1151 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1152 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1153 : *-----------------------------------------------------------------*/
1154 5023 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
1155 5023 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1156 5023 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1157 5023 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1158 :
1159 5023 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1160 : /* output of Pow2() will be: */
1161 : /* 16384 < Pow2() <= 32767 */
1162 5023 : exp_gcode0 = sub( exp_gcode0, 14 );
1163 :
1164 : /* retrieve the codebook index and calculate both gains */
1165 5023 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
1166 5023 : move16();
1167 :
1168 5023 : *gain_pit_fx = cdbk_fx[index * 2]; /*Q14*/
1169 5023 : move16();
1170 :
1171 5023 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
1172 5023 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
1173 5023 : move16();
1174 :
1175 5023 : gc_mem[1] = *gain_code_fx; /*Q16*/
1176 5023 : move32();
1177 5023 : gp_mem[1] = *gain_pit_fx; /*Q14*/
1178 5023 : move16();
1179 : }
1180 6402 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1181 : {
1182 3201 : b_fx = b_3sfr_fx; /*Q12*/
1183 3201 : move16();
1184 3201 : n_pred = 6;
1185 3201 : move16();
1186 :
1187 3201 : cdbk_fx = gp_gamma_3sfr_6b_fx; /*Q14/Q9 */
1188 :
1189 3201 : if ( EQ_16( nBits, 7 ) )
1190 : {
1191 2 : cdbk_fx = gp_gamma_3sfr_7b_fx; /*Q14*/
1192 : // PMT("verify if gp_gamma_3sfr_7b_fx is correct")
1193 : }
1194 :
1195 : /* calculate predicted gain */
1196 3201 : aux_fx[0] = 4096; /*Q12*/
1197 3201 : move16();
1198 3201 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
1199 3201 : move16();
1200 :
1201 : /*aux_fx[2] = (float)log10(gc_mem[0]);
1202 : = log2(gc_mem[0])*log10(2);*/
1203 3201 : e_tmp = norm_l( gc_mem[0] );
1204 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
1205 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
1206 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1207 3201 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1208 3201 : move16();
1209 :
1210 : /*aux[3] = (float)log10(gc_mem[1]);
1211 : = log2(gc_mem[1])*log10(2);*/
1212 3201 : e_tmp = norm_l( gc_mem[1] );
1213 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
1214 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
1215 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1216 3201 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1217 3201 : move16();
1218 :
1219 3201 : aux_fx[4] = shr( gp_mem[0], 2 ); /*Q12*/
1220 3201 : move16();
1221 3201 : aux_fx[5] = shr( gp_mem[1], 2 ); /*Q12*/
1222 3201 : move16();
1223 :
1224 : /*-----------------------------------------------------------------*
1225 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1226 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1227 : *-----------------------------------------------------------------*/
1228 3201 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
1229 3201 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1230 3201 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1231 3201 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1232 :
1233 3201 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1234 : /* output of Pow2() will be: */
1235 : /* 16384 < Pow2() <= 32767 */
1236 3201 : exp_gcode0 = sub( exp_gcode0, 14 );
1237 :
1238 : /* retrieve the codebook index and calculate both gains */
1239 3201 : index = (Word16) get_next_indice_fx( st_fx, nBits ); /*Q0*/
1240 3201 : move16();
1241 :
1242 3201 : *gain_pit_fx = cdbk_fx[( index * 2 )];
1243 3201 : move16();
1244 :
1245 3201 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
1246 3201 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16*/
1247 3201 : move32();
1248 3201 : gc_mem[2] = *gain_code_fx; /*Q16*/
1249 3201 : move32();
1250 3201 : gp_mem[2] = *gain_pit_fx; /*Q14*/
1251 3201 : move16();
1252 : }
1253 3201 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1254 : {
1255 3201 : b_fx = b_4sfr_fx; /*Q12*/
1256 3201 : n_pred = 8;
1257 3201 : move16();
1258 :
1259 :
1260 3201 : cdbk_fx = gp_gamma_4sfr_6b_fx; /*Q14*/
1261 :
1262 3201 : IF( EQ_16( nBits, 7 ) )
1263 : {
1264 0 : cdbk_fx = gp_gamma_4sfr_7b_fx; /*Q14*/
1265 : // PMT( "verify if gp_gamma_4sfr_7b_fx is correct" )
1266 : }
1267 :
1268 : /* calculate predicted gain */
1269 3201 : aux_fx[0] = 4096; /*Q12*/
1270 3201 : move16();
1271 3201 : aux_fx[1] = shl( ctype, 12 ); /*Q12*/
1272 3201 : move16();
1273 :
1274 : /*aux[2] = (float)log10(gc_mem[0]);
1275 : = log2(gc_mem[0])*log10(2);*/
1276 3201 : e_tmp = norm_l( gc_mem[0] );
1277 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[0], e_tmp ) ); /*Q15*/
1278 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[0])=16*/
1279 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1280 3201 : aux_fx[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1281 3201 : move16();
1282 :
1283 : /*aux[3] = (float)log10(gc_mem[1]);
1284 : = log2(gc_mem[1])*log10(2);*/
1285 3201 : e_tmp = norm_l( gc_mem[1] );
1286 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[1], e_tmp ) ); /*Q15*/
1287 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[1])=16*/
1288 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1289 3201 : aux_fx[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1290 3201 : move16();
1291 :
1292 : /*aux[4] = (float)log10(gc_mem[2]);
1293 : = log2(gc_mem[2])*log10(2);*/
1294 3201 : e_tmp = norm_l( gc_mem[2] );
1295 3201 : f_tmp = Log2_norm_lc( L_shl( gc_mem[2], e_tmp ) ); /*Q15*/
1296 3201 : e_tmp = sub( sub( 30, e_tmp ), 16 ); /*Q_format(gc_mem[2])=16*/
1297 3201 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */
1298 3201 : aux_fx[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1299 3201 : move16();
1300 :
1301 3201 : aux_fx[5] = shr( gp_mem[0], 2 ); /*Q12*/
1302 3201 : move16();
1303 3201 : aux_fx[6] = shr( gp_mem[1], 2 ); /*Q12*/
1304 3201 : move16();
1305 3201 : aux_fx[7] = shr( gp_mem[2], 2 ); /*Q12*/
1306 3201 : move16();
1307 :
1308 : /*-----------------------------------------------------------------*
1309 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1310 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1311 : *-----------------------------------------------------------------*/
1312 3201 : L_tmp = Dot_product( b_fx, aux_fx, n_pred ); /*Q25*/
1313 3201 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1314 3201 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1315 3201 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1316 :
1317 3201 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1318 : /* output of Pow2() will be: */
1319 : /* 16384 < Pow2() <= 32767 */
1320 3201 : exp_gcode0 = sub( exp_gcode0, 14 );
1321 :
1322 : /* retrieve the codebook index and calculate both gains */
1323 3201 : index = (Word16) get_next_indice_fx( st_fx, nBits );
1324 3201 : move16();
1325 3201 : *gain_pit_fx = cdbk_fx[( index * 2 )]; /*Q14*/
1326 3201 : move16();
1327 :
1328 3201 : L_tmp = L_mult( cdbk_fx[( ( index * 2 ) + 1 )], gcode0_fx ); /* Q9*Q0 -> Q10 */
1329 3201 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /*Q16*/
1330 3201 : move32();
1331 : }
1332 :
1333 : /* *norm_gain_code = *gain_code / *gain_inov; */
1334 16448 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1335 16448 : expg = s_max( expg, 0 );
1336 :
1337 16448 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); /*Q15*/
1338 16448 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); /*Q15*/
1339 16448 : move32();
1340 :
1341 16448 : return;
1342 : }
1343 :
1344 : /*====================================================================== */
1345 : /* FUNCTION : lp_gain_updt_fx() */
1346 : /*-----------------------------------------------------------------------*/
1347 : /* PURPOSE : Update of LP pitch and code gains (FEC) */
1348 : /* */
1349 : /*-----------------------------------------------------------------------*/
1350 : /* INPUT ARGUMENTS : */
1351 : /* _ (Word16) i_subfr : subframe number Q0 */
1352 : /* _ (Word16) gain_pit : Decoded gain pitch Q14 */
1353 : /* _ (Word32) norm_gain_code : Normalised gain code Q16 */
1354 : /* _ (Word16) L_frame : length of the frame Q0 */
1355 : /*-----------------------------------------------------------------------*/
1356 : /* OUTPUT ARGUMENTS : */
1357 : /* _ (Word16 *) T0 : close loop integer pitch */
1358 : /* _ (Word16 *) T0_frac : close loop fractional part of the pitch */
1359 : /* _ (Word16 ) pitch : pitch value Q6 */
1360 : /*-----------------------------------------------------------------------*/
1361 : /* INPUT OUTPUT ARGUMENTS */
1362 : /* _ (Word16 *) lp_gainp : LP-filtered pitch gain(FEC) Q14 */
1363 : /* _ (Word16 *) lp_gainc : LP-filtered code gain (FEC) Q3 */
1364 : /*-----------------------------------------------------------------------*/
1365 :
1366 : /*-----------------------------------------------------------------------*/
1367 : /* RETURN ARGUMENTS : */
1368 : /* _ None */
1369 : /*=======================================================================*/
1370 :
1371 :
1372 6337 : void lp_gain_updt_fx(
1373 : const Word16 i_subfr, /* i : subframe number Q0 */
1374 : const Word16 gain_pit, /* i : Decoded gain pitch Q14 */
1375 : const Word32 norm_gain_code, /* i : Normalised gain code Q16 */
1376 : Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */
1377 : Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */
1378 : const Word16 L_frame /* i : length of the frame */
1379 : )
1380 : {
1381 : Word16 tmp;
1382 :
1383 6337 : tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/
1384 6337 : IF( EQ_16( L_frame, L_FRAME ) )
1385 : {
1386 2992 : IF( EQ_16( i_subfr, 0 ) )
1387 : {
1388 748 : *lp_gainp = mult( 3277, gain_pit );
1389 748 : move16(); /*0.1 in Q15 = 3277 , (15+14)-15 -> Q14*/
1390 748 : *lp_gainc = mult_r( 3277, tmp );
1391 748 : move16(); /* (15+3)-15 -> Q3*/
1392 : }
1393 2244 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1394 : {
1395 748 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1396 748 : move16(); /*Q14 (0.2 in Q15 = 6554)*/
1397 748 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1398 748 : move16(); /*Q3*/
1399 : }
1400 1496 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1401 : {
1402 748 : *lp_gainp = add( *lp_gainp, mult( 9830, gain_pit ) );
1403 748 : move16(); /*Q14 (0.3 in Q15 = 9830)*/
1404 748 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 9830, tmp );
1405 748 : move16(); /*Q3*/
1406 : }
1407 : ELSE /* i_subfr == 3*L_SUBFR */
1408 : {
1409 748 : *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) );
1410 748 : move16(); /*Q14 (0.4 in Q15 = 13107)*/
1411 748 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp );
1412 748 : move16(); /*Q3*/
1413 : }
1414 : }
1415 : ELSE
1416 : {
1417 3345 : IF( i_subfr == 0 )
1418 : {
1419 669 : *lp_gainp = mult( 2185, gain_pit );
1420 669 : move16(); /*(1.0/15.0) in Q15 = 2185 , (15+14)-15 -> Q14*/
1421 669 : *lp_gainc = mult_r( 2185, tmp );
1422 669 : move16(); /* (15+3)-15 -> Q3*/
1423 : }
1424 2676 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1425 : {
1426 669 : *lp_gainp = add( *lp_gainp, mult( 4369, gain_pit ) );
1427 669 : move16(); /*Q14 (2.0/15.0 in Q15 = 4369)*/
1428 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 4369, tmp );
1429 669 : move16(); /*Q3*/
1430 : }
1431 2007 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1432 : {
1433 669 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1434 669 : move16(); /*Q14 (3.0/15.0 in Q15 = 6554)*/
1435 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1436 669 : move16(); /*Q3*/
1437 : }
1438 1338 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1439 : {
1440 669 : *lp_gainp = add( *lp_gainp, mult( 8738, gain_pit ) );
1441 669 : move16(); /*Q14 (4.0/15.0 in Q15 = 8738)*/
1442 669 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 8738, tmp );
1443 669 : move16(); /*Q3*/
1444 : }
1445 : ELSE /* i_subfr == 4*L_SUBFR */
1446 : {
1447 669 : *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) );
1448 669 : move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/
1449 669 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp );
1450 669 : move16(); /*Q3*/
1451 : }
1452 : }
1453 6337 : return;
1454 : }
1455 :
1456 : /*====================================================================== */
1457 : /* FUNCTION : lp_gain_updt_ivas_fx() */
1458 : /*-----------------------------------------------------------------------*/
1459 : /* PURPOSE : Update of LP pitch and code gains (FEC) */
1460 : /* */
1461 : /*-----------------------------------------------------------------------*/
1462 : /* INPUT ARGUMENTS : */
1463 : /* _ (Word16) i_subfr : subframe number Q0 */
1464 : /* _ (Word16) gain_pit : Decoded gain pitch Q14 */
1465 : /* _ (Word32) norm_gain_code : Normalised gain code Q16 */
1466 : /* _ (Word16) L_frame : length of the frame Q0 */
1467 : /*-----------------------------------------------------------------------*/
1468 : /* OUTPUT ARGUMENTS : */
1469 : /* _ (Word16 *) T0 : close loop integer pitch */
1470 : /* _ (Word16 *) T0_frac : close loop fractional part of the pitch */
1471 : /* _ (Word16 ) pitch : pitch value Q6 */
1472 : /*-----------------------------------------------------------------------*/
1473 : /* INPUT OUTPUT ARGUMENTS */
1474 : /* _ (Word16 *) lp_gainp : LP-filtered pitch gain(FEC) Q14 */
1475 : /* _ (Word16 *) lp_gainc : LP-filtered code gain (FEC) Q3 */
1476 : /*-----------------------------------------------------------------------*/
1477 :
1478 : /*-----------------------------------------------------------------------*/
1479 : /* RETURN ARGUMENTS : */
1480 : /* _ None */
1481 : /*=======================================================================*/
1482 :
1483 :
1484 548208 : void lp_gain_updt_ivas_fx(
1485 : const Word16 i_subfr, /* i : subframe number Q0 */
1486 : const Word16 gain_pit, /* i : Decoded gain pitch Q14 */
1487 : const Word32 norm_gain_code, /* i : Normalised gain code Q16 */
1488 : Word16 *lp_gainp, /* i/o: LP-filtered pitch gain(FEC) Q14 */
1489 : Word16 *lp_gainc, /* i/o: LP-filtered code gain (FEC) Q3 */
1490 : const Word16 L_frame /* i : length of the frame */
1491 : )
1492 : {
1493 : Word16 tmp;
1494 :
1495 548208 : tmp = extract_h( L_shl_sat( norm_gain_code, 3 ) ); /*(16+3)-16 -> Q3*/
1496 : /* To handle extremely low values */
1497 548208 : test();
1498 548208 : if ( norm_gain_code != 0 && tmp == 0 )
1499 : {
1500 940 : tmp = 1;
1501 940 : move16();
1502 : }
1503 :
1504 548208 : IF( EQ_16( L_frame, L_FRAME ) )
1505 : {
1506 230168 : IF( EQ_16( i_subfr, 0 ) )
1507 : {
1508 57542 : *lp_gainp = mult( 3277, gain_pit );
1509 57542 : move16(); /*0.1 in Q15 = 3277 , (15+14)-15 -> Q14*/
1510 57542 : *lp_gainc = mult_r( 3277, tmp );
1511 57542 : move16(); /* (15+3)-15 -> Q3*/
1512 : }
1513 172626 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1514 : {
1515 57542 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1516 57542 : move16(); /*Q14 (0.2 in Q15 = 6554)*/
1517 57542 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1518 57542 : move16(); /*Q3*/
1519 : }
1520 115084 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1521 : {
1522 57542 : *lp_gainp = add( *lp_gainp, mult( 9830, gain_pit ) );
1523 57542 : move16(); /*Q14 (0.3 in Q15 = 9830)*/
1524 57542 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 9830, tmp );
1525 57542 : move16(); /*Q3*/
1526 : }
1527 : ELSE /* i_subfr == 3*L_SUBFR */
1528 : {
1529 57542 : *lp_gainp = add( *lp_gainp, mult( 13107, gain_pit ) );
1530 57542 : move16(); /*Q14 (0.4 in Q15 = 13107)*/
1531 57542 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 13107, tmp );
1532 57542 : move16(); /*Q3*/
1533 : }
1534 : }
1535 : ELSE
1536 : {
1537 318040 : IF( i_subfr == 0 )
1538 : {
1539 63608 : *lp_gainp = mult( 2185, gain_pit );
1540 63608 : move16(); /*(1.0/15.0) in Q15 = 2185 , (15+14)-15 -> Q14*/
1541 63608 : *lp_gainc = mult_r( 2185, tmp );
1542 63608 : move16(); /* (15+3)-15 -> Q3*/
1543 : }
1544 254432 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) )
1545 : {
1546 63608 : *lp_gainp = add( *lp_gainp, mult( 4369, gain_pit ) );
1547 63608 : move16(); /*Q14 (2.0/15.0 in Q15 = 4369)*/
1548 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 4369, tmp );
1549 63608 : move16(); /*Q3*/
1550 : }
1551 190824 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1552 : {
1553 63608 : *lp_gainp = add( *lp_gainp, mult( 6554, gain_pit ) );
1554 63608 : move16(); /*Q14 (3.0/15.0 in Q15 = 6554)*/
1555 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 6554, tmp );
1556 63608 : move16(); /*Q3*/
1557 : }
1558 127216 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1559 : {
1560 63608 : *lp_gainp = add( *lp_gainp, mult( 8738, gain_pit ) );
1561 63608 : move16(); /*Q14 (4.0/15.0 in Q15 = 8738)*/
1562 63608 : *lp_gainc = mac_r( L_deposit_h( *lp_gainc ), 8738, tmp );
1563 63608 : move16(); /*Q3*/
1564 : }
1565 : ELSE /* i_subfr == 4*L_SUBFR */
1566 : {
1567 63608 : *lp_gainp = add( *lp_gainp, mult( 10923, gain_pit ) );
1568 63608 : move16(); /*Q14 (5.0/15.0 in Q15 = 10923)*/
1569 63608 : *lp_gainc = mac_r_sat( L_deposit_h( *lp_gainc ), 10923, tmp );
1570 63608 : move16(); /*Q3*/
1571 : }
1572 : }
1573 :
1574 : /* To handle extremely low values */
1575 548208 : test();
1576 548208 : if ( tmp != 0 && *lp_gainc == 0 )
1577 : {
1578 2270 : *lp_gainc = 1;
1579 2270 : move16();
1580 : }
1581 :
1582 548208 : return;
1583 : }
1584 :
1585 : /*-------------------------------------------------*
1586 : * Gain_dec_gaus_vbr
1587 : *
1588 : * Decode gains of purely unvoiced sounds
1589 : *-------------------------------------------------*/
1590 0 : Word32 gain_dec_gaus_fx( /* o : quantized codebook gain Q16 */
1591 : Word16 index, /* i : quantization index */
1592 : const Word16 bits, /* i : number of bits to quantize */
1593 : const Word16 lowBound, /* i : lower bound of quantizer (dB) */
1594 : const Word16 topBound, /* i : upper bound of quantizer (dB) */
1595 : const Word16 inv_gain_inov, /* o : unscaled innovation gain Q12 */
1596 : Word32 *L_norm_gain_code /* o : gain of normalized gaussian excitation Q16 */
1597 : )
1598 : {
1599 : Word16 stepSize, gain, expg, frac, expi, tmp_igi;
1600 : Word32 L_tmp, L_enr_q, L_gain;
1601 : Word16 stepSize_Exp;
1602 0 : stepSize_Exp = 14;
1603 0 : move16();
1604 : /*------------------------------------------------------------------------------------------*
1605 : * Quantize linearly the log E
1606 : *------------------------------------------------------------------------------------------*/
1607 :
1608 0 : if ( EQ_16( bits, 6 ) )
1609 : {
1610 0 : stepSize_Exp = sub( stepSize_Exp, 1 );
1611 : }
1612 0 : stepSize = shl( sub( topBound, lowBound ), sub( stepSize_Exp, bits ) ); /* QstepSize_Exp */
1613 :
1614 : /*------------------------------------------------------------------------------------------*
1615 : * Gaussian codebook gain
1616 : *------------------------------------------------------------------------------------------*/
1617 :
1618 : /* enr_q = (float)index*stepSize ,lowBound); */
1619 0 : L_enr_q = L_mult( index, stepSize ); /* Q0 * QstepSize_Exp -> QstepSize_Exp+1 */
1620 0 : L_enr_q = L_shl( L_enr_q, sub( 24 - 1, stepSize_Exp ) ); /* QstepSize_Exp+1 -> Q24 */
1621 0 : L_enr_q = L_add( L_enr_q, L_shl( L_deposit_h( lowBound ), 8 ) ); /* Q24 */
1622 : /*------------------------------------------------------------*
1623 : * gain = pow(10.0, enr/20)
1624 : * = pow(2, 3.321928*enr/20)
1625 : * = pow(2, 0.166096*enr)
1626 : *------------------------------------------------------------*/
1627 :
1628 : /* gain = (float)pow( 10.0f, enr/20.0f ); quantized codebook gain */
1629 0 : L_tmp = Mult_32_16( L_enr_q, 21771 ); /* *0.166096 in Q17 -> Q26 */
1630 0 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1631 0 : frac = L_Extract_lc( L_tmp, &expg ); /* Extract exponent of enr */
1632 0 : L_gain = Pow2( 30, frac ); /* Put 30 as exponent so that the */
1633 0 : expg = add( expg, 16 - 30 ); /* output of Pow2() will be */
1634 : /* Normalized, set result in Q16 */
1635 0 : gain = round_fx( L_gain );
1636 0 : L_gain = L_shl_sat( L_gain, expg ); /* In Q16*/
1637 : /* *norm_gain_code = gain / *inv_gain_inov;*/
1638 0 : expi = norm_s( inv_gain_inov );
1639 0 : tmp_igi = shl( inv_gain_inov, expi );
1640 0 : L_tmp = div_s( shr( gain, 1 ), tmp_igi );
1641 0 : L_tmp = L_shl_sat( L_tmp, add( 1, expi ) );
1642 0 : *L_norm_gain_code = L_shl_sat( L_tmp, add( expg, 13 ) ); /* Q16 */
1643 0 : move32();
1644 :
1645 0 : return L_gain;
1646 : }
1647 :
1648 : /*--------------------------------------------------------------------------*
1649 : * gain_dec_SQ()
1650 : *
1651 : * Decoding of pitch and codebook gains using scalar quantizers
1652 : *-------------------------------------------------------------------------*/
1653 :
1654 40578 : void gain_dec_SQ_fx(
1655 : Decoder_State *st_fx, /* i/o: decoder state structure */
1656 : const Word16 i_subfr, /* i : subframe number */
1657 : const Word16 *code, /* i : algebraic code excitation Q9*/
1658 : const Word16 Es_pred, /* i : predicted scaled innov. energy Q8 */
1659 : Word16 *gain_pit, /* o : Quantized pitch gain Q14*/
1660 : Word32 *gain_code, /* o : Quantized codeebook gain Q16*/
1661 : Word16 *gain_inov, /* o : unscaled innovation gain Q12*/
1662 : Word32 *norm_gain_code /* o : norm. gain of the codebook excitation Q16*/
1663 : )
1664 : {
1665 : Word16 index, nBits;
1666 : Word16 gcode0, Ei;
1667 : Word16 tmp16, expg, expg2, e_tmp, f_tmp, exp_gcode0, frac;
1668 : Word32 L_tmp, L_tmp1;
1669 :
1670 : /*-----------------------------------------------------------------*
1671 : * get number of bits
1672 : *-----------------------------------------------------------------*/
1673 :
1674 40578 : nBits = st_fx->acelp_cfg.gains_mode[( i_subfr / 64 )];
1675 40578 : move16();
1676 :
1677 : /*-----------------------------------------------------------------*
1678 : * decode pitch gain
1679 : *-----------------------------------------------------------------*/
1680 :
1681 40578 : index = (Word16) get_next_indice_fx( st_fx, shr( nBits, 1 ) );
1682 40578 : move16();
1683 :
1684 : /*Ei = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << (nBits>>1)) - 1); set quantization step */
1685 40578 : tmp16 = div_s( 1, sub( shl( 1, shr( nBits, 1 ) ), 1 ) ); /* Q15*/
1686 40578 : Ei = mult_r( G_PITCH_MAX_MINUS_MIN_Q13, tmp16 ); /* Q13*/
1687 :
1688 : /**gain_pit = usdequant( index, G_PITCH_MIN, Ei );*/
1689 40578 : *gain_pit = usdequant_fx( index, G_PITCH_MIN_Q14, Ei );
1690 40578 : move16(); /*Q14 */
1691 :
1692 : /*-----------------------------------------------------------------*
1693 : * calculate the predicted gain code
1694 : *-----------------------------------------------------------------*/
1695 :
1696 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
1697 : /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
1698 :
1699 40578 : L_tmp = Dot_product12( code, code, L_SUBFR, &expg );
1700 40578 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1701 40578 : expg2 = expg;
1702 40578 : move16();
1703 40578 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1704 40578 : move32();
1705 40578 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
1706 :
1707 40578 : *gain_inov = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
1708 40578 : move16();
1709 :
1710 : /*Ei = 10 * (float)log10( Ecode );*/
1711 40578 : e_tmp = norm_l( L_tmp1 );
1712 40578 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1713 40578 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1714 40578 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1715 40578 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1716 :
1717 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1718 40578 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
1719 :
1720 : /* gcode0 = pow(10.0, gcode0/20) = pow(2, 3.321928*gcode0/20) = pow(2, 0.166096*gcode0) */
1721 40578 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
1722 40578 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1723 40578 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1724 :
1725 40578 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that output of Pow2() will be: 16384 < Pow2() <= 32767 */
1726 40578 : exp_gcode0 = sub( exp_gcode0, 14 );
1727 :
1728 : /*-----------------------------------------------------------------*
1729 : * decode normalized codebook gain
1730 : *-----------------------------------------------------------------*/
1731 :
1732 40578 : index = (Word16) get_next_indice_fx( st_fx, shr( add( nBits, 1 ), 1 ) );
1733 40578 : move16();
1734 :
1735 40578 : tmp16 = gain_dequant_fx( index, G_CODE_MIN_TC_Q15, G_CODE_MAX_TC_Q0, shr( add( nBits, 1 ), 1 ), &expg );
1736 :
1737 : /**gain_code *= gcode0;*/
1738 40578 : L_tmp = L_mult( tmp16, gcode0 ); /* Q0*Q0 -> Q1*/
1739 : /**gain_code = L_shl(L_tmp,add(expg,15)); Q16*/
1740 40578 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1741 40578 : move32();
1742 :
1743 : /**norm_gain_code = *gain_code / *gain_inov;*/
1744 40578 : expg = sub( norm_s( *gain_inov ), 1 );
1745 40578 : expg = s_max( expg, 0 );
1746 :
1747 40578 : tmp16 = div_s( shr( 8192, expg ), *gain_inov ); /*Q15*/
1748 40578 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp16 ), sub( 1, expg ) ); /*Q16*/
1749 40578 : move32();
1750 :
1751 40578 : return;
1752 : }
1753 :
1754 : /*---------------------------------------------------------------------*
1755 : * gain_dec_amr_wb()
1756 : *
1757 : * Decoding of pitch and fixed codebook gains (used also in AMR-WB IO mode)
1758 : *---------------------------------------------------------------------*/
1759 :
1760 0 : void gain_dec_amr_wb_fx(
1761 : Decoder_State *st_fx, /* i/o: decoder state structure */
1762 : const Word32 core_brate, /* i : core bitrate */
1763 : Word16 *gain_pit, /* o : Quantized pitch gain Q14*/
1764 : Word32 *gain_code, /* o : Quantized codeebook gain Q16*/
1765 : Word16 *past_qua_en, /* i/o: gain quantization memory (4 words) Q10*/
1766 : Word16 *gain_inov, /* o : unscaled innovation gain Q12*/
1767 : const Word16 *code, /* i : algebraic code excitation Q9*/
1768 : Word32 *norm_gain_code /* o : norm. gain of the codebook excitation Q16*/
1769 : )
1770 : {
1771 : Word16 i, index, index2;
1772 : Word16 nbits;
1773 : Word16 gcode0, qua_en;
1774 : const Word16 *t_qua_gain;
1775 : Word16 tmp;
1776 : Word32 L_tmp;
1777 : Word16 expg, exp_gcode0, fracg;
1778 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1779 0 : Flag Overflow = 0;
1780 0 : move32();
1781 : #endif
1782 :
1783 :
1784 : /**gain_inov = 1.0f/ (float)sqrt( ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR );*/
1785 :
1786 0 : L_tmp = Dot_product12( code, code, L_SUBFR, &expg ); /*Q31 - expg*/
1787 0 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1788 0 : L_tmp = Isqrt_lc( L_tmp, &expg ); /*Q31 - expg*/
1789 :
1790 0 : *gain_inov = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); /* gain_inov in Q12 */
1791 0 : move16();
1792 :
1793 : /*-----------------------------------------------------------------*
1794 : * Select the gain quantization table
1795 : *-----------------------------------------------------------------*/
1796 0 : nbits = 7;
1797 0 : move16();
1798 0 : t_qua_gain = t_qua_gain7b_fx;
1799 :
1800 0 : if ( LT_32( core_brate, ACELP_12k65 ) )
1801 : {
1802 0 : nbits = 6;
1803 0 : move16();
1804 0 : t_qua_gain = t_qua_gain6b_fx;
1805 : }
1806 :
1807 : /*-----------------------------------------------------------------*
1808 : * predicted code gain
1809 : *-----------------------------------------------------------------*/
1810 :
1811 : /* start with predicting code energy in dB */
1812 : /**for (i=0; i<GAIN_PRED_ORDER; i++) {gcode0 += pred_gain[i] * past_qua_en[i];}*/
1813 : /*gcode0 += (float)(20.0 * log10( *gain_inov ) );*/
1814 : /* predicted energy */
1815 0 : L_tmp = L_deposit_h( MEAN_ENER ); /* MEAN_ENER in Q16 */
1816 0 : L_tmp = L_shl( L_tmp, 9 ); /* From Q16 to Q25 */
1817 :
1818 0 : FOR( i = 0; i < GAIN_PRED_ORDER; i++ )
1819 : {
1820 : /* pred_code += pred[i]*past_qua_en[i]; */
1821 0 : L_tmp = L_mac( L_tmp, pred_gain_fx[i], past_qua_en[i] ); /* Q14*Q10 -> Q25 */
1822 : }
1823 :
1824 : /* predicted codebook gain */
1825 0 : gcode0 = extract_h( L_tmp ); /* From Q25 to Q9 */
1826 :
1827 : /*-----------------------------------------------------------------*
1828 : * gcode0 = pow(10.0, gcode0/20)
1829 : * = pow(2, 3.321928*gcode0/20)
1830 : * = pow(2, 0.166096*gcode0)
1831 : *-----------------------------------------------------------------*/
1832 0 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q27 */
1833 0 : L_tmp = L_shr( L_tmp, 9 + 2 ); /* From Q27 to Q16 */
1834 0 : L_Extract( L_tmp, &exp_gcode0, &fracg ); /* Extract exponent of gcode0 */
1835 :
1836 0 : gcode0 = extract_l( Pow2( 14, fracg ) ); /* Put 14 as exponent so that */
1837 : /* output of Pow2() will be: */
1838 : /* 16384 < Pow2() <= 32767 */
1839 0 : exp_gcode0 = sub( exp_gcode0, 14 );
1840 :
1841 : /*-----------------------------------------------------------------*
1842 : * Decode pitch gain
1843 : *-----------------------------------------------------------------*/
1844 :
1845 0 : index = (Word16) get_next_indice_fx( st_fx, nbits );
1846 0 : move16();
1847 0 : index2 = shl( index, 1 );
1848 0 : *gain_pit = t_qua_gain[index2];
1849 0 : move16();
1850 :
1851 : /*-----------------------------------------------------------------*
1852 : * Decode code gain
1853 : *-----------------------------------------------------------------*/
1854 0 : qua_en = t_qua_gain[( index2 + 1 )];
1855 0 : move16();
1856 :
1857 : /* *gain_code = t_qua_gain[indice*2+1] * gcode0; */
1858 0 : L_tmp = L_mult( qua_en, gcode0 ); /* Q11*Q0 -> Q12 */
1859 0 : tmp = round_fx( L_tmp ); /* Q-4 */
1860 0 : *gain_code = L_shl( L_tmp, add( exp_gcode0, 4 ) ); /* Q12 -> Q16 */
1861 0 : move32();
1862 :
1863 : /* adjust gain according to energy of code */
1864 0 : L_tmp = Mult_32_16( *gain_code, *gain_inov );
1865 0 : *gain_code = L_shl_o( L_tmp, 3, &Overflow ); /* gcode_inov in Q12*/
1866 0 : move32();
1867 :
1868 : /*-----------------------------------------------------------------*
1869 : * update table of past quantized energies
1870 : *-----------------------------------------------------------------*/
1871 :
1872 0 : FOR( i = GAIN_PRED_ORDER - 1; i > 0; i-- )
1873 : {
1874 0 : past_qua_en[i] = past_qua_en[i - 1];
1875 0 : move16();
1876 : }
1877 : /*past_qua_en[0] = (float)(20.0*log10(qua_en));*/
1878 : /*----------------------------------------------------------*
1879 : * past_qua_en[0] = 20*log10(t_qua_gain[indice*2+1])
1880 : * = 6.0206*log2(t_qua_gain[indice*2+1])
1881 : * = 6.0206*(log2(t_qua_gain[indice*2+1]Q11 -11)
1882 : *----------------------------------------------------------*/
1883 0 : tmp = norm_l( qua_en );
1884 0 : fracg = Log2_norm_lc( L_shl( qua_en, tmp ) );
1885 0 : expg = sub( 30, tmp );
1886 0 : expg = sub( expg, 11 );
1887 0 : L_tmp = Mpy_32_16( expg, fracg, 24660 ); /* x 6.0206 in Q12 */
1888 0 : qua_en = extract_h( L_shl( L_tmp, 13 ) ); /* result in Q10 */
1889 :
1890 0 : past_qua_en[0] = qua_en;
1891 0 : move16(); /* in Q10 */
1892 :
1893 : /*-----------------------------------------------------------------*
1894 : * Normalized code gain
1895 : *-----------------------------------------------------------------*/
1896 : /**norm_gain_code = *gain_code / *gain_inov;*/
1897 0 : expg = sub( norm_s( *gain_inov ), 1 );
1898 0 : expg = s_max( expg, 0 );
1899 :
1900 0 : tmp = div_s( shr( 8192, expg ), *gain_inov ); /*Q15*/
1901 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, expg ) ); /*Q16*/
1902 0 : move32();
1903 :
1904 0 : return;
1905 : }
|