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 132997 : 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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
68 132997 : Flag Overflow = 0;
69 132997 : move32();
70 : #endif
71 :
72 132997 : Lmean_ener_code = L_deposit_l( 0 );
73 132997 : Q_res = sub( shl( Q_new, 1 ), 3 );
74 :
75 132997 : IF( EQ_16( L_frame, L_FRAME ) )
76 : {
77 61109 : weight = 8192;
78 61109 : move16(); /*0.25f in Q15*/
79 : }
80 : ELSE /* L_frame == L_FRAME16k */
81 : {
82 71888 : weight = 6554;
83 71888 : move16(); /*0.2f in Q15*/
84 : }
85 :
86 : /*----------------------------------------------------------*
87 : * calculate the average residual signal energy in four sframes
88 : *----------------------------------------------------------*/
89 :
90 736873 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
91 : {
92 : /* calculate the energy of residual signal */
93 603876 : tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
94 603876 : ener_fx = L_mult( tmp16, tmp16 );
95 38648064 : FOR( i = 1; i < L_SUBFR; i++ )
96 : {
97 38044188 : tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
98 38044188 : ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow );
99 : }
100 :
101 : /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */
102 603876 : s1 = 0;
103 603876 : move16();
104 603876 : s0 = norm_l( ener_fx );
105 :
106 603876 : IF( ener_fx != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
107 : {
108 598240 : s1 = Log2_norm_lc( L_shl( ener_fx, s0 ) );
109 598240 : s0 = sub( 30, s0 );
110 : }
111 603876 : s0 = sub( s0, add( Q_res, 6 ) );
112 603876 : Ltmp = Mpy_32_16( s0, s1, LG10 );
113 603876 : ener_dB = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 Energy in log10 */
114 603876 : test();
115 603876 : if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) )
116 : {
117 13270 : ener_dB = 0;
118 13270 : move16();
119 : }
120 :
121 : /* update the average energy of residual signal */
122 603876 : Lmean_ener_code = L_mac( Lmean_ener_code, ener_dB, weight ); /* Q24 */
123 : }
124 :
125 132997 : IF( no_ltp == 0 )
126 : {
127 : /*----------------------------------------------------------*
128 : * subtract an estimate of adaptive codebook contribution
129 : *----------------------------------------------------------*/
130 : /*mean_ener_code -= 10.0f * (0.5f * voicing[0] + 0.5f * voicing[1]);*/
131 130978 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[0], 1280 ); /*Q24*/
132 130978 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[1], 1280 ); /*Q24*/
133 130978 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
134 :
135 : /*----------------------------------------------------------*n
136 : * quantize the average predicted innovation energy
137 : *----------------------------------------------------------*/
138 130978 : SWITCH( nb_bits )
139 : {
140 112834 : case 5:
141 : {
142 112834 : qua_table = Es_pred_qua_5b_fx; // Q8
143 112834 : BREAK;
144 : }
145 17532 : case 4:
146 : {
147 17532 : qua_table = Es_pred_qua_4b_fx; // Q8
148 17532 : BREAK;
149 : }
150 612 : case 3:
151 : {
152 612 : qua_table = Es_pred_qua_3b_fx; // Q8
153 612 : BREAK;
154 : }
155 0 : default:
156 : {
157 0 : qua_table = Es_pred_qua_5b_fx; // Q8
158 0 : BREAK;
159 : }
160 : }
161 : }
162 : ELSE
163 : {
164 2019 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
165 :
166 2019 : qua_table = Es_pred_qua_4b_no_ltp_fx; // Q8
167 : }
168 : /*size = extract_l(pow2_fx[nb_bits]); */ /*maximum number of bit is 6 */
169 132997 : size = shl( 1, nb_bits ); /*maximum number of bit is 6 */
170 :
171 : /* find the nearest neighbour (codevector) */
172 132997 : *Es_pred = qua_table[0]; // Q8
173 132997 : move16();
174 132997 : tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) );
175 132997 : *indice = 0;
176 132997 : move16();
177 :
178 3928400 : FOR( i = 1; i < size; i++ )
179 : {
180 3795403 : tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) );
181 3795403 : IF( LT_16( tmp16_2, tmp16 ) )
182 : {
183 1953171 : tmp16 = tmp16_2;
184 1953171 : move16();
185 1953171 : *indice = i;
186 1953171 : move16();
187 1953171 : *Es_pred = qua_table[i]; // Q8
188 1953171 : move16();
189 : }
190 : }
191 :
192 :
193 132997 : return;
194 : }
195 : /*---------------------------------------------------------------------*
196 : * gain_enc_mless()
197 : *
198 : * Quantization of pitch and codebook gains without prediction (memory-less)
199 : * - an initial predicted gain, gcode0, is first determined based on
200 : * the predicted average innovation energy
201 : * - a correction factor gamma = g_code / gcode0 is then vector quantized along with gain_pit
202 : * - the mean-squared weighted error criterion is used for codebook search
203 : *---------------------------------------------------------------------*/
204 2940 : void gain_enc_mless_fx(
205 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
206 : const Word16 gains_mode[], /* i : gain bits Q0*/
207 : const Word16 element_mode, /* i : element mode Q0*/
208 : const Word16 L_frame, /* i : length of the frame Q0*/
209 : const Word16 i_subfr, /* i : subframe index Q0*/
210 : const Word16 tc_subfr, /* i : TC subframe index Q0*/
211 : const Word16 *xn, /* i : target vector Q_xn*/
212 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
213 : const Word16 Q_xn, /* i : xn and y1 scaling */
214 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
215 : const Word16 *code, /* i : algebraic excitation Q9*/
216 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
217 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
218 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
219 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
220 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
221 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
222 : const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/
223 : )
224 : {
225 :
226 : Word16 index, size, nBits, nBits2;
227 : Word16 gcode0, Ei, gain_code16;
228 : const Word16 *qua_table;
229 : Word16 coeff[5], exp_coeff[5];
230 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
231 : Word32 L_tmp, L_tmp1, L_tmp2;
232 : Word16 tmp1, expg;
233 : Word16 exp1, exp2;
234 : Word16 exp_num, exp_den, exp_div, frac_den;
235 : Word32 L_frac_num, L_frac_den, L_div;
236 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
237 2940 : Flag Overflow = 0;
238 2940 : move32();
239 : #endif
240 :
241 : /*-----------------------------------------------------------------*
242 : * calculate the rest of the correlation coefficients
243 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
244 : *-----------------------------------------------------------------*/
245 :
246 2940 : coeff[0] = g_corr[0];
247 2940 : move16();
248 2940 : exp_coeff[0] = g_corr[1];
249 2940 : move16();
250 2940 : coeff[1] = negate( g_corr[2] );
251 2940 : move16(); /* coeff[1] = -2 xn yy1 */
252 2940 : exp_coeff[1] = add( g_corr[3], 1 );
253 2940 : move16();
254 :
255 : /* Compute scalar product <y2[],y2[]> */
256 2940 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
257 2940 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
258 2940 : move16(); /* -18 (y2 Q9) */
259 :
260 : /* Compute scalar product -2*<xn[],y2[]> */
261 2940 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
262 2940 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
263 2940 : move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
264 :
265 : /* Compute scalar product 2*<y1[],y2[]> */
266 2940 : coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
267 2940 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
268 2940 : move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
269 :
270 : /*-----------------------------------------------------------------*
271 : * calculate the unscaled innovation energy
272 : * calculate the predicted gain code
273 : *-----------------------------------------------------------------*/
274 :
275 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
276 2940 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
277 2940 : exp_inov = sub( exp_code, 18 + 6 );
278 2940 : exp_code = sub( exp_code, 30 );
279 :
280 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
281 :
282 : /*----------------------------------------------------------------*
283 : * calculate the predicted gain code
284 : *----------------------------------------------------------------*/
285 2940 : tmp = norm_l( L_tmp );
286 2940 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
287 2940 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
288 2940 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
289 2940 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
290 :
291 : /* predicted codebook gain */
292 2940 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
293 :
294 : /*---------------------------------------------------------------*
295 : * Decode codebook gain and the adaptive excitation low-pass
296 : * filtering factor (Finalize computation )
297 : *---------------------------------------------------------------*/
298 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
299 2940 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
300 2940 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
301 2940 : move16();
302 :
303 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
304 : /*----------------------------------------------------------------*
305 : * gcode0 = pow(10.0, gcode0/20)
306 : * = pow(2, 3.321928*gcode0/20)
307 : * = pow(2, 0.166096*gcode0)
308 : *----------------------------------------------------------------*/
309 :
310 2940 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
311 2940 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
312 2940 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
313 :
314 2940 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
315 : /* output of Pow2() will be: */
316 : /* 16384 < Pow2() <= 32767 */
317 2940 : exp_gcode0 = sub( exp_gcode0, 14 );
318 :
319 : /*-----------------------------------------------------------------*
320 : * select the codebook, size and number of bits
321 : * set the gains searching range
322 : *-----------------------------------------------------------------*/
323 2940 : nBits = gains_mode[i_subfr >> 6];
324 2940 : move16();
325 :
326 2940 : test();
327 2940 : test();
328 2940 : test();
329 2940 : test();
330 2940 : test();
331 2940 : IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
332 : ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
333 : {
334 : /* *gain_pit = (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
335 : = ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
336 : = ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
337 :
338 : /* *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
339 : = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
340 : = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
341 :
342 20 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
343 20 : exp1 = add( exp_coeff[0], exp_coeff[2] );
344 :
345 20 : L_tmp2 = L_shr( L_mult( coeff[4], coeff[4] ), 2 ); /*Q31*/
346 20 : exp2 = add( exp_coeff[4], exp_coeff[4] );
347 :
348 20 : IF( GT_16( exp1, exp2 ) )
349 : {
350 20 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
351 20 : exp_den = exp1;
352 20 : move16();
353 : }
354 : ELSE
355 : {
356 0 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
357 0 : exp_den = exp2;
358 0 : move16();
359 : }
360 20 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
361 :
362 20 : frac_den = extract_h( L_frac_den ); /* Q15 */
363 20 : frac_den = s_max( frac_den, 1 ); /* Q15 */
364 20 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
365 20 : exp = norm_l( L_frac_den );
366 20 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
367 :
368 20 : L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
369 20 : exp1 = add( exp_coeff[3], exp_coeff[4] );
370 :
371 20 : L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
372 20 : exp2 = add( exp_coeff[1], exp_coeff[2] );
373 :
374 20 : IF( GT_16( exp1, exp2 ) )
375 : {
376 0 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
377 0 : exp_num = exp1;
378 0 : move16();
379 : }
380 : ELSE
381 : {
382 20 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
383 20 : exp_num = exp2;
384 20 : move16();
385 : }
386 20 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
387 :
388 20 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
389 20 : exp_div = sub( exp_num, exp_den );
390 :
391 20 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
392 :
393 20 : L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
394 20 : exp1 = add( exp_coeff[1], exp_coeff[4] );
395 :
396 20 : L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
397 20 : exp2 = add( exp_coeff[0], exp_coeff[3] );
398 :
399 20 : IF( GT_16( exp1, exp2 ) )
400 : {
401 0 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
402 0 : exp_num = exp1;
403 0 : move16();
404 : }
405 : ELSE
406 : {
407 20 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
408 20 : exp_num = exp2;
409 20 : move16();
410 : }
411 20 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
412 :
413 20 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
414 20 : exp_div = sub( exp_num, exp_den );
415 :
416 20 : *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
417 20 : move32(); /*Q16*/
418 :
419 20 : *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
420 20 : move16();
421 :
422 : /* set number of bits for two SQs */
423 20 : nBits2 = shr( add( nBits, 1 ), 1 );
424 20 : nBits = shr( nBits, 1 );
425 :
426 : /* gain_pit Q */
427 :
428 20 : tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
429 20 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
430 20 : move16();
431 20 : push_indice( hBstr, IND_GAIN_PIT, index, nBits );
432 :
433 : /* gain_code Q */
434 : /**gain_code /= gcode0;*/
435 20 : IF( gcode0 != 0 )
436 : {
437 20 : tmp = div_s( 16384, gcode0 ); /*Q15*/
438 20 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
439 20 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
440 20 : move32();
441 : }
442 :
443 20 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
444 20 : push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
445 20 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
446 20 : *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
447 : }
448 : ELSE
449 : {
450 2920 : size = shl( 1, nBits );
451 :
452 2920 : SWITCH( nBits )
453 : {
454 0 : case 7:
455 : {
456 0 : qua_table = gain_qua_mless_7b_fx;
457 0 : move16();
458 0 : if ( EQ_16( clip_gain, 1 ) )
459 : {
460 0 : size = sub( size, 30 );
461 : }
462 0 : BREAK;
463 : }
464 2920 : case 6:
465 : {
466 2920 : qua_table = gain_qua_mless_6b_fx;
467 : if ( element_mode > EVS_MONO )
468 : {
469 : }
470 2920 : move16();
471 2920 : if ( EQ_16( clip_gain, 1 ) )
472 : {
473 19 : size = sub( size, 14 );
474 : }
475 2920 : BREAK;
476 : }
477 0 : case 5:
478 : {
479 0 : qua_table = gain_qua_mless_5b_fx; // Q14
480 0 : move16();
481 0 : if ( EQ_16( clip_gain, 1 ) )
482 : {
483 0 : size = sub( size, 6 );
484 : }
485 0 : BREAK;
486 : }
487 0 : default:
488 : {
489 0 : qua_table = gain_qua_mless_6b_fx; // Q14
490 0 : move16();
491 0 : if ( EQ_16( clip_gain, 1 ) )
492 : {
493 0 : size = sub( size, 14 );
494 : }
495 0 : BREAK;
496 : }
497 : }
498 :
499 : /* in case of AVQ inactive, limit the gain_pit to 0.65 */
500 2920 : test();
501 2920 : IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
502 : {
503 0 : size = sub( size, 36 );
504 0 : nBits = sub( nBits, 1 );
505 : }
506 :
507 : /*-----------------------------------------------------------------*
508 : * search for the best quantizer
509 : *-----------------------------------------------------------------*/
510 2920 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0
511 2920 : push_indice( hBstr, IND_GAIN, index, nBits );
512 : }
513 :
514 : /* *norm_gain_code = *gain_code / *gain_inov; */
515 2940 : exp = sub( norm_s( *gain_inov ), 1 );
516 2940 : exp = s_max( exp, 0 );
517 :
518 2940 : tmp = div_s( shr( 8192, exp ), *gain_inov );
519 2940 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) );
520 2940 : move32();
521 :
522 2940 : return;
523 : }
524 :
525 522943 : void gain_enc_mless_ivas_fx(
526 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
527 : const Word16 gains_mode[], /* i : gain bits Q0*/
528 : const Word16 element_mode, /* i : element mode Q0*/
529 : const Word16 L_frame, /* i : length of the frame Q0*/
530 : const Word16 i_subfr, /* i : subframe index Q0*/
531 : const Word16 tc_subfr, /* i : TC subframe index Q0*/
532 : const Word16 *xn, /* i : target vector Q_xn*/
533 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
534 : const Word16 Q_xn, /* i : xn and y1 scaling */
535 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
536 : const Word16 *code, /* i : algebraic excitation Q9*/
537 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
538 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
539 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
540 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
541 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
542 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
543 : const Word16 clip_gain /* i : gain pitch clipping flag (1 = clipping) Q0*/
544 : )
545 : {
546 :
547 : Word16 index, size, nBits, nBits2;
548 : Word16 gcode0, Ei, gain_code16;
549 : const Word16 *qua_table;
550 : Word16 coeff[5], exp_coeff[5];
551 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
552 : Word32 L_tmp, L_tmp1, L_tmp2;
553 : Word16 tmp1, expg;
554 : Word16 exp1, exp2;
555 : Word16 exp_num, exp_den, exp_div, frac_den;
556 : Word32 L_frac_num, L_frac_den, L_div;
557 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
558 522943 : Flag Overflow = 0;
559 522943 : move32();
560 : #endif
561 :
562 : /*-----------------------------------------------------------------*
563 : * calculate the rest of the correlation coefficients
564 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
565 : *-----------------------------------------------------------------*/
566 :
567 522943 : coeff[0] = g_corr[0];
568 522943 : move16();
569 522943 : exp_coeff[0] = g_corr[1];
570 522943 : move16();
571 522943 : coeff[1] = negate( g_corr[2] );
572 522943 : move16(); /* coeff[1] = -2 xn yy1 */
573 522943 : exp_coeff[1] = add( g_corr[3], 1 );
574 522943 : move16();
575 :
576 : /* Compute scalar product <y2[],y2[]> */
577 522943 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
578 522943 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
579 522943 : move16(); /* -18 (y2 Q9) */
580 :
581 : /* Compute scalar product -2*<xn[],y2[]> */
582 522943 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
583 522943 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
584 522943 : move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
585 :
586 : /* Compute scalar product 2*<y1[],y2[]> */
587 522943 : coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
588 522943 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
589 522943 : move16(); /* -9 (y2 Q9), +1 (2 y1 y2) */
590 :
591 : /*-----------------------------------------------------------------*
592 : * calculate the unscaled innovation energy
593 : * calculate the predicted gain code
594 : *-----------------------------------------------------------------*/
595 :
596 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
597 522943 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
598 522943 : exp_inov = sub( exp_code, 18 + 6 );
599 :
600 : // To avoid crash in case code value is 0,
601 522943 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( L_tmp, exp_inov, 21474836, 0 ), -1 ) )
602 : {
603 : // setting values to avoid extra computation
604 0 : *gain_inov = 32767; /*8(max value gain_inov can hold) in Q12*/
605 0 : Ei = -9743; /* -38 in Q8*/
606 0 : move16();
607 0 : move16();
608 : }
609 : ELSE
610 : {
611 522943 : exp_code = sub( exp_code, 30 );
612 :
613 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
614 :
615 : /*----------------------------------------------------------------*
616 : * calculate the predicted gain code
617 : *----------------------------------------------------------------*/
618 522943 : tmp = norm_l( L_tmp );
619 522943 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
620 522943 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
621 522943 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
622 522943 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
623 :
624 : /*---------------------------------------------------------------*
625 : * Decode codebook gain and the adaptive excitation low-pass
626 : * filtering factor (Finalize computation )
627 : *---------------------------------------------------------------*/
628 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
629 522943 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
630 522943 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
631 522943 : move16();
632 : }
633 :
634 : /* predicted codebook gain */
635 522943 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
636 :
637 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
638 : /*----------------------------------------------------------------*
639 : * gcode0 = pow(10.0, gcode0/20)
640 : * = pow(2, 3.321928*gcode0/20)
641 : * = pow(2, 0.166096*gcode0)
642 : *----------------------------------------------------------------*/
643 :
644 522943 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
645 522943 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
646 522943 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
647 :
648 522943 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
649 : /* output of Pow2() will be: */
650 : /* 16384 < Pow2() <= 32767 */
651 522943 : exp_gcode0 = sub( exp_gcode0, 14 );
652 :
653 : /*-----------------------------------------------------------------*
654 : * select the codebook, size and number of bits
655 : * set the gains searching range
656 : *-----------------------------------------------------------------*/
657 522943 : nBits = gains_mode[i_subfr >> 6];
658 522943 : move16();
659 :
660 522943 : test();
661 522943 : test();
662 522943 : test();
663 522943 : test();
664 522943 : test();
665 522943 : IF( ( EQ_16( tc_subfr, 3 * L_SUBFR ) && EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( L_frame, L_FRAME ) ) ||
666 : ( EQ_16( tc_subfr, 4 * L_SUBFR ) && EQ_16( i_subfr, 4 * L_SUBFR ) && EQ_16( L_frame, L_FRAME16k ) ) )
667 : {
668 : /* *gain_pit = (g_corr[2]*tmp2) - (0.5f*g_corr[4]*tmp3);
669 : = ((-0.5f*g_corr[1]*g_corr[2]) - (-0.25*g_corr[3]*g_corr[4]))/tmp1;
670 : = ((0.25*g_corr[3]*g_corr[4]) - (0.5*g_corr[1]*g_corr[2]))/tmp1; */
671 :
672 : /* *gain_code = (g_corr[0]*tmp3) - (0.5f*g_corr[4]*tmp2);
673 : = ((-0.5*g_corr[3]*g_corr[0]) - (-0.25*g_corr[1]*g_corr[4]))/tmp1;
674 : = ((0.25*g_corr[1]*g_corr[4]) - (0.5*g_corr[0]*g_corr[3]))/tmp1; */
675 :
676 3625 : L_tmp1 = L_mult_sat( coeff[0], coeff[2] ); /*Q31 added saturation for -32768*-32768*/
677 3625 : exp1 = add( exp_coeff[0], exp_coeff[2] );
678 :
679 3625 : L_tmp2 = L_shr( L_mult_sat( coeff[4], coeff[4] ), 2 ); /*Q31 added saturation for -32768*-32768*/
680 3625 : exp2 = add( exp_coeff[4], exp_coeff[4] );
681 :
682 3625 : IF( GT_16( exp1, exp2 ) )
683 : {
684 3514 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
685 3514 : exp_den = exp1;
686 3514 : move16();
687 : }
688 : ELSE
689 : {
690 111 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
691 111 : exp_den = exp2;
692 111 : move16();
693 : }
694 3625 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
695 :
696 3625 : frac_den = extract_h( L_frac_den ); /* Q15 */
697 3625 : frac_den = s_max( frac_den, 1 ); /* Q15 */
698 3625 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
699 3625 : exp = norm_l( L_frac_den );
700 3625 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
701 :
702 3625 : L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
703 3625 : exp1 = add( exp_coeff[3], exp_coeff[4] );
704 :
705 3625 : L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
706 3625 : exp2 = add( exp_coeff[1], exp_coeff[2] );
707 :
708 3625 : IF( GT_16( exp1, exp2 ) )
709 : {
710 96 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
711 96 : exp_num = exp1;
712 96 : move16();
713 : }
714 : ELSE
715 : {
716 3529 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
717 3529 : exp_num = exp2;
718 3529 : move16();
719 : }
720 3625 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
721 :
722 3625 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
723 3625 : exp_div = sub( exp_num, exp_den );
724 :
725 3625 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
726 :
727 3625 : L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
728 3625 : exp1 = add( exp_coeff[1], exp_coeff[4] );
729 :
730 3625 : L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
731 3625 : exp2 = add( exp_coeff[0], exp_coeff[3] );
732 :
733 3625 : IF( GT_16( exp1, exp2 ) )
734 : {
735 51 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
736 51 : exp_num = exp1;
737 51 : move16();
738 : }
739 : ELSE
740 : {
741 3574 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
742 3574 : exp_num = exp2;
743 3574 : move16();
744 : }
745 3625 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
746 :
747 3625 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
748 3625 : exp_div = sub( exp_num, exp_den );
749 :
750 3625 : *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
751 3625 : move32(); /*Q16*/
752 :
753 3625 : *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
754 :
755 : /* set number of bits for two SQs */
756 3625 : nBits2 = shr( add( nBits, 1 ), 1 );
757 3625 : nBits = shr( nBits, 1 );
758 :
759 : /* gain_pit Q */
760 :
761 3625 : tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
762 3625 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
763 3625 : move16();
764 3625 : push_indice( hBstr, IND_GAIN_PIT, index, nBits );
765 :
766 : /* gain_code Q */
767 : /**gain_code /= gcode0;*/
768 3625 : IF( gcode0 != 0 )
769 : {
770 3625 : tmp = div_s( 16384, gcode0 ); /*Q15*/
771 3625 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
772 3625 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
773 3625 : move32();
774 : }
775 :
776 3625 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
777 3625 : push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
778 3625 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
779 3625 : *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
780 : }
781 : ELSE
782 : {
783 519318 : size = shl( 1, nBits );
784 :
785 519318 : SWITCH( nBits )
786 : {
787 749 : case 7:
788 : {
789 749 : qua_table = gain_qua_mless_7b_fx; // Q14
790 749 : if ( EQ_16( clip_gain, 1 ) )
791 : {
792 0 : size = sub( size, 30 );
793 : }
794 749 : BREAK;
795 : }
796 518057 : case 6:
797 : {
798 518057 : qua_table = gain_qua_mless_6b_fx; // Q14
799 518057 : if ( element_mode > EVS_MONO )
800 : {
801 518057 : qua_table = gain_qua_mless_6b_stereo_fx;
802 : }
803 518057 : if ( EQ_16( clip_gain, 1 ) )
804 : {
805 5942 : size = sub( size, 14 );
806 : }
807 518057 : BREAK;
808 : }
809 512 : case 5:
810 : {
811 512 : qua_table = gain_qua_mless_5b_fx; // Q14
812 512 : if ( EQ_16( clip_gain, 1 ) )
813 : {
814 0 : size = sub( size, 6 );
815 : }
816 512 : BREAK;
817 : }
818 0 : default:
819 : {
820 0 : qua_table = gain_qua_mless_6b_fx; // Q14
821 0 : if ( EQ_16( clip_gain, 1 ) )
822 : {
823 0 : size = sub( size, 14 );
824 : }
825 0 : BREAK;
826 : }
827 : }
828 :
829 : /* in case of AVQ inactive, limit the gain_pit to 0.65 */
830 519318 : test();
831 519318 : IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
832 : {
833 5320 : size = sub( size, 36 );
834 5320 : nBits = sub( nBits, 1 );
835 : }
836 :
837 : /*-----------------------------------------------------------------*
838 : * search for the best quantizer
839 : *-----------------------------------------------------------------*/
840 519318 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size );
841 519318 : push_indice( hBstr, IND_GAIN, index, nBits );
842 : }
843 :
844 : /* *norm_gain_code = *gain_code / *gain_inov; */
845 522943 : exp = sub( norm_s( *gain_inov ), 1 );
846 522943 : exp = s_max( exp, 0 );
847 :
848 522943 : tmp = div_s( shr( 8192, exp ), *gain_inov );
849 522943 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
850 522943 : move32();
851 :
852 522943 : return;
853 : }
854 :
855 : /*---------------------------------------------------------------------*
856 : * gain_enc_SQ()
857 : *
858 : * Scalar Quantization of pitch and codebook gains without prediction
859 : * - an initial predicted gain, gcode0, is first determined based on
860 : * the predicted scaled innovation energy
861 : * - a correction factor gamma = g_code / gcode0 is then vector quantized
862 : * along with gain_pit
863 : * - the mean-squared weighted error criterion is used for codebook search
864 : *---------------------------------------------------------------------*/
865 :
866 3358 : void gain_enc_SQ_fx(
867 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
868 : const Word16 gains_mode[], /* i : gain bits Q0*/
869 : const Word16 i_subfr, /* i : subframe index Q0*/
870 : const Word16 *xn, /* i : target vector Q_xn*/
871 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
872 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
873 : const Word16 *code, /* i : algebraic excitation Q9*/
874 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
875 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
876 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
877 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
878 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
879 : Word16 *g_corr, /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
880 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
881 : const Word16 Q_xn /* i : xn and y1 scaling */
882 : )
883 : {
884 : Word16 index, nBits_pitch, nBits_code;
885 : Word16 gcode0, Ei, gain_code16;
886 : Word16 coeff[5], exp_coeff[5];
887 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
888 :
889 : Word32 L_tmp, L_tmp1, L_tmp2;
890 : Word16 tmp1, expg;
891 : Word16 exp1, exp2;
892 : Word16 exp_num, exp_den, exp_div, frac_den;
893 : Word32 L_frac_num, L_frac_den, L_div;
894 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
895 3358 : Flag Overflow = 0;
896 3358 : move32();
897 : #endif
898 :
899 : /*-----------------------------------------------------------------*
900 : * calculate the rest of the correlation coefficients
901 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
902 : *-----------------------------------------------------------------*/
903 : /*g_corr[1] *= -0.5;*/
904 : /*g_corr[2] = dotp( y2, y2, L_SUBFR ) + 0.01f;*/
905 : /*g_corr[3] = dotp( xn, y2, L_SUBFR ) - 0.02f;*/
906 : /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
907 :
908 3358 : coeff[0] = g_corr[0];
909 3358 : move16();
910 3358 : exp_coeff[0] = g_corr[1];
911 3358 : move16();
912 3358 : coeff[1] = g_corr[2];
913 3358 : move16(); /* coeff[1] = xn yy1 */
914 3358 : exp_coeff[1] = g_corr[3];
915 3358 : move16();
916 :
917 : /* Compute scalar product <y2[],y2[]> */
918 3358 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
919 3358 : move16();
920 3358 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
921 3358 : move16(); /* -18 (y2 Q9) */
922 :
923 : /* Compute scalar product <xn[],y2[]> */
924 3358 : coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
925 3358 : move16();
926 3358 : exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
927 3358 : move16(); /* -9 (y2 Q9), (xn y2) */
928 :
929 : /* Compute scalar product <y1[],y2[]> */
930 3358 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
931 3358 : move16();
932 3358 : exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
933 3358 : move16(); /* -9 (y2 Q9), (y1 y2) */
934 :
935 : /*-----------------------------------------------------------------*
936 : * calculate the unscaled innovation energy
937 : * calculate the predicted gain code
938 : * calculate optimal gains
939 : *-----------------------------------------------------------------*/
940 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
941 : /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
942 :
943 3358 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
944 3358 : exp_inov = sub( exp_code, 18 + 6 );
945 3358 : exp_code = sub( exp_code, 30 );
946 :
947 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
948 : /*----------------------------------------------------------------*
949 : * calculate the predicted gain code
950 : *----------------------------------------------------------------*/
951 3358 : tmp = norm_l( L_tmp );
952 3358 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
953 3358 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
954 3358 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
955 3358 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
956 :
957 : /* predicted codebook gain */
958 3358 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
959 :
960 : /*---------------------------------------------------------------*
961 : * Decode codebook gain and the adaptive excitation low-pass
962 : * filtering factor (Finalize computation )
963 : *---------------------------------------------------------------*/
964 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
965 3358 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
966 3358 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
967 :
968 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
969 : /*----------------------------------------------------------------*
970 : * gcode0 = pow(10.0, gcode0/20)
971 : * = pow(2, 3.321928*gcode0/20)
972 : * = pow(2, 0.166096*gcode0)
973 : *----------------------------------------------------------------*/
974 :
975 3358 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
976 3358 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
977 3358 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
978 :
979 3358 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
980 : /* output of Pow2() will be: */
981 : /* 16384 < Pow2() <= 32767 */
982 3358 : exp_gcode0 = sub( exp_gcode0, 14 );
983 :
984 :
985 : /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
986 : tmp2 = g_corr[1]/tmp1;
987 : tmp1 = g_corr[3]/tmp1;
988 :
989 : *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
990 : *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
991 :
992 : /* *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
993 : = ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
994 :
995 : /* *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
996 : = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
997 :
998 3358 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
999 3358 : exp1 = add( exp_coeff[0], exp_coeff[2] );
1000 :
1001 3358 : L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
1002 3358 : exp2 = add( exp_coeff[4], exp_coeff[4] );
1003 :
1004 3358 : IF( GT_16( exp1, exp2 ) )
1005 : {
1006 3352 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1007 3352 : exp_den = exp1;
1008 3352 : move16();
1009 : }
1010 : ELSE
1011 : {
1012 6 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1013 6 : exp_den = exp2;
1014 6 : move16();
1015 : }
1016 3358 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
1017 :
1018 3358 : frac_den = extract_h( L_frac_den ); /* Q15 */
1019 3358 : frac_den = s_max( frac_den, 1 ); /* Q15 */
1020 3358 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
1021 3358 : exp = norm_l( L_frac_den );
1022 3358 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
1023 :
1024 :
1025 3358 : L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
1026 3358 : exp1 = add( exp_coeff[3], exp_coeff[4] );
1027 :
1028 3358 : L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
1029 3358 : exp2 = add( exp_coeff[1], exp_coeff[2] );
1030 :
1031 3358 : IF( GT_16( exp1, exp2 ) )
1032 : {
1033 40 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1034 40 : exp_num = exp1;
1035 40 : move16();
1036 : }
1037 : ELSE
1038 : {
1039 3318 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1040 3318 : exp_num = exp2;
1041 3318 : move16();
1042 : }
1043 3358 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1044 :
1045 3358 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1046 3358 : exp_div = sub( exp_num, exp_den );
1047 :
1048 3358 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
1049 :
1050 3358 : L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/
1051 3358 : exp1 = add( exp_coeff[1], exp_coeff[4] );
1052 :
1053 3358 : L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
1054 3358 : exp2 = add( exp_coeff[0], exp_coeff[3] );
1055 :
1056 3358 : IF( GT_16( exp1, exp2 ) )
1057 : {
1058 255 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1059 255 : exp_num = exp1;
1060 255 : move16();
1061 : }
1062 : ELSE
1063 : {
1064 3103 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1065 3103 : exp_num = exp2;
1066 3103 : move16();
1067 : }
1068 3358 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1069 :
1070 3358 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1071 3358 : exp_div = sub( exp_num, exp_den );
1072 :
1073 3358 : *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
1074 3358 : move32(); /*Q16*/
1075 :
1076 3358 : *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
1077 :
1078 : /*-----------------------------------------------------------------*
1079 : * limit the pitch gain searching range (if indicated by clip_gain)
1080 : *-----------------------------------------------------------------*/
1081 :
1082 3358 : test();
1083 3358 : test();
1084 3358 : IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
1085 : {
1086 26 : *gain_pit = 15565; /* 0.95 in Q14 */
1087 26 : move16();
1088 : }
1089 3332 : ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
1090 : {
1091 0 : *gain_pit = 10650; /* 0.65 in Q14 */
1092 0 : move16();
1093 : }
1094 :
1095 : /*-----------------------------------------------------------------*
1096 : * search for the best quantized values
1097 : *-----------------------------------------------------------------*/
1098 :
1099 3358 : nBits_pitch = gains_mode[i_subfr >> 6];
1100 3358 : move16();
1101 :
1102 : /* set number of bits for two SQs */
1103 3358 : nBits_code = shr( add( nBits_pitch, 1 ), 1 );
1104 3358 : nBits_pitch = shr( nBits_pitch, 1 );
1105 :
1106 : /* gain_pit Q */
1107 : /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/ /* set quantization step */
1108 3358 : tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
1109 :
1110 3358 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); // Q0
1111 3358 : push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
1112 :
1113 : /* gain_code Q */
1114 : /* *gain_code /= gcode0; */
1115 3358 : IF( gcode0 != 0 )
1116 : {
1117 3358 : tmp = div_s( 16384, gcode0 ); /*Q15*/
1118 3358 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
1119 3358 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1120 3358 : move32();
1121 : }
1122 :
1123 3358 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
1124 3358 : push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
1125 3358 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
1126 3358 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
1127 3358 : move32(); /*Q16*/
1128 :
1129 : /* *norm_gain_code = *gain_code / *gain_inov; */
1130 3358 : exp = sub( norm_s( *gain_inov ), 1 );
1131 3358 : exp = s_max( exp, 0 );
1132 :
1133 3358 : tmp = div_s( shr( 8192, exp ), *gain_inov );
1134 3358 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
1135 3358 : move32();
1136 :
1137 3358 : return;
1138 : }
1139 :
1140 43286 : void gain_enc_SQ_ivas_fx(
1141 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1142 : const Word16 gains_mode[], /* i : gain bits Q0*/
1143 : const Word16 i_subfr, /* i : subframe index Q0*/
1144 : const Word16 *xn, /* i : target vector Q_xn*/
1145 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
1146 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
1147 : const Word16 *code, /* i : algebraic excitation Q9*/
1148 : const Word16 Es_pred, /* i : predicted scaled innovation energy Q8*/
1149 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
1150 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
1151 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
1152 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
1153 : Word16 *g_corr, /* i/o: correlations <y1,y1>, <xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
1154 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
1155 : const Word16 Q_xn /* i : xn and y1 scaling */
1156 : )
1157 : {
1158 : Word16 index, nBits_pitch, nBits_code;
1159 : Word16 gcode0, Ei, gain_code16;
1160 : Word16 coeff[5], exp_coeff[5];
1161 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp;
1162 :
1163 : Word32 L_tmp, L_tmp1, L_tmp2;
1164 : Word16 tmp1, expg;
1165 : Word16 exp1, exp2;
1166 : Word16 exp_num, exp_den, exp_div, frac_den;
1167 : Word32 L_frac_num, L_frac_den, L_div;
1168 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1169 43286 : Flag Overflow = 0;
1170 43286 : move32();
1171 : #endif
1172 :
1173 : /*-----------------------------------------------------------------*
1174 : * calculate the rest of the correlation coefficients
1175 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>
1176 : *-----------------------------------------------------------------*/
1177 : /*g_corr[1] *= -0.5;*/
1178 : /*g_corr[2] = dotp( y2, y2, L_SUBFR ) + 0.01f;*/
1179 : /*g_corr[3] = dotp( xn, y2, L_SUBFR ) - 0.02f;*/
1180 : /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/
1181 :
1182 43286 : coeff[0] = g_corr[0];
1183 43286 : move16();
1184 43286 : exp_coeff[0] = g_corr[1];
1185 43286 : move16();
1186 43286 : coeff[1] = g_corr[2];
1187 43286 : move16(); /* coeff[1] = xn yy1 */
1188 43286 : exp_coeff[1] = g_corr[3];
1189 43286 : move16();
1190 :
1191 : /* Compute scalar product <y2[],y2[]> */
1192 43286 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
1193 43286 : move16();
1194 43286 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
1195 43286 : move16(); /* -18 (y2 Q9) */
1196 :
1197 : /* Compute scalar product <xn[],y2[]> */
1198 43286 : coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
1199 43286 : move16();
1200 43286 : exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
1201 43286 : move16(); /* -9 (y2 Q9), (xn y2) */
1202 :
1203 : /* Compute scalar product <y1[],y2[]> */
1204 43286 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
1205 43286 : move16();
1206 43286 : exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
1207 43286 : move16(); /* -9 (y2 Q9), (y1 y2) */
1208 :
1209 : /*-----------------------------------------------------------------*
1210 : * calculate the unscaled innovation energy
1211 : * calculate the predicted gain code
1212 : * calculate optimal gains
1213 : *-----------------------------------------------------------------*/
1214 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/
1215 : /**gain_inov = 1.0f / (float)sqrt( Ecode );*/
1216 :
1217 43286 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
1218 43286 : exp_inov = sub( exp_code, 18 + 6 );
1219 43286 : exp_code = sub( exp_code, 30 );
1220 :
1221 : /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
1222 : /*----------------------------------------------------------------*
1223 : * calculate the predicted gain code
1224 : *----------------------------------------------------------------*/
1225 43286 : tmp = norm_l( L_tmp );
1226 43286 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
1227 43286 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1228 43286 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
1229 43286 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1230 :
1231 : /* predicted codebook gain */
1232 43286 : gcode0 = sub( Es_pred, Ei ); /* Q8 */
1233 :
1234 : /*---------------------------------------------------------------*
1235 : * Decode codebook gain and the adaptive excitation low-pass
1236 : * filtering factor (Finalize computation )
1237 : *---------------------------------------------------------------*/
1238 : /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */
1239 43286 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
1240 43286 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
1241 :
1242 : /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */
1243 : /*----------------------------------------------------------------*
1244 : * gcode0 = pow(10.0, gcode0/20)
1245 : * = pow(2, 3.321928*gcode0/20)
1246 : * = pow(2, 0.166096*gcode0)
1247 : *----------------------------------------------------------------*/
1248 :
1249 43286 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
1250 43286 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1251 43286 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1252 :
1253 43286 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1254 : /* output of Pow2() will be: */
1255 : /* 16384 < Pow2() <= 32767 */
1256 43286 : exp_gcode0 = sub( exp_gcode0, 14 );
1257 :
1258 :
1259 : /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]);
1260 : tmp2 = g_corr[1]/tmp1;
1261 : tmp1 = g_corr[3]/tmp1;
1262 :
1263 : *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp1);
1264 : *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/
1265 :
1266 : /* *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp3);
1267 : = ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/
1268 :
1269 : /* *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2);
1270 : = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/
1271 :
1272 43286 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
1273 43286 : exp1 = add( exp_coeff[0], exp_coeff[2] );
1274 :
1275 43286 : L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
1276 43286 : exp2 = add( exp_coeff[4], exp_coeff[4] );
1277 :
1278 43286 : IF( GT_16( exp1, exp2 ) )
1279 : {
1280 43228 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1281 43228 : exp_den = exp1;
1282 43228 : move16();
1283 : }
1284 : ELSE
1285 : {
1286 58 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1287 58 : exp_den = exp2;
1288 58 : move16();
1289 : }
1290 43286 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
1291 :
1292 43286 : frac_den = extract_h( L_frac_den ); /* Q15 */
1293 43286 : frac_den = s_max( frac_den, 1 ); /* Q15 */
1294 43286 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
1295 43286 : exp = norm_l( L_frac_den );
1296 43286 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
1297 :
1298 :
1299 43286 : L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
1300 43286 : exp1 = add( exp_coeff[3], exp_coeff[4] );
1301 :
1302 43286 : L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
1303 43286 : exp2 = add( exp_coeff[1], exp_coeff[2] );
1304 :
1305 43286 : IF( GT_16( exp1, exp2 ) )
1306 : {
1307 1276 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1308 1276 : exp_num = exp1;
1309 1276 : move16();
1310 : }
1311 : ELSE
1312 : {
1313 42010 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1314 42010 : exp_num = exp2;
1315 42010 : move16();
1316 : }
1317 43286 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1318 :
1319 43286 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1320 43286 : exp_div = sub( exp_num, exp_den );
1321 :
1322 43286 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
1323 43286 : move16();
1324 :
1325 : // To be checked
1326 43286 : L_tmp1 = L_mult_o( coeff[1], coeff[4], &Overflow ); /*Q31*/
1327 43286 : exp1 = add( exp_coeff[1], exp_coeff[4] );
1328 :
1329 43286 : L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
1330 43286 : exp2 = add( exp_coeff[0], exp_coeff[3] );
1331 :
1332 43286 : IF( GT_16( exp1, exp2 ) )
1333 : {
1334 1215 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1335 1215 : exp_num = exp1;
1336 1215 : move16();
1337 : }
1338 : ELSE
1339 : {
1340 42071 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1341 42071 : exp_num = exp2;
1342 42071 : move16();
1343 : }
1344 43286 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1345 :
1346 43286 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1347 43286 : exp_div = sub( exp_num, exp_den );
1348 :
1349 43286 : *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
1350 43286 : move32(); /*Q16*/
1351 :
1352 43286 : *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) );
1353 :
1354 : /*-----------------------------------------------------------------*
1355 : * limit the pitch gain searching range (if indicated by clip_gain)
1356 : *-----------------------------------------------------------------*/
1357 :
1358 43286 : test();
1359 43286 : test();
1360 43286 : IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
1361 : {
1362 0 : *gain_pit = 15565; /* 0.95 in Q14 */
1363 0 : move16();
1364 : }
1365 43286 : ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
1366 : {
1367 990 : *gain_pit = 10650; /* 0.65 in Q14 */
1368 990 : move16();
1369 : }
1370 :
1371 : /*-----------------------------------------------------------------*
1372 : * search for the best quantized values
1373 : *-----------------------------------------------------------------*/
1374 :
1375 43286 : nBits_pitch = gains_mode[i_subfr >> 6];
1376 43286 : move16();
1377 :
1378 : /* set number of bits for two SQs */
1379 43286 : nBits_code = shr( add( nBits_pitch, 1 ), 1 );
1380 43286 : nBits_pitch = shr( nBits_pitch, 1 );
1381 :
1382 : /* gain_pit Q */
1383 : /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/ /* set quantization step */
1384 43286 : tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
1385 :
1386 43286 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) );
1387 43286 : push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
1388 :
1389 : /* gain_code Q */
1390 : /* *gain_code /= gcode0; */
1391 43286 : IF( gcode0 != 0 )
1392 : {
1393 43286 : tmp = div_s( 16384, gcode0 ); /*Q15*/
1394 43286 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
1395 43286 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1396 43286 : move32();
1397 : }
1398 :
1399 43286 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
1400 43286 : push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
1401 43286 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
1402 43286 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
1403 43286 : move32(); /*Q16*/
1404 :
1405 : /* *norm_gain_code = *gain_code / *gain_inov; */
1406 43286 : exp = sub( norm_s( *gain_inov ), 1 );
1407 43286 : exp = s_max( exp, 0 );
1408 :
1409 43286 : tmp = div_s( shr( 8192, exp ), *gain_inov );
1410 43286 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
1411 43286 : move32();
1412 :
1413 43286 : return;
1414 : }
1415 :
1416 : /*-------------------------------------------------------------------*
1417 : * gain_enc_gaus()
1418 : *
1419 : * Quantization of gain for Gaussian codebook
1420 : *-------------------------------------------------------------------*/
1421 0 : Word16 gain_enc_gaus_fx( /* o : Return index of quantization */
1422 : Word32 *gain, /* i/o: Code gain to quantize Q16*/
1423 : const Word16 bits, /* i : number of bits to quantize Q0*/
1424 : const Word16 lowBound, /* i : lower bound of quantizer (dB) Q8*/
1425 : const Word16 stepSize, /* i : Step size choice Q14*/
1426 : const Word16 inv_stepSize /* i : Step size choice Q15*/
1427 : )
1428 : {
1429 : Word16 index, exp_gain, frac_gain, wtmp;
1430 : Word16 enr_q, wenr;
1431 : Word32 Ltmp, enr;
1432 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1433 0 : Flag Overflow = 0;
1434 0 : move32();
1435 : #endif
1436 : /*enr = 20.0 * log10(*gain + 0.001) codebook gain in dB */
1437 0 : exp_gain = norm_l( *gain );
1438 0 : frac_gain = Log2_norm_lc( L_shl( *gain, exp_gain ) );
1439 0 : exp_gain = sub( 30 - 16, exp_gain );
1440 :
1441 0 : enr = Mpy_32_16( exp_gain, frac_gain, LG10 ); /* Output in Q13 */
1442 0 : wenr = extract_h( L_shl( enr, 8 + 3 ) );
1443 :
1444 : /*----------------------------------------------------------------*
1445 : * Quantize linearly the log E
1446 : *----------------------------------------------------------------*/
1447 :
1448 0 : wtmp = sub( wenr, lowBound ); /* Q8 */
1449 :
1450 0 : index = extract_l( L_shr( L_mac( 8388608, wtmp, inv_stepSize ), 16 + 8 ) ); // Q0
1451 :
1452 : /* index [0 (1<<bits)-1] */
1453 0 : index = s_min( index, sub( shl( 1, bits ), 1 ) ); // Q0
1454 0 : index = s_max( index, 0 );
1455 :
1456 0 : Ltmp = L_mac( L_shl( lowBound, 7 ), index, stepSize );
1457 0 : enr_q = round_fx( L_shl( Ltmp, 16 - 7 ) ); /* enr_q Q8 */
1458 :
1459 : /* gain = (float)pow( 10.0f, enr/20.0f ) quantized codebook gain */
1460 0 : enr = L_mult( enr_q, 21772 ); /* 0.166096 in Q17 -> Q26 */
1461 0 : enr = L_shr( enr, 10 ); /*Q26->Q16*/
1462 0 : frac_gain = L_Extract_lc( enr, &exp_gain );
1463 :
1464 0 : Ltmp = Pow2( 14, frac_gain ); /* Put 14 as exponent */
1465 0 : exp_gain = sub( exp_gain, 14 ); /* Retreive exponent of wtmp */
1466 0 : *gain = L_shl_o( Ltmp, add( 16, exp_gain ), &Overflow );
1467 0 : move32(); /*Q16*/
1468 :
1469 0 : return index;
1470 : }
1471 : /*-----------------------------------------------------------------*
1472 : * gain_enc_tc()
1473 : *
1474 : * Search and quantization of gain_code for subframes (in the
1475 : * beginning of frame) without pulses in TC - 3b coding.
1476 : * In this case:
1477 : * - gain_pit = 0
1478 : * - gain_code - scalar quantization (no prediciton history used)
1479 : *-----------------------------------------------------------------*/
1480 90 : void gain_enc_tc_fx(
1481 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1482 : const Word16 gains_mode[], /* i : gain bits Q0*/
1483 : const Word16 i_subfr, /* i : subframe index Q0*/
1484 : const Word16 xn_fx[], /* i : target vector Q_xn*/
1485 : const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/
1486 : const Word16 code_fx[], /* i : algebraic excitation Q9*/
1487 : const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/
1488 : Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/
1489 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
1490 : Word16 *gain_inov_fx, /* o : innovation gain Q12*/
1491 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q16*/
1492 : const Word16 Q_xn /* i : xn and y1 scaling */
1493 : )
1494 : {
1495 90 : Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
1496 : Word16 Ei_fx, g_code_fx, gcode0_fx;
1497 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
1498 : Word32 L_tmp, L_tmp1;
1499 90 : Word16 wgain_code = 0, gain_code16;
1500 90 : *gain_pit_fx = 0;
1501 90 : move16();
1502 90 : move16();
1503 90 : move16();
1504 :
1505 : /*----------------------------------------------------------------*
1506 : * get number of bits for gain quantization
1507 : *----------------------------------------------------------------*/
1508 90 : nBits = gains_mode[shr( i_subfr, 6 )];
1509 :
1510 : /*----------------------------------------------------------------*
1511 : * find the code pitch (for current subframe)
1512 : *----------------------------------------------------------------*/
1513 :
1514 : /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
1515 : /* Compute scalar product <y2[],y2[]> */
1516 90 : L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
1517 90 : exp_den = norm_l( L_tmp );
1518 90 : den = extract_h( L_shl( L_tmp, exp_den ) );
1519 90 : exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
1520 :
1521 : /* Compute scalar product <xn[],y2[]> */
1522 90 : L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */
1523 90 : exp_num = sub( norm_l( L_tmp1 ), 1 );
1524 90 : num = extract_h( L_shl( L_tmp1, exp_num ) );
1525 90 : exp_num = sub( add( exp_num, 8 ), Q_xn );
1526 :
1527 90 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
1528 90 : num = abs_s( num );
1529 :
1530 : /*----------------------------------------------------------------*
1531 : * compute gain = xy/yy
1532 : *----------------------------------------------------------------*/
1533 90 : g_code_fx = div_s( num, den );
1534 :
1535 90 : i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */
1536 90 : g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
1537 90 : *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i );
1538 90 : move32();
1539 :
1540 : /*----------------------------------------------------------------*
1541 : * calculate the predicted gain code
1542 : * decode codebook gain
1543 : *----------------------------------------------------------------*/
1544 :
1545 90 : *gain_pit_fx = 0;
1546 90 : move16();
1547 :
1548 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
1549 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
1550 :
1551 90 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
1552 90 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1553 90 : expg2 = expg;
1554 90 : move16();
1555 90 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1556 90 : move32();
1557 90 : L_tmp = Isqrt_lc( L_tmp, &expg );
1558 :
1559 90 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
1560 90 : move16(); /* gain_inov in Q12 */
1561 :
1562 : /*Ei = 10 * (float)log10( Ecode );*/
1563 90 : e_tmp = norm_l( L_tmp1 );
1564 90 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1565 90 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1566 90 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1567 90 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1568 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1569 90 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
1570 : /*-----------------------------------------------------------------*
1571 : * gcode0 = pow(10.0, gcode0/20)
1572 : * = pow(2, 3.321928*gcode0/20)
1573 : * = pow(2, 0.166096*gcode0)
1574 : *-----------------------------------------------------------------*/
1575 90 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1576 90 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1577 90 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1578 90 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1579 90 : exp_gcode0 = sub( exp_gcode0, 14 );
1580 90 : IF( GT_16( nBits, 3 ) )
1581 : {
1582 : /*g_code = *gain_code / gcode0;*/
1583 12 : IF( gcode0_fx != 0 )
1584 : {
1585 12 : tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/
1586 12 : L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/
1587 12 : *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1588 12 : move32();
1589 : }
1590 : ELSE
1591 : {
1592 0 : *gain_code_fx = MAX_32;
1593 0 : move32();
1594 : }
1595 :
1596 : /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
1597 12 : index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
1598 :
1599 : /**gain_code = g_code * gcode0;*/
1600 12 : L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/
1601 12 : *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1602 12 : move32();
1603 :
1604 12 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1605 : }
1606 : ELSE
1607 : {
1608 78 : index = N_GAIN_CODE_TC - 1;
1609 78 : move16();
1610 332 : FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
1611 : {
1612 330 : L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
1613 330 : L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */
1614 :
1615 330 : IF( LT_32( *gain_code_fx, L_tmp ) )
1616 : {
1617 76 : index = i;
1618 76 : move16();
1619 76 : BREAK;
1620 : }
1621 : }
1622 : /*----------------------------------------------------------------*
1623 : * 3-bit -> 2-bit encoding
1624 : *----------------------------------------------------------------*/
1625 78 : IF( EQ_16( nBits, 2 ) )
1626 : {
1627 : /* 2-bit -> 3-bit decoding */
1628 0 : index = shr( index, 1 );
1629 0 : wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )];
1630 0 : move16();
1631 : /**gain_code *= gcode0;*/
1632 0 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1633 0 : *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
1634 0 : move32(); /* Q14 -> Q16 */
1635 0 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1636 : }
1637 : ELSE /* nBits == 3 */
1638 : {
1639 78 : wgain_code = tbl_gain_code_tc_fx[index];
1640 78 : move16();
1641 : /**gain_code *= gcode0;*/
1642 78 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1643 78 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
1644 78 : move32(); /* Q14 -> Q16 */
1645 78 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1646 : }
1647 : }
1648 :
1649 : /*-----------------------------------------------------------------*
1650 : * decode normalized codebook gain
1651 : *-----------------------------------------------------------------*/
1652 : /**norm_gain_code = *gain_code / *gain_inov;*/
1653 90 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1654 90 : expg = s_max( expg, 0 );
1655 :
1656 90 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
1657 90 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16
1658 90 : move32();
1659 90 : return;
1660 : }
1661 :
1662 20149 : void gain_enc_tc_ivas_fx(
1663 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
1664 : const Word16 gains_mode[], /* i : gain bits Q0*/
1665 : const Word16 i_subfr, /* i : subframe index Q0*/
1666 : const Word16 xn_fx[], /* i : target vector Q_xn*/
1667 : const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation Q_xn*/
1668 : const Word16 code_fx[], /* i : algebraic excitation Q9*/
1669 : const Word16 Es_pred_fx, /* i : predicted scaled innovation energy Q8*/
1670 : Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain Q14*/
1671 : Word32 *gain_code_fx, /* o : quantized codebook gain Q16*/
1672 : Word16 *gain_inov_fx, /* o : innovation gain Q12*/
1673 : Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation Q6*/
1674 : const Word16 Q_xn /* i : xn and y1 scaling */
1675 : )
1676 : {
1677 20149 : Word16 i, index = 0, nBits, num, den, exp_num, exp_den;
1678 : Word16 Ei_fx, g_code_fx, gcode0_fx;
1679 : Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16;
1680 : Word32 L_tmp, L_tmp1;
1681 20149 : Word16 wgain_code = 0, gain_code16;
1682 20149 : *gain_pit_fx = 0;
1683 20149 : move16();
1684 20149 : move16();
1685 20149 : move16();
1686 :
1687 : /*----------------------------------------------------------------*
1688 : * get number of bits for gain quantization
1689 : *----------------------------------------------------------------*/
1690 20149 : nBits = gains_mode[i_subfr >> 6]; // Q0
1691 20149 : move16();
1692 :
1693 : /*----------------------------------------------------------------*
1694 : * find the code pitch (for current subframe)
1695 : *----------------------------------------------------------------*/
1696 :
1697 : /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/
1698 : /* Compute scalar product <y2[],y2[]> */
1699 20149 : L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
1700 20149 : exp_den = norm_l( L_tmp );
1701 20149 : den = extract_h( L_shl( L_tmp, exp_den ) );
1702 20149 : exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
1703 :
1704 : /* Compute scalar product <xn[],y2[]> */
1705 20149 : L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */
1706 20149 : exp_num = sub( norm_l( L_tmp1 ), 1 );
1707 20149 : num = extract_h( L_shl( L_tmp1, exp_num ) );
1708 20149 : exp_num = sub( add( exp_num, 8 ), Q_xn );
1709 :
1710 20149 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
1711 20149 : num = abs_s( num );
1712 :
1713 : /*----------------------------------------------------------------*
1714 : * compute gain = xy/yy
1715 : *----------------------------------------------------------------*/
1716 20149 : g_code_fx = div_s( num, den );
1717 :
1718 20149 : i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */
1719 20149 : g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
1720 20149 : *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); /* Q16 */
1721 20149 : move32();
1722 :
1723 : /*----------------------------------------------------------------*
1724 : * calculate the predicted gain code
1725 : * decode codebook gain
1726 : *----------------------------------------------------------------*/
1727 :
1728 20149 : *gain_pit_fx = 0;
1729 20149 : move16();
1730 :
1731 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
1732 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
1733 :
1734 20149 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
1735 20149 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1736 20149 : expg2 = expg;
1737 20149 : move16();
1738 20149 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1739 20149 : move32();
1740 20149 : L_tmp = Isqrt_lc( L_tmp, &expg );
1741 :
1742 20149 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
1743 20149 : move16(); /* gain_inov in Q12 */
1744 :
1745 : /*Ei = 10 * (float)log10( Ecode );*/
1746 20149 : e_tmp = norm_l( L_tmp1 );
1747 20149 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1748 20149 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1749 20149 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1750 20149 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1751 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1752 20149 : gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */
1753 : /*-----------------------------------------------------------------*
1754 : * gcode0 = pow(10.0, gcode0/20)
1755 : * = pow(2, 3.321928*gcode0/20)
1756 : * = pow(2, 0.166096*gcode0)
1757 : *-----------------------------------------------------------------*/
1758 20149 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1759 20149 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1760 20149 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1761 20149 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1762 20149 : exp_gcode0 = sub( exp_gcode0, 14 );
1763 20149 : IF( GT_16( nBits, 3 ) )
1764 : {
1765 : /*g_code = *gain_code / gcode0;*/
1766 1449 : IF( gcode0_fx != 0 )
1767 : {
1768 1449 : tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/
1769 1449 : L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/
1770 1449 : *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1771 1449 : move32();
1772 : }
1773 : ELSE
1774 : {
1775 0 : *gain_code_fx = MAX_32;
1776 0 : move32();
1777 : }
1778 :
1779 : /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/
1780 1449 : index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg );
1781 :
1782 : /**gain_code = g_code * gcode0;*/
1783 1449 : L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/
1784 1449 : *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1785 1449 : move32();
1786 :
1787 1449 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1788 : }
1789 : ELSE
1790 : {
1791 18700 : index = N_GAIN_CODE_TC - 1;
1792 18700 : move16();
1793 63182 : FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
1794 : {
1795 62316 : L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
1796 62316 : L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */
1797 :
1798 62316 : IF( LT_32( *gain_code_fx, L_tmp ) )
1799 : {
1800 17834 : index = i;
1801 17834 : move16();
1802 17834 : BREAK;
1803 : }
1804 : }
1805 : /*----------------------------------------------------------------*
1806 : * 3-bit -> 2-bit encoding
1807 : *----------------------------------------------------------------*/
1808 18700 : IF( EQ_16( nBits, 2 ) )
1809 : {
1810 : /* 2-bit -> 3-bit decoding */
1811 0 : index = shr( index, 1 );
1812 0 : wgain_code = tbl_gain_code_tc_fx[index * 2]; // Q13
1813 0 : move16();
1814 : /**gain_code *= gcode0;*/
1815 0 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1816 0 : *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) );
1817 0 : move32(); /* Q14 -> Q16 */
1818 0 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1819 : }
1820 : ELSE /* nBits == 3 */
1821 : {
1822 18700 : wgain_code = tbl_gain_code_tc_fx[index]; // Q13
1823 18700 : move16();
1824 : /**gain_code *= gcode0;*/
1825 18700 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1826 18700 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
1827 18700 : move32(); /* Q14 -> Q16 */
1828 18700 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1829 : }
1830 : }
1831 :
1832 : /*-----------------------------------------------------------------*
1833 : * decode normalized codebook gain
1834 : *-----------------------------------------------------------------*/
1835 : /**norm_gain_code = *gain_code / *gain_inov;*/
1836 20149 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1837 20149 : expg = s_max( expg, 0 );
1838 :
1839 20149 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
1840 20149 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q6
1841 20149 : move32();
1842 20149 : return;
1843 : }
1844 : /*-----------------------------------------------------------------*
1845 : * Find_Opt_gainQ_fx()
1846 : *
1847 : * Find the best quantizer
1848 : *-----------------------------------------------------------------*/
1849 539940 : static Word16 Find_Opt_gainQ_fx(
1850 : Word16 *coeff, /* exp(exp_coeff) */
1851 : Word16 *exp_coeff,
1852 : Word16 *gain_pit, /* Q14 */
1853 : Word32 *gain_code, /* Q16 */
1854 : Word16 gcode0, /* exp(exp_gcode0) */
1855 : Word16 exp_gcode0,
1856 : const Word16 *cdbk, /* i : Codebook used Q14*/
1857 : const Word16 size /* i : size of Codebook used Q0*/
1858 : )
1859 : {
1860 : Word16 index, i, j;
1861 : const Word16 *p;
1862 : Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
1863 : Word32 dist_min;
1864 : Word16 coeff_lo[5];
1865 : Word16 exp_max[5];
1866 : Word16 exp_code, e_max;
1867 : Word32 L_tmp, L_tmp1;
1868 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1869 539940 : Flag Overflow = 0;
1870 539940 : move32();
1871 : #endif
1872 :
1873 :
1874 : /*----------------------------------------------------------------*
1875 : * Find the best quantizer
1876 : * ~~~~~~~~~~~~~~~~~~~~~~~
1877 : * Before doing the computation we need to align exponents of coeff[]
1878 : * to be sure to have the maximum precision.
1879 : *
1880 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
1881 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
1882 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
1883 : * we divide by 2^15.
1884 : * Considering all the scaling above we have:
1885 : *
1886 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
1887 : *
1888 : * g_pitch*g_pitch = -14-14+15
1889 : * g_pitch = -14
1890 : * g_code*g_code = (2*exp_code)+15
1891 : * g_code = exp_code
1892 : * g_pitch*g_code = -14 + exp_code +15
1893 : *
1894 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
1895 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
1896 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
1897 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
1898 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
1899 : *----------------------------------------------------------------*/
1900 :
1901 539940 : exp_code = add( exp_gcode0, 6 );
1902 :
1903 539940 : exp_max[0] = sub( exp_coeff[0], 13 );
1904 539940 : move16();
1905 539940 : exp_max[1] = sub( exp_coeff[1], 14 );
1906 539940 : move16();
1907 539940 : exp_max[2] = add( exp_coeff[2], add( 15, shl( exp_code, 1 ) ) );
1908 539940 : move16();
1909 539940 : exp_max[3] = add( exp_coeff[3], exp_code );
1910 539940 : move16();
1911 539940 : exp_max[4] = add( exp_coeff[4], add( 1, exp_code ) );
1912 539940 : move16();
1913 :
1914 : /* Find maximum exponant */
1915 539940 : e_max = exp_max[0];
1916 539940 : move16();
1917 2699700 : FOR( i = 1; i < 5; i++ )
1918 : {
1919 2159760 : e_max = s_max( exp_max[i], e_max );
1920 : }
1921 :
1922 : /* align coeff[] and save in special 32 bit double precision */
1923 3239640 : FOR( i = 0; i < 5; i++ )
1924 : {
1925 2699700 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
1926 2699700 : L_tmp = L_deposit_h( coeff[i] );
1927 2699700 : L_tmp = L_shr( L_tmp, j );
1928 2699700 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
1929 2699700 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
1930 2699700 : move16();
1931 : }
1932 :
1933 : /* searching of codebook */
1934 539940 : p = cdbk; // Q14
1935 539940 : move16();
1936 539940 : dist_min = L_deposit_h( MAX_16 );
1937 539940 : index = 0;
1938 539940 : move16();
1939 35440710 : FOR( i = 0; i < size; i++ )
1940 : {
1941 34900770 : g_pitch = *p++;
1942 34900770 : move16();
1943 34900770 : g_code = *p++;
1944 34900770 : move16();
1945 :
1946 34900770 : g_code = mult_r( g_code, gcode0 ); // exp_gcode - 1
1947 34900770 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
1948 34900770 : g_pit_cod = mult_r( g_code, g_pitch );
1949 34900770 : L_tmp = L_mult( g_code, g_code );
1950 34900770 : g2_code_lo = L_Extract_lc( L_tmp, &g2_code );
1951 :
1952 34900770 : L_tmp = L_mult( coeff[2], g2_code_lo );
1953 34900770 : L_tmp = L_shr( L_tmp, 3 );
1954 34900770 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
1955 34900770 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
1956 34900770 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
1957 34900770 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
1958 34900770 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
1959 34900770 : L_tmp = L_shr( L_tmp, 12 );
1960 34900770 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
1961 34900770 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
1962 34900770 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
1963 34900770 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
1964 34900770 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
1965 :
1966 34900770 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
1967 34900770 : if ( L_tmp1 < 0 )
1968 : {
1969 6845543 : index = i;
1970 6845543 : move16();
1971 : }
1972 34900770 : dist_min = L_min( L_tmp, dist_min );
1973 : }
1974 :
1975 539940 : p = &cdbk[add( index, index )]; // Q14
1976 539940 : move16();
1977 :
1978 539940 : *gain_pit = *p++; /* selected pitch gain in Q14 */
1979 539940 : move16();
1980 539940 : g_code = *p++; /* selected code gain in Q9 */
1981 539940 : move16();
1982 :
1983 539940 : L_tmp = L_mult( g_code, gcode0 ); /* Q9*Q0 -> Q10 */
1984 539940 : L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */
1985 539940 : *gain_code = L_tmp; /* gain of code in Q16 */
1986 539940 : move16();
1987 539940 : return index;
1988 : }
1989 : /*---------------------------------------------------------------------*
1990 : * gain_enc_lbr()
1991 : *
1992 : * Quantization of pitch and codebook gains without prediction (memory-less)
1993 : * in ACELP at 6.6 and 7.5 kbps
1994 : * - the gain codebooks and gain estimation constants are different in each subframe
1995 : * - the estimated gain, gcode0, is first determined based on
1996 : * classification and/or previous quantized gains (from previous subframes in the current frame)
1997 : * - a correction factor gamma = g_code / gcode0 is then vector quantized
1998 : * along with gain_pit
1999 : * - the mean-squared error criterion is used for codebook search
2000 : *---------------------------------------------------------------------*/
2001 :
2002 0 : void gain_enc_lbr_fx(
2003 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
2004 : const Word16 gains_mode[], /* i : gain bits Q0*/
2005 : const Word16 coder_type, /* i : coding type Q0*/
2006 : const Word16 i_subfr, /* i : subframe index Q0*/
2007 : const Word16 *xn, /* i : target vector Q_xn*/
2008 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
2009 : const Word16 Q_xn, /* i : xn and y1 format */
2010 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
2011 : const Word16 *code, /* i : algebraic excitation Q9*/
2012 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
2013 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
2014 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
2015 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
2016 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
2017 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
2018 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
2019 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
2020 : const Word16 L_subfr /* i : subframe length Q0*/
2021 : )
2022 : {
2023 :
2024 0 : Word16 index = 0, size, nBits, n_pred, ctype;
2025 0 : const Word16 *b, *cdbk = 0;
2026 : Word16 gcode0, aux[10];
2027 : Word16 coeff[5], exp_coeff[5];
2028 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
2029 : Word32 L_tmp, L_tmp1, L_inov;
2030 0 : move16();
2031 0 : move16();
2032 :
2033 0 : L_subfr_sf = 6;
2034 0 : move16();
2035 0 : if ( GT_16( L_subfr, L_SUBFR ) )
2036 : {
2037 0 : L_subfr_sf = 7;
2038 0 : move16();
2039 : }
2040 : /*-----------------------------------------------------------------*
2041 : * calculate the rest of the correlation coefficients
2042 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
2043 : * c5* - not necessary to calculate
2044 : *-----------------------------------------------------------------*/
2045 :
2046 0 : coeff[0] = g_corr[0];
2047 0 : move16();
2048 0 : exp_coeff[0] = g_corr[1];
2049 0 : move16();
2050 0 : coeff[1] = negate( g_corr[2] );
2051 0 : move16(); /* coeff[1] = -2 xn yy1 */
2052 0 : exp_coeff[1] = add( g_corr[3], 1 );
2053 0 : move16();
2054 :
2055 : /* Compute scalar product <y2[],y2[]> */
2056 0 : coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
2057 0 : move16();
2058 0 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
2059 0 : move16();
2060 :
2061 : /* Compute scalar product -2*<xn[],y2[]> */
2062 :
2063 0 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
2064 0 : move16();
2065 0 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
2066 0 : move16();
2067 :
2068 : /* Compute scalar product 2*<y1[],y2[]> */
2069 :
2070 0 : coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
2071 0 : move16();
2072 0 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
2073 0 : move16();
2074 :
2075 : /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
2076 :
2077 : /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
2078 : *gain_inov = 1.0f / (float)sqrt(Ecode);*/
2079 0 : L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
2080 0 : L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
2081 0 : move32();
2082 : /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
2083 : /* output gain_inov*/
2084 0 : exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
2085 0 : L_inov = Isqrt_lc( L_inov, &exp_inov );
2086 0 : *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
2087 0 : move16();
2088 :
2089 :
2090 : /*-----------------------------------------------------------------*
2091 : * select the codebook, size and number of bits
2092 : * set the gains searching range
2093 : *-----------------------------------------------------------------*/
2094 :
2095 0 : nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
2096 0 : move16();
2097 0 : size = shl( 1, nBits );
2098 :
2099 0 : ctype = shl( sub( coder_type, 1 ), 1 );
2100 :
2101 : /*-----------------------------------------------------------------*
2102 : * calculate prediction of gcode
2103 : * search for the best codeword
2104 : *-----------------------------------------------------------------*/
2105 0 : test();
2106 0 : IF( i_subfr == 0 )
2107 : {
2108 0 : b = b_1sfr_fx; // Q12
2109 0 : move16();
2110 0 : n_pred = 2;
2111 0 : move16();
2112 :
2113 0 : SWITCH( nBits )
2114 : {
2115 0 : case 8:
2116 : {
2117 0 : cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
2118 0 : if ( EQ_16( clip_gain, 1 ) )
2119 : {
2120 0 : size = sub( size, 60 );
2121 : }
2122 0 : BREAK;
2123 : }
2124 0 : case 7:
2125 : {
2126 0 : cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
2127 0 : if ( EQ_16( clip_gain, 1 ) )
2128 : {
2129 0 : size = sub( size, 27 );
2130 : }
2131 0 : BREAK;
2132 : }
2133 0 : case 6:
2134 : {
2135 0 : cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
2136 0 : if ( EQ_16( clip_gain, 1 ) )
2137 : {
2138 0 : size = sub( size, 10 );
2139 : }
2140 0 : BREAK;
2141 : }
2142 : }
2143 :
2144 : /* calculate predicted gain */
2145 0 : aux[0] = 4096; /* 1 in Q12 */
2146 0 : move16();
2147 0 : aux[1] = shl( ctype, 12 );
2148 0 : move16();
2149 :
2150 : /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
2151 : gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
2152 : gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
2153 :
2154 0 : exp_code = sub( exp_code, 18 + 6 + 1 );
2155 0 : exp = norm_l( L_tmp );
2156 0 : frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
2157 0 : exp = sub( exp_code, exp );
2158 0 : L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
2159 :
2160 0 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2161 0 : L_tmp = Mult_32_16( L_tmp, 320 ); /*Q14, 20 in Q4*/
2162 0 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q14*/
2163 :
2164 0 : gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
2165 :
2166 : /*-----------------------------------------------------------------*
2167 : * gcode0 = pow(10.0, gcode0/20)
2168 : * = pow(2, 3.321928*gcode0/20)
2169 : * = pow(2, 0.166096*gcode0)
2170 : *-----------------------------------------------------------------*/
2171 :
2172 0 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
2173 0 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
2174 0 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2175 :
2176 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2177 : /* output of Pow2() will be: */
2178 : /* 16384 < Pow2() <= 32767 */
2179 0 : exp_gcode0 = sub( exp_gcode0, 14 );
2180 0 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2181 :
2182 0 : gc_mem[0] = *gain_code;
2183 0 : move16(); /*Q16*/
2184 0 : gp_mem[0] = *gain_pit;
2185 0 : move16(); /*Q14*/
2186 : }
2187 0 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
2188 : {
2189 0 : b = b_2sfr_fx;
2190 0 : move16();
2191 0 : n_pred = 4;
2192 0 : move16();
2193 :
2194 0 : switch ( nBits )
2195 : {
2196 0 : case 7:
2197 : {
2198 0 : cdbk = gp_gamma_2sfr_7b_fx; /* Q14/Q9 */
2199 0 : if ( EQ_16( clip_gain, 1 ) )
2200 : {
2201 0 : size = sub( size, 30 );
2202 : }
2203 0 : BREAK;
2204 : }
2205 0 : case 6:
2206 : {
2207 0 : cdbk = gp_gamma_2sfr_6b_fx; /* Q14/Q9 */
2208 0 : if ( EQ_16( clip_gain, 1 ) )
2209 : {
2210 0 : size = sub( size, 12 );
2211 : }
2212 0 : BREAK;
2213 : }
2214 : }
2215 :
2216 : /* calculate predicted gain */
2217 0 : aux[0] = 4096; /* 1 in Q12 */
2218 0 : move16();
2219 0 : aux[1] = shl( ctype, 12 );
2220 0 : move16();
2221 :
2222 : /*aux[2] = (float)log10(gc_mem[0]);
2223 : = log2(gc_mem[0])*log10(2);*/
2224 0 : exp = norm_l( gc_mem[0] );
2225 0 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2226 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
2227 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 );
2228 0 : move16(); /* Q16 */
2229 0 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2230 0 : move16();
2231 :
2232 0 : aux[3] = shr( gp_mem[0], 2 );
2233 0 : move16(); /*Q12*/
2234 :
2235 : /*-----------------------------------------------------------------*
2236 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2237 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2238 : *-----------------------------------------------------------------*/
2239 0 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2240 0 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2241 0 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2242 0 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2243 :
2244 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2245 : /* output of Pow2() will be: */
2246 : /* 16384 < Pow2() <= 32767 */
2247 0 : exp_gcode0 = sub( exp_gcode0, 14 );
2248 :
2249 0 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2250 0 : gc_mem[1] = *gain_code; // Q16
2251 0 : move32();
2252 0 : gp_mem[1] = *gain_pit; // Q14
2253 0 : move16();
2254 : }
2255 0 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
2256 : {
2257 0 : b = b_3sfr_fx; // Q12
2258 0 : move16();
2259 0 : n_pred = 6;
2260 0 : move16();
2261 0 : IF( EQ_16( nBits, 7 ) )
2262 : {
2263 0 : cdbk = gp_gamma_3sfr_7b_fx;
2264 0 : if ( clip_gain == 1 )
2265 : {
2266 0 : size -= 28;
2267 : }
2268 : }
2269 : ELSE
2270 : {
2271 0 : cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
2272 0 : if ( EQ_16( clip_gain, 1 ) )
2273 : {
2274 0 : size = sub( size, 11 );
2275 : }
2276 : }
2277 : /* calculate predicted gain */
2278 0 : aux[0] = 4096; /* 1 in Q12 */
2279 0 : move16();
2280 0 : aux[1] = shl( ctype, 12 );
2281 0 : move16();
2282 :
2283 : /*aux[2] = (float)log10(gc_mem[0]);
2284 : = log2(gc_mem[0])*log10(2);*/
2285 0 : exp = norm_l( gc_mem[0] );
2286 0 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2287 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2288 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2289 0 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2290 0 : move16();
2291 :
2292 : /*aux[3] = (float)log10(gc_mem[1]);
2293 : = log2(gc_mem[1])*log10(2);*/
2294 0 : exp = norm_l( gc_mem[1] );
2295 0 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2296 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2297 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2298 0 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2299 0 : move16();
2300 :
2301 0 : aux[4] = shr( gp_mem[0], 2 );
2302 0 : move16(); /*Q12*/
2303 0 : aux[5] = shr( gp_mem[1], 2 );
2304 0 : move16(); /*Q12*/
2305 :
2306 : /*-----------------------------------------------------------------*
2307 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2308 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2309 : *-----------------------------------------------------------------*/
2310 0 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2311 0 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2312 0 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2313 0 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2314 :
2315 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2316 : /* output of Pow2() will be: */
2317 : /* 16384 < Pow2() <= 32767 */
2318 0 : exp_gcode0 = sub( exp_gcode0, 14 );
2319 :
2320 : /*----------------------------------------------------------------*
2321 : * Find the best quantizer
2322 : * ~~~~~~~~~~~~~~~~~~~~~~~
2323 : * Before doing the computation we need to align exponents of coeff[]
2324 : * to be sure to have the maximum precision.
2325 : *
2326 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
2327 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
2328 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
2329 : * we divide by 2^15.
2330 : * Considering all the scaling above we have:
2331 : *
2332 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
2333 : *
2334 : * g_pitch*g_pitch = -14-14+15
2335 : * g_pitch = -14
2336 : * g_code*g_code = (2*exp_code)+15
2337 : * g_code = exp_code
2338 : * g_pitch*g_code = -14 + exp_code +15
2339 : *
2340 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
2341 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
2342 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
2343 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
2344 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
2345 : *----------------------------------------------------------------*/
2346 :
2347 0 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
2348 :
2349 0 : gc_mem[2] = *gain_code; // Q16
2350 0 : move32();
2351 0 : gp_mem[2] = *gain_pit; // Q14
2352 0 : move16();
2353 : }
2354 0 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
2355 : {
2356 0 : b = b_4sfr_fx; // Q12
2357 0 : move16();
2358 0 : n_pred = 8;
2359 0 : move16();
2360 0 : IF( EQ_16( nBits, 7 ) )
2361 : {
2362 0 : cdbk = gp_gamma_4sfr_7b_fx;
2363 0 : if ( clip_gain == 1 )
2364 : {
2365 0 : size -= 25;
2366 : }
2367 : }
2368 : ELSE
2369 : {
2370 0 : cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
2371 0 : if ( EQ_16( clip_gain, 1 ) )
2372 : {
2373 0 : size = sub( size, 11 );
2374 : }
2375 : }
2376 : /* calculate predicted gain */
2377 0 : aux[0] = 4096; /* 1 in Q12 */
2378 0 : move16();
2379 0 : aux[1] = shl( ctype, 12 );
2380 0 : move16();
2381 :
2382 : /*aux[2] = (float)log10(gc_mem[0]);
2383 : = log2(gc_mem[0])*log10(2);*/
2384 0 : exp = norm_l( gc_mem[0] );
2385 0 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2386 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2387 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2388 0 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2389 0 : move16();
2390 :
2391 : /*aux[3] = (float)log10(gc_mem[1]);
2392 : = log2(gc_mem[1])*log10(2);*/
2393 0 : exp = norm_l( gc_mem[1] );
2394 0 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2395 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2396 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2397 0 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2398 0 : move16();
2399 :
2400 :
2401 : /*aux[4] = (float)log10(gc_mem[2]);
2402 : = log2(gc_mem[2])*log10(2);*/
2403 0 : exp = norm_l( gc_mem[2] );
2404 0 : frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
2405 0 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/
2406 0 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2407 0 : aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2408 0 : move16();
2409 :
2410 0 : aux[5] = shr( gp_mem[0], 2 );
2411 0 : move16(); /*Q12*/
2412 0 : aux[6] = shr( gp_mem[1], 2 );
2413 0 : move16(); /*Q12*/
2414 0 : aux[7] = shr( gp_mem[2], 2 );
2415 0 : move16(); /*Q12*/
2416 : /*-----------------------------------------------------------------*
2417 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2418 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2419 : *-----------------------------------------------------------------*/
2420 0 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2421 0 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2422 0 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2423 0 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2424 :
2425 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2426 : /* output of Pow2() will be: */
2427 : /* 16384 < Pow2() <= 32767 */
2428 0 : exp_gcode0 = sub( exp_gcode0, 14 );
2429 :
2430 0 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2431 : }
2432 :
2433 : /* *norm_gain_code = *gain_code / *gain_inov; */
2434 0 : exp = sub( norm_s( *gain_inov ), 1 );
2435 0 : exp = s_max( exp, 0 );
2436 :
2437 0 : tmp = div_s( shr( 8192, exp ), *gain_inov );
2438 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
2439 0 : move32();
2440 : {
2441 0 : push_indice( hBstr, IND_GAIN, index, nBits );
2442 : }
2443 0 : return;
2444 : }
2445 :
2446 17702 : void gain_enc_lbr_ivas_fx(
2447 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
2448 : const Word16 gains_mode[], /* i : gain bits Q0*/
2449 : const Word16 coder_type, /* i : coding type Q0*/
2450 : const Word16 i_subfr, /* i : subframe index Q0*/
2451 : const Word16 *xn, /* i : target vector Q_xn*/
2452 : const Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn*/
2453 : const Word16 Q_xn, /* i : xn and y1 format */
2454 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
2455 : const Word16 *code, /* i : algebraic excitation Q9*/
2456 : Word16 *gain_pit, /* o : quantized pitch gain Q14*/
2457 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
2458 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
2459 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
2460 : Word16 *g_corr, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> mant/exp*/
2461 : Word32 gc_mem[], /* i/o: gain_code from previous subframes Q16*/
2462 : Word16 gp_mem[], /* i/o: gain_pitch from previous subframes Q14*/
2463 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
2464 : const Word16 L_subfr /* i : subframe length Q0*/
2465 : )
2466 : {
2467 :
2468 17702 : Word16 index = 0, size, nBits, n_pred, ctype;
2469 17702 : const Word16 *b, *cdbk = 0;
2470 : Word16 gcode0, aux[10];
2471 : Word16 coeff[5], exp_coeff[5];
2472 : Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp, L_subfr_sf;
2473 : Word32 L_tmp, L_tmp1, L_inov;
2474 17702 : move16();
2475 :
2476 17702 : L_subfr_sf = 6;
2477 17702 : move16();
2478 17702 : if ( GT_16( L_subfr, L_SUBFR ) )
2479 : {
2480 4150 : L_subfr_sf = 7;
2481 4150 : move16();
2482 : }
2483 : /*-----------------------------------------------------------------*
2484 : * calculate the rest of the correlation coefficients
2485 : * c2 = <y2,y2>, c3 = -2<xn,y2>, c4 = 2<y1,y2>, c5* = <xn,xn>
2486 : * c5* - not necessary to calculate
2487 : *-----------------------------------------------------------------*/
2488 :
2489 17702 : coeff[0] = g_corr[0];
2490 17702 : move16();
2491 17702 : exp_coeff[0] = g_corr[1];
2492 17702 : move16();
2493 17702 : coeff[1] = negate( g_corr[2] );
2494 17702 : move16(); /* coeff[1] = -2 xn yy1 */
2495 17702 : exp_coeff[1] = add( g_corr[3], 1 );
2496 17702 : move16();
2497 :
2498 : /* Compute scalar product <y2[],y2[]> */
2499 : #ifdef DEBUG
2500 : if ( L_subfr != L_SUBFR )
2501 : {
2502 : PMT( "Entire function needs review to accommode for L_subfr > L_SUBFR" );
2503 : }
2504 : #endif
2505 17702 : coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
2506 17702 : move16();
2507 17702 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
2508 17702 : move16();
2509 :
2510 : /* Compute scalar product -2*<xn[],y2[]> */
2511 :
2512 17702 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
2513 17702 : move16();
2514 17702 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
2515 17702 : move16();
2516 :
2517 : /* Compute scalar product 2*<y1[],y2[]> */
2518 :
2519 17702 : coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
2520 17702 : move16();
2521 17702 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
2522 17702 : move16();
2523 :
2524 : /*g_corr[2] += 0.01F; g_corr[3] -= 0.02F; g_corr[4] += 0.02F;*/
2525 :
2526 : /*Ecode = ( dotp( code, code, L_SUBFR ) + 0.01f ) / L_SUBFR;
2527 : *gain_inov = 1.0f / (float)sqrt(Ecode);*/
2528 17702 : L_tmp = Dot_product12( code, code, L_subfr, &exp_code ); /* Q9 + Q9 + 1 + (30-exp_code)*/
2529 17702 : L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
2530 17702 : move32();
2531 : /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
2532 : /* output gain_inov*/
2533 17702 : exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
2534 17702 : L_inov = Isqrt_lc( L_inov, &exp_inov );
2535 17702 : *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
2536 17702 : move16();
2537 :
2538 :
2539 : /*-----------------------------------------------------------------*
2540 : * select the codebook, size and number of bits
2541 : * set the gains searching range
2542 : *-----------------------------------------------------------------*/
2543 :
2544 17702 : nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
2545 17702 : move16();
2546 17702 : size = shl( 1, nBits );
2547 :
2548 17702 : ctype = shl( sub( coder_type, 1 ), 1 );
2549 :
2550 : /*-----------------------------------------------------------------*
2551 : * calculate prediction of gcode
2552 : * search for the best codeword
2553 : *-----------------------------------------------------------------*/
2554 17702 : test();
2555 17702 : IF( i_subfr == 0 )
2556 : {
2557 5463 : b = b_1sfr_fx; // Q12
2558 5463 : move16();
2559 5463 : n_pred = 2;
2560 5463 : move16();
2561 :
2562 5463 : SWITCH( nBits )
2563 : {
2564 2187 : case 8:
2565 : {
2566 2187 : cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
2567 2187 : if ( EQ_16( clip_gain, 1 ) )
2568 : {
2569 0 : size = sub( size, 60 );
2570 : }
2571 2187 : BREAK;
2572 : }
2573 440 : case 7:
2574 : {
2575 440 : cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
2576 440 : if ( EQ_16( clip_gain, 1 ) )
2577 : {
2578 0 : size = sub( size, 27 );
2579 : }
2580 440 : BREAK;
2581 : }
2582 2836 : case 6:
2583 : {
2584 2836 : cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
2585 2836 : if ( EQ_16( clip_gain, 1 ) )
2586 : {
2587 0 : size = sub( size, 10 );
2588 : }
2589 2836 : BREAK;
2590 : }
2591 : }
2592 :
2593 : /* calculate predicted gain */
2594 5463 : aux[0] = 4096; /* 1 in Q12 */
2595 5463 : move16();
2596 5463 : aux[1] = shl( ctype, 12 );
2597 5463 : move16();
2598 :
2599 : /* gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.5f * (float)log10(Ecode));
2600 : gcode0 = (float)pow(10, dotp(b, aux, n_pred) - 0.05f * 10 * (float)log10(Ecode));
2601 : gcode0 = (float)pow(10, 0.05(20 * dotp(b, aux, n_pred) - 10 * (float)log10(Ecode))); */
2602 : // Ecode = (Ecode / L_subfr)
2603 5463 : L_tmp = L_shr( L_tmp, L_subfr_sf ); // Q19 + (Q30-exp_code)
2604 : /* Calculation for log10(Ecode) exponent for applying log10 = Q31 - q = Q31 - Q19 - Q30 + exp_code = exp_code - Q18*/
2605 5463 : L_tmp = BASOP_Util_Log10( L_tmp, sub( exp_code, 18 ) ); // new q = Q25
2606 5463 : exp = norm_l( L_tmp );
2607 5463 : L_tmp = L_shl( L_tmp, exp ); // Q25 + exp
2608 : // 10 in Q27 , ( 10 * log10( Ecode ) )
2609 5463 : L_tmp1 = Mpy_32_32( L_tmp, 1342177280 ); // Q25 + exp + 1 + Q27 - 32 = Q21 + exp
2610 5463 : L_tmp1 = L_shr( L_tmp1, add( 7, exp ) ); // Q21 + exp - 7 - exp = Q14
2611 :
2612 5463 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2613 5463 : L_tmp = Mult_32_16( L_tmp, 320 ); /*Q14, 20 in Q4*/
2614 5463 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q14*/
2615 :
2616 5463 : gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
2617 :
2618 : /*-----------------------------------------------------------------*
2619 : * gcode0 = pow(10.0, gcode0/20)
2620 : * = pow(2, 3.321928*gcode0/20)
2621 : * = pow(2, 0.166096*gcode0)
2622 : *-----------------------------------------------------------------*/
2623 :
2624 5463 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
2625 5463 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
2626 5463 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2627 :
2628 5463 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2629 : /* output of Pow2() will be: */
2630 : /* 16384 < Pow2() <= 32767 */
2631 5463 : exp_gcode0 = sub( exp_gcode0, 14 );
2632 5463 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
2633 :
2634 5463 : gc_mem[0] = *gain_code;
2635 5463 : move16(); /*Q16*/
2636 5463 : gp_mem[0] = *gain_pit;
2637 5463 : move16(); /*Q14*/
2638 : }
2639 12239 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
2640 : {
2641 5463 : b = b_2sfr_fx; // Q12
2642 5463 : move16();
2643 5463 : n_pred = 4;
2644 5463 : move16();
2645 :
2646 5463 : switch ( nBits )
2647 : {
2648 2185 : case 7:
2649 : {
2650 2185 : cdbk = gp_gamma_2sfr_7b_fx; /* Q14 / Q9 */
2651 2185 : if ( EQ_16( clip_gain, 1 ) )
2652 : {
2653 0 : size = sub( size, 30 );
2654 : }
2655 2185 : BREAK;
2656 : }
2657 3278 : case 6:
2658 : {
2659 3278 : cdbk = gp_gamma_2sfr_6b_fx; /* Q14 / Q9 */
2660 3278 : if ( EQ_16( clip_gain, 1 ) )
2661 : {
2662 0 : size = sub( size, 12 );
2663 : }
2664 3278 : BREAK;
2665 : }
2666 : }
2667 :
2668 : /* calculate predicted gain */
2669 5463 : aux[0] = 4096; /* 1 in Q12 */
2670 5463 : move16();
2671 5463 : aux[1] = shl( ctype, 12 );
2672 5463 : move16();
2673 :
2674 : /*aux[2] = (float)log10(gc_mem[0]);
2675 : = log2(gc_mem[0])*log10(2);*/
2676 5463 : exp = norm_l( gc_mem[0] );
2677 5463 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2678 5463 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
2679 5463 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2680 5463 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2681 5463 : move16();
2682 :
2683 5463 : aux[3] = shr( gp_mem[0], 2 );
2684 5463 : move16(); /*Q12*/
2685 :
2686 : /*-----------------------------------------------------------------*
2687 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2688 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2689 : *-----------------------------------------------------------------*/
2690 5463 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2691 5463 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2692 5463 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2693 5463 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2694 :
2695 5463 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2696 : /* output of Pow2() will be: */
2697 : /* 16384 < Pow2() <= 32767 */
2698 5463 : exp_gcode0 = sub( exp_gcode0, 14 );
2699 :
2700 5463 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2701 5463 : gc_mem[1] = *gain_code; // Q16
2702 5463 : move32();
2703 5463 : gp_mem[1] = *gain_pit; // Q14
2704 5463 : move16();
2705 : }
2706 6776 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
2707 : {
2708 3388 : b = b_3sfr_fx; // Q12
2709 3388 : move16();
2710 3388 : n_pred = 6;
2711 3388 : move16();
2712 3388 : IF( EQ_16( nBits, 7 ) )
2713 : {
2714 2 : cdbk = gp_gamma_3sfr_7b_fx; /* Q14 / Q9 */
2715 2 : if ( EQ_16( clip_gain, 1 ) )
2716 : {
2717 0 : size = sub( size, 28 );
2718 : }
2719 : }
2720 : ELSE
2721 : {
2722 3386 : cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
2723 3386 : if ( EQ_16( clip_gain, 1 ) )
2724 : {
2725 0 : size = sub( size, 11 );
2726 : }
2727 : }
2728 : /* calculate predicted gain */
2729 3388 : aux[0] = 4096; // Q12
2730 3388 : move16();
2731 3388 : aux[1] = shl( ctype, 12 );
2732 3388 : move16();
2733 :
2734 : /*aux[2] = (float)log10(gc_mem[0]);
2735 : = log2(gc_mem[0])*log10(2);*/
2736 3388 : exp = norm_l( gc_mem[0] );
2737 3388 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2738 3388 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2739 3388 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2740 3388 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2741 3388 : move16();
2742 :
2743 : /*aux[3] = (float)log10(gc_mem[1]);
2744 : = log2(gc_mem[1])*log10(2);*/
2745 3388 : exp = norm_l( gc_mem[1] );
2746 3388 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2747 3388 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2748 3388 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2749 3388 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2750 3388 : move16();
2751 :
2752 3388 : aux[4] = shr( gp_mem[0], 2 );
2753 3388 : move16(); /*Q12*/
2754 3388 : aux[5] = shr( gp_mem[1], 2 );
2755 3388 : move16(); /*Q12*/
2756 :
2757 : /*-----------------------------------------------------------------*
2758 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2759 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2760 : *-----------------------------------------------------------------*/
2761 3388 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2762 3388 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2763 3388 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2764 3388 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2765 :
2766 3388 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2767 : /* output of Pow2() will be: */
2768 : /* 16384 < Pow2() <= 32767 */
2769 3388 : exp_gcode0 = sub( exp_gcode0, 14 );
2770 :
2771 : /*----------------------------------------------------------------*
2772 : * Find the best quantizer
2773 : * ~~~~~~~~~~~~~~~~~~~~~~~
2774 : * Before doing the computation we need to align exponents of coeff[]
2775 : * to be sure to have the maximum precision.
2776 : *
2777 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
2778 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
2779 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
2780 : * we divide by 2^15.
2781 : * Considering all the scaling above we have:
2782 : *
2783 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
2784 : *
2785 : * g_pitch*g_pitch = -14-14+15
2786 : * g_pitch = -14
2787 : * g_code*g_code = (2*exp_code)+15
2788 : * g_code = exp_code
2789 : * g_pitch*g_code = -14 + exp_code +15
2790 : *
2791 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
2792 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
2793 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
2794 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
2795 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
2796 : *----------------------------------------------------------------*/
2797 :
2798 3388 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
2799 :
2800 3388 : gc_mem[2] = *gain_code; /* Q16 */
2801 3388 : move32();
2802 3388 : gp_mem[2] = *gain_pit; /* Q14 */
2803 3388 : move16();
2804 : }
2805 3388 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
2806 : {
2807 3388 : b = b_4sfr_fx; /* Q12 */
2808 3388 : move16();
2809 3388 : n_pred = 8;
2810 3388 : move16();
2811 3388 : IF( EQ_16( nBits, 7 ) )
2812 : {
2813 0 : cdbk = gp_gamma_4sfr_7b_fx; /* Q14 / Q9 */
2814 0 : if ( EQ_16( clip_gain, 1 ) )
2815 : {
2816 0 : size = sub( size, 25 );
2817 : }
2818 : }
2819 : ELSE
2820 : {
2821 3388 : cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
2822 3388 : if ( EQ_16( clip_gain, 1 ) )
2823 : {
2824 0 : size = sub( size, 11 );
2825 : }
2826 : }
2827 : /* calculate predicted gain */
2828 3388 : aux[0] = 4096; // Q12
2829 3388 : move16();
2830 3388 : aux[1] = shl( ctype, 12 );
2831 3388 : move16();
2832 :
2833 : /*aux[2] = (float)log10(gc_mem[0]);
2834 : = log2(gc_mem[0])*log10(2);*/
2835 3388 : exp = norm_l( gc_mem[0] );
2836 3388 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2837 3388 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2838 3388 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2839 3388 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2840 3388 : move16();
2841 :
2842 : /*aux[3] = (float)log10(gc_mem[1]);
2843 : = log2(gc_mem[1])*log10(2);*/
2844 3388 : exp = norm_l( gc_mem[1] );
2845 3388 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2846 3388 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2847 3388 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2848 3388 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2849 3388 : move16();
2850 :
2851 : /*aux[4] = (float)log10(gc_mem[2]);
2852 : = log2(gc_mem[2])*log10(2);*/
2853 3388 : exp = norm_l( gc_mem[2] );
2854 3388 : frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
2855 3388 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/
2856 3388 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2857 3388 : aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2858 3388 : move16();
2859 :
2860 3388 : aux[5] = shr( gp_mem[0], 2 );
2861 3388 : move16(); /*Q12*/
2862 3388 : aux[6] = shr( gp_mem[1], 2 );
2863 3388 : move16(); /*Q12*/
2864 3388 : aux[7] = shr( gp_mem[2], 2 );
2865 3388 : move16(); /*Q12*/
2866 : /*-----------------------------------------------------------------*
2867 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2868 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2869 : *-----------------------------------------------------------------*/
2870 3388 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2871 3388 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2872 3388 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2873 3388 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2874 :
2875 3388 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2876 : /* output of Pow2() will be: */
2877 : /* 16384 < Pow2() <= 32767 */
2878 3388 : exp_gcode0 = sub( exp_gcode0, 14 );
2879 :
2880 3388 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2881 : }
2882 :
2883 : /* *norm_gain_code = *gain_code / *gain_inov; */
2884 17702 : exp = sub( norm_s( *gain_inov ), 1 );
2885 17702 : exp = s_max( exp, 0 );
2886 :
2887 17702 : tmp = div_s( shr( 8192, exp ), *gain_inov );
2888 17702 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
2889 17702 : move32();
2890 : {
2891 17702 : push_indice( hBstr, IND_GAIN, index, nBits );
2892 : }
2893 17702 : return;
2894 : }
2895 :
2896 : /*-------------------------------------------------------------------*
2897 : * gain_enc_amr_wb()
2898 : *
2899 : * Quantization of pitch and codebook gains (used also in AMR-WB IO mode)
2900 : * MA prediction is performed on the innovation energy (in dB with mean removed).
2901 : * An initial predicted gain, gcode0, is first determined and the correction
2902 : * factor alpha = g_code / gcode0 is quantized.
2903 : * The pitch gain and the correction factor are vector quantized and the
2904 : * mean-squared weighted error criterion is used in the quantizer search.
2905 : *-------------------------------------------------------------------*/
2906 :
2907 :
2908 0 : void gain_enc_amr_wb_fx(
2909 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
2910 : const Word16 *xn, /* i : target vector Q_xn*/
2911 : const Word16 Q_xn, /* i : xn and yy1 format */
2912 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
2913 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
2914 : const Word16 *code, /* i : algebraic excitation Q9*/
2915 : const Word32 core_brate, /* i : core bitrate Q0*/
2916 : Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain Q14*/
2917 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
2918 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
2919 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
2920 : Word16 *g_coeff, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
2921 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
2922 : Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Q10*/
2923 : )
2924 : {
2925 :
2926 : Word16 i, j, index, min_ind, size;
2927 : Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, exp_inov, qua_ener;
2928 : Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
2929 : Word16 coeff[5], coeff_lo[5], exp_coeff[5];
2930 : Word16 exp_max[5], tmp, nBits;
2931 : Word32 L_tmp, dist_min, L_inov, L_tmp1;
2932 : const Word16 *t_qua_gain, *p;
2933 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2934 0 : Flag Overflow = 0;
2935 0 : move32();
2936 : #endif
2937 :
2938 : /*----------------------------------------------------------------*
2939 : * Find the initial quantization pitch index
2940 : * Set gains search range
2941 : *----------------------------------------------------------------*/
2942 0 : IF( GE_32( core_brate, ACELP_12k65 ) )
2943 : {
2944 0 : t_qua_gain = t_qua_gain7b_fx; // Q14
2945 0 : move16();
2946 : /* pt at 1/4th of table */
2947 0 : p = t_qua_gain7b_fx + RANGE;
2948 0 : move16();
2949 :
2950 0 : j = NB_QUA_GAIN7B - RANGE;
2951 0 : move16();
2952 :
2953 0 : IF( EQ_16( clip_gain, 1 ) )
2954 : {
2955 0 : j = sub( j, 27 ); /* limit gain pitch to 1.0 */
2956 : }
2957 0 : min_ind = 0;
2958 0 : move16();
2959 0 : g_pitch = *gain_pit; // Q14
2960 0 : move16();
2961 :
2962 0 : FOR( i = 0; i < j; i++ )
2963 : {
2964 0 : if ( GT_16( g_pitch, *p ) )
2965 : {
2966 0 : min_ind = add( min_ind, 1 ); // Q0
2967 : }
2968 0 : p += 2;
2969 : }
2970 0 : size = RANGE;
2971 0 : move16();
2972 0 : nBits = 7;
2973 : }
2974 : ELSE
2975 : {
2976 0 : t_qua_gain = t_qua_gain6b_fx; // Q14
2977 0 : min_ind = 0;
2978 0 : move16();
2979 0 : size = RANGE;
2980 0 : move16();
2981 0 : if ( EQ_16( clip_gain, 1 ) )
2982 : {
2983 0 : size = sub( size, 16 ); /* limit gain pitch to 1.0 */
2984 : }
2985 0 : nBits = 6;
2986 : }
2987 : /*----------------------------------------------------------------*
2988 : * Compute coefficients needed for the quantization.
2989 : *
2990 : * coeff[0] = yy1 yy1
2991 : * coeff[1] = -2 xn yy1
2992 : * coeff[2] = y2 y2
2993 : * coeff[3] = -2 xn y2
2994 : * coeff[4] = 2 yy1 y2
2995 : *
2996 : * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
2997 : * are in vector g_coeff[].
2998 : *----------------------------------------------------------------*/
2999 0 : coeff[0] = g_coeff[0];
3000 0 : move16();
3001 0 : exp_coeff[0] = g_coeff[1];
3002 0 : move16();
3003 0 : coeff[1] = negate( g_coeff[2] );
3004 0 : move16(); /* coeff[1] = -2 xn yy1 */
3005 0 : exp_coeff[1] = add( g_coeff[3], 1 );
3006 0 : move16();
3007 :
3008 : /* Compute scalar product <y2[],y2[]> */
3009 0 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
3010 0 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
3011 0 : move16();
3012 0 : move16();
3013 :
3014 : /* Compute scalar product -2*<xn[],y2[]> */
3015 0 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
3016 0 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
3017 0 : move16();
3018 0 : move16();
3019 :
3020 : /* Compute scalar product 2*<yy1[],y2[]> */
3021 0 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
3022 0 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
3023 0 : move16();
3024 0 : move16();
3025 :
3026 : /*----------------------------------------------------------------*
3027 : * Find energy of code and compute:
3028 : *
3029 : * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)
3030 : * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)
3031 : *----------------------------------------------------------------*/
3032 0 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
3033 0 : L_inov = L_add( L_tmp, 0 );
3034 : /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
3035 : /* output gain_inov*/
3036 0 : exp_inov = sub( exp_code, 18 + 6 );
3037 0 : L_inov = Isqrt_lc( L_inov, &exp_inov );
3038 0 : *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
3039 0 : move16();
3040 :
3041 0 : exp_code = sub( exp_code, 18 + 6 + 31 );
3042 0 : frac = Log2_lc( L_tmp, &exp );
3043 0 : exp = add( exp, exp_code );
3044 0 : L_tmp = Mpy_32_16( exp, frac, -24660 ); /* x -3.0103(Q13) -> Q14 */
3045 :
3046 0 : L_tmp = L_mac( L_tmp, MEAN_ENER, 8192 ); /* + MEAN_ENER in Q14 */
3047 :
3048 : /*----------------------------------------------------------------*
3049 : * predicted codebook gain
3050 : *----------------------------------------------------------------*/
3051 0 : L_tmp = L_shl( L_tmp, 10 ); /* From Q14 to Q24 */
3052 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[0], past_qua_en[0] ); /* Q14*Q10 -> Q24 */
3053 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[1], past_qua_en[1] ); /* Q14*Q10 -> Q24 */
3054 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[2], past_qua_en[2] ); /* Q14*Q10 -> Q24 */
3055 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[3], past_qua_en[3] ); /* Q14*Q10 -> Q24 */
3056 :
3057 0 : gcode0 = extract_h( L_tmp ); /* From Q24 to Q8 */
3058 :
3059 : /*----------------------------------------------------------------*
3060 : * gcode0 = pow(10.0, gcode0/20)
3061 : * = pow(2, 3.321928*gcode0/20)
3062 : * = pow(2, 0.166096*gcode0)
3063 : *----------------------------------------------------------------*/
3064 0 : L_tmp = L_mult( gcode0, 5443 ); /* *0.166096 in Q15 -> Q24 */
3065 0 : L_tmp = L_shr( L_tmp, 8 ); /* From Q24 to Q16 */
3066 0 : L_Extract( L_tmp, &exp_gcode0, &frac ); /* Extract exponent of gcode0 */
3067 :
3068 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
3069 : /* output of Pow2() will be: */
3070 : /* 16384 < Pow2() <= 32767 */
3071 0 : exp_gcode0 = sub( exp_gcode0, 14 );
3072 :
3073 : /*----------------------------------------------------------------*
3074 : * Find the best quantizer
3075 : * ~~~~~~~~~~~~~~~~~~~~~~~
3076 : * Before doing the computation we need to aling exponents of coeff[]
3077 : * to be sure to have the maximum precision.
3078 : *
3079 : * In the table the pitch gains are in Q14, the code gains are in Q11 and
3080 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
3081 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
3082 : * we divide by 2^15.
3083 : * Considering all the scaling above we have:
3084 : *
3085 : * exp_code = exp_gcode0-11+15 = exp_gcode0+4
3086 : *
3087 : * g_pitch*g_pitch = -14-14+15
3088 : * g_pitch = -14
3089 : * g_code*g_code = (2*exp_code)+15
3090 : * g_code = exp_code
3091 : * g_pitch*g_code = -14 + exp_code +15
3092 : *
3093 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
3094 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
3095 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
3096 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
3097 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
3098 : *----------------------------------------------------------------*/
3099 :
3100 0 : exp_code = add( exp_gcode0, 4 );
3101 :
3102 0 : exp_max[0] = sub( exp_coeff[0], 13 );
3103 0 : move16();
3104 0 : exp_max[1] = sub( exp_coeff[1], 14 );
3105 0 : move16();
3106 0 : exp_max[2] = add( exp_coeff[2],
3107 0 : add( 15, shl( exp_code, 1 ) ) );
3108 0 : move16();
3109 0 : exp_max[3] = add( exp_coeff[3], exp_code );
3110 0 : move16();
3111 0 : exp_max[4] = add( exp_coeff[4],
3112 0 : add( 1, exp_code ) );
3113 0 : move16();
3114 :
3115 : /* Find maximum exponant */
3116 0 : e_max = exp_max[0];
3117 0 : move16();
3118 0 : FOR( i = 1; i < 5; i++ )
3119 : {
3120 0 : e_max = s_max( exp_max[i], e_max );
3121 : }
3122 :
3123 : /* align coeff[] and save in special 32 bit double precision */
3124 0 : FOR( i = 0; i < 5; i++ )
3125 : {
3126 0 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
3127 0 : L_tmp = L_deposit_h( coeff[i] );
3128 0 : L_tmp = L_shr( L_tmp, j );
3129 0 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
3130 0 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
3131 0 : move16();
3132 : }
3133 :
3134 : /* Codebook search */
3135 0 : dist_min = L_add( MAX_32, 0 );
3136 0 : p = &t_qua_gain[shl( min_ind, 1 )]; // Q14
3137 0 : move16();
3138 :
3139 0 : index = 0;
3140 0 : move16();
3141 0 : FOR( i = 0; i < size; i++ )
3142 : {
3143 0 : g_pitch = *p++;
3144 0 : move16();
3145 0 : g_code = *p++;
3146 0 : move16();
3147 :
3148 0 : g_code = mult_r( g_code, gcode0 ); // exp(gcode) - 1
3149 0 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
3150 0 : g_pit_cod = mult_r( g_code, g_pitch );
3151 0 : L_tmp = L_mult( g_code, g_code );
3152 0 : L_Extract( L_tmp, &g2_code, &g2_code_lo );
3153 :
3154 0 : L_tmp = L_mult( coeff[2], g2_code_lo );
3155 0 : L_tmp = L_shr( L_tmp, 3 );
3156 0 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
3157 0 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
3158 0 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
3159 0 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
3160 0 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
3161 0 : L_tmp = L_shr( L_tmp, 12 );
3162 0 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
3163 0 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
3164 0 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
3165 0 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
3166 0 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
3167 :
3168 0 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
3169 : /* splitting the if cost half the complexity of using IF macro */
3170 0 : if ( L_tmp1 < 0 )
3171 : {
3172 0 : dist_min = L_add( L_tmp, 0 );
3173 : }
3174 0 : if ( L_tmp1 < 0 )
3175 : {
3176 0 : index = i;
3177 0 : move16();
3178 : }
3179 : }
3180 : /* Read the quantized gains */
3181 0 : index = add( index, min_ind );
3182 :
3183 0 : p = &t_qua_gain[add( index, index )];
3184 0 : move16();
3185 0 : *gain_pit = *p++; /* selected pitch gain in Q14 */
3186 0 : move16();
3187 0 : g_code = *p++; /* selected code gain in Q11 */
3188 0 : move16();
3189 :
3190 0 : L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */
3191 0 : L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */
3192 :
3193 0 : *gain_code = L_tmp; /* gain of code in Q16 */
3194 0 : move16();
3195 :
3196 : /*---------------------------------------------------*
3197 : * qua_ener = 20*log10(g_code)
3198 : * = 6.0206*log2(g_code)
3199 : * = 6.0206*(log2(g_codeQ11) - 11)
3200 : *---------------------------------------------------*/
3201 0 : L_tmp = L_deposit_l( g_code );
3202 0 : frac = Log2_lc( L_tmp, &exp );
3203 0 : exp = sub( exp, 11 );
3204 0 : L_tmp = Mpy_32_16( exp, frac, 24660 ); /* x 6.0206 in Q12 */
3205 :
3206 0 : qua_ener = extract_l( L_shr( L_tmp, 3 ) ); /* result in Q10 */
3207 :
3208 : /*----------------------------------------------------------------*
3209 : * update table of past quantized energies
3210 : *----------------------------------------------------------------*/
3211 :
3212 0 : past_qua_en[3] = past_qua_en[2]; // Q10
3213 0 : move16();
3214 0 : past_qua_en[2] = past_qua_en[1]; // Q10
3215 0 : move16();
3216 0 : past_qua_en[1] = past_qua_en[0]; // Q10
3217 0 : move16();
3218 0 : past_qua_en[0] = qua_ener; // Q10
3219 0 : move16();
3220 :
3221 :
3222 0 : exp = sub( norm_s( *gain_inov ), 1 );
3223 0 : exp = s_max( exp, 0 );
3224 :
3225 0 : tmp = div_s( shr( 8192, exp ), *gain_inov );
3226 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
3227 0 : move32();
3228 :
3229 0 : push_indice( hBstr, IND_GAIN, index, nBits );
3230 :
3231 0 : return;
3232 : }
|