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