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_fx.h" /* Static table prototypes */
8 : #include "rom_com.h" /* Static table prototypes */
9 : //#include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 :
13 : /*-------------------------------------------------------------------*
14 : * Local constants
15 : *-------------------------------------------------------------------*/
16 :
17 : #define RANGE 64
18 : #define NB_QUA_GAIN7B 128 /* Number of quantization levels */
19 :
20 : /*-------------------------------------------------------------------*
21 : * Local function prototype
22 : *-------------------------------------------------------------------*/
23 :
24 : static Word16 Find_Opt_gainQ_fx( Word16 *coeff, Word16 *exp_coeff, Word16 *gain_pit, Word32 *gain_code, Word16 gcode0, Word16 exp_gcode0, const Word16 *cdbk, const Word16 size );
25 :
26 : /*==========================================================================*/
27 : /* FUNCTION : Es_pred_enc_fx() */
28 : /*--------------------------------------------------------------------------*/
29 : /* PURPOSE : Calculation and quantization of average predicted innovation energy to be*/
30 : /*--------------------------------------------------------------------------*/
31 : /* INPUT ARGUMENTS : */
32 : /* _ Word16 L_frame, i : length of the frame Q0 */
33 : /* _ Word16 *res, i : residual signal Q_new */
34 : /* _ Word16 *voicing, i : normalized correlation in three 1/2frames Q15*/
35 : /* _ Word16 coder_type, i : coder_type Q0 */
36 : /* _ Word16 bwidth, i : input signal bandwidth Q0 */
37 : /* _ Word32 core_brate, i : core bitrate Q0 */
38 : /* _ Word16 Q_new i : Scaling in speech Q0 */
39 : /*--------------------------------------------------------------------------*/
40 : /* OUTPUT ARGUMENTS : */
41 : /* _ Word16 *Es_pred, o : predicited scaled innovation energy Q8 */
42 : /*--------------------------------------------------------------------------*/
43 : /* INPUT/OUTPUT ARGUMENTS : */
44 : /* _ None. */
45 : /*--------------------------------------------------------------------------*/
46 : /* RETURN ARGUMENTS : _ None. */
47 : /*--------------------------------------------------------------------------*/
48 : /* CALLED FROM : TX */
49 : /*==========================================================================*/
50 :
51 133403 : void Es_pred_enc_fx(
52 : Word16 *Es_pred, /* o : predicited scaled innovation energy Q8*/
53 : Word16 *indice, /* o : indice of quantization Q0*/
54 : const Word16 L_frame, /* i : length of the frame Q0*/
55 : const Word16 *res, /* i : residual signal Q_new*/
56 : const Word16 *voicing, /* i : normalized correlation in three 1/2frames Q15*/
57 : const Word16 nb_bits, /* i : allocated number of bits Q0*/
58 : const Word16 no_ltp, /* i : no_ltp flag Q0*/
59 : Word16 Q_new /* i : Scaling in speech Q0*/
60 : )
61 : {
62 : Word16 i, i_subfr, size, tmp16, tmp16_2, Q_res;
63 : Word16 weight;
64 : Word16 s0, s1, ener_dB, mean_ener_code16;
65 : const Word16 *qua_table;
66 : Word32 ener_fx, Lmean_ener_code, Ltmp;
67 : #ifndef ISSUE_1867_replace_overflow_libenc
68 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
69 : Flag Overflow = 0;
70 : move32();
71 : #endif
72 : #endif
73 :
74 133403 : Lmean_ener_code = L_deposit_l( 0 );
75 133403 : Q_res = sub( shl( Q_new, 1 ), 3 );
76 :
77 133403 : IF( EQ_16( L_frame, L_FRAME ) )
78 : {
79 61429 : weight = 8192;
80 61429 : move16(); /*0.25f in Q15*/
81 : }
82 : ELSE /* L_frame == L_FRAME16k */
83 : {
84 71974 : weight = 6554;
85 71974 : move16(); /*0.2f in Q15*/
86 : }
87 :
88 : /*----------------------------------------------------------*
89 : * calculate the average residual signal energy in four sframes
90 : *----------------------------------------------------------*/
91 :
92 738989 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
93 : {
94 : /* calculate the energy of residual signal */
95 605586 : tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
96 605586 : ener_fx = L_mult( tmp16, tmp16 );
97 38757504 : FOR( i = 1; i < L_SUBFR; i++ )
98 : {
99 38151918 : tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
100 : #ifdef ISSUE_1867_replace_overflow_libenc
101 38151918 : ener_fx = L_mac_sat( ener_fx, tmp16, tmp16 );
102 : #else
103 : ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow );
104 : #endif
105 : }
106 :
107 : /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */
108 605586 : s1 = 0;
109 605586 : move16();
110 605586 : s0 = norm_l( ener_fx );
111 :
112 605586 : IF( ener_fx != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
113 : {
114 599882 : s1 = Log2_norm_lc( L_shl( ener_fx, s0 ) );
115 599882 : s0 = sub( 30, s0 );
116 : }
117 605586 : s0 = sub( s0, add( Q_res, 6 ) );
118 605586 : Ltmp = Mpy_32_16( s0, s1, LG10 );
119 605586 : ener_dB = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 Energy in log10 */
120 605586 : test();
121 605586 : if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) )
122 : {
123 13356 : ener_dB = 0;
124 13356 : move16();
125 : }
126 :
127 : /* update the average energy of residual signal */
128 605586 : Lmean_ener_code = L_mac( Lmean_ener_code, ener_dB, weight ); /* Q24 */
129 : }
130 :
131 133403 : IF( no_ltp == 0 )
132 : {
133 : /*----------------------------------------------------------*
134 : * subtract an estimate of adaptive codebook contribution
135 : *----------------------------------------------------------*/
136 : /*mean_ener_code -= 10.0f * (0.5f * voicing[0] + 0.5f * voicing[1]);*/
137 131387 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[0], 1280 ); /*Q24*/
138 131387 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[1], 1280 ); /*Q24*/
139 131387 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
140 :
141 : /*----------------------------------------------------------*n
142 : * quantize the average predicted innovation energy
143 : *----------------------------------------------------------*/
144 131387 : SWITCH( nb_bits )
145 : {
146 113152 : case 5:
147 : {
148 113152 : qua_table = Es_pred_qua_5b_fx; // Q8
149 113152 : BREAK;
150 : }
151 17623 : case 4:
152 : {
153 17623 : qua_table = Es_pred_qua_4b_fx; // Q8
154 17623 : BREAK;
155 : }
156 612 : case 3:
157 : {
158 612 : qua_table = Es_pred_qua_3b_fx; // Q8
159 612 : BREAK;
160 : }
161 0 : default:
162 : {
163 0 : qua_table = Es_pred_qua_5b_fx; // Q8
164 0 : BREAK;
165 : }
166 : }
167 : }
168 : ELSE
169 : {
170 2016 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
171 :
172 2016 : qua_table = Es_pred_qua_4b_no_ltp_fx; // Q8
173 : }
174 : /*size = extract_l(pow2_fx[nb_bits]); */ /*maximum number of bit is 6 */
175 133403 : size = shl( 1, nb_bits ); /*maximum number of bit is 6 */
176 :
177 : /* find the nearest neighbour (codevector) */
178 133403 : *Es_pred = qua_table[0]; // Q8
179 133403 : move16();
180 133403 : tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) );
181 133403 : *indice = 0;
182 133403 : move16();
183 :
184 3939984 : FOR( i = 1; i < size; i++ )
185 : {
186 : #ifdef ISSUE_1867_replace_overflow_libenc
187 3806581 : tmp16_2 = abs_s( sub_sat( mean_ener_code16, qua_table[i] ) );
188 : #else
189 : tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) );
190 : #endif
191 3806581 : IF( LT_16( tmp16_2, tmp16 ) )
192 : {
193 1959106 : tmp16 = tmp16_2;
194 1959106 : move16();
195 1959106 : *indice = i;
196 1959106 : move16();
197 1959106 : *Es_pred = qua_table[i]; // Q8
198 1959106 : move16();
199 : }
200 : }
201 :
202 :
203 133403 : return;
204 : }
205 : /*---------------------------------------------------------------------*
206 : * gain_enc_mless()
207 : *
208 : * Quantization of pitch and codebook gains without prediction (memory-less)
209 : * - an initial predicted gain, gcode0, is first determined based on
210 : * the predicted average innovation energy
211 : * - a correction factor gamma = g_code / gcode0 is then vector quantized along with gain_pit
212 : * - the mean-squared weighted error criterion is used for codebook search
213 : *---------------------------------------------------------------------*/
214 527586 : void gain_enc_mless_fx(
215 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
216 : const Word16 gains_mode[], /* i : gain bits Q0*/
217 : const Word16 element_mode, /* i : element mode Q0*/
218 : const Word16 L_frame, /* i : length of the frame Q0*/
219 : const Word16 i_subfr, /* i : subframe index Q0*/
220 : const Word16 tc_subfr, /* i : TC subframe index Q0*/
221 : const Word16 *xn, /* i : target vector Q_xn*/
222 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
223 : const Word16 Q_xn, /* i : xn and y1 scaling */
224 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
225 : const Word16 *code, /* i : algebraic excitation Q9*/
226 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
227 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
228 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
229 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
230 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
231 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
232 : const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/
233 : )
234 : {
235 :
236 : Word16 index, size, nBits, nBits2;
237 : Word16 gcode0, Ei, gain_code16;
238 : const Word16 *qua_table;
239 : Word16 coeff[5], exp_coeff[5];
240 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
241 : Word32 L_tmp, L_tmp1, L_tmp2;
242 : Word16 tmp1, expg;
243 : Word16 exp1, exp2;
244 : Word16 exp_num, exp_den, exp_div, frac_den;
245 : Word32 L_frac_num, L_frac_den, L_div;
246 : #ifndef ISSUE_1867_replace_overflow_libenc
247 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
248 : Flag Overflow = 0;
249 : move32();
250 : #endif
251 : #endif
252 :
253 : /*-----------------------------------------------------------------*
254 : * calculate the rest of the correlation coefficients
255 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
256 : *-----------------------------------------------------------------*/
257 :
258 527586 : coeff[0] = g_corr[0];
259 527586 : move16();
260 527586 : exp_coeff[0] = g_corr[1];
261 527586 : move16();
262 527586 : coeff[1] = negate( g_corr[2] );
263 527586 : move16(); /* coeff[1] = -2 xn yy1 */
264 527586 : exp_coeff[1] = add( g_corr[3], 1 );
265 527586 : move16();
266 :
267 : /* Compute scalar product <y2[],y2[]> */
268 527586 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
269 527586 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
270 527586 : move16(); /* -18 (y2 Q9) */
271 :
272 : /* Compute scalar product -2*<xn[],y2[]> */
273 527586 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
274 527586 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
275 527586 : move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
276 :
277 : /* Compute scalar product 2*<y1[],y2[]> */
278 527586 : coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
279 527586 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
280 527586 : move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
281 :
282 : /*-----------------------------------------------------------------*
283 : * calculate the unscaled innovation energy
284 : * calculate the predicted gain code
285 : *-----------------------------------------------------------------*/
286 :
287 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
288 527586 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
289 527586 : exp_inov = sub( exp_code, 18 + 6 );
290 : // To avoid crash in case code value is 0,
291 527586 : test();
292 527586 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, exp_inov, 21474836, 0 ), -1 ) && element_mode > EVS_MONO )
293 : {
294 : // setting values to avoid extra computation
295 0 : *gain_inov = 32767; /*8(max value gain_inov can hold) in Q12*/
296 0 : Ei = -9743; /* -38 in Q8*/
297 0 : move16();
298 0 : move16();
299 : }
300 : ELSE
301 : {
302 :
303 527586 : exp_code = sub( exp_code, 30 );
304 :
305 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
306 :
307 : /*----------------------------------------------------------------*
308 : * calculate the predicted gain code
309 : *----------------------------------------------------------------*/
310 527586 : tmp = norm_l( L_tmp );
311 527586 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
312 527586 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
313 527586 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
314 527586 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
315 : /*---------------------------------------------------------------*
316 : * Decode codebook gain and the adaptive excitation low-pass
317 : * filtering factor (Finalize computation )
318 : *---------------------------------------------------------------*/
319 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
320 527586 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
321 527586 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
322 527586 : move16();
323 : }
324 : /* predicted codebook gain */
325 527586 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
326 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
327 : /*----------------------------------------------------------------*
328 : * gcode0 = pow(10.0, gcode0/20)
329 : * = pow(2, 3.321928*gcode0/20)
330 : * = pow(2, 0.166096*gcode0)
331 : *----------------------------------------------------------------*/
332 :
333 527586 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
334 527586 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
335 527586 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
336 :
337 527586 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
338 : /* output of Pow2() will be: */
339 : /* 16384 < Pow2() <= 32767 */
340 527586 : exp_gcode0 = sub( exp_gcode0, 14 );
341 :
342 : /*-----------------------------------------------------------------*
343 : * select the codebook, size and number of bits
344 : * set the gains searching range
345 : *-----------------------------------------------------------------*/
346 527586 : nBits = gains_mode[i_subfr >> 6];
347 527586 : move16();
348 :
349 527586 : test();
350 527586 : test();
351 527586 : test();
352 527586 : test();
353 527586 : test();
354 527586 : IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
355 : ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
356 : {
357 : /* *gain_pit = (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
358 : = ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
359 : = ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
360 :
361 : /* *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
362 : = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
363 : = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
364 :
365 3666 : L_tmp1 = L_mult_sat( coeff[0], coeff[2] ); /*Q31*/
366 3666 : exp1 = add( exp_coeff[0], exp_coeff[2] );
367 :
368 3666 : L_tmp2 = L_shr( L_mult_sat( coeff[4], coeff[4] ), 2 ); /*Q31*/
369 3666 : exp2 = add( exp_coeff[4], exp_coeff[4] );
370 :
371 3666 : IF( GT_16( exp1, exp2 ) )
372 : {
373 3567 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
374 3567 : exp_den = exp1;
375 3567 : move16();
376 : }
377 : ELSE
378 : {
379 99 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
380 99 : exp_den = exp2;
381 99 : move16();
382 : }
383 3666 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
384 :
385 3666 : frac_den = extract_h( L_frac_den ); /* Q15 */
386 3666 : frac_den = s_max( frac_den, 1 ); /* Q15 */
387 3666 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
388 3666 : exp = norm_l( L_frac_den );
389 3666 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
390 :
391 3666 : L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
392 3666 : exp1 = add( exp_coeff[3], exp_coeff[4] );
393 :
394 3666 : L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
395 3666 : exp2 = add( exp_coeff[1], exp_coeff[2] );
396 :
397 3666 : IF( GT_16( exp1, exp2 ) )
398 : {
399 115 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
400 115 : exp_num = exp1;
401 115 : move16();
402 : }
403 : ELSE
404 : {
405 3551 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
406 3551 : exp_num = exp2;
407 3551 : move16();
408 : }
409 3666 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
410 :
411 3666 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
412 3666 : exp_div = sub( exp_num, exp_den );
413 :
414 : #ifdef ISSUE_1867_replace_overflow_libenc
415 3666 : *gain_pit = round_fx_sat( L_shl_sat( L_div, add( exp, exp_div ) ) ); /*Q14*/
416 : #else
417 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
418 : #endif
419 :
420 3666 : L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
421 3666 : exp1 = add( exp_coeff[1], exp_coeff[4] );
422 :
423 3666 : L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
424 3666 : exp2 = add( exp_coeff[0], exp_coeff[3] );
425 :
426 3666 : IF( GT_16( exp1, exp2 ) )
427 : {
428 58 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
429 58 : exp_num = exp1;
430 58 : move16();
431 : }
432 : ELSE
433 : {
434 3608 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
435 3608 : exp_num = exp2;
436 3608 : move16();
437 : }
438 3666 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
439 :
440 3666 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
441 3666 : exp_div = sub( exp_num, exp_den );
442 :
443 : #ifdef ISSUE_1867_replace_overflow_libenc
444 3666 : *gain_code = L_shl_sat( L_div, sub( add( exp, exp_div ), 14 ) );
445 : #else
446 : *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
447 : #endif
448 3666 : move32(); /*Q16*/
449 :
450 3666 : *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
451 3666 : move16();
452 :
453 : /* set number of bits for two SQs */
454 3666 : nBits2 = shr( add( nBits, 1 ), 1 );
455 3666 : nBits = shr( nBits, 1 );
456 :
457 : /* gain_pit Q */
458 :
459 3666 : tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
460 3666 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
461 3666 : move16();
462 3666 : push_indice( hBstr, IND_GAIN_PIT, index, nBits );
463 :
464 : /* gain_code Q */
465 : /**gain_code /= gcode0;*/
466 3666 : IF( gcode0 != 0 )
467 : {
468 3666 : tmp = div_s( 16384, gcode0 ); /*Q15*/
469 3666 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
470 3666 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
471 3666 : move32();
472 : }
473 :
474 3666 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
475 3666 : push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
476 3666 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
477 : #ifdef ISSUE_1867_replace_overflow_libenc
478 3666 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
479 : #else
480 : *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
481 : #endif
482 : }
483 : ELSE
484 : {
485 523920 : size = shl( 1, nBits );
486 :
487 523920 : SWITCH( nBits )
488 : {
489 749 : case 7:
490 : {
491 749 : qua_table = gain_qua_mless_7b_fx;
492 749 : move16();
493 749 : if ( EQ_16( clip_gain, 1 ) )
494 : {
495 0 : size = sub( size, 30 );
496 : }
497 749 : BREAK;
498 : }
499 522646 : case 6:
500 : {
501 522646 : qua_table = gain_qua_mless_6b_fx;
502 522646 : if ( element_mode > EVS_MONO )
503 : {
504 519755 : qua_table = gain_qua_mless_6b_stereo_fx;
505 : }
506 522646 : move16();
507 522646 : if ( EQ_16( clip_gain, 1 ) )
508 : {
509 5958 : size = sub( size, 14 );
510 : }
511 522646 : BREAK;
512 : }
513 525 : case 5:
514 : {
515 525 : qua_table = gain_qua_mless_5b_fx; // Q14
516 525 : move16();
517 525 : if ( EQ_16( clip_gain, 1 ) )
518 : {
519 0 : size = sub( size, 6 );
520 : }
521 525 : BREAK;
522 : }
523 0 : default:
524 : {
525 0 : qua_table = gain_qua_mless_6b_fx; // Q14
526 0 : move16();
527 0 : if ( EQ_16( clip_gain, 1 ) )
528 : {
529 0 : size = sub( size, 14 );
530 : }
531 0 : BREAK;
532 : }
533 : }
534 :
535 : /* in case of AVQ inactive, limit the gain_pit to 0.65 */
536 523920 : test();
537 523920 : IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
538 : {
539 5320 : size = sub( size, 36 );
540 5320 : nBits = sub( nBits, 1 );
541 : }
542 :
543 : /*-----------------------------------------------------------------*
544 : * search for the best quantizer
545 : *-----------------------------------------------------------------*/
546 523920 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0
547 523920 : push_indice( hBstr, IND_GAIN, index, nBits );
548 : }
549 :
550 : /* *norm_gain_code = *gain_code / *gain_inov; */
551 527586 : exp = sub( norm_s( *gain_inov ), 1 );
552 527586 : exp = s_max( exp, 0 );
553 :
554 527586 : tmp = div_s( shr( 8192, exp ), *gain_inov );
555 527586 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) );
556 527586 : move32();
557 :
558 527586 : return;
559 : }
560 : /*---------------------------------------------------------------------*
561 : * gain_enc_SQ()
562 : *
563 : * Scalar Quantization of pitch and codebook gains without prediction
564 : * - an initial predicted gain, gcode0, is first determined based on
565 : * the predicted scaled innovation energy
566 : * - a correction factor gamma = g_code / gcode0 is then vector quantized
567 : * along with gain_pit
568 : * - the mean-squared weighted error criterion is used for codebook search
569 : *---------------------------------------------------------------------*/
570 :
571 46508 : void gain_enc_SQ_fx(
572 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
573 : const Word16 gains_mode[], /* i : gain bits Q0*/
574 : const Word16 i_subfr, /* i : subframe index Q0*/
575 : const Word16 *xn, /* i : target vector Q_xn*/
576 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
577 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
578 : const Word16 *code, /* i : algebraic excitation Q9*/
579 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
580 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
581 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
582 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
583 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
584 : Word16 *g_corr, /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
585 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
586 : const Word16 Q_xn /* i : xn and y1 scaling */
587 : )
588 : {
589 : Word16 index, nBits_pitch, nBits_code;
590 : Word16 gcode0, Ei, gain_code16;
591 : Word16 coeff[5], exp_coeff[5];
592 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
593 :
594 : Word32 L_tmp, L_tmp1, L_tmp2;
595 : Word16 tmp1, expg;
596 : Word16 exp1, exp2;
597 : Word16 exp_num, exp_den, exp_div, frac_den;
598 : Word32 L_frac_num, L_frac_den, L_div;
599 : #ifndef ISSUE_1867_replace_overflow_libenc
600 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
601 : Flag Overflow = 0;
602 : move32();
603 : #endif
604 : #endif
605 :
606 : /*-----------------------------------------------------------------*
607 : * calculate the rest of the correlation coefficients
608 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
609 : *-----------------------------------------------------------------*/
610 : /*g_corr[1] *= -0.5;*/
611 : /*g_corr[2] = dotp( y2, y2, L_SUBFR ) + 0.01f;*/
612 : /*g_corr[3] = dotp( xn, y2, L_SUBFR ) - 0.02f;*/
613 : /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
614 :
615 46508 : coeff[0] = g_corr[0];
616 46508 : move16();
617 46508 : exp_coeff[0] = g_corr[1];
618 46508 : move16();
619 46508 : coeff[1] = g_corr[2];
620 46508 : move16(); /* coeff[1] = xn yy1 */
621 46508 : exp_coeff[1] = g_corr[3];
622 46508 : move16();
623 :
624 : /* Compute scalar product <y2[],y2[]> */
625 46508 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
626 46508 : move16();
627 46508 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
628 46508 : move16(); /* -18 (y2 Q9) */
629 :
630 : /* Compute scalar product <xn[],y2[]> */
631 46508 : coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
632 46508 : move16();
633 46508 : exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
634 46508 : move16(); /* -9 (y2 Q9), (xn y2) */
635 :
636 : /* Compute scalar product <y1[],y2[]> */
637 46508 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
638 46508 : move16();
639 46508 : exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
640 46508 : move16(); /* -9 (y2 Q9), (y1 y2) */
641 :
642 : /*-----------------------------------------------------------------*
643 : * calculate the unscaled innovation energy
644 : * calculate the predicted gain code
645 : * calculate optimal gains
646 : *-----------------------------------------------------------------*/
647 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
648 : /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
649 :
650 46508 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
651 46508 : exp_inov = sub( exp_code, 18 + 6 );
652 46508 : exp_code = sub( exp_code, 30 );
653 :
654 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
655 : /*----------------------------------------------------------------*
656 : * calculate the predicted gain code
657 : *----------------------------------------------------------------*/
658 46508 : tmp = norm_l( L_tmp );
659 46508 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
660 46508 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
661 46508 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
662 46508 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
663 :
664 : /* predicted codebook gain */
665 46508 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
666 :
667 : /*---------------------------------------------------------------*
668 : * Decode codebook gain and the adaptive excitation low-pass
669 : * filtering factor (Finalize computation )
670 : *---------------------------------------------------------------*/
671 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
672 46508 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
673 46508 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
674 :
675 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
676 : /*----------------------------------------------------------------*
677 : * gcode0 = pow(10.0, gcode0/20)
678 : * = pow(2, 3.321928*gcode0/20)
679 : * = pow(2, 0.166096*gcode0)
680 : *----------------------------------------------------------------*/
681 :
682 46508 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
683 46508 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
684 46508 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
685 :
686 46508 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
687 : /* output of Pow2() will be: */
688 : /* 16384 < Pow2() <= 32767 */
689 46508 : exp_gcode0 = sub( exp_gcode0, 14 );
690 :
691 :
692 : /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
693 : tmp2 = g_corr[1]/tmp1;
694 : tmp1 = g_corr[3]/tmp1;
695 :
696 : *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
697 : *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
698 :
699 : /* *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
700 : = ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
701 :
702 : /* *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
703 : = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
704 :
705 46508 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
706 46508 : exp1 = add( exp_coeff[0], exp_coeff[2] );
707 :
708 : #ifdef ISSUE_1867_replace_overflow_libenc
709 46508 : L_tmp2 = L_mult_sat( coeff[4], coeff[4] ); /*Q31*/
710 : #else
711 : L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
712 : #endif
713 46508 : exp2 = add( exp_coeff[4], exp_coeff[4] );
714 :
715 46508 : IF( GT_16( exp1, exp2 ) )
716 : {
717 46438 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
718 46438 : exp_den = exp1;
719 46438 : move16();
720 : }
721 : ELSE
722 : {
723 70 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
724 70 : exp_den = exp2;
725 70 : move16();
726 : }
727 46508 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
728 :
729 46508 : frac_den = extract_h( L_frac_den ); /* Q15 */
730 46508 : frac_den = s_max( frac_den, 1 ); /* Q15 */
731 46508 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
732 46508 : exp = norm_l( L_frac_den );
733 46508 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
734 :
735 :
736 46508 : L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
737 46508 : exp1 = add( exp_coeff[3], exp_coeff[4] );
738 :
739 46508 : L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
740 46508 : exp2 = add( exp_coeff[1], exp_coeff[2] );
741 :
742 46508 : IF( GT_16( exp1, exp2 ) )
743 : {
744 1265 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
745 1265 : exp_num = exp1;
746 1265 : move16();
747 : }
748 : ELSE
749 : {
750 45243 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
751 45243 : exp_num = exp2;
752 45243 : move16();
753 : }
754 : #ifdef ISSUE_1867_replace_overflow_libenc
755 46508 : L_frac_num = L_sub_sat( L_tmp2, L_tmp1 ); /*Q31*/
756 : #else
757 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
758 : #endif
759 :
760 46508 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
761 46508 : exp_div = sub( exp_num, exp_den );
762 :
763 : #ifdef ISSUE_1867_replace_overflow_libenc
764 46508 : *gain_pit = round_fx_sat( L_shl_sat( L_div, add( exp, exp_div ) ) ); /*Q14*/
765 : #else
766 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
767 : #endif
768 :
769 : #ifdef FIX_1978_SAT_MISSING_IN_GAIN_ENC
770 46508 : L_tmp1 = L_mult_sat( coeff[1], coeff[4] ); /*Q31*/
771 : #else
772 : L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/
773 : #endif
774 46508 : exp1 = add( exp_coeff[1], exp_coeff[4] );
775 :
776 : #ifdef FIX_1978_SAT_MISSING_IN_GAIN_ENC
777 46508 : L_tmp2 = L_mult_sat( coeff[0], coeff[3] ); /*Q31*/
778 : #else
779 : L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
780 : #endif
781 46508 : exp2 = add( exp_coeff[0], exp_coeff[3] );
782 :
783 46508 : IF( GT_16( exp1, exp2 ) )
784 : {
785 1399 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
786 1399 : exp_num = exp1;
787 1399 : move16();
788 : }
789 : ELSE
790 : {
791 45109 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
792 45109 : exp_num = exp2;
793 45109 : move16();
794 : }
795 : #ifdef ISSUE_1867_replace_overflow_libenc
796 46508 : L_frac_num = L_sub_sat( L_tmp2, L_tmp1 ); /*Q31*/
797 : #else
798 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
799 : #endif
800 :
801 46508 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
802 46508 : exp_div = sub( exp_num, exp_den );
803 :
804 46508 : *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
805 46508 : move32(); /*Q16*/
806 :
807 46508 : *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
808 :
809 : /*-----------------------------------------------------------------*
810 : * limit the pitch gain searching range (if indicated by clip_gain)
811 : *-----------------------------------------------------------------*/
812 :
813 46508 : test();
814 46508 : test();
815 46508 : IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
816 : {
817 29 : *gain_pit = 15565; /* 0.95 in Q14 */
818 29 : move16();
819 : }
820 46479 : ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
821 : {
822 1541 : *gain_pit = 10650; /* 0.65 in Q14 */
823 1541 : move16();
824 : }
825 :
826 : /*-----------------------------------------------------------------*
827 : * search for the best quantized values
828 : *-----------------------------------------------------------------*/
829 :
830 46508 : nBits_pitch = gains_mode[i_subfr >> 6];
831 46508 : move16();
832 :
833 : /* set number of bits for two SQs */
834 46508 : nBits_code = shr( add( nBits_pitch, 1 ), 1 );
835 46508 : nBits_pitch = shr( nBits_pitch, 1 );
836 :
837 : /* gain_pit Q */
838 : /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/ /* set quantization step */
839 46508 : tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
840 :
841 46508 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0
842 46508 : push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
843 :
844 : /* gain_code Q */
845 : /* *gain_code /= gcode0; */
846 46508 : IF( gcode0 != 0 )
847 : {
848 46508 : tmp = div_s( 16384, gcode0 ); /*Q15*/
849 46508 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
850 46508 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
851 46508 : move32();
852 : }
853 :
854 46508 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
855 46508 : push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
856 46508 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
857 46508 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
858 46508 : move32(); /*Q16*/
859 :
860 : /* *norm_gain_code = *gain_code / *gain_inov; */
861 46508 : exp = sub( norm_s( *gain_inov ), 1 );
862 46508 : exp = s_max( exp, 0 );
863 :
864 46508 : tmp = div_s( shr( 8192, exp ), *gain_inov );
865 46508 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
866 46508 : move32();
867 :
868 46508 : return;
869 : }
870 : /*-------------------------------------------------------------------*
871 : * gain_enc_gaus()
872 : *
873 : * Quantization of gain for Gaussian codebook
874 : *-------------------------------------------------------------------*/
875 0 : Word16 gain_enc_gaus_fx( /* o : Return index of quantization */
876 : Word32 *gain, /* i/o: Code gain to quantize Q16*/
877 : const Word16 bits, /* i : number of bits to quantize Q0*/
878 : const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8*/
879 : const Word16 stepSize, /* i : Step size choice Q14*/
880 : const Word16 inv_stepSize /* i : Step size choice Q15*/
881 : )
882 : {
883 : Word16 index, exp_gain, frac_gain, wtmp;
884 : Word16 enr_q, wenr;
885 : Word32 Ltmp, enr;
886 : #ifndef ISSUE_1867_replace_overflow_libenc
887 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
888 : Flag Overflow = 0;
889 : move32();
890 : #endif
891 : #endif
892 : /*enr = 20.0 * log10(*gain + 0.001) codebook gain in dB */
893 0 : exp_gain = norm_l( *gain );
894 0 : frac_gain = Log2_norm_lc( L_shl( *gain, exp_gain ) );
895 0 : exp_gain = sub( 30 - 16, exp_gain );
896 :
897 0 : enr = Mpy_32_16( exp_gain, frac_gain, LG10 ); /* Output in Q13 */
898 0 : wenr = extract_h( L_shl( enr, 8 + 3 ) );
899 :
900 : /*----------------------------------------------------------------*
901 : * Quantize linearly the log E
902 : *----------------------------------------------------------------*/
903 :
904 0 : wtmp = sub( wenr, lowBound ); /* Q8 */
905 :
906 0 : index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); // Q0
907 :
908 : /* index [0 (1<<bits)-1] */
909 0 : index = s_min( index, sub( shl( 1, bits ), 1 ) ); // Q0
910 0 : index = s_max( index, 0 );
911 :
912 0 : Ltmp = L_mac( L_shl( lowBound, 7 ), index, stepSize );
913 0 : enr_q = round_fx( L_shl( Ltmp, 16 - 7 ) ); /* enr_q Q8 */
914 :
915 : /* gain = (float)pow( 10.0f, enr/20.0f ) quantized codebook gain */
916 0 : enr = L_mult( enr_q, 21772 ); /* 0.166096 in Q17 -> Q26 */
917 0 : enr = L_shr( enr, 10 ); /*Q26->Q16*/
918 0 : frac_gain = L_Extract_lc( enr, &exp_gain );
919 :
920 0 : Ltmp = Pow2( 14, frac_gain ); /* Put 14 as exponent */
921 0 : exp_gain = sub( exp_gain, 14 ); /* Retreive exponent of wtmp */
922 : #ifdef ISSUE_1867_replace_overflow_libenc
923 0 : *gain = L_shl_sat( Ltmp, add( 16, exp_gain ) );
924 : #else
925 : *gain = L_shl_o( Ltmp, add( 16, exp_gain ), &Overflow );
926 : #endif
927 0 : move32(); /*Q16*/
928 :
929 0 : return index;
930 : }
931 : /*-----------------------------------------------------------------*
932 : * gain_enc_tc()
933 : *
934 : * Search and quantization of gain_code for subframes (in the
935 : * beginning of frame) without pulses in TC - 3b coding.
936 : * In this case:
937 : * - gain_pit = 0
938 : * - gain_code - scalar quantization (no prediciton history used)
939 : *-----------------------------------------------------------------*/
940 20393 : void gain_enc_tc_fx(
941 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
942 : const Word16 gains_mode[], /* i : gain bits Q0*/
943 : const Word16 i_subfr, /* i : subframe index Q0*/
944 : const Word16 xn_fx[], /* i : target vector Q_xn*/
945 : const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/
946 : const Word16 code_fx[], /* i : algebraic excitation Q9*/
947 : const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/
948 : Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/
949 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
950 : Word16 *gain_inov_fx, /* o : innovation gain Q12*/
951 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/
952 : const Word16 Q_xn /* i : xn and y1 scaling */
953 : )
954 : {
955 20393 : Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
956 : Word16 Ei_fx, g_code_fx, gcode0_fx;
957 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
958 : Word32 L_tmp, L_tmp1;
959 20393 : Word16 wgain_code = 0, gain_code16;
960 20393 : *gain_pit_fx = 0;
961 20393 : move16();
962 20393 : move16();
963 20393 : move16();
964 :
965 : /*----------------------------------------------------------------*
966 : * get number of bits for gain quantization
967 : *----------------------------------------------------------------*/
968 20393 : nBits = gains_mode[shr( i_subfr, 6 )];
969 :
970 : /*----------------------------------------------------------------*
971 : * find the code pitch (for current subframe)
972 : *----------------------------------------------------------------*/
973 :
974 : /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
975 : /* Compute scalar product <y2[],y2[]> */
976 20393 : L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
977 20393 : exp_den = norm_l( L_tmp );
978 20393 : den = extract_h( L_shl( L_tmp, exp_den ) );
979 20393 : exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
980 :
981 : /* Compute scalar product <xn[],y2[]> */
982 20393 : L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */
983 20393 : exp_num = sub( norm_l( L_tmp1 ), 1 );
984 20393 : num = extract_h( L_shl( L_tmp1, exp_num ) );
985 20393 : exp_num = sub( add( exp_num, 8 ), Q_xn );
986 :
987 20393 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
988 20393 : num = abs_s( num );
989 :
990 : /*----------------------------------------------------------------*
991 : * compute gain = xy/yy
992 : *----------------------------------------------------------------*/
993 20393 : g_code_fx = div_s( num, den );
994 :
995 20393 : i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */
996 20393 : g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
997 20393 : *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i );
998 20393 : move32();
999 :
1000 : /*----------------------------------------------------------------*
1001 : * calculate the predicted gain code
1002 : * decode codebook gain
1003 : *----------------------------------------------------------------*/
1004 :
1005 20393 : *gain_pit_fx = 0;
1006 20393 : move16();
1007 :
1008 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
1009 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
1010 :
1011 20393 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
1012 20393 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1013 20393 : expg2 = expg;
1014 20393 : move16();
1015 20393 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1016 20393 : move32();
1017 20393 : L_tmp = Isqrt_lc( L_tmp, &expg );
1018 :
1019 20393 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
1020 20393 : move16(); /* gain_inov in Q12 */
1021 :
1022 : /*Ei = 10 * (float)log10( Ecode );*/
1023 20393 : e_tmp = norm_l( L_tmp1 );
1024 20393 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1025 20393 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1026 20393 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1027 20393 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1028 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1029 20393 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
1030 : /*-----------------------------------------------------------------*
1031 : * gcode0 = pow(10.0, gcode0/20)
1032 : * = pow(2, 3.321928*gcode0/20)
1033 : * = pow(2, 0.166096*gcode0)
1034 : *-----------------------------------------------------------------*/
1035 20393 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1036 20393 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1037 20393 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1038 20393 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1039 20393 : exp_gcode0 = sub( exp_gcode0, 14 );
1040 20393 : IF( GT_16( nBits, 3 ) )
1041 : {
1042 : /*g_code = *gain_code / gcode0;*/
1043 1457 : IF( gcode0_fx != 0 )
1044 : {
1045 1457 : tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/
1046 1457 : L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/
1047 1457 : *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1048 1457 : move32();
1049 : }
1050 : ELSE
1051 : {
1052 0 : *gain_code_fx = MAX_32;
1053 0 : move32();
1054 : }
1055 :
1056 : /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
1057 1457 : index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
1058 :
1059 : /**gain_code = g_code * gcode0;*/
1060 1457 : L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/
1061 1457 : *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1062 1457 : move32();
1063 :
1064 1457 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1065 : }
1066 : ELSE
1067 : {
1068 18936 : index = N_GAIN_CODE_TC - 1;
1069 18936 : move16();
1070 63617 : FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
1071 : {
1072 62741 : L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
1073 62741 : L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */
1074 :
1075 62741 : IF( LT_32( *gain_code_fx, L_tmp ) )
1076 : {
1077 18060 : index = i;
1078 18060 : move16();
1079 18060 : BREAK;
1080 : }
1081 : }
1082 : /*----------------------------------------------------------------*
1083 : * 3-bit -> 2-bit encoding
1084 : *----------------------------------------------------------------*/
1085 18936 : IF( EQ_16( nBits, 2 ) )
1086 : {
1087 : /* 2-bit -> 3-bit decoding */
1088 0 : index = shr( index, 1 );
1089 0 : wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )];
1090 0 : move16();
1091 : /**gain_code *= gcode0;*/
1092 0 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1093 0 : *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
1094 0 : move32(); /* Q14 -> Q16 */
1095 0 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1096 : }
1097 : ELSE /* nBits == 3 */
1098 : {
1099 18936 : wgain_code = tbl_gain_code_tc_fx[index];
1100 18936 : move16();
1101 : /**gain_code *= gcode0;*/
1102 18936 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1103 18936 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
1104 18936 : move32(); /* Q14 -> Q16 */
1105 18936 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1106 : }
1107 : }
1108 :
1109 : /*-----------------------------------------------------------------*
1110 : * decode normalized codebook gain
1111 : *-----------------------------------------------------------------*/
1112 : /**norm_gain_code = *gain_code / *gain_inov;*/
1113 20393 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1114 20393 : expg = s_max( expg, 0 );
1115 :
1116 20393 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
1117 20393 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16
1118 20393 : move32();
1119 20393 : return;
1120 : }
1121 : /*-----------------------------------------------------------------*
1122 : * Find_Opt_gainQ_fx()
1123 : *
1124 : * Find the best quantizer
1125 : *-----------------------------------------------------------------*/
1126 541572 : static Word16 Find_Opt_gainQ_fx(
1127 : Word16 *coeff, /* exp(exp_coeff) */
1128 : Word16 *exp_coeff,
1129 : Word16 *gain_pit, /* Q14 */
1130 : Word32 *gain_code, /* Q16 */
1131 : Word16 gcode0, /* exp(exp_gcode0) */
1132 : Word16 exp_gcode0,
1133 : const Word16 *cdbk, /* i : Codebook used Q14*/
1134 : const Word16 size /* i : size of Codebook used Q0*/
1135 : )
1136 : {
1137 : Word16 index, i, j;
1138 : const Word16 *p;
1139 : Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
1140 : Word32 dist_min;
1141 : Word16 coeff_lo[5];
1142 : Word16 exp_max[5];
1143 : Word16 exp_code, e_max;
1144 : Word32 L_tmp, L_tmp1;
1145 : #ifndef ISSUE_1867_replace_overflow_libenc
1146 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1147 : Flag Overflow = 0;
1148 : move32();
1149 : #endif
1150 : #endif
1151 :
1152 :
1153 : /*----------------------------------------------------------------*
1154 : * Find the best quantizer
1155 : * ~~~~~~~~~~~~~~~~~~~~~~~
1156 : * Before doing the computation we need to align exponents of coeff[]
1157 : * to be sure to have the maximum precision.
1158 : *
1159 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
1160 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
1161 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
1162 : * we divide by 2^15.
1163 : * Considering all the scaling above we have:
1164 : *
1165 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
1166 : *
1167 : * g_pitch*g_pitch = -14-14+15
1168 : * g_pitch = -14
1169 : * g_code*g_code = (2*exp_code)+15
1170 : * g_code = exp_code
1171 : * g_pitch*g_code = -14 + exp_code +15
1172 : *
1173 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
1174 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
1175 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
1176 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
1177 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
1178 : *----------------------------------------------------------------*/
1179 :
1180 541572 : exp_code = add( exp_gcode0, 6 );
1181 :
1182 541572 : exp_max[0] = sub( exp_coeff[0], 13 );
1183 541572 : move16();
1184 541572 : exp_max[1] = sub( exp_coeff[1], 14 );
1185 541572 : move16();
1186 541572 : exp_max[2] = add( exp_coeff[2], add( 15, shl( exp_code, 1 ) ) );
1187 541572 : move16();
1188 541572 : exp_max[3] = add( exp_coeff[3], exp_code );
1189 541572 : move16();
1190 541572 : exp_max[4] = add( exp_coeff[4], add( 1, exp_code ) );
1191 541572 : move16();
1192 :
1193 : /* Find maximum exponant */
1194 541572 : e_max = exp_max[0];
1195 541572 : move16();
1196 2707860 : FOR( i = 1; i < 5; i++ )
1197 : {
1198 2166288 : e_max = s_max( exp_max[i], e_max );
1199 : }
1200 :
1201 : /* align coeff[] and save in special 32 bit double precision */
1202 3249432 : FOR( i = 0; i < 5; i++ )
1203 : {
1204 2707860 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
1205 2707860 : L_tmp = L_deposit_h( coeff[i] );
1206 2707860 : L_tmp = L_shr( L_tmp, j );
1207 2707860 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
1208 2707860 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
1209 2707860 : move16();
1210 : }
1211 :
1212 : /* searching of codebook */
1213 541572 : p = cdbk; // Q14
1214 541572 : move16();
1215 541572 : dist_min = L_deposit_h( MAX_16 );
1216 541572 : index = 0;
1217 541572 : move16();
1218 35546928 : FOR( i = 0; i < size; i++ )
1219 : {
1220 35005356 : g_pitch = *p++;
1221 35005356 : move16();
1222 35005356 : g_code = *p++;
1223 35005356 : move16();
1224 :
1225 35005356 : g_code = mult_r( g_code, gcode0 ); // exp_gcode - 1
1226 35005356 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
1227 35005356 : g_pit_cod = mult_r( g_code, g_pitch );
1228 35005356 : L_tmp = L_mult( g_code, g_code );
1229 35005356 : g2_code_lo = L_Extract_lc( L_tmp, &g2_code );
1230 :
1231 35005356 : L_tmp = L_mult( coeff[2], g2_code_lo );
1232 35005356 : L_tmp = L_shr( L_tmp, 3 );
1233 35005356 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
1234 35005356 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
1235 35005356 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
1236 35005356 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
1237 35005356 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
1238 35005356 : L_tmp = L_shr( L_tmp, 12 );
1239 35005356 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
1240 35005356 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
1241 35005356 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
1242 35005356 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
1243 35005356 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
1244 :
1245 : #ifdef ISSUE_1867_replace_overflow_libenc
1246 35005356 : L_tmp1 = L_sub_sat( L_tmp, dist_min );
1247 : #else
1248 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
1249 : #endif
1250 35005356 : if ( L_tmp1 < 0 )
1251 : {
1252 6790698 : index = i;
1253 6790698 : move16();
1254 : }
1255 35005356 : dist_min = L_min( L_tmp, dist_min );
1256 : }
1257 :
1258 541572 : p = &cdbk[add( index, index )]; // Q14
1259 541572 : move16();
1260 :
1261 541572 : *gain_pit = *p++; /* selected pitch gain in Q14 */
1262 541572 : move16();
1263 541572 : g_code = *p++; /* selected code gain in Q9 */
1264 541572 : move16();
1265 :
1266 541572 : L_tmp = L_mult( g_code, gcode0 ); /* Q9*Q0 -> Q10 */
1267 541572 : L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */
1268 541572 : *gain_code = L_tmp; /* gain of code in Q16 */
1269 541572 : move16();
1270 541572 : return index;
1271 : }
1272 : /*---------------------------------------------------------------------*
1273 : * gain_enc_lbr()
1274 : *
1275 : * Quantization of pitch and codebook gains without prediction (memory-less)
1276 : * in ACELP at 6.6 and 7.5 kbps
1277 : * - the gain codebooks and gain estimation constants are different in each subframe
1278 : * - the estimated gain, gcode0, is first determined based on
1279 : * classification and/or previous quantized gains (from previous subframes in the current frame)
1280 : * - a correction factor gamma = g_code / gcode0 is then vector quantized
1281 : * along with gain_pit
1282 : * - the mean-squared error criterion is used for codebook search
1283 : *---------------------------------------------------------------------*/
1284 :
1285 17652 : void gain_enc_lbr_fx(
1286 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1287 : const Word16 gains_mode[], /* i : gain bits Q0*/
1288 : const Word16 coder_type, /* i : coding type Q0*/
1289 : const Word16 i_subfr, /* i : subframe index Q0*/
1290 : const Word16 *xn, /* i : target vector Q_xn*/
1291 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
1292 : const Word16 Q_xn, /* i : xn and y1 format */
1293 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
1294 : const Word16 *code, /* i : algebraic excitation Q9*/
1295 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
1296 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
1297 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
1298 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
1299 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
1300 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
1301 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
1302 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
1303 : const Word16 L_subfr /* i : subframe length Q0*/
1304 : ,
1305 : const Word16 element_mode /* i : mode element Q0*/
1306 : )
1307 : {
1308 :
1309 17652 : Word16 index = 0, size, nBits, n_pred, ctype;
1310 17652 : const Word16 *b, *cdbk = 0;
1311 : Word16 gcode0, aux[10];
1312 : Word16 coeff[5], exp_coeff[5];
1313 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
1314 : Word32 L_tmp, L_tmp1, L_inov;
1315 17652 : move16();
1316 17652 : move16();
1317 :
1318 17652 : L_subfr_sf = 6;
1319 17652 : move16();
1320 17652 : if ( GT_16( L_subfr, L_SUBFR ) )
1321 : {
1322 4092 : L_subfr_sf = 7;
1323 4092 : move16();
1324 : }
1325 : /*-----------------------------------------------------------------*
1326 : * calculate the rest of the correlation coefficients
1327 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
1328 : * c5* - not necessary to calculate
1329 : *-----------------------------------------------------------------*/
1330 :
1331 17652 : coeff[0] = g_corr[0];
1332 17652 : move16();
1333 17652 : exp_coeff[0] = g_corr[1];
1334 17652 : move16();
1335 17652 : coeff[1] = negate( g_corr[2] );
1336 17652 : move16(); /* coeff[1] = -2 xn yy1 */
1337 17652 : exp_coeff[1] = add( g_corr[3], 1 );
1338 17652 : move16();
1339 :
1340 : /* Compute scalar product <y2[],y2[]> */
1341 17652 : coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
1342 17652 : move16();
1343 17652 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
1344 17652 : move16();
1345 :
1346 : /* Compute scalar product -2*<xn[],y2[]> */
1347 :
1348 17652 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
1349 17652 : move16();
1350 17652 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
1351 17652 : move16();
1352 :
1353 : /* Compute scalar product 2*<y1[],y2[]> */
1354 :
1355 17652 : coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
1356 17652 : move16();
1357 17652 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
1358 17652 : move16();
1359 :
1360 : /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
1361 :
1362 : /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
1363 : *gain_inov = 1.0f / (float)sqrt(Ecode);*/
1364 17652 : L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
1365 17652 : L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
1366 17652 : move32();
1367 : /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
1368 : /* output gain_inov*/
1369 17652 : exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
1370 17652 : L_inov = Isqrt_lc( L_inov, &exp_inov );
1371 17652 : *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
1372 17652 : move16();
1373 :
1374 :
1375 : /*-----------------------------------------------------------------*
1376 : * select the codebook, size and number of bits
1377 : * set the gains searching range
1378 : *-----------------------------------------------------------------*/
1379 :
1380 17652 : nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
1381 17652 : move16();
1382 17652 : size = shl( 1, nBits );
1383 :
1384 17652 : ctype = shl( sub( coder_type, 1 ), 1 );
1385 :
1386 : /*-----------------------------------------------------------------*
1387 : * calculate prediction of gcode
1388 : * search for the best codeword
1389 : *-----------------------------------------------------------------*/
1390 17652 : test();
1391 17652 : IF( i_subfr == 0 )
1392 : {
1393 5436 : b = b_1sfr_fx; // Q12
1394 5436 : move16();
1395 5436 : n_pred = 2;
1396 5436 : move16();
1397 :
1398 5436 : SWITCH( nBits )
1399 : {
1400 2189 : case 8:
1401 : {
1402 2189 : cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
1403 2189 : if ( EQ_16( clip_gain, 1 ) )
1404 : {
1405 0 : size = sub( size, 60 );
1406 : }
1407 2189 : BREAK;
1408 : }
1409 440 : case 7:
1410 : {
1411 440 : cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
1412 440 : if ( EQ_16( clip_gain, 1 ) )
1413 : {
1414 0 : size = sub( size, 27 );
1415 : }
1416 440 : BREAK;
1417 : }
1418 2807 : case 6:
1419 : {
1420 2807 : cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
1421 2807 : if ( EQ_16( clip_gain, 1 ) )
1422 : {
1423 0 : size = sub( size, 10 );
1424 : }
1425 2807 : BREAK;
1426 : }
1427 : }
1428 :
1429 : /* calculate predicted gain */
1430 5436 : aux[0] = 4096; /* 1 in Q12 */
1431 5436 : move16();
1432 5436 : aux[1] = shl( ctype, 12 );
1433 5436 : move16();
1434 :
1435 : /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
1436 : gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
1437 : gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
1438 :
1439 5436 : IF( element_mode > EVS_MONO )
1440 : {
1441 : // Ecode = (Ecode / L_subfr)
1442 5436 : L_tmp = L_shr( L_tmp, L_subfr_sf ); // Q19 + (Q30-exp_code)
1443 : /* Calculation for log10(Ecode) exponent for applying log10 = Q31 - q = Q31 - Q19 - Q30 + exp_code = exp_code - Q18*/
1444 5436 : L_tmp = BASOP_Util_Log10( L_tmp, sub( exp_code, 18 ) ); // new q = Q25
1445 5436 : exp = norm_l( L_tmp );
1446 5436 : L_tmp = L_shl( L_tmp, exp ); // Q25 + exp
1447 : // 10 in Q27 , ( 10 * log10( Ecode ) )
1448 5436 : L_tmp1 = Mpy_32_32( L_tmp, 1342177280 ); // Q25 + exp + 1 + Q27 - 32 = Q21 + exp
1449 5436 : L_tmp1 = L_shr( L_tmp1, add( 7, exp ) ); // Q21 + exp - 7 - exp = Q14
1450 : }
1451 : ELSE
1452 : {
1453 0 : exp_code = sub( exp_code, 18 + 6 + 1 );
1454 0 : exp = norm_l( L_tmp );
1455 0 : frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
1456 0 : exp = sub( exp_code, exp );
1457 0 : L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
1458 : }
1459 5436 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
1460 5436 : L_tmp = Mult_32_16( L_tmp, 320 ); /*Q14, 20 in Q4*/
1461 5436 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q14*/
1462 :
1463 5436 : gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
1464 :
1465 : /*-----------------------------------------------------------------*
1466 : * gcode0 = pow(10.0, gcode0/20)
1467 : * = pow(2, 3.321928*gcode0/20)
1468 : * = pow(2, 0.166096*gcode0)
1469 : *-----------------------------------------------------------------*/
1470 :
1471 5436 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
1472 5436 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1473 5436 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1474 :
1475 5436 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1476 : /* output of Pow2() will be: */
1477 : /* 16384 < Pow2() <= 32767 */
1478 5436 : exp_gcode0 = sub( exp_gcode0, 14 );
1479 5436 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
1480 :
1481 5436 : gc_mem[0] = *gain_code;
1482 5436 : move16(); /*Q16*/
1483 5436 : gp_mem[0] = *gain_pit;
1484 5436 : move16(); /*Q14*/
1485 : }
1486 12216 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
1487 : {
1488 5436 : b = b_2sfr_fx;
1489 5436 : move16();
1490 5436 : n_pred = 4;
1491 5436 : move16();
1492 :
1493 5436 : switch ( nBits )
1494 : {
1495 2187 : case 7:
1496 : {
1497 2187 : cdbk = gp_gamma_2sfr_7b_fx; /* Q14/Q9 */
1498 2187 : if ( EQ_16( clip_gain, 1 ) )
1499 : {
1500 0 : size = sub( size, 30 );
1501 : }
1502 2187 : BREAK;
1503 : }
1504 3249 : case 6:
1505 : {
1506 3249 : cdbk = gp_gamma_2sfr_6b_fx; /* Q14/Q9 */
1507 3249 : if ( EQ_16( clip_gain, 1 ) )
1508 : {
1509 0 : size = sub( size, 12 );
1510 : }
1511 3249 : BREAK;
1512 : }
1513 : }
1514 :
1515 : /* calculate predicted gain */
1516 5436 : aux[0] = 4096; /* 1 in Q12 */
1517 5436 : move16();
1518 5436 : aux[1] = shl( ctype, 12 );
1519 5436 : move16();
1520 :
1521 : /*aux[2] = (float)log10(gc_mem[0]);
1522 : = log2(gc_mem[0])*log10(2);*/
1523 5436 : exp = norm_l( gc_mem[0] );
1524 5436 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
1525 5436 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
1526 5436 : L_tmp1 = Mpy_32_16( exp, frac, 9864 );
1527 5436 : move16(); /* Q16 */
1528 5436 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1529 5436 : move16();
1530 :
1531 5436 : aux[3] = shr( gp_mem[0], 2 );
1532 5436 : move16(); /*Q12*/
1533 :
1534 : /*-----------------------------------------------------------------*
1535 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1536 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1537 : *-----------------------------------------------------------------*/
1538 5436 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
1539 5436 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1540 5436 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1541 5436 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1542 :
1543 5436 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1544 : /* output of Pow2() will be: */
1545 : /* 16384 < Pow2() <= 32767 */
1546 5436 : exp_gcode0 = sub( exp_gcode0, 14 );
1547 :
1548 5436 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
1549 5436 : gc_mem[1] = *gain_code; // Q16
1550 5436 : move32();
1551 5436 : gp_mem[1] = *gain_pit; // Q14
1552 5436 : move16();
1553 : }
1554 6780 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
1555 : {
1556 3390 : b = b_3sfr_fx; // Q12
1557 3390 : move16();
1558 3390 : n_pred = 6;
1559 3390 : move16();
1560 3390 : IF( EQ_16( nBits, 7 ) )
1561 : {
1562 2 : cdbk = gp_gamma_3sfr_7b_fx;
1563 2 : if ( clip_gain == 1 )
1564 : {
1565 0 : size -= 28;
1566 : }
1567 : }
1568 : ELSE
1569 : {
1570 3388 : cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
1571 3388 : if ( EQ_16( clip_gain, 1 ) )
1572 : {
1573 0 : size = sub( size, 11 );
1574 : }
1575 : }
1576 : /* calculate predicted gain */
1577 3390 : aux[0] = 4096; /* 1 in Q12 */
1578 3390 : move16();
1579 3390 : aux[1] = shl( ctype, 12 );
1580 3390 : move16();
1581 :
1582 : /*aux[2] = (float)log10(gc_mem[0]);
1583 : = log2(gc_mem[0])*log10(2);*/
1584 3390 : exp = norm_l( gc_mem[0] );
1585 3390 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
1586 3390 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
1587 3390 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
1588 3390 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1589 3390 : move16();
1590 :
1591 : /*aux[3] = (float)log10(gc_mem[1]);
1592 : = log2(gc_mem[1])*log10(2);*/
1593 3390 : exp = norm_l( gc_mem[1] );
1594 3390 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
1595 3390 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
1596 3390 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
1597 3390 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1598 3390 : move16();
1599 :
1600 3390 : aux[4] = shr( gp_mem[0], 2 );
1601 3390 : move16(); /*Q12*/
1602 3390 : aux[5] = shr( gp_mem[1], 2 );
1603 3390 : move16(); /*Q12*/
1604 :
1605 : /*-----------------------------------------------------------------*
1606 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1607 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1608 : *-----------------------------------------------------------------*/
1609 3390 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
1610 3390 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1611 3390 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1612 3390 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1613 :
1614 3390 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1615 : /* output of Pow2() will be: */
1616 : /* 16384 < Pow2() <= 32767 */
1617 3390 : exp_gcode0 = sub( exp_gcode0, 14 );
1618 :
1619 : /*----------------------------------------------------------------*
1620 : * Find the best quantizer
1621 : * ~~~~~~~~~~~~~~~~~~~~~~~
1622 : * Before doing the computation we need to align exponents of coeff[]
1623 : * to be sure to have the maximum precision.
1624 : *
1625 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
1626 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
1627 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
1628 : * we divide by 2^15.
1629 : * Considering all the scaling above we have:
1630 : *
1631 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
1632 : *
1633 : * g_pitch*g_pitch = -14-14+15
1634 : * g_pitch = -14
1635 : * g_code*g_code = (2*exp_code)+15
1636 : * g_code = exp_code
1637 : * g_pitch*g_code = -14 + exp_code +15
1638 : *
1639 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
1640 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
1641 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
1642 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
1643 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
1644 : *----------------------------------------------------------------*/
1645 :
1646 3390 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
1647 :
1648 3390 : gc_mem[2] = *gain_code; // Q16
1649 3390 : move32();
1650 3390 : gp_mem[2] = *gain_pit; // Q14
1651 3390 : move16();
1652 : }
1653 3390 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
1654 : {
1655 3390 : b = b_4sfr_fx; // Q12
1656 3390 : move16();
1657 3390 : n_pred = 8;
1658 3390 : move16();
1659 3390 : IF( EQ_16( nBits, 7 ) )
1660 : {
1661 0 : cdbk = gp_gamma_4sfr_7b_fx;
1662 0 : if ( clip_gain == 1 )
1663 : {
1664 0 : size -= 25;
1665 : }
1666 : }
1667 : ELSE
1668 : {
1669 3390 : cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
1670 3390 : if ( EQ_16( clip_gain, 1 ) )
1671 : {
1672 0 : size = sub( size, 11 );
1673 : }
1674 : }
1675 : /* calculate predicted gain */
1676 3390 : aux[0] = 4096; /* 1 in Q12 */
1677 3390 : move16();
1678 3390 : aux[1] = shl( ctype, 12 );
1679 3390 : move16();
1680 :
1681 : /*aux[2] = (float)log10(gc_mem[0]);
1682 : = log2(gc_mem[0])*log10(2);*/
1683 3390 : exp = norm_l( gc_mem[0] );
1684 3390 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
1685 3390 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
1686 3390 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
1687 3390 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1688 3390 : move16();
1689 :
1690 : /*aux[3] = (float)log10(gc_mem[1]);
1691 : = log2(gc_mem[1])*log10(2);*/
1692 3390 : exp = norm_l( gc_mem[1] );
1693 3390 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
1694 3390 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
1695 3390 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
1696 3390 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1697 3390 : move16();
1698 :
1699 :
1700 : /*aux[4] = (float)log10(gc_mem[2]);
1701 : = log2(gc_mem[2])*log10(2);*/
1702 3390 : exp = norm_l( gc_mem[2] );
1703 3390 : frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
1704 3390 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/
1705 3390 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
1706 3390 : aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
1707 3390 : move16();
1708 :
1709 3390 : aux[5] = shr( gp_mem[0], 2 );
1710 3390 : move16(); /*Q12*/
1711 3390 : aux[6] = shr( gp_mem[1], 2 );
1712 3390 : move16(); /*Q12*/
1713 3390 : aux[7] = shr( gp_mem[2], 2 );
1714 3390 : move16(); /*Q12*/
1715 : /*-----------------------------------------------------------------*
1716 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
1717 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
1718 : *-----------------------------------------------------------------*/
1719 3390 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
1720 3390 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
1721 3390 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
1722 3390 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1723 :
1724 3390 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1725 : /* output of Pow2() will be: */
1726 : /* 16384 < Pow2() <= 32767 */
1727 3390 : exp_gcode0 = sub( exp_gcode0, 14 );
1728 :
1729 3390 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
1730 : }
1731 :
1732 : /* *norm_gain_code = *gain_code / *gain_inov; */
1733 17652 : exp = sub( norm_s( *gain_inov ), 1 );
1734 17652 : exp = s_max( exp, 0 );
1735 :
1736 17652 : tmp = div_s( shr( 8192, exp ), *gain_inov );
1737 17652 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
1738 17652 : move32();
1739 : {
1740 17652 : push_indice( hBstr, IND_GAIN, index, nBits );
1741 : }
1742 17652 : return;
1743 : }
1744 :
1745 : /*-------------------------------------------------------------------*
1746 : * gain_enc_amr_wb()
1747 : *
1748 : * Quantization of pitch and codebook gains (used also in AMR-WB IO mode)
1749 : * MA prediction is performed on the innovation energy (in dB with mean removed).
1750 : * An initial predicted gain, gcode0, is first determined and the correction
1751 : * factor alpha = g_code / gcode0 is quantized.
1752 : * The pitch gain and the correction factor are vector quantized and the
1753 : * mean-squared weighted error criterion is used in the quantizer search.
1754 : *-------------------------------------------------------------------*/
1755 :
1756 :
1757 0 : void gain_enc_amr_wb_fx(
1758 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1759 : const Word16 *xn, /* i : target vector Q_xn*/
1760 : const Word16 Q_xn, /* i : xn and yy1 format */
1761 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
1762 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
1763 : const Word16 *code, /* i : algebraic excitation Q9*/
1764 : const Word32 core_brate, /* i : core bitrate Q0*/
1765 : Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain Q14*/
1766 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
1767 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
1768 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
1769 : Word16 *g_coeff, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
1770 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
1771 : Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Q10*/
1772 : )
1773 : {
1774 :
1775 : Word16 i, j, index, min_ind, size;
1776 : Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, exp_inov, qua_ener;
1777 : Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
1778 : Word16 coeff[5], coeff_lo[5], exp_coeff[5];
1779 : Word16 exp_max[5], tmp, nBits;
1780 : Word32 L_tmp, dist_min, L_inov, L_tmp1;
1781 : const Word16 *t_qua_gain, *p;
1782 : #ifndef ISSUE_1867_replace_overflow_libenc
1783 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1784 : Flag Overflow = 0;
1785 : move32();
1786 : #endif
1787 : #endif
1788 :
1789 : /*----------------------------------------------------------------*
1790 : * Find the initial quantization pitch index
1791 : * Set gains search range
1792 : *----------------------------------------------------------------*/
1793 0 : IF( GE_32( core_brate, ACELP_12k65 ) )
1794 : {
1795 0 : t_qua_gain = t_qua_gain7b_fx; // Q14
1796 0 : move16();
1797 : /* pt at 1/4th of table */
1798 0 : p = t_qua_gain7b_fx + RANGE;
1799 0 : move16();
1800 :
1801 0 : j = NB_QUA_GAIN7B - RANGE;
1802 0 : move16();
1803 :
1804 0 : IF( EQ_16( clip_gain, 1 ) )
1805 : {
1806 0 : j = sub( j, 27 ); /* limit gain pitch to 1.0 */
1807 : }
1808 0 : min_ind = 0;
1809 0 : move16();
1810 0 : g_pitch = *gain_pit; // Q14
1811 0 : move16();
1812 :
1813 0 : FOR( i = 0; i < j; i++ )
1814 : {
1815 0 : if ( GT_16( g_pitch, *p ) )
1816 : {
1817 0 : min_ind = add( min_ind, 1 ); // Q0
1818 : }
1819 0 : p += 2;
1820 : }
1821 0 : size = RANGE;
1822 0 : move16();
1823 0 : nBits = 7;
1824 : }
1825 : ELSE
1826 : {
1827 0 : t_qua_gain = t_qua_gain6b_fx; // Q14
1828 0 : min_ind = 0;
1829 0 : move16();
1830 0 : size = RANGE;
1831 0 : move16();
1832 0 : if ( EQ_16( clip_gain, 1 ) )
1833 : {
1834 0 : size = sub( size, 16 ); /* limit gain pitch to 1.0 */
1835 : }
1836 0 : nBits = 6;
1837 : }
1838 : /*----------------------------------------------------------------*
1839 : * Compute coefficients needed for the quantization.
1840 : *
1841 : * coeff[0] = yy1 yy1
1842 : * coeff[1] = -2 xn yy1
1843 : * coeff[2] = y2 y2
1844 : * coeff[3] = -2 xn y2
1845 : * coeff[4] = 2 yy1 y2
1846 : *
1847 : * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
1848 : * are in vector g_coeff[].
1849 : *----------------------------------------------------------------*/
1850 0 : coeff[0] = g_coeff[0];
1851 0 : move16();
1852 0 : exp_coeff[0] = g_coeff[1];
1853 0 : move16();
1854 0 : coeff[1] = negate( g_coeff[2] );
1855 0 : move16(); /* coeff[1] = -2 xn yy1 */
1856 0 : exp_coeff[1] = add( g_coeff[3], 1 );
1857 0 : move16();
1858 :
1859 : /* Compute scalar product <y2[],y2[]> */
1860 0 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
1861 0 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
1862 0 : move16();
1863 0 : move16();
1864 :
1865 : /* Compute scalar product -2*<xn[],y2[]> */
1866 0 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
1867 0 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
1868 0 : move16();
1869 0 : move16();
1870 :
1871 : /* Compute scalar product 2*<yy1[],y2[]> */
1872 0 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
1873 0 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
1874 0 : move16();
1875 0 : move16();
1876 :
1877 : /*----------------------------------------------------------------*
1878 : * Find energy of code and compute:
1879 : *
1880 : * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)
1881 : * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)
1882 : *----------------------------------------------------------------*/
1883 0 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
1884 0 : L_inov = L_add( L_tmp, 0 );
1885 : /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
1886 : /* output gain_inov*/
1887 0 : exp_inov = sub( exp_code, 18 + 6 );
1888 0 : L_inov = Isqrt_lc( L_inov, &exp_inov );
1889 0 : *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
1890 0 : move16();
1891 :
1892 0 : exp_code = sub( exp_code, 18 + 6 + 31 );
1893 0 : frac = Log2_lc( L_tmp, &exp );
1894 0 : exp = add( exp, exp_code );
1895 0 : L_tmp = Mpy_32_16( exp, frac, -24660 ); /* x -3.0103(Q13) -> Q14 */
1896 :
1897 0 : L_tmp = L_mac( L_tmp, MEAN_ENER, 8192 ); /* + MEAN_ENER in Q14 */
1898 :
1899 : /*----------------------------------------------------------------*
1900 : * predicted codebook gain
1901 : *----------------------------------------------------------------*/
1902 0 : L_tmp = L_shl( L_tmp, 10 ); /* From Q14 to Q24 */
1903 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[0], past_qua_en[0] ); /* Q14*Q10 -> Q24 */
1904 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[1], past_qua_en[1] ); /* Q14*Q10 -> Q24 */
1905 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[2], past_qua_en[2] ); /* Q14*Q10 -> Q24 */
1906 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[3], past_qua_en[3] ); /* Q14*Q10 -> Q24 */
1907 :
1908 0 : gcode0 = extract_h( L_tmp ); /* From Q24 to Q8 */
1909 :
1910 : /*----------------------------------------------------------------*
1911 : * gcode0 = pow(10.0, gcode0/20)
1912 : * = pow(2, 3.321928*gcode0/20)
1913 : * = pow(2, 0.166096*gcode0)
1914 : *----------------------------------------------------------------*/
1915 0 : L_tmp = L_mult( gcode0, 5443 ); /* *0.166096 in Q15 -> Q24 */
1916 0 : L_tmp = L_shr( L_tmp, 8 ); /* From Q24 to Q16 */
1917 0 : L_Extract( L_tmp, &exp_gcode0, &frac ); /* Extract exponent of gcode0 */
1918 :
1919 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1920 : /* output of Pow2() will be: */
1921 : /* 16384 < Pow2() <= 32767 */
1922 0 : exp_gcode0 = sub( exp_gcode0, 14 );
1923 :
1924 : /*----------------------------------------------------------------*
1925 : * Find the best quantizer
1926 : * ~~~~~~~~~~~~~~~~~~~~~~~
1927 : * Before doing the computation we need to aling exponents of coeff[]
1928 : * to be sure to have the maximum precision.
1929 : *
1930 : * In the table the pitch gains are in Q14, the code gains are in Q11 and
1931 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
1932 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
1933 : * we divide by 2^15.
1934 : * Considering all the scaling above we have:
1935 : *
1936 : * exp_code = exp_gcode0-11+15 = exp_gcode0+4
1937 : *
1938 : * g_pitch*g_pitch = -14-14+15
1939 : * g_pitch = -14
1940 : * g_code*g_code = (2*exp_code)+15
1941 : * g_code = exp_code
1942 : * g_pitch*g_code = -14 + exp_code +15
1943 : *
1944 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
1945 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
1946 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
1947 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
1948 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
1949 : *----------------------------------------------------------------*/
1950 :
1951 0 : exp_code = add( exp_gcode0, 4 );
1952 :
1953 0 : exp_max[0] = sub( exp_coeff[0], 13 );
1954 0 : move16();
1955 0 : exp_max[1] = sub( exp_coeff[1], 14 );
1956 0 : move16();
1957 0 : exp_max[2] = add( exp_coeff[2],
1958 0 : add( 15, shl( exp_code, 1 ) ) );
1959 0 : move16();
1960 0 : exp_max[3] = add( exp_coeff[3], exp_code );
1961 0 : move16();
1962 0 : exp_max[4] = add( exp_coeff[4],
1963 0 : add( 1, exp_code ) );
1964 0 : move16();
1965 :
1966 : /* Find maximum exponant */
1967 0 : e_max = exp_max[0];
1968 0 : move16();
1969 0 : FOR( i = 1; i < 5; i++ )
1970 : {
1971 0 : e_max = s_max( exp_max[i], e_max );
1972 : }
1973 :
1974 : /* align coeff[] and save in special 32 bit double precision */
1975 0 : FOR( i = 0; i < 5; i++ )
1976 : {
1977 0 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
1978 0 : L_tmp = L_deposit_h( coeff[i] );
1979 0 : L_tmp = L_shr( L_tmp, j );
1980 0 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
1981 0 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
1982 0 : move16();
1983 : }
1984 :
1985 : /* Codebook search */
1986 0 : dist_min = L_add( MAX_32, 0 );
1987 0 : p = &t_qua_gain[shl( min_ind, 1 )]; // Q14
1988 0 : move16();
1989 :
1990 0 : index = 0;
1991 0 : move16();
1992 0 : FOR( i = 0; i < size; i++ )
1993 : {
1994 0 : g_pitch = *p++;
1995 0 : move16();
1996 0 : g_code = *p++;
1997 0 : move16();
1998 :
1999 0 : g_code = mult_r( g_code, gcode0 ); // exp(gcode) - 1
2000 0 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
2001 0 : g_pit_cod = mult_r( g_code, g_pitch );
2002 0 : L_tmp = L_mult( g_code, g_code );
2003 0 : L_Extract( L_tmp, &g2_code, &g2_code_lo );
2004 :
2005 0 : L_tmp = L_mult( coeff[2], g2_code_lo );
2006 0 : L_tmp = L_shr( L_tmp, 3 );
2007 0 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
2008 0 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
2009 0 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
2010 0 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
2011 0 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
2012 0 : L_tmp = L_shr( L_tmp, 12 );
2013 0 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
2014 0 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
2015 0 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
2016 0 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
2017 0 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
2018 :
2019 : #ifdef ISSUE_1867_replace_overflow_libenc
2020 0 : L_tmp1 = L_sub_sat( L_tmp, dist_min );
2021 : #else
2022 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
2023 : #endif
2024 : /* splitting the if cost half the complexity of using IF macro */
2025 0 : if ( L_tmp1 < 0 )
2026 : {
2027 0 : dist_min = L_add( L_tmp, 0 );
2028 : }
2029 0 : if ( L_tmp1 < 0 )
2030 : {
2031 0 : index = i;
2032 0 : move16();
2033 : }
2034 : }
2035 : /* Read the quantized gains */
2036 0 : index = add( index, min_ind );
2037 :
2038 0 : p = &t_qua_gain[add( index, index )];
2039 0 : move16();
2040 0 : *gain_pit = *p++; /* selected pitch gain in Q14 */
2041 0 : move16();
2042 0 : g_code = *p++; /* selected code gain in Q11 */
2043 0 : move16();
2044 :
2045 0 : L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */
2046 : #ifdef ISSUE_1867_replace_overflow_libenc
2047 0 : L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 4 ) ); /* Q12 -> Q16 */
2048 : #else
2049 : L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */
2050 : #endif
2051 :
2052 0 : *gain_code = L_tmp; /* gain of code in Q16 */
2053 0 : move16();
2054 :
2055 : /*---------------------------------------------------*
2056 : * qua_ener = 20*log10(g_code)
2057 : * = 6.0206*log2(g_code)
2058 : * = 6.0206*(log2(g_codeQ11) - 11)
2059 : *---------------------------------------------------*/
2060 0 : L_tmp = L_deposit_l( g_code );
2061 0 : frac = Log2_lc( L_tmp, &exp );
2062 0 : exp = sub( exp, 11 );
2063 0 : L_tmp = Mpy_32_16( exp, frac, 24660 ); /* x 6.0206 in Q12 */
2064 :
2065 0 : qua_ener = extract_l( L_shr( L_tmp, 3 ) ); /* result in Q10 */
2066 :
2067 : /*----------------------------------------------------------------*
2068 : * update table of past quantized energies
2069 : *----------------------------------------------------------------*/
2070 :
2071 0 : past_qua_en[3] = past_qua_en[2]; // Q10
2072 0 : move16();
2073 0 : past_qua_en[2] = past_qua_en[1]; // Q10
2074 0 : move16();
2075 0 : past_qua_en[1] = past_qua_en[0]; // Q10
2076 0 : move16();
2077 0 : past_qua_en[0] = qua_ener; // Q10
2078 0 : move16();
2079 :
2080 :
2081 0 : exp = sub( norm_s( *gain_inov ), 1 );
2082 0 : exp = s_max( exp, 0 );
2083 :
2084 0 : tmp = div_s( shr( 8192, exp ), *gain_inov );
2085 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
2086 0 : move32();
2087 :
2088 0 : push_indice( hBstr, IND_GAIN, index, nBits );
2089 :
2090 0 : return;
2091 : }
|