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"
7 : //#include "prot_fx.h"
8 : #include "basop_util.h"
9 : #include "options.h"
10 : #include "rom_enc.h"
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 :
14 : /*--------------------------------------------------------------------------------------*
15 : * Local constant
16 : *--------------------------------------------------------------------------------------*/
17 :
18 : #define _1_Q11 ( 2048 /*1.0f Q11*/ ) /* 1.0f in 4Q11 */
19 : /*--------------------------------------------------------------------------------------*
20 : * E_ACELP_update_cor
21 : *--------------------------------------------------------------------------------------*/
22 8838575 : static void E_ACELP_update_cor_fx(
23 : const Word16 pos[], /* i Q0*/
24 : Word16 nb_pulse, /* i Q0*/
25 : const Word16 sign[], /* i Q13*/
26 : const Word16 R[], /* i Q9+scale*/
27 : const Word16 cor_in[], /* i Q9*/
28 : Word16 cor_out[] /* o Q9*/
29 : )
30 : {
31 : Word16 sign_x, sign_y;
32 : const Word16 *pRx, *pRy;
33 : Word16 i, tmp;
34 :
35 8838575 : IF( EQ_16( nb_pulse, 2 ) )
36 : {
37 : /* Update product of autocorrelation and already fixed pulses. with the
38 : * two newly found ones */
39 8180113 : sign_x = sign[pos[0]]; /*Q13*/
40 8180113 : move16();
41 8180113 : sign_y = sign[pos[1]]; /*Q13*/
42 8180113 : move16();
43 :
44 8180113 : IF( s_xor( sign_x, sign_y ) < 0 )
45 : {
46 4789415 : i = 1;
47 4789415 : move16();
48 4789415 : if ( sign_x > 0 )
49 : {
50 2402032 : i = 0;
51 2402032 : move16();
52 : }
53 4789415 : pRx = R - pos[i]; /*Q9+scale*/
54 4789415 : pRy = R - pos[1 - i]; /*Q9+scale*/
55 : /* different sign x and y */
56 311311975 : FOR( i = 0; i < L_SUBFR; i++ )
57 : {
58 306522560 : tmp = sub( pRx[i], pRy[i] );
59 306522560 : if ( cor_in != NULL )
60 : {
61 279765440 : tmp = add( tmp, cor_in[i] ); /* Q9 */
62 : }
63 306522560 : cor_out[i] = tmp; /* Q9 */
64 306522560 : move16();
65 : }
66 : }
67 : ELSE
68 : {
69 3390698 : pRx = R - pos[0]; /*Q9+scale*/
70 3390698 : pRy = R - pos[1]; /*Q9+scale*/
71 3390698 : IF( sign_x > 0 )
72 : {
73 : /* sign x and y is positive */
74 109419050 : FOR( i = 0; i < L_SUBFR; i++ )
75 : {
76 107735680 : tmp = add( pRx[i], pRy[i] );
77 107735680 : if ( cor_in != NULL )
78 : {
79 79296512 : tmp = add( tmp, cor_in[i] ); /* Q9 */
80 : }
81 107735680 : cor_out[i] = tmp; /* Q9 */
82 107735680 : move16();
83 : }
84 : }
85 : ELSE
86 : {
87 : /* sign x and y is negative */
88 110976320 : FOR( i = 0; i < L_SUBFR; i++ )
89 : {
90 109268992 : tmp = add( pRx[i], pRy[i] );
91 109268992 : if ( cor_in != NULL )
92 : {
93 81462016 : tmp = sub( cor_in[i], tmp ); /* Q9 */
94 : }
95 109268992 : if ( cor_in == NULL )
96 : {
97 27806976 : tmp = negate( tmp );
98 : }
99 109268992 : cor_out[i] = tmp; /* Q9 */
100 109268992 : move16();
101 : }
102 : }
103 : }
104 : }
105 658462 : ELSE IF( EQ_16( nb_pulse, 4 ) )
106 : {
107 658462 : E_ACELP_update_cor_fx( pos, 2, sign, R, cor_in, cor_out );
108 658462 : E_ACELP_update_cor_fx( pos + 2, 2, sign, R, cor_out, cor_out );
109 : }
110 : else
111 : {
112 0 : assert( !"Number of pulses not supported" );
113 : }
114 8838575 : }
115 : /*--------------------------------------------------------------------------------------*
116 : * E_ACELP_2pulse_searchx
117 : * Iterations: nb_pos_ix*16
118 : *--------------------------------------------------------------------------------------*/
119 6224725 : static void E_ACELP_2pulse_searchx_fx(
120 : const Word16 nb_pos_ix, /*Q0*/
121 : const Word16 track_x, /*Q0*/
122 : const Word16 track_y, /*Q0*/
123 : Word16 *R, /*Q9+scale*/
124 : Word16 *ps, /*Qdn*/
125 : Word16 *alp, /*Q6*/
126 : Word16 *ix, /*Q0*/
127 : Word16 *iy, /*Q0*/
128 : Word16 dn[], /*Qdn*/
129 : Word16 *dn2, /*Q0*/
130 : Word16 cor[], /*Q9*/
131 : Word16 sign[], /*Q13*/
132 : Word16 sign_val_2 /*Q15*/ )
133 : {
134 : Word16 i, x;
135 : Word32 y;
136 : Word16 *pos_x, pos[2];
137 : Word32 xy_save;
138 : Word16 ps0, ps1, alp2_16, ps2, sq;
139 : Word32 alp0, alp1, alp2, s;
140 : Word16 *pR, sgnx;
141 : Word16 sqk[2], alpk[2], ik;
142 : #ifndef ISSUE_1867_replace_overflow_libenc
143 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
144 : Flag Overflow = 0;
145 : move32();
146 : #endif
147 : #endif
148 :
149 : /* eight dn2 max positions per track */
150 6224725 : pos_x = &dn2[( track_x * 8 )]; /*Qdn*/
151 6224725 : move16();
152 : /* save these to limit memory searches */
153 6224725 : ps0 = *ps; /*Qdn*/
154 6224725 : move16();
155 : /*alp0 = *alp + 2.0f*R[0]; move16();*/
156 6224725 : alp0 = L_deposit_h( *alp ); /* Qalp = Q_R*Q_signval */
157 6224725 : alp0 = L_mac_sat( alp0, R[0], sign_val_2 ); /*Q9+scale+Q15*/
158 :
159 : /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
160 6224725 : sqk[0] = -1;
161 6224725 : move16();
162 6224725 : alpk[0] = 1;
163 6224725 : move16();
164 6224725 : x = pos_x[0];
165 6224725 : move16();
166 6224725 : sgnx = sign[track_y]; /*Q13*/
167 6224725 : move16();
168 6224725 : if ( sign[x] < 0 )
169 : {
170 3082074 : sgnx = negate( sgnx );
171 : }
172 : #ifdef ISSUE_1867_replace_overflow_libenc
173 6224725 : if ( mac_r_sat( L_mac_sat( L_mac_sat( alp0, cor[x], sign[x] ), cor[track_y], sign[track_y] ), R[track_y - x], sgnx ) < 0 )
174 : #else
175 : if ( mac_ro( L_mac_o( L_mac_o( alp0, cor[x], sign[x], &Overflow ), cor[track_y], sign[track_y], &Overflow ), R[track_y - x], sgnx, &Overflow ) < 0 )
176 : #endif
177 : {
178 0 : sqk[0] = 1;
179 0 : move16();
180 : }
181 6224725 : ik = 0;
182 6224725 : move16();
183 :
184 6224725 : xy_save = L_mac0( L_deposit_l( track_y ), track_x, L_SUBFR ); /*Q0*/
185 :
186 : /* loop track 1 */
187 45420767 : FOR( i = 0; i < nb_pos_ix; i++ )
188 : {
189 39196042 : x = pos_x[i]; /*Q0*/
190 39196042 : move16();
191 39196042 : sgnx = sign[x]; /*Q13*/
192 39196042 : move16();
193 : /* dn[x] has only nb_pos_ix positions saved */
194 : /*ps1 = ps0 + dn[x]; INDIRECT(1);ADD(1);*/
195 39196042 : ps1 = add_sat( ps0, dn[x] ); /*Qdn*/
196 : /*alp1 = alp0 + 2*sgnx*cor[x]; INDIRECT(1);MULT(1); MAC(1);*/
197 : #ifdef ISSUE_1867_replace_overflow_libenc
198 39196042 : alp1 = L_mac_sat( alp0, cor[x], sgnx ); /* Qalp = (Q_R=Q_cor)*Q_signval */
199 : #else
200 : alp1 = L_mac_o( alp0, cor[x], sgnx, &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */
201 : #endif
202 39196042 : pR = R - x; /*Q9+scale*/
203 :
204 666332714 : FOR( y = track_y; y < L_SUBFR; y += 4 )
205 : {
206 : /*ps2 = ps1 + dn[y]; ADD(1);*/
207 627136672 : ps2 = add_sat( ps1, dn[y] ); /*Qdn*/
208 : /*alp2 = alp1 + 2.0f*sign[y]*(cor[y] + sgnx*pR[y]); MULT(1); MAC(2);*/
209 : /*alp2 = alp1 + 2.0f*sign[y]*cor[y] + 2.0f*sign[y]*sgnx*pR[y]; MULT(1); MAC(2);*/
210 627136672 : assert( sign[y] == sign_val_2 || sign[y] == -sign_val_2 );
211 :
212 : /* Compiler warning workaround (not instrumented) */
213 627136672 : assert( sgnx != 0 );
214 627136672 : alp2_16 = 0;
215 :
216 : #ifdef ISSUE_1867_replace_overflow_libenc
217 627136672 : alp2 = L_mac_sat( alp1, cor[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
218 : #else
219 : alp2 = L_mac_o( alp1, cor[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */
220 : #endif
221 627136672 : if ( sgnx > 0 )
222 : {
223 : #ifdef ISSUE_1867_replace_overflow_libenc
224 311372848 : alp2_16 = mac_r_sat( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
225 : #else
226 : alp2_16 = mac_ro( alp2, pR[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */
227 : #endif
228 : }
229 627136672 : if ( sgnx < 0 )
230 : {
231 : #ifdef ISSUE_1867_replace_overflow_libenc
232 315763824 : alp2_16 = msu_r_sat( alp2, pR[y], sign[y] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
233 : #else
234 : alp2_16 = msu_ro( alp2, pR[y], sign[y], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */
235 : #endif
236 : }
237 627136672 : alpk[1 - ik] = alp2_16; /* Qalp */
238 627136672 : move16();
239 :
240 : /*sq = ps2 * ps2; MULT(1);*/
241 627136672 : sq = mult_r( ps2, ps2 ); /* (3+3)Q -> 6Q9 */
242 627136672 : sqk[1 - ik] = sq; /* Q9 */
243 627136672 : move16();
244 :
245 :
246 : /*s = (alpk * sq) - (sqk * alp2); MULT(1);MAC(1);*/
247 : #ifdef ISSUE_1867_replace_overflow_libenc
248 627136672 : s = L_msu_sat( L_mult( alpk[ik], sq ), sqk[ik], alp2_16 ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */
249 : #else
250 : s = L_msu_o( L_mult( alpk[ik], sq ), sqk[ik], alp2_16, &Overflow ); /* Q_sq = Q_sqk, Q_alpk = Q_alp */
251 : #endif
252 627136672 : if ( s > 0 )
253 : {
254 35887661 : ik = sub( 1, ik );
255 : }
256 627136672 : if ( s > 0 )
257 : {
258 35887661 : xy_save = L_mac0( y, x, L_SUBFR ); /* Q0 */
259 : }
260 627136672 : assert( ( ( s >= 0 && i == 0 && y == track_y ) ) || ( y > track_y ) || ( i > 0 ) );
261 : }
262 : }
263 6224725 : ps1 = extract_l( xy_save );
264 6224725 : pos[1] = s_and( ps1, L_SUBFR - 1 );
265 6224725 : move16();
266 6224725 : pos[0] = lshr( ps1, 6 ); /* Q0 */
267 6224725 : move16();
268 : /* Update numerator */
269 6224725 : *ps = add( add( ps0, dn[pos[0]] ), dn[pos[1]] ); /* Qdn */
270 6224725 : move16();
271 :
272 : /* Update denominator */
273 6224725 : *alp = alpk[ik]; /* Q_alp */
274 6224725 : move16();
275 :
276 6224725 : E_ACELP_update_cor_fx( pos, 2, sign, R, cor, cor );
277 :
278 6224725 : *ix = pos[0]; /* Q0 */
279 6224725 : move16();
280 6224725 : *iy = pos[1]; /* Q0 */
281 6224725 : move16();
282 :
283 6224725 : assert( ( ( pos[0] & 3 ) == track_x ) && ( ( pos[1] & 3 ) == track_y ) ); /* sanity check */
284 6224725 : }
285 :
286 : /*--------------------------------------------------------------------------------------*
287 : * E_ACELP_1pulse_searchx
288 : *--------------------------------------------------------------------------------------*/
289 609296 : static void E_ACELP_1pulse_searchx_fx(
290 : UWord8 tracks[2], /*Q0*/
291 : Word16 *R, /*Q9+scale*/
292 : Word16 *ps, /* Qdn */
293 : Word16 *alp, /*Q6*/
294 : Word16 *ix, /*Q0*/
295 : Word16 dn[], /* Qdn */
296 : Word16 cor[], /* Q9 */
297 : Word16 sign[], /* Q13 */
298 : Word16 sign_val_1 /* Q15 */ )
299 : {
300 609296 : Word16 x, x_save = 0;
301 : Word16 ps0;
302 : Word32 alp0;
303 : Word16 ps1, sq;
304 : Word16 alp1;
305 : Word32 s;
306 : Word16 ntracks, t;
307 : Word16 sqk[2], alpk[2], ik;
308 609296 : move16();
309 : #ifndef ISSUE_1867_replace_overflow_libenc
310 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
311 : Flag Overflow = 0;
312 : move32();
313 : #endif
314 : #endif
315 : /* save these to limit memory searches */
316 : /*alp0 = *alp + R[0]; INDIRECT(1);*/
317 609296 : ps0 = *ps; /* Qdn */
318 609296 : move16();
319 609296 : alp0 = L_deposit_h( *alp ); /* Q22 */
320 609296 : alp0 = L_mac( alp0, R[0], sign_val_1 ); /* Qalp = (Q_R=Q_cor)*Q_signval */
321 :
322 : /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
323 609296 : move16();
324 609296 : move16();
325 609296 : alpk[0] = 1;
326 609296 : sqk[0] = -1;
327 609296 : ik = 0;
328 609296 : move16();
329 : #ifdef ISSUE_1867_replace_overflow_libenc
330 609296 : if ( mac_r_sat( alp0, cor[tracks[0]], sign[tracks[0]] ) < 0 )
331 : #else
332 : if ( mac_ro( alp0, cor[tracks[0]], sign[tracks[0]], &Overflow ) < 0 )
333 : #endif
334 : {
335 0 : sqk[0] = 1;
336 0 : move16();
337 : }
338 :
339 609296 : x_save = tracks[0]; /* Q0 */
340 609296 : move16();
341 :
342 609296 : ntracks = 1;
343 609296 : move16();
344 609296 : if ( NE_16( tracks[1], tracks[0] ) )
345 : {
346 159238 : ntracks = 2;
347 159238 : move16();
348 : }
349 1377830 : FOR( t = 0; t < ntracks; ++t )
350 : {
351 13065078 : FOR( x = tracks[t]; x < L_SUBFR; x += 4 )
352 : {
353 : /* ps1 = ps0 + dn[x]; ADD(1);*/
354 12296544 : ps1 = add( ps0, dn[x] );
355 : /* alp1 = alp0 + 2*sign[x]*cor[x]; MAC(1); MULT(1);*/
356 12296544 : assert( sign[x] == sign_val_1 << 1 || sign[x] == -( sign_val_1 << 1 ) );
357 : #ifdef ISSUE_1867_replace_overflow_libenc
358 12296544 : alp1 = mac_r_sat( alp0, cor[x], sign[x] ); /* Qalp = (Q_R=Q_cor)*Q_signval */
359 : #else
360 : alp1 = mac_ro( alp0, cor[x], sign[x], &Overflow ); /* Qalp = (Q_R=Q_cor)*Q_signval */
361 : #endif
362 12296544 : alpk[1 - ik] = alp1; /* Qalp */
363 12296544 : move16();
364 :
365 :
366 : /*sq = ps1 * ps1; MULT(1);*/
367 12296544 : sq = mult_r( ps1, ps1 ); /* 6Q9 */
368 12296544 : sqk[1 - ik] = sq; /* Q9 */
369 12296544 : move16();
370 :
371 : /*s = (alpk[ik] * sq) - (sqk[ik] * alp1); MULT(1);MAC(1);*/
372 : #ifdef ISSUE_1867_replace_overflow_libenc
373 12296544 : s = L_msu_sat( L_mult_sat( alpk[ik], sq ), sqk[ik], alp1 ); /* Q9+Qalp+1 */
374 : #else
375 : s = L_msu_o( L_mult_o( alpk[ik], sq, &Overflow ), sqk[ik], alp1, &Overflow ); /* Q9+Qalp+1 */
376 : #endif
377 12296544 : if ( s > 0 )
378 : {
379 2217000 : ik = sub( 1, ik );
380 : }
381 12296544 : if ( s > 0 )
382 : {
383 2217000 : x_save = x;
384 2217000 : move16();
385 : }
386 12296544 : assert( t > 0 || ( ( s >= 0 ) && ( x == tracks[t] ) ) || x > tracks[t] );
387 : }
388 : }
389 :
390 609296 : *ps = add( ps0, dn[x_save] ); /* Qdn */
391 609296 : move16();
392 609296 : *alp = alpk[ik]; /* Qalp */
393 609296 : move16();
394 609296 : *ix = x_save; /* Q0 */
395 609296 : move16();
396 609296 : }
397 :
398 : /*--------------------------------------------------------------------------------------*
399 : * E_ACELP_4tsearchx_fx
400 : * Autocorrelation method for searching pulse positions effectively
401 : * Algorithm is identical to traditional covariance method
402 : *--------------------------------------------------------------------------------------*/
403 394697 : void E_ACELP_4tsearchx_fx(
404 : Word16 dn[], /*Qdn*/
405 : const Word16 cn[], /*Q_new*/
406 : Word16 Rw[], /*Q9*/
407 : Word16 code[], /*Q9*/
408 : const PulseConfig *config,
409 : Word16 ind[] /*Q0*/
410 : ,
411 : const Word16 element_mode )
412 : {
413 : Word16 sign[L_SUBFR], vec[L_SUBFR];
414 : Word16 cor[L_SUBFR];
415 : Word16 R_buf[2 * L_SUBFR - 1], *R;
416 : Word16 dn2[L_SUBFR];
417 394697 : Word16 ps2k, ps /* same format as dn[] */, ps2, alpk, alp = 0 /* Q13 and later Q_Rw*Q_signval=Q_cor*Q_signval */;
418 : Word32 s;
419 : Word16 codvec[NB_PULSE_MAX];
420 : Word16 pos_max[4];
421 : Word16 dn2_pos[8 * 4];
422 : UWord8 ipos[NB_PULSE_MAX];
423 394697 : Word16 i, j, k, st, pos = 0;
424 : Word16 scale;
425 : Word16 sign_val_1, sign_val_2;
426 : Word16 nb_pulse, nb_pulse_m2;
427 394697 : Word16 psk = 0;
428 : Word16 val, index, track;
429 394697 : move16();
430 394697 : move16();
431 394697 : move16();
432 :
433 394697 : ps = 0; /* to avoid compilation warnings */
434 394697 : move16();
435 :
436 :
437 394697 : alp = config->alp; /* Q13 */
438 394697 : move16();
439 394697 : nb_pulse = config->nb_pulse;
440 394697 : move16();
441 394697 : move16();
442 394697 : nb_pulse_m2 = sub( nb_pulse, 2 );
443 :
444 : /* Init to avoid crash when the search does not find a solution */
445 394697 : IF( EQ_16( element_mode, EVS_MONO ) )
446 : {
447 82458 : FOR( k = 0; k < nb_pulse; k++ )
448 : {
449 76007 : codvec[k] = k;
450 76007 : move16();
451 : }
452 : }
453 : ELSE
454 : {
455 5277753 : FOR( k = 0; k < nb_pulse; k++ )
456 : {
457 4889507 : codvec[k] = s_and( k, 3 );
458 4889507 : move16();
459 : }
460 : }
461 394697 : scale = 0;
462 394697 : move16();
463 394697 : s = L_mult0( Rw[0], Rw[0] ); /*Q18*/
464 25260608 : FOR( i = 1; i < L_SUBFR; i++ )
465 : {
466 24865911 : s = L_mac0( s, Rw[i], Rw[i] ); /*Q18*/
467 : }
468 394697 : if ( s_and( (Word16) GE_16( nb_pulse, 9 ), (Word16) GT_32( s, 0x800000 ) ) )
469 : {
470 292418 : scale = -1;
471 292418 : move16();
472 : }
473 394697 : if ( s_and( (Word16) GE_16( nb_pulse, 13 ), (Word16) GT_32( s, 0x4000000 ) ) )
474 : {
475 48561 : scale = -2;
476 48561 : move16();
477 : }
478 394697 : IF( GE_16( nb_pulse, 18 ) )
479 : {
480 53966 : if ( GT_32( s, 0x200000 ) )
481 : {
482 53966 : scale = -1;
483 53966 : move16();
484 : }
485 53966 : if ( GT_32( s, 0x400000 ) )
486 : {
487 53966 : scale = -2;
488 53966 : move16();
489 : }
490 53966 : if ( GT_32( s, 0x4000000 ) )
491 : {
492 13862 : scale = -3;
493 13862 : move16();
494 : }
495 : }
496 394697 : if ( s_and( (Word16) GE_16( nb_pulse, 28 ), (Word16) GT_32( s, 0x800000 ) ) )
497 : {
498 463 : scale = -3;
499 463 : move16();
500 : }
501 394697 : if ( s_and( (Word16) GE_16( nb_pulse, 36 ), (Word16) GT_32( s, 0x4000000 ) ) )
502 : {
503 0 : scale = -4;
504 0 : move16();
505 : }
506 :
507 : /* Set up autocorrelation vector */
508 394697 : R = R_buf + L_SUBFR - 1;
509 394697 : Copy_Scale_sig( Rw, R, L_SUBFR, scale ); /*Q9+scale*/
510 25260608 : FOR( k = 1; k < L_SUBFR; k++ )
511 : {
512 24865911 : R[-k] = R[k];
513 24865911 : move16();
514 : }
515 :
516 : /* Sign value */
517 394697 : sign_val_2 = 0x2000; /* Q15 */
518 394697 : move16();
519 394697 : if ( GE_16( nb_pulse, 24 ) )
520 : {
521 25152 : sign_val_2 = shr( sign_val_2, 1 ); /* Q15 */
522 : }
523 394697 : sign_val_1 = shr( sign_val_2, 1 ); /* Q15 */
524 :
525 : /*
526 : * Find sign for each pulse position.
527 : */
528 394697 : E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, sign_val_2, L_SUBFR );
529 :
530 : /*
531 : * Select the most important 8 position per track according to dn2[].
532 : */
533 394697 : E_ACELP_findcandidates( dn2, dn2_pos, pos_max );
534 :
535 : /*
536 : * Deep first search:
537 : */
538 :
539 : /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */
540 394697 : ps2k = -1;
541 394697 : move16();
542 394697 : alpk = 1;
543 394697 : move16();
544 :
545 : /* Number of iterations */
546 1796989 : FOR( k = 0; k < config->nbiter; k++ )
547 : {
548 1402292 : E_ACELP_setup_pulse_search_pos( config, k, ipos );
549 :
550 : /* index to first non-fixed position */
551 1402292 : pos = config->fixedpulses; /* Q0 */
552 1402292 : move16();
553 :
554 1402292 : IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */
555 : {
556 105366 : ps = 0;
557 105366 : move16();
558 105366 : alp = 0;
559 105366 : move16();
560 105366 : set16_fx( cor, 0, L_SUBFR );
561 : }
562 : ELSE
563 : {
564 1296926 : assert( config->fixedpulses == 2 || config->fixedpulses == 4 );
565 :
566 : /* set fixed positions */
567 5207702 : FOR( i = 0; i < pos; ++i )
568 : {
569 3910776 : ind[i] = pos_max[ipos[i]]; /* Q0 */
570 3910776 : move16();
571 : }
572 :
573 : /* multiplication of autocorrelation with signed fixed pulses */
574 1296926 : E_ACELP_update_cor_fx( ind, config->fixedpulses, sign, R, NULL, cor );
575 :
576 : /* normalisation contribution of fixed part */
577 1296926 : s = L_mult0( cor[ind[0]], sign[ind[0]] ); /* Q22 */
578 1296926 : ps = dn[ind[0]]; /* Qdn */
579 1296926 : move16();
580 3910776 : FOR( i = 1; i < pos; ++i )
581 : {
582 2613850 : s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q22 */
583 2613850 : ps = add( ps, dn[ind[i]] ); /* Qdn */
584 : }
585 1296926 : alp = round_fx( s ); /*mac0 >>1 sign = 2 Q6*/
586 : }
587 :
588 : /* other stages of 2 pulses */
589 1402292 : st = 0;
590 1402292 : move16();
591 8236313 : FOR( j = pos; j < nb_pulse; j += 2 )
592 : {
593 6834021 : IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */
594 : {
595 : /*
596 : * Calculate correlation of all possible positions
597 : * of the next 2 pulses with previous fixed pulses.
598 : * Each pulse can have 16 possible positions.
599 : */
600 :
601 6224725 : E_ACELP_2pulse_searchx_fx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp,
602 6224725 : &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 );
603 : }
604 : ELSE /* single pulse search */
605 : {
606 609296 : E_ACELP_1pulse_searchx_fx( &ipos[j], R, &ps, &alp,
607 609296 : &ind[j], dn, cor, sign, sign_val_1 );
608 : }
609 :
610 6834021 : test();
611 6834021 : IF( GT_16( alp, ONE_IN_Q14 ) && ( element_mode > EVS_MONO ) )
612 : {
613 1850 : alp = shr( alp, 1 );
614 1850 : Scale_sig( cor, L_SUBFR, -1 ); /*Q8*/
615 1850 : Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); /*Q8+scale*/
616 1850 : Scale_sig( dn, L_SUBFR, -1 ); /*Qdn-1*/
617 : }
618 6834021 : st = add( st, 1 );
619 : }
620 :
621 : /* memorise the best codevector */
622 : /*ps2 = ps * ps; MULT(1);*/
623 1402292 : ps2 = mult( ps, ps ); /* 2*Qdn+1 */
624 :
625 : /*s = (alpk * ps2) - (ps2k * alp); MULT(2);ADD(1);*/
626 1402292 : s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); /* 2*Qdn+8 */
627 :
628 1402292 : IF( s > 0 )
629 : {
630 768183 : ps2k = ps2;
631 768183 : move16();
632 768183 : psk = ps;
633 768183 : move16();
634 768183 : alpk = alp;
635 768183 : move16();
636 768183 : Copy( ind, codvec, nb_pulse ); /* Q0 */
637 : }
638 : }
639 :
640 :
641 : /*
642 : * Store weighted energy of code, build the codeword and index of codevector.
643 : */
644 394697 : IF( EQ_16( element_mode, EVS_MONO ) )
645 : {
646 6451 : E_ACELP_build_code( nb_pulse, codvec, sign, code, ind );
647 : }
648 : ELSE
649 : {
650 : /* Store weighted energy of code, build the codeword and index of codevector. */
651 388246 : set16_fx( code, 0, L_SUBFR );
652 388246 : set16_fx( ind, -1, NPMAXPT * 4 );
653 :
654 5277753 : FOR( k = 0; k < config->nb_pulse; k++ )
655 : {
656 4889507 : i = codvec[k]; /* read pulse position Q0*/
657 4889507 : move16();
658 4889507 : val = sign[i]; /* read sign Q13*/
659 4889507 : move16();
660 :
661 4889507 : index = shr( i, 2 ); /* pos of pulse (0..15) */
662 : // track = i % 4;
663 4889507 : track = s_and( i, 3 );
664 4889507 : IF( L_mult0( val, psk ) > 0 )
665 : {
666 2413175 : code[i] = add( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */
667 2413175 : move16();
668 2413175 : codvec[k] = add( codvec[k], 2 * L_SUBFR ); /* Q0 */
669 2413175 : move16();
670 : }
671 : ELSE
672 : {
673 2476332 : code[i] = sub( code[i], ONE_IN_Q9 /*1.0f*/ ); /* Q9 */
674 2476332 : move16();
675 2476332 : index = add( index, 16 ); /* Q0 */
676 : }
677 :
678 4889507 : i = imult1616( track, NPMAXPT );
679 11424024 : WHILE( ind[i] >= 0 )
680 : {
681 6534517 : i++;
682 : }
683 :
684 4889507 : ind[i] = index;
685 4889507 : move16();
686 : }
687 : }
688 394697 : }
|