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