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