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