Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <assert.h>
5 : #include "typedef.h"
6 : #include <stdint.h>
7 : #include <string.h>
8 : #include "options.h"
9 : #include "cnst.h"
10 : //#include "prot_fx.h"
11 : #include "basop_util.h"
12 : #include "rom_com_fx.h"
13 : #include "rom_com.h"
14 : #include "rom_enc.h"
15 : #include "prot_fx.h" /* Function prototypes */
16 : #include "prot_fx_enc.h" /* Function prototypes */
17 :
18 :
19 : #define _2_ 0x4000 /*Q12*/
20 : #define _1_ 0x2000 /*Q12*/
21 : #define _1_Q9 0x200
22 :
23 : static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ );
24 :
25 : void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ );
26 :
27 : void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ );
28 :
29 : Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn );
30 :
31 : void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ );
32 :
33 : void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ );
34 :
35 : void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ );
36 :
37 : /*
38 : * E_ACELP_h_vec_corrx
39 : *
40 : * Parameters:
41 : * h I: scaled impulse response
42 : * vec I: vector to correlate with h[]
43 : * track I: track to use
44 : * sign I: sign vector
45 : * rrixix I: correlation of h[x] with h[x]
46 : * cor O: result of correlation (16 elements)
47 : *
48 : * Function:
49 : * Calculate the correlations of h[] with vec[] for the specified track
50 : *
51 : * Returns:
52 : * void
53 : */
54 1780225 : void E_ACELP_h_vec_corr1_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/, Word16 dn2_pos[] /*Q0*/, Word16 nb_pulse /*Q0*/ )
55 : {
56 : Word16 i, j;
57 : Word16 dn, corr;
58 : Word16 *dn2;
59 : Word16 *p0, *p1, *p2;
60 : Word32 L_sum;
61 : #ifndef ISSUE_1867_replace_overflow_libenc
62 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
63 : Flag Overflow = 0;
64 : move32();
65 : #endif
66 : #endif
67 :
68 1780225 : dn2 = &dn2_pos[( track * 8 )]; /*Q0*/
69 1780225 : p0 = rrixix[track]; /*Q9*/
70 :
71 13503289 : FOR( i = 0; i < nb_pulse; i++ )
72 : {
73 11723064 : dn = dn2[i]; /*Q0*/
74 11723064 : move16();
75 11723064 : L_sum = L_deposit_l( 0 );
76 11723064 : p1 = h; /*Qx*/
77 11723064 : p2 = &vec[dn]; /*Qx*/
78 409447548 : FOR( j = dn; j < L_SUBFR - 1; j++ )
79 : {
80 : #ifdef ISSUE_1867_replace_overflow_libenc
81 397724484 : L_sum = L_mac_sat( L_sum, *p1++, *p2++ ); /*2*Qx+1*/
82 : #else
83 : L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /*2*Qx+1*/
84 : #endif
85 : }
86 :
87 : #ifdef ISSUE_1867_replace_overflow_libenc
88 11723064 : corr = mac_r_sat( L_sum, *p1++, *p2++ ); /*Q9*/
89 : #else
90 : corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/
91 : #endif
92 :
93 : /*cor[dn >> 2] = sign[dn] * s + p0[dn >> 2];*/
94 11723064 : j = shr( dn, 2 );
95 11723064 : if ( sign[dn] > 0 )
96 : {
97 : #ifdef ISSUE_1867_replace_overflow_libenc
98 5767703 : corr = add_sat( p0[j], corr ); /*Q9*/
99 : #else
100 : corr = add_o( p0[j], corr, &Overflow ); /*Q9*/
101 : #endif
102 : }
103 11723064 : if ( sign[dn] < 0 )
104 : {
105 : #ifdef ISSUE_1867_replace_overflow_libenc
106 5955361 : corr = sub_sat( p0[j], corr ); /*Q9*/
107 : #else
108 : corr = sub_o( p0[j], corr, &Overflow ); /*Q9*/
109 : #endif
110 : }
111 :
112 11723064 : cor[j] = corr; /*Q9*/
113 11723064 : move16();
114 : }
115 1780225 : return;
116 : }
117 :
118 2588971 : void E_ACELP_h_vec_corr2_fx( Word16 h[] /*Qx*/, Word16 vec[] /*Qx*/, UWord8 track /*Q0*/, Word16 sign[] /*Q15*/, Word16 ( *rrixix )[16] /*Q9*/, Word16 cor[] /*Q9*/ )
119 : {
120 : Word16 i, j, pos, corr;
121 : Word16 *p0, *p1, *p2;
122 : Word32 L_sum;
123 : #ifndef ISSUE_1867_replace_overflow_libenc
124 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
125 : Flag Overflow = 0;
126 : move32();
127 : #endif
128 : #endif
129 :
130 2588971 : p0 = rrixix[track]; /*Q9*/
131 :
132 2588971 : pos = track; /*Q0*/
133 2588971 : move16();
134 44012507 : FOR( i = 0; i < 16; i++ )
135 : {
136 41423536 : L_sum = L_deposit_l( 0 );
137 41423536 : p1 = h; /*Qx*/
138 41423536 : p2 = &vec[pos]; /*Qx*/
139 1348238112 : FOR( j = pos; j < L_SUBFR - 1; j++ )
140 : {
141 : #ifdef ISSUE_1867_replace_overflow_libenc
142 1306814576 : L_sum = L_mac_sat( L_sum, *p1++, *p2++ ); /* 2*Qx+1 */
143 : #else
144 : L_sum = L_mac_o( L_sum, *p1++, *p2++, &Overflow ); /* 2*Qx+1 */
145 : #endif
146 : }
147 : #ifdef ISSUE_1867_replace_overflow_libenc
148 41423536 : corr = mac_r_sat( L_sum, *p1++, *p2++ ); /*Q9*/
149 : #else
150 : corr = mac_ro( L_sum, *p1++, *p2++, &Overflow ); /*Q9*/
151 : #endif
152 :
153 : /*cor[i] = s * sign[track] + p0[i];*/
154 :
155 : #ifdef ISSUE_1867_replace_overflow_libenc
156 41423536 : if ( sign[pos] > 0 )
157 : {
158 20456426 : corr = add_sat( *p0++, corr ); /*Q9*/
159 : }
160 41423536 : if ( sign[pos] < 0 )
161 : {
162 20967110 : corr = sub_sat( *p0++, corr ); /*Q9*/
163 : }
164 : #else
165 : if ( sign[pos] > 0 )
166 : {
167 : corr = add_o( *p0++, corr, &Overflow ); /*Q9*/
168 : }
169 : if ( sign[pos] < 0 )
170 : {
171 : corr = sub_o( *p0++, corr, &Overflow ); /*Q9*/
172 : }
173 : #endif
174 41423536 : cor[i] = corr; /*Q9*/
175 41423536 : move16();
176 :
177 41423536 : pos = add( pos, 4 );
178 : }
179 2588971 : return;
180 : }
181 :
182 :
183 : /*
184 : * E_ACELP_2pulse_search
185 : *
186 : * Parameters:
187 : * nb_pos_ix I: nb of pos for pulse 1 (1..8)
188 : * track_x I: track of pulse 1
189 : * track_y I: track of pulse 2
190 : * ps I/O: correlation of all fixed pulses
191 : * alp I/O: energy of all fixed pulses
192 : * ix O: position of pulse 1
193 : * iy O: position of pulse 2
194 : * dn I: corr. between target and h[]
195 : * dn2 I: vector of selected positions
196 : * cor_x I: corr. of pulse 1 with fixed pulses
197 : * cor_y I: corr. of pulse 2 with fixed pulses
198 : * rrixiy I: corr. of pulse 1 with pulse 2
199 : *
200 : * Function:
201 : * Find the best positions of 2 pulses in a subframe
202 : *
203 : * Returns:
204 : * void
205 : */
206 1780225 : static void E_ACELP_2pulse_search( Word16 nb_pos_ix /*Q0*/, UWord8 track_x /*Q0*/, UWord8 track_y /*Q0*/, Word16 *ps /*Qdn*/, Word16 *alp /*Qx*/, Word16 *ix /*Q0*/, Word16 *iy /*Q0*/, Word16 dn[] /*Qdn*/, Word16 *dn2 /*Q0*/, Word16 cor_x[] /*Qx*/, Word16 cor_y[] /*Qx*/, Word16 ( *rrixiy )[256] /*Q9*/ )
207 : {
208 : Word16 x, x2, y, i, *pos_x;
209 : Word16 ps0, ps1, alp2_16, ps2, sq;
210 : Word32 alp0, alp1, alp2, s;
211 : Word16 *p1, *p2;
212 : Word16 sqk[2], alpk[2], ik;
213 : Word32 xy_save;
214 1780225 : Word16 check = 0; /* debug code not instrumented */
215 :
216 : #ifndef ISSUE_1867_replace_overflow_libenc
217 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
218 : Flag Overflow = 0;
219 : move32();
220 : #endif
221 : #endif
222 :
223 :
224 : /* eight dn2 max positions per track */
225 : /*pos_x = &dn2[track_x << 3]; SHIFT(1); PTR_INIT(1);*/
226 1780225 : pos_x = &dn2[( track_x * 8 )]; /*Qdn*/
227 1780225 : move16();
228 :
229 : /* save these to limit memory searches */
230 1780225 : alp0 = L_deposit_h( *alp ); /*Qx-16*/
231 1780225 : ps0 = *ps; /*Qdn*/
232 1780225 : move16();
233 :
234 1780225 : alpk[0] = 1;
235 1780225 : move16();
236 1780225 : sqk[0] = -1;
237 1780225 : move16();
238 1780225 : x2 = shr( pos_x[0], 2 ); /*Qdn*/
239 : #ifdef ISSUE_1867_replace_overflow_libenc
240 1780225 : if ( mac_r_sat( L_mac_sat( L_mac_sat( alp0, cor_x[x2], _1_ ), cor_y[0], _1_ ), rrixiy[track_x][( x2 * 16 )], _1_ ) < 0 )
241 : #else
242 : if ( mac_ro( L_mac_o( L_mac_o( alp0, cor_x[x2], _1_, &Overflow ), cor_y[0], _1_, &Overflow ), rrixiy[track_x][( x2 * 16 )], _1_, &Overflow ) < 0 )
243 : #endif
244 : {
245 0 : sqk[0] = 1;
246 0 : move16();
247 : }
248 1780225 : ik = 0;
249 1780225 : move16();
250 1780225 : xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/
251 :
252 : /* loop track 1 */
253 13503289 : FOR( i = 0; i < nb_pos_ix; i++ )
254 : {
255 11723064 : x = pos_x[i]; /*Qdn*/
256 11723064 : move16();
257 11723064 : x2 = shr( x, 2 );
258 : /* dn[x] has only nb_pos_ix positions saved */
259 : /*ps1 = ps0 + dn[x];*/
260 11723064 : ps1 = add( ps0, dn[x] ); /*Qdn*/
261 :
262 : /*alp1 = alp0 + cor_x[x2];*/
263 : #ifdef ISSUE_1867_replace_overflow_libenc
264 11723064 : alp1 = L_mac_sat( alp0, cor_x[x2], _1_ ); /*Q22*/
265 : #else
266 : alp1 = L_mac_o( alp0, cor_x[x2], _1_, &Overflow ); /*Q22*/
267 : #endif
268 :
269 11723064 : p1 = cor_y; /*Qx*/
270 11723064 : p2 = &rrixiy[track_x][( x2 * 16 )]; /*Q9*/
271 :
272 199292088 : FOR( y = track_y; y < L_SUBFR; y += 4 )
273 : {
274 : /*ps2 = ps1 + dn[y];*/
275 187569024 : ps2 = add( ps1, dn[y] ); /*Qdn*/
276 187569024 : move16();
277 :
278 : /*alp2 = alp1 + (*p1++) + (*p2++);*/
279 : #ifdef ISSUE_1867_replace_overflow_libenc
280 187569024 : alp2 = L_mac_sat( alp1, *p1++, _1_ ); /*Qx+12+1*/
281 187569024 : alp2_16 = mac_r_sat( alp2, *p2++, _1_ ); /*Q6*/
282 : #else
283 : alp2 = L_mac_o( alp1, *p1++, _1_, &Overflow ); /*Qx+12+1*/
284 : alp2_16 = mac_ro( alp2, *p2++, _1_, &Overflow ); /*Q6*/
285 : #endif
286 187569024 : alpk[1 - ik] = alp2_16; /*Q6*/
287 187569024 : move16();
288 :
289 : /*sq = ps2 * ps2;*/
290 187569024 : sq = mult( ps2, ps2 ); /*2*Qdn+1*/
291 187569024 : sqk[1 - ik] = sq; /*2*Qdn+1*/
292 187569024 : move16();
293 :
294 : /*s = (alpk[ik] * sq) - (sqk[0] * alp2);*/
295 187569024 : s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp2_16 ); /*Q16*/
296 :
297 187569024 : if ( s > 0 )
298 : {
299 8650328 : ik = sub( 1, ik );
300 8650328 : move16();
301 8650328 : check = 1; /* debug code not instrumented */
302 8650328 : move16();
303 : }
304 187569024 : if ( s > 0 )
305 : {
306 8650328 : xy_save = L_mac0( y, x, L_SUBFR ); /*Qdn*/
307 : }
308 : }
309 : }
310 :
311 1780225 : assert( check ); /* debug code not instrumented */
312 :
313 1780225 : ps2 = extract_l( xy_save ); /*Qdn*/
314 1780225 : *iy = s_and( ps2, L_SUBFR - 1 ); /*Q0*/
315 1780225 : move16();
316 1780225 : *ix = lshr( ps2, 6 ); /*Q0*/
317 1780225 : move16();
318 :
319 : /**ps = ps0 + dn[*ix] + dn[*iy];*/
320 1780225 : *ps = add( ps0, add( dn[*ix], dn[*iy] ) ); /*Qdn*/
321 1780225 : move16();
322 :
323 1780225 : *alp = alpk[ik]; /*Q6*/
324 1780225 : move16();
325 1780225 : return;
326 : }
327 :
328 :
329 : /*
330 : * E_ACELP_1pulse_search
331 : *
332 : * Parameters:
333 : * track_x I: track of pulse 1
334 : * track_y I: track of pulse 2
335 : * ps I/O: correlation of all fixed pulses
336 : * alp I/O: energy of all fixed pulses
337 : * ix O: position of pulse 1
338 : * dn I: corr. between target and h[]
339 : * cor_x I: corr. of pulse 1 with fixed pulses
340 : * cor_y I: corr. of pulse 2 with fixed pulses
341 : *
342 : * Function:
343 : * Find the best positions of 1 pulse in a subframe
344 : *
345 : * Returns:
346 : * void
347 : */
348 404373 : static void E_ACELP_1pulse_search( UWord8 tracks[2],
349 : Word16 *ps, /*Qdn*/
350 : Word16 *alp, /*Qx*/
351 : Word16 *ix, /*Q0*/
352 : Word16 dn[], /*Qdn*/
353 : Word16 cor_x[], /*Q6*/
354 : Word16 cor_y[] /*Q6*/ )
355 : {
356 404373 : Word16 x, x_save = 0;
357 : Word16 ps0;
358 : Word16 ps1, sq;
359 : Word16 alp1;
360 : Word32 s, alp0;
361 : Word16 sqk[2], alpk[2], ik;
362 : Word16 ntracks, t;
363 404373 : Word16 check = 0; /* debug code not instrumented */
364 :
365 : /* save these to limit memory searches */
366 404373 : alp0 = L_deposit_h( *alp );
367 404373 : ps0 = *ps; /*Qdn*/
368 404373 : move16();
369 :
370 404373 : alpk[0] = 1;
371 404373 : move16();
372 404373 : sqk[0] = -1;
373 404373 : move16();
374 404373 : if ( mac_r_sat( alp0, cor_x[( tracks[0] / 4 )], _1_ ) < 0 )
375 : {
376 0 : sqk[0] = 1;
377 0 : move16();
378 : }
379 404373 : ik = 0;
380 404373 : move16();
381 :
382 404373 : ntracks = 1;
383 404373 : move16();
384 404373 : if ( NE_16( tracks[1], tracks[0] ) )
385 : {
386 243354 : ntracks = 2;
387 243354 : move16();
388 : }
389 1052100 : FOR( t = 0; t < ntracks; ++t )
390 : {
391 647727 : if ( t != 0 )
392 : {
393 243354 : cor_x = cor_y;
394 243354 : move16();
395 : }
396 11011359 : FOR( x = tracks[t]; x < L_SUBFR; x += 4 )
397 : {
398 : /*ps1 = ps0 + dn[x]; ADD(1);*/
399 10363632 : ps1 = add( ps0, dn[x] ); /*Qdn*/
400 :
401 : /*alp1 = alp0 + cor_x[x>>2]; SHIFT(1);ADD(1);*/
402 10363632 : alp1 = mac_r_sat( alp0, cor_x[( x / 4 )], _1_ ); /*Q6*/
403 10363632 : alpk[1 - ik] = alp1; /*Q6*/
404 10363632 : move16();
405 :
406 : /*sq = ps1 * ps1; MULT(1);*/
407 10363632 : sq = mult( ps1, ps1 ); /*2*Qdn+1*/
408 10363632 : sqk[1 - ik] = sq; /*2*Qdn+1*/
409 10363632 : move16();
410 :
411 : /*s = (alpk * sq) - (sqk * alp1); MULT(1);MAC(1); */
412 10363632 : s = L_msu( L_mult( alpk[ik], sq ), sqk[ik], alp1 ); /*Q16*/
413 :
414 10363632 : if ( s > 0 )
415 : {
416 1695235 : ik = sub( 1, ik );
417 1695235 : check = 1; /* debug code not instrumented */
418 : }
419 10363632 : if ( s > 0 )
420 : {
421 1695235 : x_save = x;
422 1695235 : move16();
423 : }
424 : }
425 :
426 647727 : assert( check ); /* debug code not instrumented */
427 : }
428 404373 : *ps = add( ps0, dn[x_save] ); /*2*Qdn+1*/
429 404373 : move16();
430 404373 : *alp = alpk[ik]; /*Q6*/
431 404373 : move16();
432 404373 : *ix = x_save; /*Q0*/
433 404373 : move16();
434 404373 : return;
435 : }
436 :
437 :
438 : /*
439 : * E_ACELP_xh_corr
440 : *
441 : * Parameters:
442 : * h I: impulse response (of weighted synthesis filter) (Q12)
443 : * x I: target signal (Q0)
444 : * y O: correlation between x[] and h[] <12b
445 : *
446 : * Function:
447 : * Compute the correlation between the target signal and the impulse
448 : * response of the weighted synthesis filter.
449 : *
450 : * y[i]=sum(j=i,l-1) x[j]*h[j-i], i=0,l-1
451 : *
452 : * Vector size is L_SUBFR
453 : *
454 : * Returns:
455 : * void
456 : */
457 0 : static void E_ACELP_xh_corr( Word16 *x /*Qx*/, Word16 *y /*Qy*/, Word16 *h /*Q12*/, Word16 L_subfr /*Q0*/ )
458 : {
459 : Word16 i, j, k;
460 : Word32 L_tmp, y32[L_SUBFR16k], L_maxloc, L_tot;
461 :
462 0 : assert( L_subfr <= L_SUBFR16k );
463 :
464 : /* first keep the result on 32 bits and find absolute maximum */
465 0 : L_tot = L_deposit_l( 1 );
466 :
467 0 : FOR( k = 0; k < 4; k++ )
468 : {
469 0 : L_maxloc = L_deposit_l( 0 );
470 0 : FOR( i = k; i < L_subfr; i += 4 )
471 : {
472 0 : L_tmp = L_mac0( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] Qx+Q12*/
473 0 : FOR( j = i; j < L_subfr - 1; j++ )
474 : {
475 0 : L_tmp = L_mac0( L_tmp, x[j + 1], h[j + 1 - i] ); /*Qx+Q12*/
476 : }
477 :
478 0 : y32[i] = L_tmp; /*Qx+Q12*/
479 0 : move32();
480 0 : L_tmp = L_abs( L_tmp ); /*Qx+Q12*/
481 0 : L_maxloc = L_max( L_tmp, L_maxloc ); /*Qx+Q12*/
482 : }
483 : /* tot += 3*max / 8 */
484 0 : L_maxloc = L_shr( L_maxloc, 2 );
485 : /* Do not warn saturation of L_tot, since its for headroom estimation. */
486 : BASOP_SATURATE_WARNING_OFF_EVS
487 0 : L_tot = L_add_sat( L_tot, L_maxloc ); /* +max/4 */
488 0 : L_tot = L_add_sat( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */
489 : BASOP_SATURATE_WARNING_ON_EVS
490 : }
491 :
492 : /* Find the number of right shifts to do on y32[] so that */
493 : /* 6.0 x sumation of max of dn[] in each track not saturate. */
494 :
495 0 : j = sub( norm_l( L_tot ), 4 + 16 ); /* 4 -> 16 x tot */
496 :
497 0 : Copy_Scale_sig_32_16( y32, y, L_subfr, j ); /*Qy = Qx+Q12+j*/
498 0 : return;
499 : }
500 :
501 : /**
502 : * \brief calculate autocorrelation of vector x
503 : * \param x input vector 4Q11
504 : * \param y output (autocorrelation coefficients)
505 : * \param L_subfr length of x (and y)
506 : * \param bits amount of target headroom bits for y
507 : * \return exponent of y
508 : */
509 407727 : Word16 E_ACELP_hh_corr( Word16 *x /*Q11*/, Word16 *y /*Qy*/, Word16 L_subfr /*Q0*/, Word16 bits /*Q0*/ )
510 : {
511 407727 : Word16 i, j, k = 0; /* initialize just to avoid compiler warning */
512 : Word32 L_tmp, L_sum;
513 :
514 26094528 : FOR( i = 0; i < L_subfr - 1; i++ )
515 : {
516 : Word64 L_tmp_64;
517 : Word64 L_sum_64;
518 :
519 25686801 : L_tmp_64 = W_mult0_16_16( x[i], x[0] ); /*Q22*/
520 430151985 : FOR( j = i + 2; j < L_subfr; j += 2 )
521 : {
522 404465184 : L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/
523 : }
524 25686801 : L_sum_64 = L_tmp_64;
525 25686801 : move64();
526 :
527 25686801 : L_tmp_64 = W_mult0_16_16( x[i + 1], x[1] ); /*Q22*/
528 417512448 : FOR( j = i + 3; j < L_subfr; j += 2 )
529 : {
530 391825647 : L_tmp_64 = W_mac0_16_16( L_tmp_64, x[j], x[j - i] ); /*Q22*/
531 : }
532 25686801 : L_sum_64 = W_add_nosat( W_shr( L_sum_64, 1 ), W_shr( L_tmp_64, 1 ) );
533 25686801 : L_sum = W_sat_l( L_sum_64 ); /*Q22*/
534 : /* L_sum = L_shr( L_sum, 1 ); */
535 25686801 : if ( i == 0 )
536 : {
537 407727 : k = norm_l( L_sum );
538 : }
539 25686801 : if ( i == 0 )
540 : {
541 407727 : k = sub( k, bits );
542 : }
543 :
544 25686801 : y[i] = round_fx( L_shl( L_sum, k ) ); /*Q22+k-16*/
545 : }
546 :
547 407727 : L_tmp = L_mult0( x[i], x[0] ); /*Q22*/
548 407727 : L_sum = L_shr( L_tmp, 1 );
549 407727 : y[i] = round_fx( L_shl( L_sum, k ) ); /*Qy = Q22+k-16*/
550 :
551 407727 : k = add( 1, k );
552 :
553 407727 : return k;
554 : }
555 :
556 : /*
557 : * E_ACELP_xy1_corr
558 : *
559 : * Parameters:
560 : * xn I: target signal
561 : * y1 I: filtered adaptive codebook excitation
562 : * g_coeff O: correlations <y1,y1> and -2<xn,y1>
563 : * norm_flag I: flag to trigger normalization of the result
564 : * L_subfr I: length of data
565 : * exp_xn I: common exponent of xn[] and y1[]
566 : *
567 : * Function:
568 : * Find the correlations between the target xn[] and the filtered adaptive
569 : * codebook excitation y1[]. ( <y1,y1> and -2<xn,y1> )
570 : * Subframe size = L_SUBFR
571 : *
572 : * Returns:
573 : * pitch gain (0 ... 1.2F) (Q14)
574 : */
575 4410 : Word16 E_ACELP_xy1_corr_fx( Word16 xn[] /*Q15-exp_xn*/, Word16 y1[] /*Q15-exp_xn*/, ACELP_CbkCorr *g_corr, Word16 norm_flag /*Q0*/, Word16 L_subfr /*Q0*/, Word16 exp_xn )
576 : {
577 : Word16 i, Q_xn;
578 : Word16 xy, yy, exp_xy, exp_yy, gain;
579 : Word32 L_off;
580 : #ifndef ISSUE_1867_replace_overflow_libenc
581 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
582 : Flag Overflow = 0;
583 : move32();
584 : #endif
585 : #endif
586 :
587 4410 : L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, s_min( add( exp_xn, exp_xn ), 31 ) );
588 4410 : L_off = L_max( 1, L_off ); /* ensure at least a '1' */
589 :
590 : /* Compute scalar product t1: <y1[] * y1[]> */
591 : #ifdef ISSUE_1867_replace_overflow_libenc
592 4410 : yy = round_fx_sat( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ) ); /*Q15 - exp_yy*/
593 : #else
594 : yy = round_fx_o( Dot_product15_offs( y1, y1, L_subfr, &exp_yy, L_off ), &Overflow ); /*Q15 - exp_yy*/
595 : #endif
596 :
597 : /* Compute scalar product t0: <xn[] * y1[]> */
598 : #ifdef ISSUE_1867_replace_overflow_libenc
599 4410 : xy = round_fx_sat( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ) ); /*Q15 - exp_xy*/
600 : #else
601 : xy = round_fx_o( Dot_product12_offs( xn, y1, L_subfr, &exp_xy, L_off ), &Overflow ); /*Q15 - exp_xy*/
602 : #endif
603 : /* Compute doubled format out of the exponent */
604 4410 : Q_xn = shl( sub( 15, exp_xn ), 1 );
605 4410 : g_corr->y1y1 = yy;
606 4410 : move16();
607 4410 : g_corr->y1y1_e = sub( exp_yy, Q_xn );
608 4410 : move16();
609 4410 : g_corr->xy1 = xy;
610 4410 : move16();
611 4410 : g_corr->xy1_e = sub( exp_xy, Q_xn );
612 4410 : move16();
613 :
614 : /* If (xy < 0) gain = 0 */
615 4410 : IF( xy < 0 )
616 : {
617 49 : move16();
618 49 : gain = 0;
619 49 : GOTO bail;
620 : }
621 :
622 : /* compute gain = xy/yy */
623 :
624 4361 : xy = mult_r( xy, 0x4000 ); /* Be sure xy < yy Q15 - exp_xy*/
625 4361 : gain = div_s( xy, yy ); /*Q14*/
626 :
627 4361 : i = add( exp_xy, 1 - 1 ); /* -1 -> gain in Q14 */
628 4361 : i = sub( i, exp_yy );
629 : BASOP_SATURATE_WARNING_OFF_EVS
630 4361 : gain = shl_sat( gain, i ); /* saturation can occur here */
631 : BASOP_SATURATE_WARNING_ON_EVS
632 : /* gain = s_max(0, gain); */ /* see above xy < 0. */
633 :
634 : /* if (gain > 1.2) gain = 1.2 in Q14 */
635 :
636 4361 : gain = s_min( 19661 /*1.2f Q14*/ /* 19661 */, gain ); /*Q14*/
637 :
638 : /*Limit the energy of pitch contribution*/
639 4361 : IF( norm_flag )
640 : {
641 : Word16 tmp, exp_tmp, exp_div;
642 :
643 : /* Compute scalar product <xn[],xn[]> */
644 : #ifdef ISSUE_1867_replace_overflow_libenc
645 4361 : tmp = round_fx_sat( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ) ); /*Q15 - exp_tmp*/
646 : #else
647 : tmp = round_fx_o( Dot_product12_offs( xn, xn, L_subfr, &exp_tmp, 1 ), &Overflow ); /*Q15 - exp_tmp*/
648 : #endif
649 : /* gain_p_snr = sqrt(<xn,xn>/<y1,y1>) */
650 4361 : tmp = BASOP_Util_Divide1616_Scale( tmp, yy, &exp_div );
651 4361 : exp_tmp = add( sub( exp_tmp, exp_yy ), exp_div );
652 :
653 4361 : tmp = Sqrt16( tmp, &exp_tmp ); /*Q15 - exp_tmp*/
654 :
655 : /* Note: shl works as shl or shr. */
656 4361 : exp_tmp = sub( exp_tmp, 1 );
657 : BASOP_SATURATE_WARNING_OFF_EVS
658 : #ifdef ISSUE_1867_replace_overflow_libenc
659 4361 : tmp = round_fx_sat( L_shl_sat( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp ) ); /*Q14*/
660 : #else
661 : tmp = round_fx_o( L_shl_o( Mpy_32_16_1( 1717986944l /*ACELP_GAINS_CONST Q31*/, tmp ), exp_tmp, &Overflow ), &Overflow ); /*Q14*/
662 : #endif
663 : BASOP_SATURATE_WARNING_ON_EVS
664 :
665 4361 : gain = s_min( gain, tmp ); /*Q14*/
666 : }
667 :
668 0 : bail:
669 :
670 :
671 4410 : return ( gain );
672 : }
673 :
674 : /*
675 : * E_ACELP_xy2_corr
676 : *
677 : * Parameters:
678 : * xn I: target signal in Q_xn
679 : * y1 I: filtered adaptive codebook excitation in Q_xn
680 : * y2 I: filtered fixed codebook excitation in Q9
681 : * g_corr O: correlations <y2,y2>, -2<xn,y2>, 2<y1,y2>
682 : * L_subfr I: subframe size
683 : *
684 : * Function:
685 : * Find the correlations between the target xn[], the filtered adaptive
686 : * codebook exc. y1[], and the filtered fixed codebook innovation y2[].
687 : * ( <y2,y2> , -2<xn,y2> and 2<y1,y2> )
688 : * Subrame size = L_SUBFR
689 : *
690 : * Returns:
691 : * pitch gain (0 ... 1.2F)
692 : */
693 11120 : void E_ACELP_xy2_corr( Word16 xn[] /*Q_xn*/, Word16 y1[] /*Q_xn*/, Word16 y2[] /*Q9*/, ACELP_CbkCorr *g_corr, Word16 L_subfr /*Q0*/, Word16 exp_xn )
694 : {
695 : Word16 xny2, y2y2, y1y2, xx, exp_xny2, exp_y2y2, exp_y1y2, exp_xx;
696 : Word32 L_off;
697 :
698 : BASOP_SATURATE_ERROR_ON_EVS;
699 :
700 : /* Compute scalar product <y2[],y2[]> */
701 11120 : y2y2 = extract_h( Dot_product15_offs( y2, y2, L_subfr, &exp_y2y2, 5243l /*0.01f Q19*/ ) ); /*Q15-exp_y2y2*/
702 :
703 : /* L_off = 1L; */
704 11120 : L_off = L_shr( 10737418l /*0.01f/2.0f Q31*/, sub( 30 - 9, exp_xn ) );
705 :
706 : /* Compute scalar product <xn[],y2[]> */
707 11120 : xny2 = extract_h( Dot_product12_offs( xn, y2, L_subfr, &exp_xny2, L_off ) ); /*Q15-exp_xny2*/
708 :
709 : /* Compute scalar product <y1[],y2[]> */
710 11120 : y1y2 = extract_h( Dot_product12_offs( y1, y2, L_subfr, &exp_y1y2, L_off ) ); /*Q15-exp_y1y2*/
711 :
712 : /* Compute scalar product <xn[],xn[]> */
713 11120 : L_off = L_shr( 21474836l /*0.01f Q31*/, s_min( 31, sub( 30, shl( exp_xn, 1 ) ) ) );
714 11120 : xx = extract_h( Dot_product12_offs( xn, xn, L_subfr, &exp_xx, L_off ) ); /*Q15-exp_xx*/
715 :
716 :
717 11120 : g_corr->y2y2 = y2y2;
718 11120 : move16();
719 11120 : g_corr->y2y2_e = exp_y2y2;
720 11120 : move16();
721 11120 : g_corr->xy2 = xny2;
722 11120 : move16();
723 11120 : g_corr->xy2_e = exp_xny2;
724 11120 : move16();
725 11120 : g_corr->y1y2 = y1y2;
726 11120 : move16();
727 11120 : g_corr->y1y2_e = exp_y1y2;
728 11120 : move16();
729 11120 : g_corr->xx = xx;
730 11120 : move16();
731 11120 : g_corr->xx_e = exp_xx;
732 11120 : move16();
733 :
734 :
735 : BASOP_SATURATE_ERROR_OFF_EVS;
736 11120 : return;
737 : }
738 :
739 :
740 : /*
741 : * E_ACELP_codebook_target_update
742 : *
743 : * Parameters:
744 : * x I: old target (for pitch search) (Q_xn)
745 : * x2 O: new target (for codebook search) (Q_xn)
746 : * y I: filtered adaptive codebook vector (Q_xn)
747 : * gain I: adaptive codebook gain (Q14)
748 : *
749 : * Function:
750 : * Update the target vector for codebook search.
751 : * Subframe size = L_SUBFR
752 : * Returns:
753 : * void
754 : */
755 7470 : void E_ACELP_codebook_target_update_fx( Word16 *x /*Q_xn*/, Word16 *x2 /*Q_xn*/, Word16 *y /*Q_xn*/, Word16 gain /*Q14*/, Word16 L_subfr /*Q0*/ )
756 : {
757 : Word16 i, Q15_flag;
758 : Word32 L_tmp;
759 : #ifndef ISSUE_1867_replace_overflow_libenc
760 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
761 : Flag Overflow = 0;
762 : move32();
763 : #endif
764 : #endif
765 7470 : assert( gain >= 0 );
766 :
767 7470 : Q15_flag = 0;
768 7470 : move16();
769 7470 : if ( LT_16( gain, 1 << 14 ) )
770 : {
771 6421 : Q15_flag = 1;
772 6421 : move16();
773 : }
774 7470 : gain = shl( gain, Q15_flag ); /*Q14*/
775 :
776 485550 : FOR( i = 0; i < L_subfr; i++ )
777 : {
778 478080 : L_tmp = L_deposit_h( x[i] ); /*Q_xn+16*/
779 478080 : if ( Q15_flag == 0 )
780 : {
781 : #ifdef ISSUE_1867_replace_overflow_libenc
782 67136 : L_tmp = L_msu_sat( L_tmp, y[i], gain ); /*Q_xn+15*/
783 : #else
784 : L_tmp = L_msu_o( L_tmp, y[i], gain, &Overflow ); /*Q_xn+15*/
785 : #endif
786 : }
787 : #ifdef ISSUE_1867_replace_overflow_libenc
788 478080 : x2[i] = msu_r_sat( L_tmp, y[i], gain ); /*Q_xn*/
789 : #else
790 : x2[i] = msu_ro( L_tmp, y[i], gain, &Overflow ); /*Q_xn*/
791 : #endif
792 478080 : move16();
793 : }
794 7470 : }
795 :
796 :
797 : /*
798 : * E_ACELP_pulsesign
799 : *
800 : * Parameters:
801 : * cn I: residual after long term prediction <12b
802 : * dn I: corr. between target and h[]. <12b
803 : * dn2 I/O: dn2[] = mix of dn[] and cn[]
804 : * sign O: sign of pulse 0 or -1
805 : * vec O: negative sign of pulse
806 : * alp I: energy of all fixed pulses Q13
807 : * sign_val I: value for signs
808 : * L_subfr I: subframe length
809 : *
810 : * Function:
811 : * Determine sign of each pulse position, store them in "sign"
812 : * and change dn to all positive.
813 : * Subframe size = L_SUBFR
814 : * Returns:
815 : * void
816 : */
817 578907 : void E_ACELP_pulsesign( const Word16 cn[] /*Q_xn*/, Word16 dn[] /*Qdn*/, Word16 dn2[] /*Qdn2*/, Word16 sign[] /*Q13*/, Word16 vec[] /*Q15*/, const Word16 alp /*Q13*/, const Word16 sign_val /*Q15*/, const Word16 L_subfr /*Q0*/ )
818 : {
819 : Word16 i;
820 : Word32 Lval, Lcor;
821 : Word16 k_cn, k_dn, sign_neg, e_dn, e_cn;
822 : Word16 signs[3];
823 : Word16 *ptr16;
824 : Word16 val, index;
825 : #ifndef ISSUE_1867_replace_overflow_libenc
826 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
827 : Flag Overflow = 0;
828 : move32();
829 : #endif
830 : #endif
831 :
832 :
833 : /* calculate energy for normalization of cn[] and dn[] */
834 578907 : Lval = L_mac0( 1, cn[0], cn[0] ); /*2*Q_xn*/
835 578907 : Lcor = L_mac0( 1, dn[0], dn[0] ); /*2*Qdn*/
836 :
837 37050048 : FOR( i = 1; i < L_subfr; i++ )
838 : {
839 : #ifdef ISSUE_1867_replace_overflow_libenc
840 36471141 : Lval = L_mac0_sat( Lval, cn[i], cn[i] ); /*2*Q_xn*/
841 : #else
842 : Lval = L_mac0_o( Lval, cn[i], cn[i], &Overflow ); /*2*Q_xn*/
843 : #endif
844 36471141 : Lcor = L_mac0( Lcor, dn[i], dn[i] ); /*2*Qdn*/
845 : }
846 :
847 578907 : e_dn = 31;
848 578907 : move16();
849 578907 : e_cn = 31;
850 578907 : move16();
851 :
852 578907 : Lval = Sqrt32( Lval, &e_dn ); /*Q31 - e_dn*/
853 578907 : Lcor = Sqrt32( Lcor, &e_cn ); /*Q31 - e_cn*/
854 578907 : i = sub( e_dn, e_cn );
855 578907 : if ( i < 0 )
856 343413 : Lval = L_shl( Lval, i );
857 578907 : if ( i > 0 )
858 130883 : Lcor = L_shr( Lcor, i );
859 :
860 : #ifdef ISSUE_1867_replace_overflow_libenc
861 578907 : k_dn = round_fx_sat( Lval ); /*Q15 - e_dn*/
862 578907 : k_cn = round_fx_sat( Lcor ); /*Q15 - e_cn*/
863 : #else
864 : k_dn = round_fx_o( Lval, &Overflow ); /*Q15 - e_dn*/
865 : k_cn = round_fx_o( Lcor, &Overflow ); /*Q15 - e_cn*/
866 : #endif
867 :
868 578907 : k_cn = mult_r( 0x2000, k_cn ); /* 1 in Q13 */
869 578907 : k_dn = mult_r( alp, k_dn ); /* alp in Q13 */
870 :
871 578907 : sign_neg = negate( sign_val ); /*Q15*/
872 :
873 578907 : signs[0] = sign_neg; /*Q15*/
874 578907 : move16();
875 578907 : signs[1] = sign_val; /*Q15*/
876 578907 : move16();
877 578907 : signs[2] = sign_neg; /*Q15*/
878 578907 : move16();
879 578907 : ptr16 = &signs[1]; /*Q15*/
880 :
881 37628955 : FOR( i = 0; i < L_subfr; i++ )
882 : {
883 : /*cor = (s * cn[i]) + (alp * dn[i]); MULT(1);MAC(1);*/
884 37050048 : Lcor = L_mult( cn[i], k_cn ); /*Q_xn + Q15 - e_cn + 1*/
885 37050048 : Lcor = L_mac( Lcor, dn[i], k_dn ); /*Qdn + Q15 - e_dn + 1*/
886 : #ifdef ISSUE_1867_replace_overflow_libenc
887 37050048 : val = round_fx_sat( L_shl_sat( Lcor, 4 ) ); /*shifting by 4 may overflow but improves accuracy Qdn + 4 - e_dn*/
888 : #else
889 : val = round_fx_o( L_shl_o( Lcor, 4, &Overflow ), &Overflow ); /*shifting by 4 may overflow but improves accuracy Qdn + 4 - e_dn*/
890 : #endif
891 :
892 37050048 : index = shr( val, 15 );
893 37050048 : sign[i] = ptr16[index]; /*Q15*/
894 37050048 : move16(); /* yields -1 (when ps < 0) or 0 (when ps >= 0) */
895 37050048 : vec[i] = ptr16[index + 1]; /*Q15*/
896 37050048 : move16();
897 :
898 37050048 : if ( val < 0 )
899 : {
900 18672717 : dn[i] = negate( dn[i] ); /*Qdn*/
901 18672717 : move16();
902 : }
903 37050048 : dn2[i] = abs_s( val ); /*Qdn2 = Qdn + 4 - e_dn*/
904 37050048 : move16(); /* dn2[] = mix of dn[] and cn[] */
905 : }
906 578907 : }
907 :
908 :
909 578907 : void E_ACELP_findcandidates( Word16 dn2[] /*Qx*/, Word16 dn2_pos[] /*Q0*/, Word16 pos_max[] /*Q0*/ )
910 : {
911 : Word16 i, k, j, i8;
912 : Word16 *ps_ptr;
913 :
914 2894535 : FOR( i = 0; i < 4; i++ )
915 : {
916 2315628 : i8 = shl( i, 3 );
917 20840652 : FOR( k = i8; k < i8 + 8; k++ )
918 : {
919 18525024 : ps_ptr = &dn2[i]; /*Qx*/
920 :
921 296400384 : FOR( j = i + 4; j < L_SUBFR; j += 4 )
922 : {
923 277875360 : if ( GT_16( dn2[j], *ps_ptr ) )
924 : {
925 43646531 : ps_ptr = &dn2[j]; /*Qx*/
926 43646531 : move16();
927 : }
928 : }
929 :
930 18525024 : *ps_ptr = -1; /* dn2 < 0 when position is selected */
931 18525024 : move16();
932 18525024 : dn2_pos[k] = (Word16) ( ps_ptr - dn2 );
933 18525024 : move16();
934 : }
935 2315628 : pos_max[i] = dn2_pos[i8]; /*Q0*/
936 2315628 : move16();
937 : }
938 578907 : }
939 :
940 :
941 11789440 : static void E_ACELP_apply_sign( Word16 *p0 /*Qx*/, Word16 *psign0 /*Q15*/ )
942 : {
943 11789440 : p0[0] = mult_r( p0[0], psign0[0] ); /*Qx*/
944 11789440 : move16();
945 11789440 : p0[1] = mult_r( p0[1], psign0[4] );
946 11789440 : move16();
947 11789440 : p0[2] = mult_r( p0[2], psign0[8] );
948 11789440 : move16();
949 11789440 : p0[3] = mult_r( p0[3], psign0[12] );
950 11789440 : move16();
951 11789440 : p0[4] = mult_r( p0[4], psign0[16] );
952 11789440 : move16();
953 11789440 : p0[5] = mult_r( p0[5], psign0[20] );
954 11789440 : move16();
955 11789440 : p0[6] = mult_r( p0[6], psign0[24] );
956 11789440 : move16();
957 11789440 : p0[7] = mult_r( p0[7], psign0[28] );
958 11789440 : move16();
959 11789440 : p0[8] = mult_r( p0[8], psign0[32] );
960 11789440 : move16();
961 11789440 : p0[9] = mult_r( p0[9], psign0[36] );
962 11789440 : move16();
963 11789440 : p0[10] = mult_r( p0[10], psign0[40] );
964 11789440 : move16();
965 11789440 : p0[11] = mult_r( p0[11], psign0[44] );
966 11789440 : move16();
967 11789440 : p0[12] = mult_r( p0[12], psign0[48] );
968 11789440 : move16();
969 11789440 : p0[13] = mult_r( p0[13], psign0[52] );
970 11789440 : move16();
971 11789440 : p0[14] = mult_r( p0[14], psign0[56] );
972 11789440 : move16();
973 11789440 : p0[15] = mult_r( p0[15], psign0[60] );
974 11789440 : move16();
975 11789440 : }
976 :
977 184210 : void E_ACELP_vec_neg_fx( Word16 h[] /*Qx*/, Word16 h_inv[] /*Qx*/, Word16 L_subfr /*Q0*/ )
978 : {
979 : Word16 i;
980 :
981 11973650 : FOR( i = 0; i < L_subfr; i++ )
982 : {
983 11789440 : h_inv[i] = negate( h[i] );
984 11789440 : move16();
985 : }
986 184210 : }
987 :
988 :
989 184210 : void E_ACELP_corrmatrix_fx( Word16 h[] /*Q12*/, Word16 sign[] /*Q0*/, Word16 vec[] /*Q15*/, Word16 rrixix[4][16] /*Q9*/, Word16 rrixiy[4][256] /*Q9*/ )
990 : {
991 :
992 : Word16 *p0, *p1, *p2, *p3, *psign0, *psign1, *psign2, *psign3;
993 : Word16 *ptr_h1, *ptr_h2, *ptr_hf;
994 : Word32 cor;
995 : Word16 i, /* j, */ k, pos;
996 :
997 : /*
998 : * Compute rrixix[][] needed for the codebook search.
999 : */
1000 :
1001 : /* storage order --> i3i3, i2i2, i1i1, i0i0 */
1002 :
1003 : /* Init pointers to last position of rrixix[] */
1004 184210 : p0 = &rrixix[0][16 - 1]; /* Q9 */
1005 184210 : p1 = &rrixix[1][16 - 1];
1006 184210 : p2 = &rrixix[2][16 - 1];
1007 184210 : p3 = &rrixix[3][16 - 1];
1008 :
1009 184210 : ptr_h1 = h; /*Q12*/
1010 184210 : cor = L_deposit_l( 0 );
1011 3131570 : FOR( i = 0; i < 16; i++ )
1012 : {
1013 2947360 : cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
1014 2947360 : ptr_h1++;
1015 2947360 : *p3-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */
1016 2947360 : cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
1017 2947360 : ptr_h1++;
1018 2947360 : *p2-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */
1019 2947360 : cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
1020 2947360 : ptr_h1++;
1021 2947360 : *p1-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */
1022 2947360 : cor = L_mac( cor, *ptr_h1, *ptr_h1 ); /*Q25*/
1023 2947360 : ptr_h1++;
1024 2947360 : *p0-- = round_fx( L_shr( cor, 1 ) ); /* Q9 */
1025 : }
1026 :
1027 :
1028 : /*
1029 : * Compute rrixiy[][] needed for the codebook search.
1030 : */
1031 :
1032 : /* storage order --> i2i3, i1i2, i0i1, i3i0 */
1033 :
1034 184210 : pos = 256 - 1;
1035 184210 : move16();
1036 184210 : ptr_hf = h + 1; /*Q12*/
1037 3131570 : FOR( k = 0; k < 16; k++ )
1038 : {
1039 2947360 : p3 = &rrixiy[2][pos]; /* Q9 */
1040 2947360 : p2 = &rrixiy[1][pos];
1041 2947360 : p1 = &rrixiy[0][pos];
1042 2947360 : p0 = &rrixiy[3][pos - 16];
1043 :
1044 2947360 : cor = L_deposit_h( 0 );
1045 2947360 : ptr_h1 = h; /*Q12*/
1046 2947360 : ptr_h2 = ptr_hf; /*Q12*/
1047 :
1048 25052560 : FOR( i = k; i < 16 - 1; i++ )
1049 : {
1050 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1051 22105200 : *p3 = round_fx( cor ); /*Q9*/
1052 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1053 22105200 : *p2 = round_fx( cor ); /*Q9*/
1054 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1055 22105200 : *p1 = round_fx( cor ); /*Q9*/
1056 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1057 22105200 : *p0 = round_fx( cor ); /*Q9*/
1058 :
1059 22105200 : p3 -= ( 16 + 1 );
1060 22105200 : p2 -= ( 16 + 1 );
1061 22105200 : p1 -= ( 16 + 1 );
1062 22105200 : p0 -= ( 16 + 1 );
1063 : }
1064 2947360 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1065 2947360 : *p3 = round_fx( cor ); /*Q9*/
1066 2947360 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1067 2947360 : *p2 = round_fx( cor ); /*Q9*/
1068 2947360 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1069 2947360 : *p1 = round_fx( cor ); /*Q9*/
1070 2947360 : move16();
1071 2947360 : move16();
1072 2947360 : move16();
1073 :
1074 2947360 : pos -= 16;
1075 2947360 : move16();
1076 2947360 : ptr_hf += 4;
1077 : }
1078 :
1079 : /* storage order --> i3i0, i2i3, i1i2, i0i1 */
1080 :
1081 184210 : pos = 256 - 1;
1082 184210 : move16();
1083 184210 : ptr_hf = h + 3; /*Q12*/
1084 3131570 : FOR( k = 0; k < 16; k++ )
1085 : {
1086 2947360 : p3 = &rrixiy[3][pos]; /*Q9*/
1087 2947360 : p2 = &rrixiy[2][pos - 1];
1088 2947360 : p1 = &rrixiy[1][pos - 1];
1089 2947360 : p0 = &rrixiy[0][pos - 1];
1090 :
1091 2947360 : cor = L_deposit_h( 0 );
1092 2947360 : ptr_h1 = h; /*Q12*/
1093 2947360 : ptr_h2 = ptr_hf; /*Q12*/
1094 25052560 : FOR( i = k; i < 16 - 1; i++ )
1095 : {
1096 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1097 22105200 : *p3 = round_fx( cor ); /*Q9*/
1098 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1099 22105200 : *p2 = round_fx( cor ); /*Q9*/
1100 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1101 22105200 : *p1 = round_fx( cor ); /*Q9*/
1102 22105200 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1103 22105200 : *p0 = round_fx( cor ); /*Q9*/
1104 22105200 : move16();
1105 22105200 : move16();
1106 22105200 : move16();
1107 22105200 : move16();
1108 :
1109 22105200 : p3 -= ( 16 + 1 );
1110 22105200 : p2 -= ( 16 + 1 );
1111 22105200 : p1 -= ( 16 + 1 );
1112 22105200 : p0 -= ( 16 + 1 );
1113 : }
1114 2947360 : cor = L_mac( cor, *ptr_h1++, *ptr_h2++ ); /*Q25*/
1115 2947360 : *p3 = round_fx( cor ); /*Q9*/
1116 2947360 : move16();
1117 :
1118 2947360 : pos--;
1119 2947360 : ptr_hf += 4;
1120 : }
1121 :
1122 : /*
1123 : * Modification of rrixiy[][] to take signs into account.
1124 : */
1125 :
1126 184210 : p0 = &rrixiy[0][0]; /*Q9*/
1127 :
1128 : /* speed-up: 11% */
1129 184210 : p1 = &rrixiy[1][0];
1130 184210 : p2 = &rrixiy[2][0];
1131 184210 : p3 = &rrixiy[3][0];
1132 :
1133 3131570 : FOR( i = 0; i < L_SUBFR; i += 4 )
1134 : {
1135 :
1136 2947360 : psign0 = &vec[1]; /*Q15*/
1137 2947360 : if ( sign[i + 0] > 0 )
1138 1455155 : psign0 = &sign[1];
1139 :
1140 2947360 : psign1 = &vec[2]; /*Q15*/
1141 2947360 : if ( sign[i + 1] > 0 )
1142 1456864 : psign1 = &sign[2];
1143 :
1144 2947360 : psign2 = &vec[3]; /*Q15*/
1145 2947360 : if ( sign[i + 2] > 0 )
1146 1456876 : psign2 = &sign[3];
1147 :
1148 2947360 : psign3 = &vec[0]; /*Q15*/
1149 2947360 : if ( sign[i + 3] > 0 )
1150 1454098 : psign3 = &sign[0];
1151 :
1152 2947360 : E_ACELP_apply_sign( p0, psign0 );
1153 2947360 : p0 += 16;
1154 :
1155 2947360 : E_ACELP_apply_sign( p1, psign1 );
1156 2947360 : p1 += 16;
1157 :
1158 2947360 : E_ACELP_apply_sign( p2, psign2 );
1159 2947360 : p2 += 16;
1160 :
1161 2947360 : E_ACELP_apply_sign( p3, psign3 );
1162 2947360 : p3 += 16;
1163 : }
1164 184210 : return;
1165 : }
1166 :
1167 184210 : void E_ACELP_4tsearch_fx( Word16 dn[] /*Qdn*/, const Word16 cn[] /*Q_xn*/, const Word16 H[] /*Q12*/, Word16 code[] /*Q9*/, const PulseConfig *config, Word16 ind[] /*Q0*/, Word16 y[] /*Qy*/, const Word16 element_mode )
1168 : {
1169 : Word16 sign[L_SUBFR], vec[L_SUBFR];
1170 : Word16 cor_x[16], cor_y[16], h_buf[4 * L_SUBFR];
1171 : Word16 rrixix[4][16];
1172 : Word16 rrixiy[4][256];
1173 : Word16 dn2[L_SUBFR];
1174 184210 : Word16 psk, ps, alpk, alp = 0;
1175 : Word16 codvec[NB_PULSE_MAX];
1176 : Word16 pos_max[4];
1177 : Word16 dn2_pos[8 * 4];
1178 : UWord8 ipos[NB_PULSE_MAX];
1179 : Word16 *p0, *p1, *p2, *p3;
1180 : Word16 *h, *h_inv;
1181 : Word16 i, j, k, l, st, pos;
1182 : Word16 val, tmp, scale;
1183 : Word32 s, L_tmp;
1184 : Word16 nb_pulse, nb_pulse_m2;
1185 184210 : Word16 check = 0; /* debug code not instrumented */
1186 : #ifndef ISSUE_1867_replace_overflow_libenc
1187 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1188 : Flag Overflow = 0;
1189 : move32();
1190 : #endif
1191 : #endif
1192 :
1193 :
1194 184210 : alp = config->alp; /* Q13 */ /* initial value for energy of all fixed pulses */
1195 184210 : move16();
1196 184210 : nb_pulse = config->nb_pulse;
1197 184210 : move16();
1198 184210 : nb_pulse_m2 = sub( nb_pulse, 2 );
1199 :
1200 184210 : set16_fx( codvec, 0, nb_pulse );
1201 :
1202 : /*
1203 : * Find sign for each pulse position.
1204 : */
1205 :
1206 184210 : E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, 0x7fff, L_SUBFR );
1207 :
1208 : /*
1209 : * Select the most important 8 position per track according to dn2[].
1210 : */
1211 184210 : E_ACELP_findcandidates( dn2, dn2_pos, pos_max );
1212 :
1213 : /*
1214 : * Compute h_inv[i].
1215 : */
1216 184210 : set16_fx( h_buf, 0, L_SUBFR );
1217 :
1218 184210 : set16_fx( h_buf + ( 2 * L_SUBFR ), 0, L_SUBFR );
1219 :
1220 184210 : h = h_buf + L_SUBFR;
1221 184210 : h_inv = h_buf + ( 3 * L_SUBFR );
1222 :
1223 : /*Check the energy if it is too high then scale to prevent an overflow*/
1224 184210 : scale = 0;
1225 184210 : move16();
1226 184210 : L_tmp = L_deposit_l( 0 );
1227 : BASOP_SATURATE_WARNING_OFF_EVS
1228 11973650 : FOR( i = 0; i < L_SUBFR; i++ )
1229 : {
1230 : #ifdef ISSUE_1867_replace_overflow_libenc
1231 11789440 : L_tmp = L_mac_sat( L_tmp, H[i], H[i] ); /*Q25*/
1232 : #else
1233 : L_tmp = L_mac_o( L_tmp, H[i], H[i], &Overflow ); /*Q25*/
1234 : #endif
1235 : }
1236 184210 : val = extract_h( L_tmp ); /*Q9*/
1237 : BASOP_SATURATE_WARNING_ON_EVS
1238 :
1239 184210 : if ( GT_16( val, 0x2000 ) )
1240 : {
1241 18453 : scale = -1;
1242 18453 : move16();
1243 : }
1244 184210 : if ( GT_16( val, 0x7000 ) )
1245 : {
1246 2224 : scale = -2;
1247 2224 : move16();
1248 : }
1249 184210 : test();
1250 184210 : if ( EQ_16( val, 32767 ) && element_mode > EVS_MONO )
1251 : {
1252 1680 : scale = -3;
1253 1680 : move16();
1254 : }
1255 184210 : Copy_Scale_sig( H, h, L_SUBFR, scale ); /*Q12+scale*/
1256 :
1257 184210 : E_ACELP_vec_neg_fx( h, h_inv, L_SUBFR );
1258 :
1259 :
1260 : /*
1261 : * Compute correlation matrices needed for the codebook search.
1262 : */
1263 184210 : E_ACELP_corrmatrix_fx( h, sign, vec, rrixix, rrixiy );
1264 :
1265 :
1266 : /*
1267 : * Deep first search:
1268 : * ------------------
1269 : * 20 bits (4p): 4 iter x ((4x16)+(8x16)) = 768 tests
1270 : * 36 bits (8p): 4 iter x ((1x1)+(4x16)+(8x16)+(8x16)) = 1280 tests
1271 : * 52 bits (12p): 3 iter x ((1x1)+(1x1)+(4x16)+(6x16)
1272 : * +(8x16)+(8x16)) = 1248 tests
1273 : * 64 bits (16p): 2 iter x ((1x1)+(1x1)+(4x16)+(6x16)
1274 : * +(6x16)+(8x16)+(8x16)+(8x16)) = 1280 tests
1275 : */
1276 184210 : psk = -1;
1277 184210 : move16();
1278 184210 : alpk = 1;
1279 184210 : move16();
1280 :
1281 : /*Number of iterations*/
1282 954971 : FOR( k = 0; k < config->nbiter; k++ )
1283 : {
1284 770761 : E_ACELP_setup_pulse_search_pos( config, k, ipos );
1285 :
1286 : /* format of alp changes to Q(15-ALP2_E) */
1287 :
1288 770761 : pos = config->fixedpulses;
1289 770761 : move16();
1290 :
1291 770761 : IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
1292 : {
1293 731413 : ps = 0;
1294 731413 : move16();
1295 731413 : alp = 0;
1296 731413 : move16();
1297 731413 : set16_fx( vec, 0, L_SUBFR );
1298 : }
1299 39348 : ELSE IF( EQ_16( config->fixedpulses, 2 ) ) /* 2222 and 3322 */
1300 : {
1301 : /* first stage: fix 2 pulses */
1302 39343 : ind[0] = pos_max[ipos[0]];
1303 39343 : move16();
1304 39343 : ind[1] = pos_max[ipos[1]];
1305 39343 : move16();
1306 39343 : ps = add( dn[ind[0]], dn[ind[1]] );
1307 :
1308 : /*alp = rrixix[ipos[0]][ind[0] >> 2] + rrixix[ipos[1]][ind[1] >> 2] +
1309 : rrixiy[ipos[0]][((ind[0] >> 2) << 4) + (ind[1] >> 2)];*/
1310 :
1311 39343 : i = shr( ind[0], 2 );
1312 39343 : j = shr( ind[1], 2 );
1313 39343 : l = add( shl( i, 4 ), j );
1314 39343 : s = L_mult( rrixix[ipos[0]][i], _1_ ); /* Q9+Q12+1 */
1315 39343 : s = L_mac( s, rrixix[ipos[1]][j], _1_ ); /* Q9+Q12+1 */
1316 39343 : alp = mac_r( s, rrixiy[ipos[0]][l], _1_ ); /* Q9+Q12+1-16 */
1317 :
1318 39343 : p0 = h - ind[0]; /*Q12+scale*/
1319 39343 : if ( sign[ind[0]] < 0 )
1320 : {
1321 19238 : p0 = h_inv - ind[0]; /*Q12+scale*/
1322 : }
1323 :
1324 39343 : p1 = h - ind[1]; /*Q12+scale*/
1325 39343 : if ( sign[ind[1]] < 0 )
1326 : {
1327 19241 : p1 = h_inv - ind[1]; /*Q12+scale*/
1328 : }
1329 :
1330 2557295 : FOR( i = 0; i < L_SUBFR; i++ )
1331 : {
1332 2517952 : vec[i] = add( *p0++, *p1++ ); /*Q12+scale*/
1333 2517952 : move16();
1334 : }
1335 : }
1336 : ELSE /* 3333 and above */
1337 : {
1338 : /* first stage: fix 4 pulses */
1339 :
1340 5 : ind[0] = pos_max[ipos[0]]; /*Q0*/
1341 5 : move16();
1342 5 : ind[1] = pos_max[ipos[1]]; /*Q0*/
1343 5 : move16();
1344 5 : ind[2] = pos_max[ipos[2]]; /*Q0*/
1345 5 : move16();
1346 5 : ind[3] = pos_max[ipos[3]]; /*Q0*/
1347 5 : move16();
1348 :
1349 : /*ps = dn[ind[0]] + dn[ind[1]] + dn[ind[2]] + dn[ind[3]];*/
1350 5 : ps = add( add( add( dn[ind[0]], dn[ind[1]] ), dn[ind[2]] ), dn[ind[3]] );
1351 :
1352 5 : p0 = h - ind[0]; /*Q12+scale*/
1353 5 : if ( sign[ind[0]] < 0 )
1354 : {
1355 0 : p0 = h_inv - ind[0]; /*Q12+scale*/
1356 : }
1357 :
1358 5 : p1 = h - ind[1]; /*Q12+scale*/
1359 5 : if ( sign[ind[1]] < 0 )
1360 : {
1361 0 : p1 = h_inv - ind[1]; /*Q12+scale*/
1362 : }
1363 :
1364 5 : p2 = h - ind[2]; /*Q12+scale*/
1365 5 : if ( sign[ind[2]] < 0 )
1366 : {
1367 5 : p2 = h_inv - ind[2]; /*Q12+scale*/
1368 : }
1369 :
1370 5 : p3 = h - ind[3]; /*Q12+scale*/
1371 5 : if ( sign[ind[3]] < 0 )
1372 : {
1373 5 : p3 = h_inv - ind[3]; /*Q12+scale*/
1374 : }
1375 :
1376 325 : FOR( i = 0; i < L_SUBFR; i++ )
1377 : {
1378 320 : vec[i] = add( add( add( *p0++, *p1++ ), *p2++ ), *p3++ ); /*Q12+scale*/
1379 320 : move16();
1380 : }
1381 :
1382 5 : L_tmp = L_mult( vec[0], vec[0] ); /*Q25+2*scale*/
1383 320 : FOR( i = 1; i < L_SUBFR; i++ )
1384 : #ifdef ISSUE_1867_replace_overflow_libenc
1385 315 : L_tmp = L_mac_sat( L_tmp, vec[i], vec[i] ); /*Q25+2*scale*/
1386 : #else
1387 : L_tmp = L_mac_o( L_tmp, vec[i], vec[i], &Overflow ); /*Q25+2*scale*/
1388 : #endif
1389 :
1390 5 : alp = round_fx( L_shr( L_tmp, 3 ) ); /*Q6+2*scale*/
1391 :
1392 : /*alp *= 0.5F; */
1393 : }
1394 :
1395 : /* other stages of 2 pulses */
1396 770761 : st = 0;
1397 770761 : move16();
1398 2955359 : FOR( j = pos; j < nb_pulse; j += 2 )
1399 : {
1400 2184598 : IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */
1401 : {
1402 : /*
1403 : * Calculate correlation of all possible positions
1404 : * of the next 2 pulses with previous fixed pulses.
1405 : * Each pulse can have 16 possible positions.
1406 : */
1407 1780225 : E_ACELP_h_vec_corr1_fx( h, vec, ipos[j], sign, rrixix, cor_x, dn2_pos, config->nbpos[st] );
1408 :
1409 1780225 : E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
1410 :
1411 : /*
1412 : * Find best positions of 2 pulses.
1413 : */
1414 1780225 : E_ACELP_2pulse_search( config->nbpos[st], ipos[j], ipos[j + 1], &ps, &alp,
1415 1780225 : &ind[j], &ind[j + 1], dn, dn2_pos, cor_x, cor_y, rrixiy );
1416 : }
1417 : ELSE /* single pulse search */
1418 : {
1419 404373 : E_ACELP_h_vec_corr2_fx( h, vec, ipos[j], sign, rrixix, cor_x );
1420 :
1421 404373 : E_ACELP_h_vec_corr2_fx( h, vec, ipos[j + 1], sign, rrixix, cor_y );
1422 :
1423 404373 : E_ACELP_1pulse_search( &ipos[j], &ps, &alp,
1424 404373 : &ind[j], dn, cor_x, cor_y );
1425 : }
1426 :
1427 2184598 : IF( GT_16( nb_pulse_m2, j ) )
1428 : {
1429 1413837 : p0 = h - ind[j]; /*Q12+scale*/
1430 1413837 : if ( sign[ind[j]] < 0 )
1431 : {
1432 715792 : p0 = h_inv - ind[j]; /*Q12+scale*/
1433 : }
1434 :
1435 1413837 : p1 = h - ind[j + 1]; /*Q12+scale*/
1436 1413837 : if ( sign[ind[j + 1]] < 0 )
1437 : {
1438 713737 : p1 = h_inv - ind[j + 1]; /*Q12+scale*/
1439 : }
1440 :
1441 :
1442 91899405 : FOR( i = 0; i < L_SUBFR; i++ )
1443 : {
1444 90485568 : tmp = add( *p0++, *p1++ );
1445 : #ifdef ISSUE_1867_replace_overflow_libenc
1446 90485568 : vec[i] = add_sat( vec[i], tmp ); /* can saturate here. */
1447 : #else
1448 : vec[i] = add_o( vec[i], tmp, &Overflow ); /* can saturate here. */
1449 : #endif
1450 90485568 : move16();
1451 : }
1452 : }
1453 2184598 : st = add( st, 1 );
1454 : }
1455 :
1456 : /* memorise the best codevector */
1457 :
1458 : /*ps = ps * ps; MULT(1);*/
1459 770761 : ps = mult( ps, ps );
1460 : /*s = (alpk * ps) - (psk * alp); MULT(2);ADD(1);*/
1461 770761 : s = L_msu( L_mult( alpk, ps ), psk, alp ); /*Q9+Q6+1=Q16*/
1462 :
1463 770761 : if ( psk < 0 )
1464 : {
1465 184210 : s = 1;
1466 184210 : move32();
1467 : }
1468 770761 : IF( s > 0 )
1469 : {
1470 366507 : psk = ps;
1471 366507 : move16();
1472 366507 : alpk = alp;
1473 366507 : move16();
1474 366507 : Copy( ind, codvec, nb_pulse ); /*Q0*/
1475 366507 : check = 1; /* debug code not instrumented */
1476 : }
1477 : }
1478 :
1479 184210 : assert( check ); /* debug code not instrumented */
1480 :
1481 : /*
1482 : * Build the codeword, the filtered codeword and index of codevector, as well as store weighted correlations.
1483 : */
1484 :
1485 184210 : E_ACELP_build_code( nb_pulse, codvec, sign, code, ind );
1486 :
1487 184210 : set16_fx( y, 0, L_SUBFR );
1488 1182787 : FOR( k = 0; k < nb_pulse; ++k )
1489 : {
1490 998577 : i = codvec[k]; /*Q0*/
1491 998577 : move16();
1492 998577 : p0 = h_inv - i; /*Q12+scale*/
1493 998577 : if ( sign[i] > 0 )
1494 : {
1495 493976 : p0 -= 2 * L_SUBFR;
1496 : }
1497 64907505 : FOR( i = 0; i < L_SUBFR; i++ )
1498 : {
1499 : #ifdef ISSUE_1867_replace_overflow_libenc
1500 63908928 : y[i] = add_sat( y[i], *p0++ ); /*Q12+scale*/
1501 : #else
1502 : y[i] = add_o( y[i], *p0++, &Overflow ); /*Q12+scale*/
1503 : #endif
1504 63908928 : move16();
1505 : }
1506 : }
1507 184210 : return;
1508 : }
1509 : /*
1510 : * E_ACELP_4t_fx
1511 : *
1512 : * Parameters:
1513 : * dn I: corr. between target and h[].
1514 : * cn I: residual after Word32 term prediction
1515 : * H I: impulse response of weighted synthesis filter (Q12)
1516 : * code O: algebraic (fixed) codebook excitation (Q9)
1517 : * y O: filtered fixed codebook excitation (Q9)
1518 : * nbbits I: 20, 36, 44, 52, 64, 72 or 88 bits
1519 : * mode I: speech mode
1520 : * _index O: index
1521 : *
1522 : * Function:
1523 : * 20, 36, 44, 52, 64, 72, 88 bits algebraic codebook.
1524 : * 4 tracks x 16 positions per track = 64 samples.
1525 : *
1526 : * 20 bits 5 + 5 + 5 + 5 --> 4 pulses in a frame of 64 samples.
1527 : * 36 bits 9 + 9 + 9 + 9 --> 8 pulses in a frame of 64 samples.
1528 : * 44 bits 13 + 9 + 13 + 9 --> 10 pulses in a frame of 64 samples.
1529 : * 52 bits 13 + 13 + 13 + 13 --> 12 pulses in a frame of 64 samples.
1530 : * 64 bits 2 + 2 + 2 + 2 + 14 + 14 + 14 + 14 -->
1531 : * 16 pulses in a frame of 64 samples.
1532 : * 72 bits 10 + 2 + 10 + 2 + 10 + 14 + 10 + 14 -->
1533 : * 18 pulses in a frame of 64 samples.
1534 : * 88 bits 11 + 11 + 11 + 11 + 11 + 11 + 11 + 11 -->
1535 : * 24 pulses in a frame of 64 samples.
1536 : *
1537 : * All pulses can have two (2) possible amplitudes: +1 or -1.
1538 : * Each pulse can sixteen (16) possible positions.
1539 : *
1540 : * Returns:
1541 : * void
1542 : */
1543 514242 : void E_ACELP_4t_fx(
1544 : Word16 dn[], /*Qdn*/
1545 : Word16 cn[] /* Q_xn */,
1546 : Word16 H[], /*Q12*/
1547 : Word16 R[], /*Qx*/
1548 : Word8 acelpautoc, /*Q0*/
1549 : Word16 code[], /*Q9*/
1550 : Word16 cdk_index, /*Q0*/
1551 : Word16 _index[], /*Q0*/
1552 : const Word16 L_frame, /*Q0*/
1553 : const Word16 last_L_frame, /*Q0*/
1554 : const Word32 total_brate, /*Q0*/
1555 : const Word16 i_subfr, /*Q0*/
1556 : const Word16 cmpl_flag /*Q0*/
1557 : ,
1558 : const Word16 element_mode /*Q0*/
1559 : )
1560 : {
1561 : PulseConfig config;
1562 : Word16 ind[NPMAXPT * 4];
1563 : Word16 y[L_SUBFR];
1564 :
1565 514242 : move16();
1566 514242 : move16();
1567 514242 : move16();
1568 514242 : move16();
1569 514242 : move16();
1570 514242 : move16();
1571 514242 : move16();
1572 514242 : move16();
1573 514242 : move16();
1574 514242 : move16();
1575 514242 : move16();
1576 514242 : move16();
1577 514242 : move16();
1578 514242 : move16();
1579 514242 : move16();
1580 514242 : move16();
1581 514242 : memcpy( &config, &PulseConfTable[cdk_index], sizeof( PulseConfTable[cdk_index] ) );
1582 :
1583 :
1584 514242 : if ( cmpl_flag > 0 )
1585 : {
1586 10365 : config.nbiter = cmpl_flag;
1587 10365 : move16();
1588 : }
1589 514242 : test();
1590 514242 : test();
1591 514242 : IF( NE_16( L_frame, last_L_frame ) && EQ_32( total_brate, ACELP_24k40 ) && LT_32( i_subfr, 5 * L_SUBFR ) )
1592 : {
1593 0 : config.nbiter = sub( config.nbiter, 1 );
1594 0 : config.nbiter = s_max( config.nbiter, 1 );
1595 : }
1596 :
1597 514242 : IF( acelpautoc )
1598 : {
1599 333696 : E_ACELP_4tsearchx_fx( dn, cn, R, code, &config, ind, element_mode );
1600 : }
1601 : ELSE
1602 : {
1603 180546 : E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y, element_mode );
1604 : }
1605 514242 : E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index );
1606 514242 : return;
1607 : }
1608 578907 : static void E_ACELP_indexing_shift(
1609 : Word16 wordcnt, /* i: 16-bit word count including the newly shifted-in bits Q0*/
1610 : Word16 shift_bits, /* i: number of bits to shift in from the lsb Q0*/
1611 : UWord16 lsb_bits, /* i: bits to shift in from the lsb Q0*/
1612 : const UWord16 src[], /* i: source buffer Q0*/
1613 : UWord16 dst[] /* o: destination buffer Q(shift_bits)*/
1614 : )
1615 : {
1616 : Word16 right_shift, i;
1617 :
1618 578907 : assert( shift_bits <= 16 );
1619 :
1620 578907 : right_shift = sub( 16, shift_bits );
1621 :
1622 1853050 : FOR( i = sub( wordcnt, 1 ); i > 0; --i )
1623 : {
1624 1274143 : dst[i] = s_or( lshl( src[i], shift_bits ), lshr( src[i - 1], right_shift ) ); /*Q0+shift_bits*/
1625 1274143 : move16();
1626 : }
1627 578907 : dst[i] = s_or( lshl( src[i], shift_bits ), lsb_bits ); /*Q(shift_bits)*/
1628 578907 : move16();
1629 578907 : return;
1630 : }
1631 :
1632 : #define MAX_IDX_LEN 9
1633 :
1634 578907 : Word16 E_ACELP_indexing_fx(
1635 : const Word16 code[], /*Q9*/
1636 : const PulseConfig *config,
1637 : Word16 num_tracks, /*Q0*/
1638 : Word16 prm[] /*Q(shift_bits)*/ )
1639 : {
1640 : Word16 track, shift_bits;
1641 : Word16 p[NB_TRACK_FCB_4T], wordcnt;
1642 : UWord32 s[NB_TRACK_FCB_4T], n[NB_TRACK_FCB_4T];
1643 : UWord16 idx[MAX_IDX_LEN];
1644 : Word16 saved_bits;
1645 :
1646 578907 : assert( num_tracks == NB_TRACK_FCB_4T );
1647 :
1648 578907 : saved_bits = 0;
1649 578907 : move16();
1650 :
1651 : /*
1652 : * Code state of pulses of all tracks
1653 : * */
1654 578907 : wordcnt = shr( add( config->bits, 15 ), 4 ); /* ceil(bits/16) */
1655 :
1656 578907 : set16_fx( (Word16 *) idx, 0, wordcnt );
1657 :
1658 578907 : IF( EQ_16( config->bits, 43 ) ) /* EVS pulse indexing */
1659 : {
1660 33676 : saved_bits = E_ACELP_code43bit_fx( code, s, p, idx );
1661 : }
1662 : ELSE
1663 : {
1664 2726155 : FOR( track = 0; track < num_tracks; track++ )
1665 : {
1666 : /* Code track of length 2^4 where step between tracks is 4. */
1667 2180924 : E_ACELP_codearithp_fx( code + track, &n[track], &s[track], &p[track] );
1668 : }
1669 545231 : fcb_pulse_track_joint_fx( idx, wordcnt, s, p, num_tracks );
1670 : }
1671 :
1672 : /* check if we need to code track positions */
1673 578907 : track = 0;
1674 578907 : move16();
1675 578907 : shift_bits = 0;
1676 578907 : move16();
1677 578907 : SWITCH( config->codetrackpos )
1678 : {
1679 74714 : case TRACKPOS_FIXED_TWO:
1680 : /* Code position of consecutive tracks with single extra pulses */
1681 : /* Find track with one pulse less. */
1682 74714 : if ( NE_16( p[0], p[1] ) )
1683 : {
1684 : /* Either 0110 or 1001 */
1685 37198 : track = 1;
1686 37198 : move16();
1687 : }
1688 74714 : if ( GT_16( p[3], p[1] ) )
1689 : {
1690 37535 : track = add( track, 2 );
1691 37535 : move16();
1692 : }
1693 74714 : shift_bits = 2;
1694 74714 : move16();
1695 74714 : BREAK;
1696 :
1697 67326 : case TRACKPOS_FREE_THREE:
1698 : /* Code position of track with one pulse less than others */
1699 : /* Find track with one pulse less. */
1700 67326 : if ( LT_16( p[1], p[0] ) )
1701 : {
1702 16467 : track = 1;
1703 16467 : move16();
1704 : }
1705 67326 : if ( LT_16( p[2], p[0] ) )
1706 : {
1707 17035 : track = 2;
1708 17035 : move16();
1709 : }
1710 67326 : if ( LT_16( p[3], p[0] ) )
1711 : {
1712 17263 : track = 3;
1713 17263 : move16();
1714 : }
1715 67326 : shift_bits = 2;
1716 67326 : move16();
1717 67326 : BREAK;
1718 :
1719 22477 : case TRACKPOS_FREE_ONE:
1720 : /* Code position of track with one pulse less than others */
1721 : /* Find track with one pulse less. */
1722 22477 : if ( GT_16( p[1], p[0] ) )
1723 : {
1724 5878 : track = 1;
1725 5878 : move16();
1726 : }
1727 22477 : if ( GT_16( p[2], p[0] ) )
1728 : {
1729 5475 : track = 2;
1730 5475 : move16();
1731 : }
1732 22477 : if ( GT_16( p[3], p[0] ) )
1733 : {
1734 5767 : track = 3;
1735 5767 : move16();
1736 : }
1737 22477 : shift_bits = 2;
1738 22477 : move16();
1739 22477 : BREAK;
1740 :
1741 414390 : case TRACKPOS_FIXED_EVEN:
1742 : case TRACKPOS_FIXED_FIRST:
1743 414390 : BREAK;
1744 :
1745 0 : default:
1746 0 : printf( "Codebook mode not implemented.\n" );
1747 0 : assert( 0 ); /* mode not yet implemented*/
1748 : BREAK;
1749 : }
1750 :
1751 578907 : E_ACELP_indexing_shift( wordcnt, shift_bits, track, idx, (UWord16 *) prm );
1752 :
1753 578907 : return saved_bits;
1754 : }
1755 :
1756 : /*--------------------------------------------------------------------------*
1757 : * E_ACELP_adaptive_codebook
1758 : *
1759 : * Find adaptive codebook.
1760 : *--------------------------------------------------------------------------*/
1761 3060 : void E_ACELP_adaptive_codebook(
1762 : Word16 *exc, /* i/o: pointer to the excitation frame Q_new */
1763 : Word16 T0, /* i : integer pitch lag Q0 */
1764 : Word16 T0_frac, /* i : fraction of lag Q0 */
1765 : Word16 T0_res, /* i : pitch resolution Q0 */
1766 : Word16 T0_res_max, /* i : maximum pitch resolution Q0 */
1767 : Word16 mode, /* i : filtering mode (0: no, 1: yes, 2: adaptive) Q0 */
1768 : Word16 i_subfr, /* i : subframe index */
1769 : Word16 L_subfr, /* i : subframe length Q0 */
1770 : Word16 L_frame, /* i : subframe length Q0 */
1771 : Word16 *h1, /* i : impulse response of weighted synthesis filter 1Q14+shift */
1772 : Word16 clip_gain, /* i : flag to indicate ??? Q14 */
1773 : Word16 *xn, /* i : Close-loop Pitch search target vector Q_xn */
1774 : Word16 *y1, /* o : zero-memory filtered adaptive excitation Q_xn */
1775 : ACELP_CbkCorr *g_corr, /* o : ACELP correlation values */
1776 : Word16 **pt_indice, /* i/o: quantization indices pointer */
1777 : Word16 *pitch_gain, /* o : adaptive codebook gain 1Q14 */
1778 : Word16 exp_xn /* i : exponent of xn (Q_xn-15) */
1779 : ,
1780 : Word16 rf_mode,
1781 : Word16 rf_coder_type,
1782 : Word16 *lp_select
1783 :
1784 : )
1785 : {
1786 : Word16 y2[L_SUBFR], xn2[L_SUBFR], code[L_SUBFR];
1787 : ACELP_CbkCorr g_corr2;
1788 3060 : Word16 gain1 = 0, gain2 = 0, fac_m, fac_n;
1789 3060 : move16();
1790 3060 : move16();
1791 : Word16 i, select, exp_ener;
1792 : Word32 L_tmp, L_ener;
1793 : const Word16 *pitch_inter;
1794 : Word16 pit_L_interpol, pit_up_samp;
1795 3060 : Word16 use_prev_sf_pit_gain = 0;
1796 3060 : move16();
1797 :
1798 3060 : test();
1799 3060 : IF( EQ_16( rf_mode, 1 ) && EQ_16( rf_coder_type, 100 ) )
1800 : {
1801 0 : use_prev_sf_pit_gain = 1;
1802 0 : move16();
1803 : }
1804 :
1805 : BASOP_SATURATE_ERROR_ON_EVS;
1806 :
1807 3060 : L_ener = L_deposit_l( 0 );
1808 :
1809 : /* find pitch excitation */
1810 : /*for &exc[i_subfr]*/
1811 3060 : IF( EQ_16( T0_res, shr( T0_res_max, 1 ) ) )
1812 : {
1813 2948 : T0_frac = shl( T0_frac, 1 ); /*Q0*/
1814 : }
1815 :
1816 3060 : test();
1817 3060 : IF( EQ_16( T0_res_max, 6 ) && rf_mode == 0 )
1818 : {
1819 3060 : pitch_inter = pitch_inter6_2; /*Q14*/
1820 3060 : pit_L_interpol = PIT_L_INTERPOL6_2;
1821 3060 : move16();
1822 3060 : pit_up_samp = PIT_UP_SAMP6;
1823 3060 : move16();
1824 : }
1825 : ELSE
1826 : {
1827 0 : pitch_inter = pitch_inter4_2; /*Q14*/
1828 0 : pit_L_interpol = L_INTERPOL2;
1829 0 : move16();
1830 0 : pit_up_samp = PIT_UP_SAMP;
1831 0 : move16();
1832 : }
1833 :
1834 3060 : pred_lt4( &exc[i_subfr], &exc[i_subfr], T0, T0_frac, L_SUBFR + 1, pitch_inter, pit_L_interpol, pit_up_samp );
1835 :
1836 3060 : test();
1837 3060 : IF( EQ_16( mode, NORMAL_OPERATION ) || ( EQ_16( mode, FULL_BAND ) ) )
1838 : {
1839 1350 : E_UTIL_f_convolve( &exc[i_subfr], h1, y1, L_subfr );
1840 :
1841 1350 : IF( use_prev_sf_pit_gain == 0 )
1842 : {
1843 1350 : gain1 = E_ACELP_xy1_corr_fx( xn, y1, g_corr, 1, L_subfr, exp_xn ); /*Q14*/
1844 :
1845 : /* clip gain if necessary to avoid problem at decoder */
1846 1350 : test();
1847 1350 : IF( clip_gain && GT_16( gain1, 15565 /*0.95 Q14*/ ) )
1848 : {
1849 0 : gain1 = 15565 /*0.95f Q14*/;
1850 0 : move16();
1851 : }
1852 1350 : *pitch_gain = gain1; /*Q14*/
1853 1350 : move16();
1854 : }
1855 :
1856 : /* find energy of new target xn2[] */
1857 1350 : E_ACELP_codebook_target_update_fx( xn, xn2, y1, gain1, L_subfr );
1858 1350 : L_ener = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31-exp_ener*/
1859 1350 : L_ener = L_shr( L_ener, sub( 31, exp_ener ) ); /*Q0*/
1860 : }
1861 :
1862 : /*-----------------------------------------------------------------*
1863 : * - find pitch excitation filtered by 1st order LP filter. *
1864 : * - find filtered pitch exc. y2[]=exc[] convolved with h1[]) *
1865 : * - compute pitch gain2 *
1866 : *-----------------------------------------------------------------*/
1867 3060 : test();
1868 3060 : IF( EQ_16( mode, NORMAL_OPERATION ) || EQ_16( mode, LOW_PASS ) )
1869 : {
1870 : /* find pitch excitation with lp filter */
1871 3060 : fac_m = 20972 /*0.64f Q15*/;
1872 3060 : move16();
1873 3060 : if ( EQ_16( L_frame, L_FRAME16k ) )
1874 : {
1875 3060 : fac_m = 19005 /*0.58f Q15*/;
1876 3060 : move16();
1877 : }
1878 : /* fac_n = 0.5*(1.0-fac_m); */
1879 3060 : fac_n = mult_r( sub( 0x7FFF, fac_m ), 0x4000 ); /*Q15*/
1880 198900 : FOR( i = 0; i < L_subfr; i++ )
1881 : {
1882 195840 : L_tmp = L_mult( fac_n, exc[i - 1 + i_subfr] ); /*Q_new+Q16*/
1883 195840 : L_tmp = L_mac( L_tmp, fac_m, exc[i + 0 + i_subfr] ); /*Q_new+Q16*/
1884 195840 : code[i] = mac_r( L_tmp, fac_n, exc[i + 1 + i_subfr] ); /*Q_new*/
1885 195840 : move16();
1886 : }
1887 3060 : E_UTIL_f_convolve( code, h1, y2, L_subfr );
1888 3060 : gain2 = E_ACELP_xy1_corr_fx( xn, y2, &g_corr2, 1, L_subfr, exp_xn ); /*Q14*/
1889 :
1890 : /* clip gain if necessary to avoid problem at decoder */
1891 3060 : test();
1892 3060 : IF( clip_gain && GT_16( gain2, 15565 /*0.95 Q14*/ ) )
1893 : {
1894 0 : gain2 = 15565 /*0.95f Q14*/;
1895 0 : move16();
1896 : }
1897 :
1898 : /* find energy of new target xn2[] */
1899 3060 : E_ACELP_codebook_target_update_fx( xn, xn2, y2, gain2, L_subfr );
1900 3060 : L_tmp = Dot_product12_offs( xn2, xn2, L_subfr, &exp_ener, 0 ); /*Q31 - exp_ener*/
1901 3060 : L_tmp = L_shr( L_tmp, sub( 31, exp_ener ) ); /*Q0*/
1902 :
1903 : /*-----------------------------------------------------------------*
1904 : * use the best prediction (minimise quadratic error). *
1905 : *-----------------------------------------------------------------*/
1906 3060 : test();
1907 3060 : IF( EQ_16( mode, LOW_PASS ) || LT_32( L_tmp, L_ener ) )
1908 : {
1909 : /* use the lp filter for pitch excitation prediction */
1910 2646 : select = LOW_PASS;
1911 2646 : move16();
1912 2646 : Copy( code, &exc[i_subfr], L_subfr ); /*Q_new*/
1913 2646 : Copy( y2, y1, L_subfr ); /*Q_xn*/
1914 2646 : *pitch_gain = gain2; /*Q14*/
1915 2646 : move16();
1916 2646 : g_corr->y1y1 = g_corr2.y1y1;
1917 2646 : move16();
1918 2646 : g_corr->xy1 = g_corr2.xy1;
1919 2646 : move16();
1920 2646 : g_corr->y1y1_e = g_corr2.y1y1_e;
1921 2646 : move16();
1922 2646 : g_corr->xy1_e = g_corr2.xy1_e;
1923 2646 : move16();
1924 : }
1925 : ELSE
1926 : {
1927 : /* no filter used for pitch excitation prediction */
1928 414 : select = FULL_BAND;
1929 414 : move16();
1930 414 : *pitch_gain = gain1; /*Q14*/
1931 414 : move16();
1932 : }
1933 :
1934 3060 : IF( EQ_16( mode, NORMAL_OPERATION ) )
1935 : {
1936 1350 : **pt_indice = select;
1937 1350 : ( *pt_indice )++;
1938 1350 : move16();
1939 : }
1940 : }
1941 : ELSE
1942 : {
1943 : /* no filter used for pitch excitation prediction */
1944 0 : select = FULL_BAND;
1945 0 : move16();
1946 : }
1947 3060 : *lp_select = select;
1948 3060 : move16();
1949 :
1950 : BASOP_SATURATE_ERROR_OFF_EVS;
1951 3060 : }
1952 :
1953 :
1954 : /*--------------------------------------------------------------------------*
1955 : * E_ACELP_innovative_codebook_fx
1956 : *
1957 : * Find innovative codebook.
1958 : *--------------------------------------------------------------------------*/
1959 3060 : void E_ACELP_innovative_codebook_fx(
1960 : Word16 *exc, /* i : pointer to the excitation frame Q_new */
1961 : Word16 T0, /* i : integer pitch lag Q0 */
1962 : Word16 T0_frac, /* i : fraction of lag Q0 */
1963 : Word16 T0_res, /* i : pitch resolution Q0 */
1964 : Word16 pitch_gain, /* i : adaptive codebook gain 1Q14 */
1965 : Word16 tilt_code, /* i : tilt factor Q15 */
1966 : ACELP_config *acelp_cfg, /* i/o: configuration of the ACELP */
1967 : Word16 i_subfr, /* i : subframe index */
1968 : const Word16 *Aq, /* i : quantized LPC coefficients 3Q12 */
1969 : Word16 *h1, /* i : impulse response of weighted synthesis filter 1Q14+shift */
1970 : Word16 *xn, /* i : Close-loop Pitch search target vector Q_xn */
1971 : Word16 *cn, /* i : Innovative codebook search target vector Q_new */
1972 : Word16 *y1, /* i : zero-memory filtered adaptive excitation Q_xn */
1973 : Word16 *y2, /* o : zero-memory filtered algebraic excitation Q9 */
1974 : Word8 acelpautoc, /* i : autocorrelation mode enabled */
1975 : Word16 **pt_indice, /* i/o: quantization indices pointer */
1976 : Word16 *code, /* o : innovative codebook Q9 Q9 */
1977 : Word16 shift, /* i : Scaling to get 12 bits */
1978 : const Word16 L_frame, /* i : length of the frame Q0*/
1979 : const Word16 last_L_frame, /* i : length of the last frame Q0*/
1980 : const Word32 total_brate /* i : ttoal bit-rate Q0*/
1981 : )
1982 : {
1983 : Word16 xn2[L_SUBFR] /* Q_xn */, cn2[L_SUBFR] /* Q_xn */, dn[L_SUBFR] /* Rw2*cn2 */, h2[L_SUBFR] /* 4Q11 */;
1984 : Word16 Rw2[L_SUBFR];
1985 : Word16 pitch, idx;
1986 :
1987 :
1988 3060 : pitch = T0;
1989 3060 : move16();
1990 3060 : idx = shr( i_subfr, 6 );
1991 3060 : if ( GT_16( T0_frac, shr( T0_res, 1 ) ) )
1992 : {
1993 729 : pitch = add( pitch, 1 );
1994 : }
1995 :
1996 : BASOP_SATURATE_ERROR_ON_EVS;
1997 :
1998 : /* Update target vector for ACELP codebook search */
1999 3060 : E_ACELP_codebook_target_update_fx( xn, xn2, y1, pitch_gain, L_SUBFR );
2000 :
2001 : /* Include fixed-gain pitch contribution into impulse resp. h1[] */
2002 3060 : Copy_Scale_sig( h1, h2, L_SUBFR, sub( -3, shift ) ); /*h2 1Q14+shift -> 4Q11, 1bit of headroom for Residu and xh_corr*/
2003 :
2004 3060 : cb_shape_fx( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt,
2005 3060 : acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, h2, tilt_code, pitch, 1, L_SUBFR );
2006 :
2007 : /* Correlation between target xn2[] and impulse response h1[] */
2008 3060 : IF( acelpautoc )
2009 : {
2010 : /* h2: 4Q11, Rw2: (Rw2_e)Q */
2011 3060 : /* Rw2_e = */ E_ACELP_hh_corr( h2, Rw2, L_SUBFR, 3 );
2012 :
2013 3060 : E_ACELP_conv( xn2, h2, cn2 );
2014 :
2015 : /* dn_e -> Rw2_e*Q_xn */
2016 3060 : /*dn_e = */ E_ACELP_toeplitz_mul_fx( Rw2, cn2, dn, L_SUBFR, sub( (Word16) PulseConfTable[acelp_cfg->fixed_cdk_index[idx]].nb_pulse, 24 ) > 0 );
2017 : }
2018 : ELSE
2019 : {
2020 : BASOP_SATURATE_WARNING_OFF_EVS;
2021 0 : E_ACELP_codebook_target_update_fx( cn, cn2, &exc[i_subfr], pitch_gain, L_SUBFR );
2022 : BASOP_SATURATE_WARNING_ON_EVS;
2023 0 : Scale_sig( cn2, L_SUBFR, shift );
2024 0 : E_ACELP_xh_corr( xn2, dn, h2, L_SUBFR );
2025 : }
2026 :
2027 : /* Innovative codebook search */
2028 3060 : assert( acelp_cfg->fixed_cdk_index[idx] < ACELP_FIXED_CDK_NB );
2029 :
2030 3060 : E_ACELP_4t_fx( dn, cn2, h2, Rw2, acelpautoc, code, acelp_cfg->fixed_cdk_index[idx], *pt_indice, L_frame, last_L_frame, total_brate, i_subfr, 0, 0 );
2031 3060 : *pt_indice += 8;
2032 :
2033 : /* Generate weighted code */
2034 3060 : E_ACELP_weighted_code( code, h2, 11, y2 );
2035 :
2036 : /*-------------------------------------------------------*
2037 : * - Add the fixed-gain pitch contribution to code[]. *
2038 : *-------------------------------------------------------*/
2039 :
2040 3060 : cb_shape_fx( acelp_cfg->pre_emphasis, acelp_cfg->pitch_sharpening, acelp_cfg->phase_scrambling, acelp_cfg->formant_enh, acelp_cfg->formant_tilt,
2041 3060 : acelp_cfg->formant_enh_num, acelp_cfg->formant_enh_den, Aq, code, tilt_code, pitch, 1, L_SUBFR );
2042 :
2043 : BASOP_SATURATE_ERROR_OFF_EVS;
2044 3060 : return;
2045 : }
2046 :
2047 :
2048 : /*--------------------------------------------------------------------------*
2049 : * E_ACELP_codearithp_fx
2050 : *
2051 : * Fixed bit-length arithmetic coding of pulses
2052 : * v - (input) pulse vector
2053 : * ps - (output) encoded state
2054 : * n - (output) range of possible states (0...n-1)
2055 : * p - (output) number of pulses found
2056 : *--------------------------------------------------------------------------*/
2057 2180924 : static void E_ACELP_codearithp_fx( const Word16 v[] /*Q9*/, UWord32 *n /*Q0*/, UWord32 *ps /*Q0*/, Word16 *p /*Q0*/ )
2058 : {
2059 : Word16 k, nb_pulse, i, t, pos[NPMAXPT], posno;
2060 : Word16 sign, m;
2061 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2062 : UWord32 s;
2063 : #else
2064 : UWord64 W_s;
2065 : #endif
2066 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2067 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2068 : Flag Overflow = 0;
2069 : Flag Carry = 0;
2070 : #endif
2071 2180924 : move32();
2072 2180924 : move32();
2073 : #endif
2074 :
2075 : /* Collect different pulse positions to pos[], number of them to posno */
2076 2180924 : posno = 0;
2077 2180924 : move16();
2078 2180924 : t = 0;
2079 2180924 : move16();
2080 37075708 : FOR( k = 0; k < L_SUBFR; k += 4 )
2081 : {
2082 34894784 : if ( v[k] != 0 )
2083 : {
2084 5307237 : pos[posno++] = t;
2085 5307237 : move16();
2086 : }
2087 34894784 : t = add( t, 1 );
2088 34894784 : move16();
2089 34894784 : if ( sub( posno, NPMAXPT ) >= 0 )
2090 : {
2091 0 : BREAK;
2092 : }
2093 : }
2094 :
2095 : /* Iterate over the different pulse positions */
2096 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2097 : s = L_deposit_l( 0 );
2098 : #else
2099 2180924 : W_s = 0;
2100 : #endif
2101 2180924 : t = 0;
2102 2180924 : move16();
2103 2180924 : nb_pulse = 0;
2104 2180924 : move16();
2105 7488161 : FOR( k = 0; k < posno; ++k )
2106 : {
2107 5307237 : sign = shr( v[( pos[k] * 4 )], 9 ); /* sign with multiplicity Q0*/
2108 5307237 : m = abs_s( sign ); /* multiplicity */
2109 5307237 : nb_pulse = add( nb_pulse, m );
2110 : /* Code m-1 pulses */
2111 5627331 : FOR( i = 1; i < m; ++i )
2112 : {
2113 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2114 : Carry = 0;
2115 : #endif
2116 320094 : move32();
2117 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2118 : s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow );
2119 : #else
2120 320094 : W_s = W_add( W_s, pulsestostates[pos[k]][t] );
2121 : #endif
2122 320094 : t = add( t, 1 );
2123 320094 : if ( sub( t, NPMAXPT ) > 0 )
2124 : {
2125 0 : BREAK;
2126 : }
2127 : }
2128 :
2129 : /* Code sign */
2130 : /* We use L_add_c since we want to work with unsigned UWord32 */
2131 : /* Therefore, we have to clear carry */
2132 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2133 : Carry = 0;
2134 : #endif
2135 5307237 : move32();
2136 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2137 : s = L_lshl( s, 1 );
2138 : #else
2139 5307237 : W_s = W_lshl( W_s, 1 );
2140 : #endif
2141 5307237 : if ( sign < 0 )
2142 : {
2143 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2144 : s = L_add_co( s, 1, &Carry, &Overflow );
2145 : #else
2146 2686087 : W_s = W_add( W_s, 1 );
2147 : #endif
2148 : }
2149 :
2150 : /* Code last pulse */
2151 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2152 : Carry = 0;
2153 : #endif
2154 5307237 : move32();
2155 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2156 : s = L_add_co( s, pulsestostates[pos[k]][t], &Carry, &Overflow );
2157 : #else
2158 5307237 : W_s = W_add( W_s, pulsestostates[pos[k]][t] );
2159 : #endif
2160 5307237 : t = add( t, 1 );
2161 : }
2162 :
2163 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2164 : *ps = s; /*Q0*/
2165 : #else
2166 2180924 : *ps = (UWord32) W_s; /*Q0*/
2167 : #endif
2168 2180924 : move32();
2169 2180924 : *n = L_deposit_l( 0 );
2170 2180924 : if ( nb_pulse )
2171 : {
2172 2157323 : *n = pulsestostates[NB_POS_FCB_4T][nb_pulse - 1]; /*Q0*/
2173 2157323 : move32();
2174 : }
2175 :
2176 2180924 : *p = nb_pulse; /*Q0*/
2177 2180924 : move16();
2178 2180924 : return;
2179 : }
2180 :
2181 545231 : void fcb_pulse_track_joint_fx( UWord16 *idxs /*Q0*/, Word16 wordcnt /*Q0*/, UWord32 *index_n /*Q0*/, Word16 *pulse_num /*Q0*/, Word16 track_num /*Q0*/ )
2182 : {
2183 : Word16 hi_to_low[10];
2184 : UWord32 index, index_mask;
2185 : Word32 indx_tmp;
2186 : Word16 indx_flag, indx_flag_1;
2187 : Word16 track, track_num1, pulse_num0, pulse_num1;
2188 : Word16 indx_flag_2;
2189 :
2190 545231 : Copy( hi_to_low_tmpl, hi_to_low, 10 ); /*Q0*/
2191 :
2192 545231 : indx_flag = 0;
2193 545231 : move16();
2194 545231 : indx_flag_1 = 0;
2195 545231 : move16();
2196 545231 : indx_flag_2 = 0;
2197 545231 : move16();
2198 :
2199 2726155 : FOR( track = 0; track < track_num; track++ )
2200 : {
2201 2180924 : indx_flag = add( indx_flag, shr( pulse_num[track], 2 ) );
2202 2180924 : indx_flag_1 = add( indx_flag_1, shr( pulse_num[track], 1 ) );
2203 2180924 : indx_flag_2 = add( indx_flag_2, shr( pulse_num[track], 3 ) );
2204 : }
2205 :
2206 545231 : IF( GE_16( indx_flag_2, 1 ) )
2207 : {
2208 46 : hi_to_low[7] = 9;
2209 46 : move16();
2210 46 : index_mask = 0xFFFFFF; /*Q0*/
2211 46 : move32();
2212 : }
2213 : ELSE
2214 : {
2215 545185 : if ( LT_16( indx_flag, track_num ) )
2216 : {
2217 462561 : hi_to_low[4] = 1;
2218 462561 : move16();
2219 : }
2220 545185 : index_mask = L_shr( 0xFFFF, sub( 9, hi_to_low[4] ) ); /*Q0*/
2221 : }
2222 :
2223 545231 : IF( GE_16( indx_flag_1, track_num ) )
2224 : {
2225 345349 : indx_tmp = L_deposit_l( 0 );
2226 345349 : index = L_shr( index_n[0], low_len[pulse_num[0]] ); /*Q0*/
2227 1381396 : FOR( track = 1; track < track_num; track++ )
2228 : {
2229 1036047 : pulse_num0 = pulse_num[track - 1]; /*Q0*/
2230 1036047 : move16();
2231 1036047 : pulse_num1 = pulse_num[track]; /*Q0*/
2232 1036047 : move16();
2233 1036047 : indx_tmp = L_lshr( index_n[track], low_len[pulse_num1] ); /*Q0*/
2234 : /* index = index * indx_fact[pulse_num1] + indx_tmp; */
2235 1036047 : index = UL_Mpy_32_32( index, UL_deposit_l( indx_fact[pulse_num1] ) ); /*Q0*/
2236 1036047 : index = UL_addNsD( index, indx_tmp );
2237 1036047 : index_n[track - 1] = L_add( L_and( index_n[track - 1], low_mask[pulse_num0] ),
2238 1036047 : L_and( L_lshl( index, low_len[pulse_num0] ), index_mask ) ); /*Q0*/
2239 :
2240 1036047 : index = L_lshr( index, hi_to_low[pulse_num0] );
2241 : }
2242 345349 : track_num1 = sub( track_num, 1 );
2243 345349 : move16();
2244 345349 : pulse_num1 = pulse_num[track_num1]; /*Q0*/
2245 345349 : move16();
2246 345349 : index_n[track_num1] = L_and( L_add( L_and( index_n[track_num1], low_mask[pulse_num1] ),
2247 345349 : L_lshl( index, low_len[pulse_num1] ) ),
2248 : index_mask ); /*Q0*/
2249 345349 : index = L_lshr( index, hi_to_low[pulse_num1] );
2250 345349 : IF( GE_16( indx_flag, track_num ) )
2251 : {
2252 82670 : IF( GE_16( indx_flag_2, 1 ) )
2253 : {
2254 46 : idxs[0] = extract_l( index_n[0] );
2255 46 : idxs[1] = extract_l( L_add( L_lshl( index_n[1], 8 ), L_lshr( index_n[0], 16 ) ) );
2256 46 : idxs[2] = extract_l( L_lshr( index_n[1], 8 ) );
2257 46 : idxs[3] = extract_l( index_n[2] );
2258 46 : idxs[4] = extract_l( L_add( L_lshl( index_n[3], 8 ), L_lshr( index_n[2], 16 ) ) );
2259 46 : idxs[5] = extract_l( L_lshr( index_n[3], 8 ) );
2260 46 : track = 6;
2261 46 : move16();
2262 : }
2263 : ELSE
2264 : {
2265 413120 : FOR( track = 0; track < track_num; track++ )
2266 : {
2267 330496 : idxs[track] = extract_l( index_n[track] );
2268 : }
2269 : }
2270 : }
2271 : ELSE
2272 : {
2273 262679 : idxs[0] = extract_l( L_add( L_lshl( index_n[0], 8 ), index_n[1] ) );
2274 262679 : idxs[1] = extract_l( L_add( L_lshl( index_n[2], 8 ), index_n[3] ) );
2275 262679 : track = 2;
2276 262679 : move16();
2277 : }
2278 : }
2279 : ELSE
2280 : {
2281 199882 : index = index_n[0]; /*Q0*/
2282 199882 : move32();
2283 799528 : FOR( track = 1; track < 4; track++ )
2284 : {
2285 599646 : pulse_num1 = pulse_num[track]; /*Q0*/
2286 599646 : index = L_add( L_lshl( index, index_len[pulse_num1] ), index_n[track] );
2287 : }
2288 199882 : track = 0;
2289 199882 : move16();
2290 : }
2291 1441123 : FOR( ; track < wordcnt; track++ )
2292 : {
2293 895892 : idxs[track] = extract_l( index );
2294 895892 : index = L_lshr( index, 16 );
2295 : }
2296 545231 : return;
2297 : }
|