Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : #include "cnst.h" /* Common constants */
9 : #include "basop_util.h"
10 : #include "rom_com.h" /* Common constants */
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 : #include "basop_util.h" /* Function prototypes */
14 :
15 :
16 : static Word16 gain_enc( /* o : quantization pitch index <Q0> */
17 : const Word16 *code, /* i : algebraic excitation <Q9> */
18 : Word16 lcode, /* i : Subframe size in range: 40,64,80 <Q0> */
19 : Word16 *gain_pit, /* o : quantized pitch gain <Q16> */
20 : /* i/o : only func=1,coder_type=1 quantized pitch gain <Q16> */
21 : Word32 *gain_code, /* o : quantized codebook gain <Q16> */
22 : ACELP_CbkCorr *g_coeff, /* i : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
23 : Word16 mean_ener, /* i : only func=0: mean_ener defined in open-loop (3 bits) <Q8> */
24 : const Word16 clip_gain, /* i : only func=0,1: gain pitch clipping flag (1 = clipping) <Q0> */
25 : Word32 *past_gcode, /* o : past gain of code <Q16> */
26 : Word16 *gain_inov, /* o : Q12 innovation gain <Q12> */
27 : const Word16 coder_type, /* i : only func=0,1: coder type <Q0> */
28 : const Word16 func_type /* i : algorithm: 0=gain_enc_mless, 1=gain_enc_2 <Q0> */
29 : );
30 :
31 : /*-------------------------------------------------------------------------*
32 : * procedure q_gain2_plus *
33 : * ~~~~~~~~~~~~~~~~~~~~~~ *
34 : * Quantization of pitch and codebook gains. *
35 : * The following routines is Q_gains updated for AMR_WB_PLUS. *
36 : * MA prediction is removed and MEAN_ENER is now quantized with 2 bits and *
37 : * transmitted once every ACELP frame to the gains decoder. *
38 : * The pitch gain and the code gain are vector quantized and the *
39 : * mean-squared weighted error criterion is used in the quantizer search. *
40 : *-------------------------------------------------------------------------*/
41 3060 : void encode_acelp_gains_fx(
42 : Word16 *code,
43 : Word16 gains_mode,
44 : Word16 mean_ener_code,
45 : Word16 clip_gain,
46 : ACELP_CbkCorr *g_corr,
47 : Word16 *gain_pit,
48 : Word32 *gain_code,
49 : Word16 **pt_indice,
50 : Word32 *past_gcode,
51 : Word16 *gain_inov,
52 : Word16 L_subfr,
53 : Word16 *code2,
54 : Word32 *gain_code2,
55 : Word16 noisy_speech_flag /* i : noisy speech flag */
56 : )
57 : {
58 3060 : Word16 index = 0, func_type = 0;
59 3060 : move16();
60 3060 : move16();
61 :
62 : BASOP_SATURATE_ERROR_ON_EVS;
63 :
64 3060 : SWITCH( gains_mode )
65 : {
66 3060 : case 1:
67 : case 2:
68 : case 3:
69 : /* Memory-less gain coding */
70 3060 : gains_mode = sub( gains_mode, 1 );
71 3060 : func_type = FUNC_GAIN_ENC_MLESS;
72 3060 : move16();
73 3060 : BREAK;
74 0 : case 4:
75 : case 5:
76 0 : assert( 0 );
77 : BREAK;
78 0 : case 6:
79 : /* UV gains quantizer (6 bits/subfr) */
80 0 : gains_mode = sub( gains_mode, 6 );
81 0 : func_type = FUNC_GAIN_ENC_UV;
82 0 : move16();
83 0 : BREAK;
84 0 : case 7:
85 0 : gains_mode = sub( gains_mode, 7 );
86 0 : func_type = FUNC_GAIN_ENC_GACELP_UV;
87 0 : move16();
88 0 : BREAK;
89 0 : default:
90 0 : IVAS_ERROR( IVAS_ERR_INTERNAL, "invalid gains coding for acelp!" );
91 0 : func_type = 0;
92 0 : move16(); /*To avoid compiler warning*/
93 0 : BREAK;
94 : }
95 :
96 3060 : IF( func_type == FUNC_GAIN_ENC_MLESS )
97 : {
98 3060 : index = gain_enc( code, L_subfr, gain_pit, gain_code, g_corr, mean_ener_code,
99 : clip_gain, past_gcode, gain_inov, gains_mode, func_type );
100 : }
101 : ELSE
102 : {
103 0 : index = gain_enc_uv_fx( code, code2, L_subfr, gain_pit, gain_code, gain_code2,
104 : noisy_speech_flag, g_corr, mean_ener_code, past_gcode, gain_inov, func_type );
105 : }
106 :
107 3060 : move16();
108 3060 : **pt_indice = index;
109 3060 : ( *pt_indice )++;
110 :
111 : BASOP_SATURATE_ERROR_OFF_EVS;
112 3060 : }
113 :
114 : /*---------------------------------------------------------------------*
115 : * procedure gain_enc_mless
116 : * Quantization of pitch and codebook gains.
117 : * - an initial predicted gain, gcode0, is first determined based on
118 : * the predicted scaled innovation energy
119 : * - the correction factor gamma = g_code / gcode0 is then vector quantized
120 : * along with gain_pit
121 : * - the mean-squared weighted error criterion is used for the quantizer search
122 : *---------------------------------------------------------------------*/
123 :
124 3060 : static Word16 gain_enc( /* o : quantization pitch index <Q0> */
125 : const Word16 *code, /* i : algebraic excitation <Q9> */
126 : Word16 lcode, /* i : Subframe size in range: 40,64,80 <Q0> */
127 : Word16 *gain_pit, /* o : quantized pitch gain <Q16> */
128 : /* i/o : only func=1,coder_type=1 quantized pitch gain <Q16> */
129 : Word32 *gain_code, /* o : quantized codebook gain <Q16> */
130 : ACELP_CbkCorr *g_coeff, /* i : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
131 : Word16 mean_ener, /* i : only func=0: mean_ener defined in open-loop (3 bits) <Q8> */
132 : const Word16 clip_gain, /* i : only func=0,1: gain pitch clipping flag (1 = clipping) <Q0> */
133 : Word32 *past_gcode, /* o : past gain of code <Q16> */
134 : Word16 *gain_inov, /* o : Q12 innovation gain <Q12> */
135 : const Word16 coder_type, /* i : only func=0,1: coder type <Q0> */
136 : const Word16 func_type /* i : algorithm: 0=gain_enc_mless, 1=gain_enc_2 <Q0> */
137 : )
138 : {
139 : Word16 i, j, index, size, min_index, exp_L_tmp1;
140 : Word16 gcode0, gcode0_gi, exp_gcode0, exp_sum, exp_code, g_code_shl;
141 :
142 : Word16 g_code;
143 : Word16 coeff0, coeff1, coeff2, coeff3, coeff4, exp_coeff0, exp_coeff1, exp_coeff2, exp_coeff3, exp_coeff4;
144 : Word16 shr_coeff0, shr_coeff1, shr_coeff2, shr_coeff3, shr_coeff4;
145 : const Word16 *p;
146 : const Word16 *t_qua_gain;
147 : Word32 L_tmp, dist_min, L_tmp1;
148 :
149 3060 : assert( ( func_type != FUNC_GAIN_ENC_UV ) && ( func_type != FUNC_GAIN_ENC_GACELP_UV ) );
150 :
151 : /* Debug test value (not instrumented) */
152 3060 : gcode0 = -3000;
153 3060 : move16();
154 :
155 : /*----------------------------------------------------------------*
156 : * - calculate the unscaled innovation energy
157 : * - calculate the predicted gain code
158 : *----------------------------------------------------------------*/
159 :
160 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
161 3060 : L_tmp = calc_gain_inov( code, lcode, &L_tmp1, &exp_L_tmp1 );
162 3060 : move16();
163 3060 : *gain_inov = round_fx_sat( L_shl_sat( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
164 3060 : move16();
165 :
166 : /*----------------------------------------------------------------*
167 : * calculate the predicted gain code
168 : *----------------------------------------------------------------*/
169 :
170 3060 : IF( func_type == FUNC_GAIN_ENC_MLESS )
171 : {
172 : /*j = 10 * log10((dot_product(code, code, lcode) + 0.01) / lcode) */
173 3060 : j = BASOP_Util_lin2dB( L_tmp1, exp_L_tmp1, 1 ); /* Q8 */
174 :
175 : /* predicted codebook gain */
176 3060 : gcode0 = sub( mean_ener, j ); /* Q8 */
177 : }
178 :
179 : /*----------------------------------------------------------------*
180 : * Compute coefficients needed for the quantization.
181 : *
182 : * coeff[0] = yy1 yy1
183 : * coeff[1] = -2 xn yy1
184 : * coeff[2] = y2 y2
185 : * coeff[3] = -2 xn y2
186 : * coeff[4] = 2 yy1 y2
187 : *
188 : * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
189 : * are in vector g_coeff[].
190 : *----------------------------------------------------------------*/
191 :
192 3060 : coeff0 = g_coeff->y1y1;
193 3060 : move16();
194 3060 : exp_coeff0 = g_coeff->y1y1_e;
195 3060 : move16();
196 3060 : coeff2 = g_coeff->y2y2;
197 3060 : move16();
198 3060 : exp_coeff2 = g_coeff->y2y2_e;
199 3060 : move16();
200 :
201 3060 : coeff1 = g_coeff->xy1;
202 3060 : move16();
203 3060 : exp_coeff1 = add( g_coeff->xy1_e, 1 );
204 3060 : coeff3 = g_coeff->xy2;
205 3060 : move16();
206 3060 : exp_coeff3 = add( g_coeff->xy2_e, 1 );
207 3060 : coeff4 = g_coeff->y1y2;
208 3060 : move16();
209 3060 : exp_coeff4 = add( g_coeff->y1y2_e, 1 );
210 :
211 : /*---------------------------------------------------------------*
212 : * Decode codebook gain and the adaptive excitation low-pass
213 : * filtering factor (Finalize computation )
214 : *---------------------------------------------------------------*/
215 :
216 :
217 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
218 : /*----------------------------------------------------------------*
219 : * gcode0 = pow(10.0, gcode0/20) gcode in Q8
220 : * = pow(2, 3.321928*gcode0/20)
221 : * = pow(2, 0.166096*gcode0)
222 : *----------------------------------------------------------------*/
223 :
224 : /* Check if gcode0 was uninitialized. */
225 3060 : assert( gcode0 != -3000 );
226 :
227 3060 : L_tmp = L_mult( gcode0, 5443 /*0.166096f Q15*/ );
228 3060 : exp_gcode0 = add( 1, extract_l( L_shr( L_tmp, 24 ) ) );
229 3060 : L_tmp = L_lshl( L_tmp, 7 );
230 3060 : L_tmp = L_and( 0x7FFFFFFF, L_tmp );
231 :
232 3060 : L_tmp = Pow2( 30, round_fx( L_tmp ) );
233 3060 : gcode0 = round_fx( L_tmp );
234 : /* exponent of gcode0 = exp_gcode0 */
235 :
236 : /*-----------------------------------------------------------------*
237 : * gain quantization initializations
238 : * - find the initial quantization pitch index
239 : * - set the gains searching range
240 : *----------------------------------------------------------------*/
241 :
242 : /*----------------------------------------------------------------*
243 : * Find the best quantizer
244 : *
245 : * Before doing the computation we need to align exponents of coeff[]
246 : * to be sure to have the maximum precision.
247 : *
248 : * In the table the pitch gains are in Q14, the code gains are in Q11 and
249 : * are multiplied by gcode0 which have been multiplied by 2^exp_gcode0.
250 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
251 : * we divide by 2^15.
252 : * Considering all the scaling above we have:
253 : *
254 : * exp_code = exp_gcode0 + 4
255 : * if (func_type == gain_enc_2)
256 : * gcode0 *= gain_inov (in Q12) => exp_code += 3
257 : *
258 : * g_pitch*g_pitch = +1+1
259 : * g_pitch = +1
260 : * g_code*g_code = (2*exp_code)
261 : * g_code = exp_code
262 : * g_pitch*g_code = + 1 + exp_code
263 : *
264 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] + 2
265 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] + 1
266 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] + (2*exp_code)
267 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
268 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
269 : *----------------------------------------------------------------*/
270 :
271 3060 : exp_code = add( exp_gcode0, 4 );
272 :
273 3060 : exp_coeff0 = add( exp_coeff0, 2 );
274 3060 : exp_coeff1 = add( exp_coeff1, 1 );
275 3060 : exp_coeff2 = add( exp_coeff2, shl( exp_code, 1 ) );
276 3060 : exp_coeff3 = add( exp_coeff3, exp_code );
277 3060 : exp_coeff4 = add( exp_coeff4, add( 1, exp_code ) );
278 :
279 : /* Find maximum exponent */
280 3060 : exp_sum = s_max( exp_coeff1, exp_coeff0 );
281 3060 : exp_sum = s_max( exp_coeff2, exp_sum );
282 3060 : exp_sum = s_max( exp_coeff3, exp_sum );
283 3060 : exp_sum = s_max( exp_coeff4, exp_sum );
284 3060 : exp_sum = add( exp_sum, 2 );
285 :
286 : /* Align exponents of summands in loop far below. */
287 3060 : shr_coeff0 = sub( exp_sum, exp_coeff0 );
288 3060 : shr_coeff1 = sub( exp_sum, exp_coeff1 );
289 3060 : shr_coeff2 = sub( exp_sum, exp_coeff2 );
290 3060 : shr_coeff3 = sub( exp_sum, exp_coeff3 );
291 3060 : shr_coeff4 = sub( exp_sum, exp_coeff4 );
292 : /* Codebook search */
293 :
294 3060 : dist_min = L_deposit_h( MAX_16 );
295 :
296 3060 : min_index = 0;
297 3060 : move16();
298 :
299 : {
300 : Word16 size_clip;
301 :
302 :
303 3060 : IF( coder_type == 0 )
304 : {
305 :
306 0 : t_qua_gain = E_ROM_qua_gain5b_const;
307 0 : size_clip = 9;
308 0 : size = NB_QUA_GAIN5B;
309 : }
310 3060 : ELSE IF( coder_type == 1 )
311 : {
312 :
313 135 : t_qua_gain = E_ROM_qua_gain6b_const;
314 135 : size_clip = 6;
315 135 : size = NB_QUA_GAIN6B; /* searching range of the gain quantizer */
316 : }
317 : ELSE
318 : {
319 :
320 2925 : t_qua_gain = E_ROM_qua_gain7b_const;
321 2925 : size_clip = 21;
322 2925 : size = NB_QUA_GAIN7B;
323 : }
324 3060 : move16();
325 3060 : move16();
326 :
327 3060 : if ( EQ_16( clip_gain, 1 ) )
328 : {
329 0 : size = sub( size, size_clip ); /* limit pitch gain to 1.0 */
330 : }
331 3060 : gcode0_gi = gcode0;
332 3060 : move16();
333 : }
334 3060 : p = t_qua_gain;
335 :
336 3060 : index = 0;
337 3060 : move16();
338 :
339 : /* divide all coeff1,2,3,4 by coeff0 */
340 : /* in order to skip multiplication with coeff0 in loop */
341 3060 : assert( coeff0 >= 0x4000 );
342 3060 : coeff0 = div_s( 0x4000, coeff0 );
343 3060 : coeff1 = mult_r( coeff1, coeff0 );
344 3060 : coeff2 = mult_r( coeff2, coeff0 );
345 3060 : coeff3 = mult_r( coeff3, coeff0 );
346 3060 : coeff4 = mult_r( coeff4, coeff0 );
347 :
348 386100 : FOR( i = 0; i < size; i++ )
349 : {
350 : /*
351 : Note: gcode0_gi: either gcode0 or gcode0*gain_inov
352 : g_pitch = *p++;
353 : g_code = gcode0_gi * *p++;
354 :
355 : dist = g_pitch*g_pitch * coeff.y1y1
356 : + g_pitch * coeff.xy1 (negated)
357 : + g_code*g_code * coeff.y2y2
358 : + g_code * coeff.xy2 (negated)
359 : + g_pitch*g_code * coeff.y1y2;
360 : */
361 :
362 : /* Since g_code has a significant dynamic, we prefer to normalize this 16-bit value */
363 383040 : g_code_shl = norm_s( p[2 * i + 1] );
364 383040 : g_code = shl( p[2 * i + 1], g_code_shl );
365 383040 : g_code = mult_r( g_code, gcode0_gi );
366 : BASOP_SATURATE_WARNING_OFF_EVS /* needed to skip overflow warnings due to exceeding shift values */
367 383040 : L_tmp = L_shr( Mpy_32_16_1( L_mult( g_code, g_code ), coeff2 ), shr_coeff2 );
368 383040 : if ( g_code_shl != 0 )
369 374130 : L_tmp = L_shr( L_tmp, g_code_shl );
370 383040 : L_tmp = L_sub( L_tmp, L_shr( L_mult( g_code, coeff3 ), shr_coeff3 ) );
371 383040 : L_tmp = L_add( L_tmp, L_shr( Mpy_32_16_1( L_mult( g_code, p[2 * i + 0] ), coeff4 ), shr_coeff4 ) );
372 383040 : if ( g_code_shl != 0 )
373 374130 : L_tmp = L_shr( L_tmp, g_code_shl );
374 : /* Here, we use L_mult0 to compensate the factor 0.5 applied to coeff[1..4] before */
375 383040 : L_tmp = L_add( L_tmp, L_shr( L_mult0( p[2 * i + 0], p[2 * i + 0] ), shr_coeff0 ) );
376 383040 : L_tmp = L_sub( L_tmp, L_shr( L_mult( p[2 * i + 0], coeff1 ), shr_coeff1 ) );
377 383040 : L_tmp1 = L_sub_sat( L_tmp, dist_min );
378 : BASOP_SATURATE_WARNING_ON_EVS
379 383040 : if ( L_tmp1 < 0 )
380 : {
381 62796 : index = i;
382 62796 : move16();
383 : }
384 383040 : if ( L_tmp1 < 0 )
385 : {
386 62796 : dist_min = L_min( L_tmp, dist_min );
387 : }
388 : }
389 3060 : index = add( index, min_index );
390 3060 : *gain_pit = t_qua_gain[2 * index + 0];
391 3060 : move16();
392 3060 : g_code = t_qua_gain[2 * index + 1];
393 3060 : move16();
394 :
395 3060 : L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q15 -> Q27 */
396 3060 : exp_gcode0 = add( exp_gcode0, -11 );
397 3060 : L_tmp = L_shl_sat( L_tmp, exp_gcode0 ); /* Q27 -> Q16 */
398 :
399 3060 : *gain_code = L_tmp;
400 3060 : move32();
401 : /* Q16/Q12 => Q5 */
402 3060 : L_tmp = L_deposit_h( BASOP_Util_Divide3216_Scale( L_tmp, *gain_inov, &i ) );
403 3060 : *past_gcode = L_shl_sat( L_tmp, sub( i, 15 - 12 ) );
404 3060 : move16();
405 :
406 3060 : return index;
407 : }
408 :
409 :
410 8060 : Word16 gain_enc_uv_fx( /* o : quantization pitch index <Q0> */
411 : const Word16 *code, /* i : algebraic excitation <Q9> */
412 : const Word16 *code2, /* i : gaussian excitation <Q9> */
413 : Word16 lcode, /* i : Subframe size in range: 40,64,80 <Q0> */
414 : Word16 *gain_pit, /* o : quantized pitch gain <Q16> */
415 : Word32 *gain_code, /* o : quantized codebook gain <Q16> */
416 : Word32 *gain_code2, /* o : quantized codebook gain <Q16> */
417 : Word16 noisy_speech_flag, /* i : noisy speech flag */
418 : ACELP_CbkCorr *g_coeff, /* i : correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> */
419 : Word16 mean_ener, /* i : only func=0: mean_ener defined in open-loop (3 bits) <Q8> */
420 : Word32 *past_gcode, /* o : past gain of code <Q16> */
421 : Word16 *gain_inov, /* o : Q12 innovation gain <Q12> */
422 : const Word16 func_type /* i : algorithm: 2=gain_enc_uv_fx, 3=gain_enc_gacelp_uv <Q0> */
423 : )
424 : {
425 : Word16 i, index, exp_L_tmp1, tmp;
426 : Word16 exp_gcode;
427 : Word16 g_code;
428 : Word32 L_tmp, L_tmp1;
429 : Word8 gacelp_uv;
430 : Word32 pred_nrg_frame;
431 : Word16 exp_gcode2, g_code2, norm_code2;
432 : Word16 c, c_e, c_index2, c_index2_e, c_first, c_first_e;
433 : Word16 s, tmp1, s1;
434 : Word16 index2;
435 8060 : const Word16 log2_scale = 16;
436 8060 : move16();
437 8060 : pred_nrg_frame = 0; /* to suppress compilation warnings */
438 8060 : g_code2 = 0; /* to suppress compilation warnings */
439 8060 : exp_gcode2 = 0; /* to suppress compilation warnings */
440 8060 : move32();
441 8060 : move16();
442 8060 : move16();
443 :
444 8060 : assert( ( func_type != FUNC_GAIN_ENC_MLESS ) );
445 :
446 : /* Debug check value (not instrumented) */
447 8060 : index2 = -3000;
448 8060 : move16();
449 :
450 8060 : gacelp_uv = 0;
451 8060 : move16();
452 8060 : if ( EQ_16( func_type, FUNC_GAIN_ENC_GACELP_UV ) )
453 : {
454 8060 : gacelp_uv = 1;
455 8060 : move16();
456 : }
457 :
458 : /*----------------------------------------------------------------*
459 : * - calculate the unscaled innovation energy
460 : * - calculate the predicted gain code
461 : *----------------------------------------------------------------*/
462 :
463 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
464 8060 : L_tmp = calc_gain_inov( code, lcode, NULL, NULL );
465 8060 : *gain_inov = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* gain_inov in Q12 */
466 8060 : move16();
467 :
468 : /*----------------------------------------------------------------*
469 : * calculate the predicted gain code
470 : *----------------------------------------------------------------*/
471 8060 : IF( gacelp_uv != 0 )
472 : {
473 : /* pred_nrg_frame = (float)pow(10.0,mean_ener/20.0); */
474 8060 : L_tmp = L_mult( mean_ener, 10885 /*0.166096f * 2 Q15*/ ); /* 6Q25 */
475 8060 : pred_nrg_frame = BASOP_Util_InvLog2( L_sub( L_tmp, 503316480l /*15.f Q25*/ ) ); /* 15Q16 */
476 :
477 : /* gcode = pred_nrg_frame * (*gain_inov); */
478 8060 : L_tmp = Mpy_32_16_1( pred_nrg_frame, *gain_inov ); /* 18Q13 */
479 8060 : i = norm_l( L_tmp );
480 8060 : g_code = round_fx_sat( L_shl( L_tmp, i ) );
481 8060 : exp_gcode = sub( 18, i );
482 :
483 : /* norm_code2 = 1.0f / sqrt((dot_product(code2, code2, lcode) + 0.01f) / lcode); */
484 8060 : L_tmp = calc_gain_inov( code2, lcode, NULL, NULL );
485 8060 : norm_code2 = round_fx( L_shl( L_tmp, 15 - 3 ) ); /* Q12 */
486 :
487 : /* g_code2 = pred_nrg_frame * norm_code2; */
488 8060 : L_tmp = Mpy_32_16_1( pred_nrg_frame, norm_code2 ); /* 18Q13 */
489 8060 : i = norm_l( L_tmp );
490 8060 : g_code2 = round_fx_sat( L_shl_sat( L_tmp, i ) );
491 8060 : exp_gcode2 = sub( 18, i );
492 : }
493 : ELSE
494 : {
495 0 : g_code = *gain_inov;
496 0 : move16();
497 0 : exp_gcode = 3;
498 0 : move16();
499 : }
500 :
501 8060 : tmp = BASOP_Util_Divide1616_Scale( g_coeff->xy2, mult_r( g_coeff->y2y2, g_code ), &i ); /*Correlation based*/
502 8060 : L_tmp = L_shl( L_deposit_h( tmp ), add( i, sub( g_coeff->xy2_e, add( g_coeff->y2y2_e, add( exp_gcode, log2_scale ) ) ) ) );
503 : /* exponent of L_tmp is 16, accounted below by adding log2(2^16) */
504 :
505 8060 : index = 0;
506 8060 : move16();
507 :
508 8060 : IF( L_tmp > 0 )
509 : {
510 : /*index = (int)(((20.f*log10(g_code)+30.f)/1.9f)+0.5f))); */
511 : /* Since ((20*log10(x)+30)/1.9)+0.5 = 63 (max index) implies x is between 2^15 and 2^16,
512 : L_tmp might saturate at 65535 and above. That is why log2_scale is 16. */
513 8060 : tmp = BASOP_Util_lin2dB( L_tmp, 16, 0 ); /* Q8 */
514 :
515 8060 : IF( gacelp_uv != 0 )
516 : {
517 8060 : L_tmp = L_mult( add( tmp, 5120 /*20.0f Q8*/ ), 26214 /*1.0f/1.25f Q15*/ );
518 : }
519 : ELSE
520 : {
521 0 : L_tmp = L_mult( add( tmp, 7680 /*30.0f Q8*/ ), 17246 /*1.0f/1.9f Q15*/ );
522 : }
523 :
524 8060 : index = round_fx( L_shr( L_tmp, 8 ) );
525 8060 : index = s_max( 0, s_min( 63, index ) );
526 8060 : if ( gacelp_uv != 0 )
527 8060 : index = s_min( 31, index );
528 : }
529 :
530 : /* *gain_code= (float) pow(10.f,(((index*1.9f)-30.f)/20.f)); */
531 :
532 : /*----------------------------------------------------------------*
533 : * gcode0 = pow(10.0, gcode0/20)
534 : * = pow(2, 3.321928*gcode0/20)
535 : * = pow(2, 0.166096*gcode0)
536 : *----------------------------------------------------------------*/
537 8060 : IF( gacelp_uv != 0 )
538 : {
539 8060 : L_tmp = L_mac( -111465139l /*-0.166096*20.0f Q25*/, shl( index, 16 - 7 ), 6803 /*0.166096f*1.25f Q15*/ );
540 : }
541 : ELSE
542 : {
543 0 : L_tmp = L_mac( -167197708l /*-0.166096*30.0f Q25*/, shl( index, 16 - 7 ), 10341 /*0.166096f*1.9f Q15*/ );
544 : }
545 8060 : i = add( 1, extract_l( L_shr( L_tmp, 25 ) ) );
546 8060 : L_tmp = L_lshl( L_tmp, 6 );
547 8060 : L_tmp = L_and( 0x7FFFFFFF, L_tmp );
548 :
549 8060 : L_tmp = Pow2( 30, round_fx( L_tmp ) );
550 8060 : L_tmp = L_shl( L_tmp, sub( i, ( 31 - 16 ) ) ); /* Q16 */
551 :
552 8060 : IF( gacelp_uv != 0 )
553 : {
554 : /* *past_gcode = L_tmp * pred_nrg_frame; */
555 8060 : i = norm_l( L_tmp );
556 8060 : L_tmp1 = L_shl( L_tmp, i );
557 8060 : exp_L_tmp1 = sub( 15, i );
558 :
559 8060 : i = norm_l( pred_nrg_frame );
560 8060 : L_tmp1 = Mpy_32_32( L_tmp1, L_shl( pred_nrg_frame, i ) );
561 8060 : exp_L_tmp1 = add( exp_L_tmp1, sub( 15, i ) );
562 :
563 8060 : *past_gcode = L_shl( L_tmp1, sub( exp_L_tmp1, 15 ) ); /* Q16 */
564 8060 : move32();
565 : }
566 : ELSE
567 : {
568 0 : *past_gcode = L_tmp; /*unscaled gain*/
569 0 : move32();
570 : }
571 :
572 :
573 8060 : *gain_code = L_shl_sat( Mpy_32_16_1( *past_gcode, *gain_inov ), 3 );
574 8060 : move32();
575 :
576 8060 : *gain_pit = 0;
577 8060 : move16();
578 :
579 8060 : IF( gacelp_uv != 0 )
580 : {
581 : /* c_first = 0.8f*g_coeff->xx - (*gain_code) * (*gain_code) * g_coeff->y2y2; */
582 : /* c_first = g_coeff->xx - (*gain_code) * (*gain_code) * g_coeff->y2y2; */
583 8060 : tmp = g_coeff->xx;
584 8060 : move16();
585 8060 : if ( noisy_speech_flag != 0 )
586 : {
587 532 : tmp = mult_r( 26214 /*0.8f Q15*/, tmp );
588 : }
589 :
590 8060 : s1 = norm_l( *gain_code );
591 8060 : tmp1 = round_fx_sat( L_shl( *gain_code, s1 ) );
592 8060 : s1 = sub( 15, s1 );
593 8060 : tmp1 = mult_r( mult_r( tmp1, tmp1 ), g_coeff->y2y2 );
594 :
595 8060 : c_first_e = BASOP_Util_Add_MantExp( tmp, g_coeff->xx_e,
596 8060 : negate( tmp1 ), add( g_coeff->y2y2_e, shl( s1, 1 ) ),
597 : &c_first );
598 :
599 8060 : L_tmp = Mpy_32_16_1( *gain_code, BASOP_Util_Divide1616_Scale( g_code2, g_code, &s ) );
600 8060 : L_tmp = L_shl( L_tmp, sub( sub( add( s, exp_gcode2 ), exp_gcode ), 2 ) ); /* Q16 */
601 8060 : L_tmp1 = L_add( L_tmp, 0 );
602 :
603 8060 : s1 = norm_l( *gain_code );
604 8060 : tmp1 = round_fx_sat( L_shl( *gain_code, s1 ) );
605 8060 : s1 = sub( 15, s1 );
606 :
607 8060 : c_index2 = 0x7FFF;
608 8060 : move16();
609 8060 : c_index2_e = 127;
610 8060 : move16();
611 40300 : FOR( i = 0; i < 4; i++ )
612 : {
613 : /* c = c_first - L_tmp1 * (L_tmp1 * g_coeff->y1y1 + 2 * (*gain_code) * g_coeff->y1y2); */
614 32240 : s = norm_l( L_tmp1 );
615 32240 : tmp = round_fx_sat( L_shl_sat( L_tmp1, s ) );
616 32240 : s = sub( 15, s );
617 :
618 32240 : c_e = BASOP_Util_Add_MantExp( mult_r( tmp, g_coeff->y1y1 ), add( s, g_coeff->y1y1_e ),
619 32240 : mult_r( tmp1, g_coeff->y1y2 ), add( add( s1, g_coeff->y1y2_e ), 1 ),
620 : &c );
621 32240 : c = mult_r( c, tmp );
622 32240 : c_e = add( c_e, s );
623 32240 : c_e = BASOP_Util_Add_MantExp( c_first, c_first_e, negate( c ), c_e, &c );
624 :
625 32240 : tmp = 0;
626 32240 : move16();
627 32240 : if ( LT_16( c_e, c_index2_e ) )
628 : {
629 17694 : tmp = 1;
630 17694 : move16();
631 : }
632 32240 : test();
633 32240 : if ( EQ_16( c_e, c_index2_e ) && LT_16( abs_s( c ), abs_s( c_index2 ) ) )
634 : {
635 9188 : tmp = 1;
636 9188 : move16();
637 : }
638 :
639 32240 : IF( tmp != 0 )
640 : {
641 26882 : index2 = i;
642 26882 : move16();
643 26882 : c_index2 = c;
644 26882 : move16();
645 26882 : c_index2_e = c_e;
646 26882 : move16();
647 26882 : *gain_code2 = L_tmp1;
648 26882 : move32();
649 : }
650 :
651 32240 : L_tmp1 = L_add( L_tmp1, L_tmp );
652 : }
653 :
654 : /* check if value was uninitialized */
655 8060 : assert( index2 != -3000 );
656 8060 : index = add( index, shl( index2, 5 ) );
657 : }
658 :
659 :
660 8060 : return index;
661 : }
|