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 132562 : 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 132562 : Flag Overflow = 0;
69 132562 : move32();
70 : #endif
71 :
72 132562 : Lmean_ener_code = L_deposit_l( 0 );
73 132562 : Q_res = sub( shl( Q_new, 1 ), 3 );
74 :
75 132562 : IF( EQ_16( L_frame, L_FRAME ) )
76 : {
77 60740 : weight = 8192;
78 60740 : move16(); /*0.25f in Q15*/
79 : }
80 : ELSE /* L_frame == L_FRAME16k */
81 : {
82 71822 : weight = 6554;
83 71822 : move16(); /*0.2f in Q15*/
84 : }
85 :
86 : /*----------------------------------------------------------*
87 : * calculate the average residual signal energy in four sframes
88 : *----------------------------------------------------------*/
89 :
90 734632 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
91 : {
92 : /* calculate the energy of residual signal */
93 602070 : tmp16 = mult_r( res[i_subfr + 0], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
94 602070 : ener_fx = L_mult( tmp16, tmp16 );
95 38532480 : FOR( i = 1; i < L_SUBFR; i++ )
96 : {
97 37930410 : tmp16 = mult_r( res[i_subfr + i], 8192 /* 1 in Q13 */ ); /* remove 2bits Q_new - 2*/
98 37930410 : ener_fx = L_mac_o( ener_fx, tmp16, tmp16, &Overflow );
99 : }
100 :
101 : /* ener = 10 * (float)log10(ener / (float)L_SUBFR) */
102 602070 : s1 = 0;
103 602070 : move16();
104 602070 : s0 = norm_l( ener_fx );
105 :
106 602070 : IF( ener_fx != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
107 : {
108 596379 : s1 = Log2_norm_lc( L_shl( ener_fx, s0 ) );
109 596379 : s0 = sub( 30, s0 );
110 : }
111 602070 : s0 = sub( s0, add( Q_res, 6 ) );
112 602070 : Ltmp = Mpy_32_16( s0, s1, LG10 );
113 602070 : ener_dB = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 Energy in log10 */
114 602070 : test();
115 602070 : if ( ( ener_dB < 0 ) && ( no_ltp == 0 ) )
116 : {
117 12405 : ener_dB = 0;
118 12405 : move16();
119 : }
120 :
121 : /* update the average energy of residual signal */
122 602070 : Lmean_ener_code = L_mac( Lmean_ener_code, ener_dB, weight ); /* Q24 */
123 : }
124 :
125 132562 : 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 130561 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[0], 1280 ); /*Q24*/
132 130561 : Lmean_ener_code = L_msu( Lmean_ener_code, voicing[1], 1280 ); /*Q24*/
133 130561 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
134 :
135 : /*----------------------------------------------------------*n
136 : * quantize the average predicted innovation energy
137 : *----------------------------------------------------------*/
138 130561 : SWITCH( nb_bits )
139 : {
140 112602 : case 5:
141 : {
142 112602 : qua_table = Es_pred_qua_5b_fx; // Q8
143 112602 : BREAK;
144 : }
145 17355 : case 4:
146 : {
147 17355 : qua_table = Es_pred_qua_4b_fx; // Q8
148 17355 : BREAK;
149 : }
150 604 : case 3:
151 : {
152 604 : qua_table = Es_pred_qua_3b_fx; // Q8
153 604 : 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 2001 : mean_ener_code16 = extract_h( Lmean_ener_code ); /*Q8*/
165 :
166 2001 : 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 132562 : size = shl( 1, nb_bits ); /*maximum number of bit is 6 */
170 :
171 : /* find the nearest neighbour (codevector) */
172 132562 : *Es_pred = qua_table[0]; // Q8
173 132562 : move16();
174 132562 : tmp16 = abs_s( sub( mean_ener_code16, qua_table[0] ) );
175 132562 : *indice = 0;
176 132562 : move16();
177 :
178 3917792 : FOR( i = 1; i < size; i++ )
179 : {
180 3785230 : tmp16_2 = abs_s( sub_o( mean_ener_code16, qua_table[i], &Overflow ) );
181 3785230 : IF( LT_16( tmp16_2, tmp16 ) )
182 : {
183 1949791 : tmp16 = tmp16_2;
184 1949791 : move16();
185 1949791 : *indice = i;
186 1949791 : move16();
187 1949791 : *Es_pred = qua_table[i]; // Q8
188 1949791 : move16();
189 : }
190 : }
191 :
192 :
193 132562 : 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 2916 : 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 2916 : Flag Overflow = 0;
238 2916 : 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 2916 : coeff[0] = g_corr[0];
247 2916 : move16();
248 2916 : exp_coeff[0] = g_corr[1];
249 2916 : move16();
250 2916 : coeff[1] = negate( g_corr[2] );
251 2916 : move16(); /* coeff[1] = -2 xn yy1 */
252 2916 : exp_coeff[1] = add( g_corr[3], 1 );
253 2916 : move16();
254 :
255 : /* Compute scalar product <y2[],y2[]> */
256 2916 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
257 2916 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
258 2916 : move16(); /* -18 (y2 Q9) */
259 :
260 : /* Compute scalar product -2*<xn[],y2[]> */
261 2916 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
262 2916 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
263 2916 : move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
264 :
265 : /* Compute scalar product 2*<y1[],y2[]> */
266 2916 : coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
267 2916 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
268 2916 : 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 2916 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
277 2916 : exp_inov = sub( exp_code, 18 + 6 );
278 2916 : 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 2916 : tmp = norm_l( L_tmp );
286 2916 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
287 2916 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
288 2916 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
289 2916 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
290 :
291 : /* predicted codebook gain */
292 2916 : 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 2916 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
300 2916 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
301 2916 : 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 2916 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
311 2916 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
312 2916 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
313 :
314 2916 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
315 : /* output of Pow2() will be: */
316 : /* 16384 < Pow2() <= 32767 */
317 2916 : 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 2916 : nBits = gains_mode[i_subfr >> 6];
324 2916 : move16();
325 :
326 2916 : test();
327 2916 : test();
328 2916 : test();
329 2916 : test();
330 2916 : test();
331 2916 : 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 23 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
343 23 : exp1 = add( exp_coeff[0], exp_coeff[2] );
344 :
345 23 : L_tmp2 = L_shr( L_mult( coeff[4], coeff[4] ), 2 ); /*Q31*/
346 23 : exp2 = add( exp_coeff[4], exp_coeff[4] );
347 :
348 23 : IF( GT_16( exp1, exp2 ) )
349 : {
350 23 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
351 23 : exp_den = exp1;
352 23 : 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 23 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
361 :
362 23 : frac_den = extract_h( L_frac_den ); /* Q15 */
363 23 : frac_den = s_max( frac_den, 1 ); /* Q15 */
364 23 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
365 23 : exp = norm_l( L_frac_den );
366 23 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
367 :
368 23 : L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
369 23 : exp1 = add( exp_coeff[3], exp_coeff[4] );
370 :
371 23 : L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
372 23 : exp2 = add( exp_coeff[1], exp_coeff[2] );
373 :
374 23 : IF( GT_16( exp1, exp2 ) )
375 : {
376 1 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
377 1 : exp_num = exp1;
378 1 : move16();
379 : }
380 : ELSE
381 : {
382 22 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
383 22 : exp_num = exp2;
384 22 : move16();
385 : }
386 23 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
387 :
388 23 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
389 23 : exp_div = sub( exp_num, exp_den );
390 :
391 23 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
392 :
393 23 : L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
394 23 : exp1 = add( exp_coeff[1], exp_coeff[4] );
395 :
396 23 : L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
397 23 : exp2 = add( exp_coeff[0], exp_coeff[3] );
398 :
399 23 : IF( GT_16( exp1, exp2 ) )
400 : {
401 1 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
402 1 : exp_num = exp1;
403 1 : move16();
404 : }
405 : ELSE
406 : {
407 22 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
408 22 : exp_num = exp2;
409 22 : move16();
410 : }
411 23 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
412 :
413 23 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
414 23 : exp_div = sub( exp_num, exp_den );
415 :
416 23 : *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
417 23 : move32(); /*Q16*/
418 :
419 23 : *gain_pit = s_max( G_PITCH_MIN_TC192_Q14, s_min( *gain_pit, G_PITCH_MAX_TC192_Q14 ) );
420 23 : move16();
421 :
422 : /* set number of bits for two SQs */
423 23 : nBits2 = shr( add( nBits, 1 ), 1 );
424 23 : nBits = shr( nBits, 1 );
425 :
426 : /* gain_pit Q */
427 :
428 23 : tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
429 23 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
430 23 : move16();
431 23 : push_indice( hBstr, IND_GAIN_PIT, index, nBits );
432 :
433 : /* gain_code Q */
434 : /**gain_code /= gcode0;*/
435 23 : IF( gcode0 != 0 )
436 : {
437 23 : tmp = div_s( 16384, gcode0 ); /*Q15*/
438 23 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
439 23 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
440 23 : move32();
441 : }
442 :
443 23 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
444 23 : push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
445 23 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
446 23 : *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
447 : }
448 : ELSE
449 : {
450 2893 : size = shl( 1, nBits );
451 :
452 2893 : 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 2893 : case 6:
465 : {
466 2893 : qua_table = gain_qua_mless_6b_fx;
467 : if ( element_mode > EVS_MONO )
468 : {
469 : }
470 2893 : move16();
471 2893 : if ( EQ_16( clip_gain, 1 ) )
472 : {
473 23 : size = sub( size, 14 );
474 : }
475 2893 : 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 2893 : test();
501 2893 : 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 2893 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size ); // Q0
511 2893 : push_indice( hBstr, IND_GAIN, index, nBits );
512 : }
513 :
514 : /* *norm_gain_code = *gain_code / *gain_inov; */
515 2916 : exp = sub( norm_s( *gain_inov ), 1 );
516 2916 : exp = s_max( exp, 0 );
517 :
518 2916 : tmp = div_s( shr( 8192, exp ), *gain_inov );
519 2916 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) );
520 2916 : move32();
521 :
522 2916 : return;
523 : }
524 :
525 521364 : 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 521364 : Flag Overflow = 0;
559 521364 : 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 521364 : coeff[0] = g_corr[0];
568 521364 : move16();
569 521364 : exp_coeff[0] = g_corr[1];
570 521364 : move16();
571 521364 : coeff[1] = negate( g_corr[2] );
572 521364 : move16(); /* coeff[1] = -2 xn yy1 */
573 521364 : exp_coeff[1] = add( g_corr[3], 1 );
574 521364 : move16();
575 :
576 : /* Compute scalar product <y2[],y2[]> */
577 521364 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
578 521364 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
579 521364 : move16(); /* -18 (y2 Q9) */
580 :
581 : /* Compute scalar product -2*<xn[],y2[]> */
582 521364 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
583 521364 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn );
584 521364 : move16(); /* -9 (y2 Q9), +1 (2 xn y2) */
585 :
586 : /* Compute scalar product 2*<y1[],y2[]> */
587 521364 : coeff[4] = extract_h( Dot_product12( y1, y2, L_SUBFR, &exp ) );
588 521364 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn );
589 521364 : 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 521364 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
598 521364 : exp_inov = sub( exp_code, 18 + 6 );
599 :
600 : // To avoid crash in case code value is 0,
601 521364 : 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 521364 : 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 521364 : tmp = norm_l( L_tmp );
619 521364 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
620 521364 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
621 521364 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
622 521364 : 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 521364 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
630 521364 : *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
631 521364 : move16();
632 : }
633 :
634 : /* predicted codebook gain */
635 521364 : 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 521364 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
645 521364 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
646 521364 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
647 :
648 521364 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
649 : /* output of Pow2() will be: */
650 : /* 16384 < Pow2() <= 32767 */
651 521364 : 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 521364 : nBits = gains_mode[i_subfr >> 6];
658 521364 : move16();
659 :
660 521364 : test();
661 521364 : test();
662 521364 : test();
663 521364 : test();
664 521364 : test();
665 521364 : 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 3610 : L_tmp1 = L_mult_sat( coeff[0], coeff[2] ); /*Q31 added saturation for -32768*-32768*/
677 3610 : exp1 = add( exp_coeff[0], exp_coeff[2] );
678 :
679 3610 : L_tmp2 = L_shr( L_mult_sat( coeff[4], coeff[4] ), 2 ); /*Q31 added saturation for -32768*-32768*/
680 3610 : exp2 = add( exp_coeff[4], exp_coeff[4] );
681 :
682 3610 : IF( GT_16( exp1, exp2 ) )
683 : {
684 3506 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
685 3506 : exp_den = exp1;
686 3506 : move16();
687 : }
688 : ELSE
689 : {
690 104 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
691 104 : exp_den = exp2;
692 104 : move16();
693 : }
694 3610 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
695 :
696 3610 : frac_den = extract_h( L_frac_den ); /* Q15 */
697 3610 : frac_den = s_max( frac_den, 1 ); /* Q15 */
698 3610 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
699 3610 : exp = norm_l( L_frac_den );
700 3610 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
701 :
702 3610 : L_tmp1 = L_shr( L_mult( coeff[3], coeff[4] ), 2 ); /*Q31*/
703 3610 : exp1 = add( exp_coeff[3], exp_coeff[4] );
704 :
705 3610 : L_tmp2 = L_shr( L_mult( coeff[1], coeff[2] ), 1 ); /*Q31*/
706 3610 : exp2 = add( exp_coeff[1], exp_coeff[2] );
707 :
708 3610 : IF( GT_16( exp1, exp2 ) )
709 : {
710 124 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
711 124 : exp_num = exp1;
712 124 : move16();
713 : }
714 : ELSE
715 : {
716 3486 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
717 3486 : exp_num = exp2;
718 3486 : move16();
719 : }
720 3610 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
721 :
722 3610 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
723 3610 : exp_div = sub( exp_num, exp_den );
724 :
725 3610 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
726 :
727 3610 : L_tmp1 = L_shr( L_mult( coeff[1], coeff[4] ), 2 ); /*Q31*/
728 3610 : exp1 = add( exp_coeff[1], exp_coeff[4] );
729 :
730 3610 : L_tmp2 = L_shr( L_mult( coeff[0], coeff[3] ), 1 ); /*Q31*/
731 3610 : exp2 = add( exp_coeff[0], exp_coeff[3] );
732 :
733 3610 : IF( GT_16( exp1, exp2 ) )
734 : {
735 55 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
736 55 : exp_num = exp1;
737 55 : move16();
738 : }
739 : ELSE
740 : {
741 3555 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
742 3555 : exp_num = exp2;
743 3555 : move16();
744 : }
745 3610 : L_frac_num = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
746 :
747 3610 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
748 3610 : exp_div = sub( exp_num, exp_den );
749 :
750 3610 : *gain_code = L_shl_o( L_div, sub( add( exp, exp_div ), 14 ), &Overflow );
751 3610 : move32(); /*Q16*/
752 :
753 3610 : *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 3610 : nBits2 = shr( add( nBits, 1 ), 1 );
757 3610 : nBits = shr( nBits, 1 );
758 :
759 : /* gain_pit Q */
760 :
761 3610 : tmp1 = mult_r( G_PITCH_MAX_MINUS_MIN_TC192_Q13, div_s( 1, sub( shl( 1, nBits ), 1 ) ) ); /*Q13*/ /* set quantization step */
762 3610 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_TC192_Q14, tmp1, shl( 1, nBits ) );
763 3610 : move16();
764 3610 : push_indice( hBstr, IND_GAIN_PIT, index, nBits );
765 :
766 : /* gain_code Q */
767 : /**gain_code /= gcode0;*/
768 3610 : IF( gcode0 != 0 )
769 : {
770 3610 : tmp = div_s( 16384, gcode0 ); /*Q15*/
771 3610 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
772 3610 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
773 3610 : move32();
774 : }
775 :
776 3610 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_TC192_Q14, LG10_G_CODE_MAX_TC192_Q13, nBits2, &expg );
777 3610 : push_indice( hBstr, IND_GAIN_CODE, index, nBits2 );
778 3610 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
779 3610 : *gain_code = L_shl_o( L_tmp, add( add( expg, exp_gcode0 ), 15 ), &Overflow ); /*Q16*/
780 : }
781 : ELSE
782 : {
783 517754 : size = shl( 1, nBits );
784 :
785 517754 : SWITCH( nBits )
786 : {
787 751 : case 7:
788 : {
789 751 : qua_table = gain_qua_mless_7b_fx; // Q14
790 751 : if ( EQ_16( clip_gain, 1 ) )
791 : {
792 0 : size = sub( size, 30 );
793 : }
794 751 : BREAK;
795 : }
796 516497 : case 6:
797 : {
798 516497 : qua_table = gain_qua_mless_6b_fx; // Q14
799 516497 : if ( element_mode > EVS_MONO )
800 : {
801 516497 : qua_table = gain_qua_mless_6b_stereo_fx;
802 : }
803 516497 : if ( EQ_16( clip_gain, 1 ) )
804 : {
805 5940 : size = sub( size, 14 );
806 : }
807 516497 : BREAK;
808 : }
809 506 : case 5:
810 : {
811 506 : qua_table = gain_qua_mless_5b_fx; // Q14
812 506 : if ( EQ_16( clip_gain, 1 ) )
813 : {
814 0 : size = sub( size, 6 );
815 : }
816 506 : 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 517754 : test();
831 517754 : IF( EQ_16( clip_gain, 2 ) && EQ_16( nBits, 6 ) )
832 : {
833 5325 : size = sub( size, 36 );
834 5325 : nBits = sub( nBits, 1 );
835 : }
836 :
837 : /*-----------------------------------------------------------------*
838 : * search for the best quantizer
839 : *-----------------------------------------------------------------*/
840 517754 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, qua_table, size );
841 517754 : push_indice( hBstr, IND_GAIN, index, nBits );
842 : }
843 :
844 : /* *norm_gain_code = *gain_code / *gain_inov; */
845 521364 : exp = sub( norm_s( *gain_inov ), 1 );
846 521364 : exp = s_max( exp, 0 );
847 :
848 521364 : tmp = div_s( shr( 8192, exp ), *gain_inov );
849 521364 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
850 521364 : move32();
851 :
852 521364 : 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 43280 : 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 43280 : Flag Overflow = 0;
1170 43280 : 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 43280 : coeff[0] = g_corr[0];
1183 43280 : move16();
1184 43280 : exp_coeff[0] = g_corr[1];
1185 43280 : move16();
1186 43280 : coeff[1] = g_corr[2];
1187 43280 : move16(); /* coeff[1] = xn yy1 */
1188 43280 : exp_coeff[1] = g_corr[3];
1189 43280 : move16();
1190 :
1191 : /* Compute scalar product <y2[],y2[]> */
1192 43280 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
1193 43280 : move16();
1194 43280 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) );
1195 43280 : move16(); /* -18 (y2 Q9) */
1196 :
1197 : /* Compute scalar product <xn[],y2[]> */
1198 43280 : coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) );
1199 43280 : move16();
1200 43280 : exp_coeff[3] = add( sub( exp, 9 ), Q_xn );
1201 43280 : move16(); /* -9 (y2 Q9), (xn y2) */
1202 :
1203 : /* Compute scalar product <y1[],y2[]> */
1204 43280 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
1205 43280 : move16();
1206 43280 : exp_coeff[4] = add( sub( exp, 9 ), Q_xn );
1207 43280 : 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 43280 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
1218 43280 : exp_inov = sub( exp_code, 18 + 6 );
1219 43280 : 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 43280 : tmp = norm_l( L_tmp );
1226 43280 : frac = Log2_norm_lc( L_shl( L_tmp, tmp ) );
1227 43280 : tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1228 43280 : L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */
1229 43280 : Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1230 :
1231 : /* predicted codebook gain */
1232 43280 : 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 43280 : L_tmp = Isqrt_lc( L_tmp, &exp_inov );
1240 43280 : *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 43280 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
1250 43280 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1251 43280 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1252 :
1253 43280 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1254 : /* output of Pow2() will be: */
1255 : /* 16384 < Pow2() <= 32767 */
1256 43280 : 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 43280 : L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/
1273 43280 : exp1 = add( exp_coeff[0], exp_coeff[2] );
1274 :
1275 43280 : L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/
1276 43280 : exp2 = add( exp_coeff[4], exp_coeff[4] );
1277 :
1278 43280 : IF( GT_16( exp1, exp2 ) )
1279 : {
1280 43202 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1281 43202 : exp_den = exp1;
1282 43202 : move16();
1283 : }
1284 : ELSE
1285 : {
1286 78 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1287 78 : exp_den = exp2;
1288 78 : move16();
1289 : }
1290 43280 : L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/
1291 :
1292 43280 : frac_den = extract_h( L_frac_den ); /* Q15 */
1293 43280 : frac_den = s_max( frac_den, 1 ); /* Q15 */
1294 43280 : L_frac_den = L_max( L_frac_den, 1 ); /* Q31 */
1295 43280 : exp = norm_l( L_frac_den );
1296 43280 : tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/
1297 :
1298 :
1299 43280 : L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/
1300 43280 : exp1 = add( exp_coeff[3], exp_coeff[4] );
1301 :
1302 43280 : L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/
1303 43280 : exp2 = add( exp_coeff[1], exp_coeff[2] );
1304 :
1305 43280 : IF( GT_16( exp1, exp2 ) )
1306 : {
1307 1306 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1308 1306 : exp_num = exp1;
1309 1306 : move16();
1310 : }
1311 : ELSE
1312 : {
1313 41974 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1314 41974 : exp_num = exp2;
1315 41974 : move16();
1316 : }
1317 43280 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1318 :
1319 43280 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1320 43280 : exp_div = sub( exp_num, exp_den );
1321 :
1322 43280 : *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/
1323 43280 : move16();
1324 :
1325 : // To be checked
1326 43280 : L_tmp1 = L_mult_o( coeff[1], coeff[4], &Overflow ); /*Q31*/
1327 43280 : exp1 = add( exp_coeff[1], exp_coeff[4] );
1328 :
1329 43280 : L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/
1330 43280 : exp2 = add( exp_coeff[0], exp_coeff[3] );
1331 :
1332 43280 : IF( GT_16( exp1, exp2 ) )
1333 : {
1334 1285 : L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/
1335 1285 : exp_num = exp1;
1336 1285 : move16();
1337 : }
1338 : ELSE
1339 : {
1340 41995 : L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/
1341 41995 : exp_num = exp2;
1342 41995 : move16();
1343 : }
1344 43280 : L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/
1345 :
1346 43280 : L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/
1347 43280 : exp_div = sub( exp_num, exp_den );
1348 :
1349 43280 : *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) );
1350 43280 : move32(); /*Q16*/
1351 :
1352 43280 : *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 43280 : test();
1359 43280 : test();
1360 43280 : IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 /* 0.95 in Q14 */ ) )
1361 : {
1362 2 : *gain_pit = 15565; /* 0.95 in Q14 */
1363 2 : move16();
1364 : }
1365 43278 : ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 /* 0.65 in Q14 */ ) )
1366 : {
1367 1029 : *gain_pit = 10650; /* 0.65 in Q14 */
1368 1029 : move16();
1369 : }
1370 :
1371 : /*-----------------------------------------------------------------*
1372 : * search for the best quantized values
1373 : *-----------------------------------------------------------------*/
1374 :
1375 43280 : nBits_pitch = gains_mode[i_subfr >> 6];
1376 43280 : move16();
1377 :
1378 : /* set number of bits for two SQs */
1379 43280 : nBits_code = shr( add( nBits_pitch, 1 ), 1 );
1380 43280 : 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 43280 : tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */
1385 :
1386 43280 : index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) );
1387 43280 : push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch );
1388 :
1389 : /* gain_code Q */
1390 : /* *gain_code /= gcode0; */
1391 43280 : IF( gcode0 != 0 )
1392 : {
1393 43280 : tmp = div_s( 16384, gcode0 ); /*Q15*/
1394 43280 : L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/
1395 43280 : *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1396 43280 : move32();
1397 : }
1398 :
1399 43280 : index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg );
1400 43280 : push_indice( hBstr, IND_GAIN_CODE, index, nBits_code );
1401 43280 : L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/
1402 43280 : *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) );
1403 43280 : move32(); /*Q16*/
1404 :
1405 : /* *norm_gain_code = *gain_code / *gain_inov; */
1406 43280 : exp = sub( norm_s( *gain_inov ), 1 );
1407 43280 : exp = s_max( exp, 0 );
1408 :
1409 43280 : tmp = div_s( shr( 8192, exp ), *gain_inov );
1410 43280 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
1411 43280 : move32();
1412 :
1413 43280 : 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 102 : 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 102 : 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 102 : Word16 wgain_code = 0, gain_code16;
1500 102 : *gain_pit_fx = 0;
1501 102 : move16();
1502 102 : move16();
1503 102 : move16();
1504 :
1505 : /*----------------------------------------------------------------*
1506 : * get number of bits for gain quantization
1507 : *----------------------------------------------------------------*/
1508 102 : 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 102 : L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
1517 102 : exp_den = norm_l( L_tmp );
1518 102 : den = extract_h( L_shl( L_tmp, exp_den ) );
1519 102 : exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
1520 :
1521 : /* Compute scalar product <xn[],y2[]> */
1522 102 : L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */
1523 102 : exp_num = sub( norm_l( L_tmp1 ), 1 );
1524 102 : num = extract_h( L_shl( L_tmp1, exp_num ) );
1525 102 : exp_num = sub( add( exp_num, 8 ), Q_xn );
1526 :
1527 102 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
1528 102 : num = abs_s( num );
1529 :
1530 : /*----------------------------------------------------------------*
1531 : * compute gain = xy/yy
1532 : *----------------------------------------------------------------*/
1533 102 : g_code_fx = div_s( num, den );
1534 :
1535 102 : i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */
1536 102 : g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
1537 102 : *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i );
1538 102 : move32();
1539 :
1540 : /*----------------------------------------------------------------*
1541 : * calculate the predicted gain code
1542 : * decode codebook gain
1543 : *----------------------------------------------------------------*/
1544 :
1545 102 : *gain_pit_fx = 0;
1546 102 : move16();
1547 :
1548 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
1549 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
1550 :
1551 102 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
1552 102 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1553 102 : expg2 = expg;
1554 102 : move16();
1555 102 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1556 102 : move32();
1557 102 : L_tmp = Isqrt_lc( L_tmp, &expg );
1558 :
1559 102 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
1560 102 : move16(); /* gain_inov in Q12 */
1561 :
1562 : /*Ei = 10 * (float)log10( Ecode );*/
1563 102 : e_tmp = norm_l( L_tmp1 );
1564 102 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1565 102 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1566 102 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1567 102 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1568 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1569 102 : 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 102 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1576 102 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1577 102 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1578 102 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1579 102 : exp_gcode0 = sub( exp_gcode0, 14 );
1580 102 : 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 90 : index = N_GAIN_CODE_TC - 1;
1609 90 : move16();
1610 386 : FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
1611 : {
1612 383 : L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
1613 383 : L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */
1614 :
1615 383 : IF( LT_32( *gain_code_fx, L_tmp ) )
1616 : {
1617 87 : index = i;
1618 87 : move16();
1619 87 : BREAK;
1620 : }
1621 : }
1622 : /*----------------------------------------------------------------*
1623 : * 3-bit -> 2-bit encoding
1624 : *----------------------------------------------------------------*/
1625 90 : 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 90 : wgain_code = tbl_gain_code_tc_fx[index];
1640 90 : move16();
1641 : /**gain_code *= gcode0;*/
1642 90 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1643 90 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
1644 90 : move32(); /* Q14 -> Q16 */
1645 90 : 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 102 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1654 102 : expg = s_max( expg, 0 );
1655 :
1656 102 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
1657 102 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q16
1658 102 : move32();
1659 102 : return;
1660 : }
1661 :
1662 20048 : 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 20048 : 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 20048 : Word16 wgain_code = 0, gain_code16;
1682 20048 : *gain_pit_fx = 0;
1683 20048 : move16();
1684 20048 : move16();
1685 20048 : move16();
1686 :
1687 : /*----------------------------------------------------------------*
1688 : * get number of bits for gain quantization
1689 : *----------------------------------------------------------------*/
1690 20048 : nBits = gains_mode[i_subfr >> 6]; // Q0
1691 20048 : 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 20048 : L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */
1700 20048 : exp_den = norm_l( L_tmp );
1701 20048 : den = extract_h( L_shl( L_tmp, exp_den ) );
1702 20048 : exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) );
1703 :
1704 : /* Compute scalar product <xn[],y2[]> */
1705 20048 : L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */
1706 20048 : exp_num = sub( norm_l( L_tmp1 ), 1 );
1707 20048 : num = extract_h( L_shl( L_tmp1, exp_num ) );
1708 20048 : exp_num = sub( add( exp_num, 8 ), Q_xn );
1709 :
1710 20048 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
1711 20048 : num = abs_s( num );
1712 :
1713 : /*----------------------------------------------------------------*
1714 : * compute gain = xy/yy
1715 : *----------------------------------------------------------------*/
1716 20048 : g_code_fx = div_s( num, den );
1717 :
1718 20048 : i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */
1719 20048 : g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */
1720 20048 : *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); /* Q16 */
1721 20048 : move32();
1722 :
1723 : /*----------------------------------------------------------------*
1724 : * calculate the predicted gain code
1725 : * decode codebook gain
1726 : *----------------------------------------------------------------*/
1727 :
1728 20048 : *gain_pit_fx = 0;
1729 20048 : move16();
1730 :
1731 : /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;
1732 : *gain_inov = 1.0f / (float)sqrt( Ecode );*/
1733 :
1734 20048 : L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg );
1735 20048 : expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */
1736 20048 : expg2 = expg;
1737 20048 : move16();
1738 20048 : L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */
1739 20048 : move32();
1740 20048 : L_tmp = Isqrt_lc( L_tmp, &expg );
1741 :
1742 20048 : *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) );
1743 20048 : move16(); /* gain_inov in Q12 */
1744 :
1745 : /*Ei = 10 * (float)log10( Ecode );*/
1746 20048 : e_tmp = norm_l( L_tmp1 );
1747 20048 : f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) );
1748 20048 : e_tmp = sub( expg2, add( 1, e_tmp ) );
1749 20048 : L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
1750 20048 : Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */
1751 : /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/
1752 20048 : 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 20048 : L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */
1759 20048 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
1760 20048 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
1761 20048 : gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
1762 20048 : exp_gcode0 = sub( exp_gcode0, 14 );
1763 20048 : IF( GT_16( nBits, 3 ) )
1764 : {
1765 : /*g_code = *gain_code / gcode0;*/
1766 1415 : IF( gcode0_fx != 0 )
1767 : {
1768 1415 : tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/
1769 1415 : L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/
1770 1415 : *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/
1771 1415 : 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 1415 : 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 1415 : L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/
1784 1415 : *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/
1785 1415 : move32();
1786 :
1787 1415 : push_indice( hBstr, IND_GAIN_CODE, index, nBits );
1788 : }
1789 : ELSE
1790 : {
1791 18633 : index = N_GAIN_CODE_TC - 1;
1792 18633 : move16();
1793 63084 : FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ )
1794 : {
1795 62209 : L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */
1796 62209 : L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */
1797 :
1798 62209 : IF( LT_32( *gain_code_fx, L_tmp ) )
1799 : {
1800 17758 : index = i;
1801 17758 : move16();
1802 17758 : BREAK;
1803 : }
1804 : }
1805 : /*----------------------------------------------------------------*
1806 : * 3-bit -> 2-bit encoding
1807 : *----------------------------------------------------------------*/
1808 18633 : 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 18633 : wgain_code = tbl_gain_code_tc_fx[index]; // Q13
1823 18633 : move16();
1824 : /**gain_code *= gcode0;*/
1825 18633 : L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */
1826 18633 : *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) );
1827 18633 : move32(); /* Q14 -> Q16 */
1828 18633 : 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 20048 : expg = sub( norm_s( *gain_inov_fx ), 1 );
1837 20048 : expg = s_max( expg, 0 );
1838 :
1839 20048 : tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx );
1840 20048 : *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); // Q6
1841 20048 : move32();
1842 20048 : return;
1843 : }
1844 : /*-----------------------------------------------------------------*
1845 : * Find_Opt_gainQ_fx()
1846 : *
1847 : * Find the best quantizer
1848 : *-----------------------------------------------------------------*/
1849 538361 : 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 538361 : Flag Overflow = 0;
1870 538361 : 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 538361 : exp_code = add( exp_gcode0, 6 );
1902 :
1903 538361 : exp_max[0] = sub( exp_coeff[0], 13 );
1904 538361 : move16();
1905 538361 : exp_max[1] = sub( exp_coeff[1], 14 );
1906 538361 : move16();
1907 538361 : exp_max[2] = add( exp_coeff[2], add( 15, shl( exp_code, 1 ) ) );
1908 538361 : move16();
1909 538361 : exp_max[3] = add( exp_coeff[3], exp_code );
1910 538361 : move16();
1911 538361 : exp_max[4] = add( exp_coeff[4], add( 1, exp_code ) );
1912 538361 : move16();
1913 :
1914 : /* Find maximum exponant */
1915 538361 : e_max = exp_max[0];
1916 538361 : move16();
1917 2691805 : FOR( i = 1; i < 5; i++ )
1918 : {
1919 2153444 : e_max = s_max( exp_max[i], e_max );
1920 : }
1921 :
1922 : /* align coeff[] and save in special 32 bit double precision */
1923 3230166 : FOR( i = 0; i < 5; i++ )
1924 : {
1925 2691805 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
1926 2691805 : L_tmp = L_deposit_h( coeff[i] );
1927 2691805 : L_tmp = L_shr( L_tmp, j );
1928 2691805 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
1929 2691805 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
1930 2691805 : move16();
1931 : }
1932 :
1933 : /* searching of codebook */
1934 538361 : p = cdbk; // Q14
1935 538361 : move16();
1936 538361 : dist_min = L_deposit_h( MAX_16 );
1937 538361 : index = 0;
1938 538361 : move16();
1939 35334987 : FOR( i = 0; i < size; i++ )
1940 : {
1941 34796626 : g_pitch = *p++;
1942 34796626 : move16();
1943 34796626 : g_code = *p++;
1944 34796626 : move16();
1945 :
1946 34796626 : g_code = mult_r( g_code, gcode0 ); // exp_gcode - 1
1947 34796626 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
1948 34796626 : g_pit_cod = mult_r( g_code, g_pitch );
1949 34796626 : L_tmp = L_mult( g_code, g_code );
1950 34796626 : g2_code_lo = L_Extract_lc( L_tmp, &g2_code );
1951 :
1952 34796626 : L_tmp = L_mult( coeff[2], g2_code_lo );
1953 34796626 : L_tmp = L_shr( L_tmp, 3 );
1954 34796626 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
1955 34796626 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
1956 34796626 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
1957 34796626 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
1958 34796626 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
1959 34796626 : L_tmp = L_shr( L_tmp, 12 );
1960 34796626 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
1961 34796626 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
1962 34796626 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
1963 34796626 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
1964 34796626 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
1965 :
1966 34796626 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
1967 34796626 : if ( L_tmp1 < 0 )
1968 : {
1969 6833843 : index = i;
1970 6833843 : move16();
1971 : }
1972 34796626 : dist_min = L_min( L_tmp, dist_min );
1973 : }
1974 :
1975 538361 : p = &cdbk[add( index, index )]; // Q14
1976 538361 : move16();
1977 :
1978 538361 : *gain_pit = *p++; /* selected pitch gain in Q14 */
1979 538361 : move16();
1980 538361 : g_code = *p++; /* selected code gain in Q9 */
1981 538361 : move16();
1982 :
1983 538361 : L_tmp = L_mult( g_code, gcode0 ); /* Q9*Q0 -> Q10 */
1984 538361 : L_tmp = L_shl_sat( L_tmp, add( exp_gcode0, 6 ) ); /* Q10 -> Q16 */
1985 538361 : *gain_code = L_tmp; /* gain of code in Q16 */
1986 538361 : move16();
1987 538361 : 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 17714 : 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 17714 : Word16 index = 0, size, nBits, n_pred, ctype;
2469 17714 : 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 17714 : move16();
2475 :
2476 17714 : L_subfr_sf = 6;
2477 17714 : move16();
2478 17714 : if ( GT_16( L_subfr, L_SUBFR ) )
2479 : {
2480 4218 : L_subfr_sf = 7;
2481 4218 : 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 17714 : coeff[0] = g_corr[0];
2490 17714 : move16();
2491 17714 : exp_coeff[0] = g_corr[1];
2492 17714 : move16();
2493 17714 : coeff[1] = negate( g_corr[2] );
2494 17714 : move16(); /* coeff[1] = -2 xn yy1 */
2495 17714 : exp_coeff[1] = add( g_corr[3], 1 );
2496 17714 : 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 17714 : coeff[2] = extract_h( Dot_product12( y2, y2, L_subfr, &exp ) );
2506 17714 : move16();
2507 17714 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
2508 17714 : move16();
2509 :
2510 : /* Compute scalar product -2*<xn[],y2[]> */
2511 :
2512 17714 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_subfr, &exp ) ) );
2513 17714 : move16();
2514 17714 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
2515 17714 : move16();
2516 :
2517 : /* Compute scalar product 2*<y1[],y2[]> */
2518 :
2519 17714 : coeff[4] = extract_h( Dot_product12( y1, y2, L_subfr, &exp ) );
2520 17714 : move16();
2521 17714 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
2522 17714 : 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 17714 : L_tmp = Dot_product12( code, code, L_subfr, &exp_code );
2529 17714 : L_inov = L_tmp; /* sets to 'L_tmp' in 1 clock */
2530 17714 : move32();
2531 : /* exp_code: -18 (code in Q9), -6 (/L_SUBFR), -31 (L_tmp Q31->Q0) */
2532 : /* output gain_inov*/
2533 17714 : exp_inov = sub( exp_code, add( 18, L_subfr_sf ) );
2534 17714 : L_inov = Isqrt_lc( L_inov, &exp_inov );
2535 17714 : *gain_inov = extract_h( L_shl_sat( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
2536 17714 : move16();
2537 :
2538 :
2539 : /*-----------------------------------------------------------------*
2540 : * select the codebook, size and number of bits
2541 : * set the gains searching range
2542 : *-----------------------------------------------------------------*/
2543 :
2544 17714 : nBits = gains_mode[shr( i_subfr, L_subfr_sf )];
2545 17714 : move16();
2546 17714 : size = shl( 1, nBits );
2547 :
2548 17714 : ctype = shl( sub( coder_type, 1 ), 1 );
2549 :
2550 : /*-----------------------------------------------------------------*
2551 : * calculate prediction of gcode
2552 : * search for the best codeword
2553 : *-----------------------------------------------------------------*/
2554 17714 : test();
2555 17714 : IF( i_subfr == 0 )
2556 : {
2557 5483 : b = b_1sfr_fx; // Q12
2558 5483 : move16();
2559 5483 : n_pred = 2;
2560 5483 : move16();
2561 :
2562 5483 : SWITCH( nBits )
2563 : {
2564 2174 : case 8:
2565 : {
2566 2174 : cdbk = gp_gamma_1sfr_8b_fx; /* Q14 / Q9 */
2567 2174 : if ( EQ_16( clip_gain, 1 ) )
2568 : {
2569 0 : size = sub( size, 60 );
2570 : }
2571 2174 : BREAK;
2572 : }
2573 442 : case 7:
2574 : {
2575 442 : cdbk = gp_gamma_1sfr_7b_fx; /* Q14 / Q9 */
2576 442 : if ( EQ_16( clip_gain, 1 ) )
2577 : {
2578 0 : size = sub( size, 27 );
2579 : }
2580 442 : BREAK;
2581 : }
2582 2867 : case 6:
2583 : {
2584 2867 : cdbk = gp_gamma_1sfr_6b_fx; /* Q14 / Q9 */
2585 2867 : if ( EQ_16( clip_gain, 1 ) )
2586 : {
2587 0 : size = sub( size, 10 );
2588 : }
2589 2867 : BREAK;
2590 : }
2591 : }
2592 :
2593 : /* calculate predicted gain */
2594 5483 : aux[0] = 4096; /* 1 in Q12 */
2595 5483 : move16();
2596 5483 : aux[1] = shl( ctype, 12 );
2597 5483 : 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 :
2603 5483 : exp_code = sub( exp_code, 18 + 6 + 1 );
2604 5483 : exp = norm_l( L_tmp );
2605 5483 : frac = Log2_norm_lc( L_shl( L_tmp, exp ) );
2606 5483 : exp = sub( exp_code, exp );
2607 5483 : L_tmp1 = Mpy_32_16( exp, frac, 24660 ); /* Q14 */ /* 10*log10(2) in Q13*/
2608 :
2609 5483 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2610 5483 : L_tmp = Mult_32_16( L_tmp, 320 ); /*Q14, 20 in Q4*/
2611 5483 : L_tmp = L_sub( L_tmp, L_tmp1 ); /*Q14*/
2612 :
2613 5483 : gcode0 = round_fx( L_shl( L_tmp, 10 ) ); /* Q8 */
2614 :
2615 : /*-----------------------------------------------------------------*
2616 : * gcode0 = pow(10.0, gcode0/20)
2617 : * = pow(2, 3.321928*gcode0/20)
2618 : * = pow(2, 0.166096*gcode0)
2619 : *-----------------------------------------------------------------*/
2620 :
2621 5483 : L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */
2622 5483 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
2623 5483 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2624 :
2625 5483 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2626 : /* output of Pow2() will be: */
2627 : /* 16384 < Pow2() <= 32767 */
2628 5483 : exp_gcode0 = sub( exp_gcode0, 14 );
2629 5483 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
2630 :
2631 5483 : gc_mem[0] = *gain_code;
2632 5483 : move16(); /*Q16*/
2633 5483 : gp_mem[0] = *gain_pit;
2634 5483 : move16(); /*Q14*/
2635 : }
2636 12231 : ELSE IF( EQ_16( i_subfr, L_SUBFR ) || EQ_16( L_subfr, 2 * L_SUBFR ) )
2637 : {
2638 5483 : b = b_2sfr_fx; // Q12
2639 5483 : move16();
2640 5483 : n_pred = 4;
2641 5483 : move16();
2642 :
2643 5483 : switch ( nBits )
2644 : {
2645 2172 : case 7:
2646 : {
2647 2172 : cdbk = gp_gamma_2sfr_7b_fx; /* Q14 / Q9 */
2648 2172 : if ( EQ_16( clip_gain, 1 ) )
2649 : {
2650 0 : size = sub( size, 30 );
2651 : }
2652 2172 : BREAK;
2653 : }
2654 3311 : case 6:
2655 : {
2656 3311 : cdbk = gp_gamma_2sfr_6b_fx; /* Q14 / Q9 */
2657 3311 : if ( EQ_16( clip_gain, 1 ) )
2658 : {
2659 0 : size = sub( size, 12 );
2660 : }
2661 3311 : BREAK;
2662 : }
2663 : }
2664 :
2665 : /* calculate predicted gain */
2666 5483 : aux[0] = 4096; /* 1 in Q12 */
2667 5483 : move16();
2668 5483 : aux[1] = shl( ctype, 12 );
2669 5483 : move16();
2670 :
2671 : /*aux[2] = (float)log10(gc_mem[0]);
2672 : = log2(gc_mem[0])*log10(2);*/
2673 5483 : exp = norm_l( gc_mem[0] );
2674 5483 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2675 5483 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_1sfr_fx)=16*/
2676 5483 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2677 5483 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2678 5483 : move16();
2679 :
2680 5483 : aux[3] = shr( gp_mem[0], 2 );
2681 5483 : move16(); /*Q12*/
2682 :
2683 : /*-----------------------------------------------------------------*
2684 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2685 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2686 : *-----------------------------------------------------------------*/
2687 5483 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2688 5483 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2689 5483 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2690 5483 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2691 :
2692 5483 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2693 : /* output of Pow2() will be: */
2694 : /* 16384 < Pow2() <= 32767 */
2695 5483 : exp_gcode0 = sub( exp_gcode0, 14 );
2696 :
2697 5483 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2698 5483 : gc_mem[1] = *gain_code; // Q16
2699 5483 : move32();
2700 5483 : gp_mem[1] = *gain_pit; // Q14
2701 5483 : move16();
2702 : }
2703 6748 : ELSE IF( EQ_16( i_subfr, 2 * L_SUBFR ) )
2704 : {
2705 3374 : b = b_3sfr_fx; // Q12
2706 3374 : move16();
2707 3374 : n_pred = 6;
2708 3374 : move16();
2709 3374 : IF( EQ_16( nBits, 7 ) )
2710 : {
2711 2 : cdbk = gp_gamma_3sfr_7b_fx; /* Q14 / Q9 */
2712 2 : if ( EQ_16( clip_gain, 1 ) )
2713 : {
2714 0 : size = sub( size, 28 );
2715 : }
2716 : }
2717 : ELSE
2718 : {
2719 3372 : cdbk = gp_gamma_3sfr_6b_fx; /* Q14 / Q9 */
2720 3372 : if ( EQ_16( clip_gain, 1 ) )
2721 : {
2722 0 : size = sub( size, 11 );
2723 : }
2724 : }
2725 : /* calculate predicted gain */
2726 3374 : aux[0] = 4096; // Q12
2727 3374 : move16();
2728 3374 : aux[1] = shl( ctype, 12 );
2729 3374 : move16();
2730 :
2731 : /*aux[2] = (float)log10(gc_mem[0]);
2732 : = log2(gc_mem[0])*log10(2);*/
2733 3374 : exp = norm_l( gc_mem[0] );
2734 3374 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2735 3374 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2736 3374 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2737 3374 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2738 3374 : move16();
2739 :
2740 : /*aux[3] = (float)log10(gc_mem[1]);
2741 : = log2(gc_mem[1])*log10(2);*/
2742 3374 : exp = norm_l( gc_mem[1] );
2743 3374 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2744 3374 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2745 3374 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2746 3374 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2747 3374 : move16();
2748 :
2749 3374 : aux[4] = shr( gp_mem[0], 2 );
2750 3374 : move16(); /*Q12*/
2751 3374 : aux[5] = shr( gp_mem[1], 2 );
2752 3374 : move16(); /*Q12*/
2753 :
2754 : /*-----------------------------------------------------------------*
2755 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2756 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2757 : *-----------------------------------------------------------------*/
2758 3374 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2759 3374 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2760 3374 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2761 3374 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2762 :
2763 3374 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2764 : /* output of Pow2() will be: */
2765 : /* 16384 < Pow2() <= 32767 */
2766 3374 : exp_gcode0 = sub( exp_gcode0, 14 );
2767 :
2768 : /*----------------------------------------------------------------*
2769 : * Find the best quantizer
2770 : * ~~~~~~~~~~~~~~~~~~~~~~~
2771 : * Before doing the computation we need to align exponents of coeff[]
2772 : * to be sure to have the maximum precision.
2773 : *
2774 : * In the table the pitch gains are in Q14, the code gains are in Q9 and
2775 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
2776 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
2777 : * we divide by 2^15.
2778 : * Considering all the scaling above we have:
2779 : *
2780 : * exp_code = exp_gcode0-9+15 = exp_gcode0+6
2781 : *
2782 : * g_pitch*g_pitch = -14-14+15
2783 : * g_pitch = -14
2784 : * g_code*g_code = (2*exp_code)+15
2785 : * g_code = exp_code
2786 : * g_pitch*g_code = -14 + exp_code +15
2787 : *
2788 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
2789 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
2790 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
2791 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
2792 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
2793 : *----------------------------------------------------------------*/
2794 :
2795 3374 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size );
2796 :
2797 3374 : gc_mem[2] = *gain_code; /* Q16 */
2798 3374 : move32();
2799 3374 : gp_mem[2] = *gain_pit; /* Q14 */
2800 3374 : move16();
2801 : }
2802 3374 : ELSE IF( EQ_16( i_subfr, 3 * L_SUBFR ) )
2803 : {
2804 3374 : b = b_4sfr_fx; /* Q12 */
2805 3374 : move16();
2806 3374 : n_pred = 8;
2807 3374 : move16();
2808 3374 : IF( EQ_16( nBits, 7 ) )
2809 : {
2810 0 : cdbk = gp_gamma_4sfr_7b_fx; /* Q14 / Q9 */
2811 0 : if ( EQ_16( clip_gain, 1 ) )
2812 : {
2813 0 : size = sub( size, 25 );
2814 : }
2815 : }
2816 : ELSE
2817 : {
2818 3374 : cdbk = gp_gamma_4sfr_6b_fx; /* Q14 / Q9 */
2819 3374 : if ( EQ_16( clip_gain, 1 ) )
2820 : {
2821 0 : size = sub( size, 11 );
2822 : }
2823 : }
2824 : /* calculate predicted gain */
2825 3374 : aux[0] = 4096; // Q12
2826 3374 : move16();
2827 3374 : aux[1] = shl( ctype, 12 );
2828 3374 : move16();
2829 :
2830 : /*aux[2] = (float)log10(gc_mem[0]);
2831 : = log2(gc_mem[0])*log10(2);*/
2832 3374 : exp = norm_l( gc_mem[0] );
2833 3374 : frac = Log2_norm_lc( L_shl( gc_mem[0], exp ) );
2834 3374 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[0])=16*/
2835 3374 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2836 3374 : aux[2] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2837 3374 : move16();
2838 :
2839 : /*aux[3] = (float)log10(gc_mem[1]);
2840 : = log2(gc_mem[1])*log10(2);*/
2841 3374 : exp = norm_l( gc_mem[1] );
2842 3374 : frac = Log2_norm_lc( L_shl( gc_mem[1], exp ) );
2843 3374 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[1])=16*/
2844 3374 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2845 3374 : aux[3] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2846 3374 : move16();
2847 :
2848 : /*aux[4] = (float)log10(gc_mem[2]);
2849 : = log2(gc_mem[2])*log10(2);*/
2850 3374 : exp = norm_l( gc_mem[2] );
2851 3374 : frac = Log2_norm_lc( L_shl( gc_mem[2], exp ) );
2852 3374 : exp = sub( sub( 30, exp ), 16 ); /*Q_format(gc_mem[2])=16*/
2853 3374 : L_tmp1 = Mpy_32_16( exp, frac, 9864 ); /* Q16 */
2854 3374 : aux[4] = round_fx( L_shl( L_tmp1, 12 ) ); /* Q12 */
2855 3374 : move16();
2856 :
2857 3374 : aux[5] = shr( gp_mem[0], 2 );
2858 3374 : move16(); /*Q12*/
2859 3374 : aux[6] = shr( gp_mem[1], 2 );
2860 3374 : move16(); /*Q12*/
2861 3374 : aux[7] = shr( gp_mem[2], 2 );
2862 3374 : move16(); /*Q12*/
2863 : /*-----------------------------------------------------------------*
2864 : * gcode0 = pow(10.0, dotp(b, aux, n_pred)
2865 : * = pow(2, 3.321928*dotp(b, aux, n_pred)
2866 : *-----------------------------------------------------------------*/
2867 3374 : L_tmp = Dot_product( b, aux, n_pred ); /*Q25*/
2868 3374 : L_tmp = Mult_32_16( L_tmp, 27213 ); /* *3.321928 in Q13 -> Q23 */
2869 3374 : L_tmp = L_shr( L_tmp, 7 ); /* From Q23 to Q16 */
2870 3374 : frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */
2871 :
2872 3374 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
2873 : /* output of Pow2() will be: */
2874 : /* 16384 < Pow2() <= 32767 */
2875 3374 : exp_gcode0 = sub( exp_gcode0, 14 );
2876 :
2877 3374 : index = Find_Opt_gainQ_fx( coeff, exp_coeff, gain_pit, gain_code, gcode0, exp_gcode0, cdbk, size ); // Q0
2878 : }
2879 :
2880 : /* *norm_gain_code = *gain_code / *gain_inov; */
2881 17714 : exp = sub( norm_s( *gain_inov ), 1 );
2882 17714 : exp = s_max( exp, 0 );
2883 :
2884 17714 : tmp = div_s( shr( 8192, exp ), *gain_inov );
2885 17714 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
2886 17714 : move32();
2887 : {
2888 17714 : push_indice( hBstr, IND_GAIN, index, nBits );
2889 : }
2890 17714 : return;
2891 : }
2892 :
2893 : /*-------------------------------------------------------------------*
2894 : * gain_enc_amr_wb()
2895 : *
2896 : * Quantization of pitch and codebook gains (used also in AMR-WB IO mode)
2897 : * MA prediction is performed on the innovation energy (in dB with mean removed).
2898 : * An initial predicted gain, gcode0, is first determined and the correction
2899 : * factor alpha = g_code / gcode0 is quantized.
2900 : * The pitch gain and the correction factor are vector quantized and the
2901 : * mean-squared weighted error criterion is used in the quantizer search.
2902 : *-------------------------------------------------------------------*/
2903 :
2904 :
2905 0 : void gain_enc_amr_wb_fx(
2906 : BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */
2907 : const Word16 *xn, /* i : target vector Q_xn*/
2908 : const Word16 Q_xn, /* i : xn and yy1 format */
2909 : const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn*/
2910 : const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9*/
2911 : const Word16 *code, /* i : algebraic excitation Q9*/
2912 : const Word32 core_brate, /* i : core bitrate Q0*/
2913 : Word16 *gain_pit, /* i/o: pitch gain / Quantized pitch gain Q14*/
2914 : Word32 *gain_code, /* o : quantized codebook gain Q16*/
2915 : Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12*/
2916 : Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16*/
2917 : Word16 *g_coeff, /* i/o: correlations <y1,y1>, -2<xn,y1>,<y2,y2>, -2<xn,y2> and 2<y1,y2> Qx*/
2918 : const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) Q0*/
2919 : Word16 *past_qua_en /* i/o: gain quantization memory (4 words) Q10*/
2920 : )
2921 : {
2922 :
2923 : Word16 i, j, index, min_ind, size;
2924 : Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, exp_inov, qua_ener;
2925 : Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo;
2926 : Word16 coeff[5], coeff_lo[5], exp_coeff[5];
2927 : Word16 exp_max[5], tmp, nBits;
2928 : Word32 L_tmp, dist_min, L_inov, L_tmp1;
2929 : const Word16 *t_qua_gain, *p;
2930 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2931 0 : Flag Overflow = 0;
2932 0 : move32();
2933 : #endif
2934 :
2935 : /*----------------------------------------------------------------*
2936 : * Find the initial quantization pitch index
2937 : * Set gains search range
2938 : *----------------------------------------------------------------*/
2939 0 : IF( GE_32( core_brate, ACELP_12k65 ) )
2940 : {
2941 0 : t_qua_gain = t_qua_gain7b_fx; // Q14
2942 0 : move16();
2943 : /* pt at 1/4th of table */
2944 0 : p = t_qua_gain7b_fx + RANGE;
2945 0 : move16();
2946 :
2947 0 : j = NB_QUA_GAIN7B - RANGE;
2948 0 : move16();
2949 :
2950 0 : IF( EQ_16( clip_gain, 1 ) )
2951 : {
2952 0 : j = sub( j, 27 ); /* limit gain pitch to 1.0 */
2953 : }
2954 0 : min_ind = 0;
2955 0 : move16();
2956 0 : g_pitch = *gain_pit; // Q14
2957 0 : move16();
2958 :
2959 0 : FOR( i = 0; i < j; i++ )
2960 : {
2961 0 : if ( GT_16( g_pitch, *p ) )
2962 : {
2963 0 : min_ind = add( min_ind, 1 ); // Q0
2964 : }
2965 0 : p += 2;
2966 : }
2967 0 : size = RANGE;
2968 0 : move16();
2969 0 : nBits = 7;
2970 : }
2971 : ELSE
2972 : {
2973 0 : t_qua_gain = t_qua_gain6b_fx; // Q14
2974 0 : min_ind = 0;
2975 0 : move16();
2976 0 : size = RANGE;
2977 0 : move16();
2978 0 : if ( EQ_16( clip_gain, 1 ) )
2979 : {
2980 0 : size = sub( size, 16 ); /* limit gain pitch to 1.0 */
2981 : }
2982 0 : nBits = 6;
2983 : }
2984 : /*----------------------------------------------------------------*
2985 : * Compute coefficients needed for the quantization.
2986 : *
2987 : * coeff[0] = yy1 yy1
2988 : * coeff[1] = -2 xn yy1
2989 : * coeff[2] = y2 y2
2990 : * coeff[3] = -2 xn y2
2991 : * coeff[4] = 2 yy1 y2
2992 : *
2993 : * Product <yy1 yy1> and <xn yy1> have been computed in Adpt_enr() and
2994 : * are in vector g_coeff[].
2995 : *----------------------------------------------------------------*/
2996 0 : coeff[0] = g_coeff[0];
2997 0 : move16();
2998 0 : exp_coeff[0] = g_coeff[1];
2999 0 : move16();
3000 0 : coeff[1] = negate( g_coeff[2] );
3001 0 : move16(); /* coeff[1] = -2 xn yy1 */
3002 0 : exp_coeff[1] = add( g_coeff[3], 1 );
3003 0 : move16();
3004 :
3005 : /* Compute scalar product <y2[],y2[]> */
3006 0 : coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) );
3007 0 : exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); /* -18 (y2 Q9) */
3008 0 : move16();
3009 0 : move16();
3010 :
3011 : /* Compute scalar product -2*<xn[],y2[]> */
3012 0 : coeff[3] = extract_h( L_negate( Dot_product12( xn, y2, L_SUBFR, &exp ) ) );
3013 0 : exp_coeff[3] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 xn y2) */
3014 0 : move16();
3015 0 : move16();
3016 :
3017 : /* Compute scalar product 2*<yy1[],y2[]> */
3018 0 : coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) );
3019 0 : exp_coeff[4] = add( sub( exp, 9 - 1 ), Q_xn ); /* -9 (y2 Q9), +1 (2 yy1 y2) */
3020 0 : move16();
3021 0 : move16();
3022 :
3023 : /*----------------------------------------------------------------*
3024 : * Find energy of code and compute:
3025 : *
3026 : * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr)
3027 : * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr)
3028 : *----------------------------------------------------------------*/
3029 0 : L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code );
3030 0 : L_inov = L_add( L_tmp, 0 );
3031 : /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */
3032 : /* output gain_inov*/
3033 0 : exp_inov = sub( exp_code, 18 + 6 );
3034 0 : L_inov = Isqrt_lc( L_inov, &exp_inov );
3035 0 : *gain_inov = extract_h( L_shl( L_inov, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */
3036 0 : move16();
3037 :
3038 0 : exp_code = sub( exp_code, 18 + 6 + 31 );
3039 0 : frac = Log2_lc( L_tmp, &exp );
3040 0 : exp = add( exp, exp_code );
3041 0 : L_tmp = Mpy_32_16( exp, frac, -24660 ); /* x -3.0103(Q13) -> Q14 */
3042 :
3043 0 : L_tmp = L_mac( L_tmp, MEAN_ENER, 8192 ); /* + MEAN_ENER in Q14 */
3044 :
3045 : /*----------------------------------------------------------------*
3046 : * predicted codebook gain
3047 : *----------------------------------------------------------------*/
3048 0 : L_tmp = L_shl( L_tmp, 10 ); /* From Q14 to Q24 */
3049 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[0], past_qua_en[0] ); /* Q14*Q10 -> Q24 */
3050 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[1], past_qua_en[1] ); /* Q14*Q10 -> Q24 */
3051 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[2], past_qua_en[2] ); /* Q14*Q10 -> Q24 */
3052 0 : L_tmp = L_mac0( L_tmp, pred_gain_fx[3], past_qua_en[3] ); /* Q14*Q10 -> Q24 */
3053 :
3054 0 : gcode0 = extract_h( L_tmp ); /* From Q24 to Q8 */
3055 :
3056 : /*----------------------------------------------------------------*
3057 : * gcode0 = pow(10.0, gcode0/20)
3058 : * = pow(2, 3.321928*gcode0/20)
3059 : * = pow(2, 0.166096*gcode0)
3060 : *----------------------------------------------------------------*/
3061 0 : L_tmp = L_mult( gcode0, 5443 ); /* *0.166096 in Q15 -> Q24 */
3062 0 : L_tmp = L_shr( L_tmp, 8 ); /* From Q24 to Q16 */
3063 0 : L_Extract( L_tmp, &exp_gcode0, &frac ); /* Extract exponent of gcode0 */
3064 :
3065 0 : gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
3066 : /* output of Pow2() will be: */
3067 : /* 16384 < Pow2() <= 32767 */
3068 0 : exp_gcode0 = sub( exp_gcode0, 14 );
3069 :
3070 : /*----------------------------------------------------------------*
3071 : * Find the best quantizer
3072 : * ~~~~~~~~~~~~~~~~~~~~~~~
3073 : * Before doing the computation we need to aling exponents of coeff[]
3074 : * to be sure to have the maximum precision.
3075 : *
3076 : * In the table the pitch gains are in Q14, the code gains are in Q11 and
3077 : * are multiply by gcode0 which have been multiply by 2^exp_gcode0.
3078 : * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code
3079 : * we divide by 2^15.
3080 : * Considering all the scaling above we have:
3081 : *
3082 : * exp_code = exp_gcode0-11+15 = exp_gcode0+4
3083 : *
3084 : * g_pitch*g_pitch = -14-14+15
3085 : * g_pitch = -14
3086 : * g_code*g_code = (2*exp_code)+15
3087 : * g_code = exp_code
3088 : * g_pitch*g_code = -14 + exp_code +15
3089 : *
3090 : * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13
3091 : * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14
3092 : * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code)
3093 : * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code
3094 : * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code
3095 : *----------------------------------------------------------------*/
3096 :
3097 0 : exp_code = add( exp_gcode0, 4 );
3098 :
3099 0 : exp_max[0] = sub( exp_coeff[0], 13 );
3100 0 : move16();
3101 0 : exp_max[1] = sub( exp_coeff[1], 14 );
3102 0 : move16();
3103 0 : exp_max[2] = add( exp_coeff[2],
3104 0 : add( 15, shl( exp_code, 1 ) ) );
3105 0 : move16();
3106 0 : exp_max[3] = add( exp_coeff[3], exp_code );
3107 0 : move16();
3108 0 : exp_max[4] = add( exp_coeff[4],
3109 0 : add( 1, exp_code ) );
3110 0 : move16();
3111 :
3112 : /* Find maximum exponant */
3113 0 : e_max = exp_max[0];
3114 0 : move16();
3115 0 : FOR( i = 1; i < 5; i++ )
3116 : {
3117 0 : e_max = s_max( exp_max[i], e_max );
3118 : }
3119 :
3120 : /* align coeff[] and save in special 32 bit double precision */
3121 0 : FOR( i = 0; i < 5; i++ )
3122 : {
3123 0 : j = add( sub( e_max, exp_max[i] ), 2 ); /* /4 to avoid overflow */
3124 0 : L_tmp = L_deposit_h( coeff[i] );
3125 0 : L_tmp = L_shr( L_tmp, j );
3126 0 : L_Extract( L_tmp, &coeff[i], &coeff_lo[i] );
3127 0 : coeff_lo[i] = shr( coeff_lo[i], 3 ); /* lo >> 3 */
3128 0 : move16();
3129 : }
3130 :
3131 : /* Codebook search */
3132 0 : dist_min = L_add( MAX_32, 0 );
3133 0 : p = &t_qua_gain[shl( min_ind, 1 )]; // Q14
3134 0 : move16();
3135 :
3136 0 : index = 0;
3137 0 : move16();
3138 0 : FOR( i = 0; i < size; i++ )
3139 : {
3140 0 : g_pitch = *p++;
3141 0 : move16();
3142 0 : g_code = *p++;
3143 0 : move16();
3144 :
3145 0 : g_code = mult_r( g_code, gcode0 ); // exp(gcode) - 1
3146 0 : g2_pitch = mult_r( g_pitch, g_pitch ); // Q13
3147 0 : g_pit_cod = mult_r( g_code, g_pitch );
3148 0 : L_tmp = L_mult( g_code, g_code );
3149 0 : L_Extract( L_tmp, &g2_code, &g2_code_lo );
3150 :
3151 0 : L_tmp = L_mult( coeff[2], g2_code_lo );
3152 0 : L_tmp = L_shr( L_tmp, 3 );
3153 0 : L_tmp = L_mac( L_tmp, coeff_lo[0], g2_pitch );
3154 0 : L_tmp = L_mac( L_tmp, coeff_lo[1], g_pitch );
3155 0 : L_tmp = L_mac( L_tmp, coeff_lo[2], g2_code );
3156 0 : L_tmp = L_mac( L_tmp, coeff_lo[3], g_code );
3157 0 : L_tmp = L_mac( L_tmp, coeff_lo[4], g_pit_cod );
3158 0 : L_tmp = L_shr( L_tmp, 12 );
3159 0 : L_tmp = L_mac( L_tmp, coeff[0], g2_pitch ); /* 15 - coeff_exp + 13 - 1 */
3160 0 : L_tmp = L_mac( L_tmp, coeff[1], g_pitch ); /* 15 - coeff_exp + 13 - 1 */
3161 0 : L_tmp = L_mac( L_tmp, coeff[2], g2_code ); /* 15 - coeff_exp + 13 - 1 */
3162 0 : L_tmp = L_mac( L_tmp, coeff[3], g_code ); /* 15 - coeff_exp + 13 - 1 */
3163 0 : L_tmp = L_mac( L_tmp, coeff[4], g_pit_cod ); /* 15 - coeff_exp + 13 - 1 */
3164 :
3165 0 : L_tmp1 = L_sub_o( L_tmp, dist_min, &Overflow );
3166 : /* splitting the if cost half the complexity of using IF macro */
3167 0 : if ( L_tmp1 < 0 )
3168 : {
3169 0 : dist_min = L_add( L_tmp, 0 );
3170 : }
3171 0 : if ( L_tmp1 < 0 )
3172 : {
3173 0 : index = i;
3174 0 : move16();
3175 : }
3176 : }
3177 : /* Read the quantized gains */
3178 0 : index = add( index, min_ind );
3179 :
3180 0 : p = &t_qua_gain[add( index, index )];
3181 0 : move16();
3182 0 : *gain_pit = *p++; /* selected pitch gain in Q14 */
3183 0 : move16();
3184 0 : g_code = *p++; /* selected code gain in Q11 */
3185 0 : move16();
3186 :
3187 0 : L_tmp = L_mult( g_code, gcode0 ); /* Q11*Q0 -> Q12 */
3188 0 : L_tmp = L_shl_o( L_tmp, add( exp_gcode0, 4 ), &Overflow ); /* Q12 -> Q16 */
3189 :
3190 0 : *gain_code = L_tmp; /* gain of code in Q16 */
3191 0 : move16();
3192 :
3193 : /*---------------------------------------------------*
3194 : * qua_ener = 20*log10(g_code)
3195 : * = 6.0206*log2(g_code)
3196 : * = 6.0206*(log2(g_codeQ11) - 11)
3197 : *---------------------------------------------------*/
3198 0 : L_tmp = L_deposit_l( g_code );
3199 0 : frac = Log2_lc( L_tmp, &exp );
3200 0 : exp = sub( exp, 11 );
3201 0 : L_tmp = Mpy_32_16( exp, frac, 24660 ); /* x 6.0206 in Q12 */
3202 :
3203 0 : qua_ener = extract_l( L_shr( L_tmp, 3 ) ); /* result in Q10 */
3204 :
3205 : /*----------------------------------------------------------------*
3206 : * update table of past quantized energies
3207 : *----------------------------------------------------------------*/
3208 :
3209 0 : past_qua_en[3] = past_qua_en[2]; // Q10
3210 0 : move16();
3211 0 : past_qua_en[2] = past_qua_en[1]; // Q10
3212 0 : move16();
3213 0 : past_qua_en[1] = past_qua_en[0]; // Q10
3214 0 : move16();
3215 0 : past_qua_en[0] = qua_ener; // Q10
3216 0 : move16();
3217 :
3218 :
3219 0 : exp = sub( norm_s( *gain_inov ), 1 );
3220 0 : exp = s_max( exp, 0 );
3221 :
3222 0 : tmp = div_s( shr( 8192, exp ), *gain_inov );
3223 0 : *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); // Q16
3224 0 : move32();
3225 :
3226 0 : push_indice( hBstr, IND_GAIN, index, nBits );
3227 :
3228 0 : return;
3229 : }
|