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