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