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