Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h"
6 : #include "prot_fx.h"
7 : #include "cnst.h"
8 : #include "basop_util.h"
9 : #include "rom_com.h"
10 :
11 : /*-------------------------------------------------------------------
12 : * Local constants
13 : *-------------------------------------------------------------------*/
14 :
15 : #define ALPHA 27853 /*0.85f Q15*/
16 : #define MAX_TCX_LTP_FILTER_LEN 8
17 : #define MAX_TRANSITION_LEN 240 /* L_FRAME_48K / 4 */
18 :
19 59921 : void tcx_ltp_get_lpc(
20 : Word16 *x, /* Qx */
21 : const Word16 L, /* Q0 */
22 : Word16 *A, /* Qx */
23 : const Word16 order /* Q0 */
24 : )
25 : {
26 : Word16 i, j, s, s2, tmp;
27 : Word32 r, L_tmp;
28 :
29 59921 : Word16 tmpbuf[L_FRAME_MAX], *p = x;
30 : Word16 r_l[TCXLTP_LTP_ORDER + 1], r_h[TCXLTP_LTP_ORDER + 1];
31 :
32 :
33 59921 : assert( L <= L_FRAME_MAX );
34 :
35 : /* calc r[0], determine shift */
36 59921 : s = 0;
37 59921 : move16();
38 59921 : r = L_deposit_l( 0 );
39 18458705 : FOR( j = 0; j < L; j++ )
40 : {
41 18398784 : L_tmp = L_sub( r, 0x40000000 /* 1 in Q30 */ ); /* Q30 */
42 18398784 : if ( L_tmp > 0 )
43 5199 : s = sub( s, 1 );
44 18398784 : if ( L_tmp > 0 )
45 5199 : r = L_shr( r, 2 );
46 :
47 18398784 : tmp = shl( x[j], s ); /* Qx + s */
48 18398784 : r = L_mac0_sat( r, tmp, tmp ); /* Q30 */
49 : }
50 59921 : r = L_max( r, L_shl( 100, shl( s, 1 ) ) ); /* Q30 */
51 59921 : r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
52 59921 : s2 = norm_l( r );
53 59921 : r = L_shl( r, s2 );
54 59921 : s2 = sub( s2, 1 );
55 59921 : r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
56 59921 : move16();
57 59921 : move16();
58 :
59 59921 : IF( s < 0 )
60 : {
61 : /* shift buffer by s, recompute r[0] to reduce risk of instable LPC */
62 4364 : r = L_deposit_l( 0 );
63 4364 : tmp = lshl( (Word16) 0x8000, s ); /* factor corresponding to right shift by -s */
64 :
65 : {
66 4364 : Word64 r64 = 0;
67 4364 : move64();
68 1519116 : FOR( j = 0; j < L; j++ )
69 : {
70 1514752 : tmpbuf[j] = mult_r( x[j], tmp ); /* Qx */
71 1514752 : move16();
72 1514752 : r64 = W_mac0_16_16( r64, tmpbuf[j], tmpbuf[j] ); /* Q30 */
73 : }
74 4364 : r = W_sat_l( r64 ); /* Q30 */
75 : }
76 4364 : r = L_max( r, L_shl( 100, shl( s, 1 ) ) ); /* Q30 */
77 4364 : r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
78 4364 : s2 = norm_l( r );
79 4364 : r = L_shl( r, s2 );
80 4364 : s2 = sub( s2, 1 );
81 4364 : r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
82 4364 : move16();
83 4364 : move16();
84 :
85 4364 : p = tmpbuf;
86 : }
87 :
88 : /* calc r[1...] */
89 1020617 : FOR( i = 1; i <= order; i++ )
90 : {
91 960696 : r = L_deposit_l( 0 );
92 :
93 960696 : tmp = sub( L, i );
94 : {
95 960696 : Word64 r64 = 0;
96 960696 : move64();
97 288795324 : FOR( j = 0; j < tmp; j++ )
98 : {
99 287834628 : r64 = W_mac0_16_16( r64, p[j], p[j + i] ); /* Q30 */
100 : }
101 960696 : r = W_sat_l( r64 );
102 : }
103 960696 : r = L_shl( r, s2 );
104 960696 : r_l[i] = L_Extract_lc( r, &r_h[i] ); /* Q14 */
105 960696 : move16();
106 960696 : move16();
107 : }
108 :
109 59921 : E_LPC_lev_dur( r_h, r_l, A, NULL, order, NULL );
110 59921 : }
111 :
112 0 : void tcx_ltp_get_lpc_fx(
113 : Word32 *x, /* Qx */
114 : const Word16 L, /* Q0 */
115 : Word32 *A, /* Qx */
116 : const Word16 order /* Q0 */
117 : )
118 : {
119 : Word16 i, j, s, s2;
120 : Word32 r, tmp, L_tmp;
121 :
122 0 : Word32 tmpbuf[L_FRAME_MAX], *p = x;
123 : Word16 r_l[TCXLTP_LTP_ORDER + 1], r_h[TCXLTP_LTP_ORDER + 1];
124 :
125 :
126 0 : assert( L <= L_FRAME_MAX );
127 :
128 : /* calc r[0], determine shift */
129 0 : s = 0;
130 0 : move16();
131 0 : r = L_deposit_l( 0 );
132 0 : FOR( j = 0; j < L; j++ )
133 : {
134 0 : L_tmp = L_sub( r, 0x40000000 /* 1 in Q30 */ ); /* Q30 */
135 0 : if ( L_tmp > 0 )
136 0 : s = sub( s, 1 );
137 0 : if ( L_tmp > 0 )
138 0 : r = L_shr( r, 2 );
139 :
140 0 : tmp = L_shl( x[j], s ); /* Qx + s */
141 0 : r = Madd_32_32( r, tmp, tmp );
142 : }
143 0 : r = L_max( r, L_shl( 100, shl( s, 1 ) ) ); /* Q30 */
144 0 : r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
145 0 : s2 = norm_l( r );
146 0 : r = L_shl( r, s2 );
147 0 : s2 = sub( s2, 1 );
148 0 : r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
149 0 : move16();
150 0 : move16();
151 :
152 0 : IF( s < 0 )
153 : {
154 : /* shift buffer by s, recompute r[0] to reduce risk of instable LPC */
155 0 : r = L_deposit_l( 0 );
156 0 : tmp = lshl( (Word16) 0x8000, s ); /* factor corresponding to right shift by -s */
157 :
158 : {
159 0 : Word64 r64 = 0;
160 0 : move64();
161 0 : FOR( j = 0; j < L; j++ )
162 : {
163 0 : tmpbuf[j] = Mpy_32_32( x[j], tmp );
164 0 : move32();
165 0 : r64 = W_add( r64, W_mult0_32_32( tmpbuf[j], tmpbuf[j] ) );
166 : }
167 0 : r = W_sat_l( r64 );
168 : }
169 0 : r = L_max( r, L_shl( 100, shl( s, 1 ) ) ); /* Q30 */
170 0 : r = Mpy_32_16_1( r, 16386 /*1.0001f Q14*/ ); /* Q29 */
171 0 : s2 = norm_l( r );
172 0 : r = L_shl( r, s2 );
173 0 : s2 = sub( s2, 1 );
174 0 : r_l[0] = L_Extract_lc( r, &r_h[0] ); /* Q14 */
175 0 : move16();
176 0 : move16();
177 :
178 0 : p = tmpbuf;
179 : }
180 :
181 : /* calc r[1...] */
182 0 : FOR( i = 1; i <= order; i++ )
183 : {
184 0 : r = L_deposit_l( 0 );
185 :
186 0 : tmp = sub( L, i );
187 : {
188 0 : Word64 r64 = 0;
189 0 : move64();
190 0 : FOR( j = 0; j < tmp; j++ )
191 : {
192 0 : r64 = W_add( r64, Mpy_32_32( p[j], p[j + i] ) ); /* Q30 */
193 : }
194 0 : r = W_sat_l( r64 );
195 : }
196 0 : r = L_shl( r, s2 );
197 0 : r_l[i] = L_Extract_lc( r, &r_h[i] ); /* Q14 */
198 0 : move16();
199 0 : move16();
200 : }
201 :
202 0 : E_LPC_lev_dur_fx( r_h, r_l, A, NULL, order, NULL );
203 0 : }
204 :
205 245 : static void tcx_ltp_get_zir(
206 : Word16 *zir, /* Qx */
207 : const Word16 length, /* Q0 */
208 : Word16 *synth_ltp, /* Qx */
209 : Word16 *synth, /* Qx */
210 : Word16 *A, /* Qx */
211 : const Word16 lpcorder, /* Q0 */
212 : const Word16 gain, /* Q15 */
213 : const Word16 pitch_int, /* Q0 */
214 : const Word16 pitch_fr, /* Q0 */
215 : const Word16 pitres, /* Q0 */
216 : const Word16 filtIdx /* Q0 */
217 : )
218 : {
219 : Word16 buf[TCXLTP_LTP_ORDER], alpha, step;
220 : Word16 *x0, *x1;
221 : Word16 *y0, *y1;
222 : Word32 s, s2;
223 : const Word16 *w0, *w1, *v0, *v1;
224 : Word16 i, j, k, L;
225 :
226 245 : x0 = &synth_ltp[-pitch_int]; /* Qx */
227 245 : x1 = x0 - 1;
228 245 : y0 = synth; /* Qx */
229 245 : y1 = y0 - 1;
230 :
231 245 : assert( filtIdx >= 0 );
232 :
233 245 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
234 245 : w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr]; /* Q15 */
235 245 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
236 245 : v1 = &tcxLtpFilters[filtIdx].filt[pitres]; /* Q15 */
237 245 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
238 245 : move16();
239 :
240 6125 : FOR( j = 0; j < lpcorder; j++ )
241 : {
242 5880 : s = L_deposit_l( 0 );
243 5880 : s2 = L_deposit_l( 0 );
244 5880 : k = 0;
245 5880 : move16();
246 38928 : FOR( i = 0; i < L; i++ )
247 : {
248 33048 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
249 33048 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
250 33048 : k = k + pitres;
251 : }
252 :
253 : /* s2 *= ALPHA;
254 : buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */
255 5880 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) );
256 5880 : buf[j] = add_sat( sub_sat( synth[j], synth_ltp[j] ), mult_r_sat( gain, i ) ); /* Qx */
257 5880 : move16();
258 :
259 5880 : x0++;
260 5880 : x1++;
261 5880 : y0++;
262 5880 : y1++;
263 : }
264 :
265 245 : set16_fx( zir, 0, length );
266 :
267 245 : E_UTIL_synthesis( 0, A, zir, zir, length, buf, 0, lpcorder );
268 :
269 245 : alpha = 0x7FFF; /* 1 in Q15 */
270 245 : move16();
271 : /* step = 1.f/(float)(length/2); */
272 245 : step = shl( 4, norm_s( length ) );
273 245 : if ( s_and( length, sub( length, 1 ) ) != 0 )
274 : {
275 245 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
276 : }
277 245 : if ( EQ_16( length, 240 ) )
278 : {
279 152 : step = 273 /*1.f/120.f Q15*/;
280 152 : move16();
281 : }
282 :
283 25925 : FOR( j = length / 2; j < length; j++ )
284 : {
285 25680 : zir[j] = mult_r( zir[j], alpha ); /* Qx */
286 25680 : move16();
287 25680 : alpha = sub( alpha, step );
288 : }
289 245 : }
290 :
291 0 : static void tcx_ltp_get_zir_fx(
292 : Word32 *zir, /* Qx */
293 : const Word16 length, /* Q0 */
294 : Word32 *synth_ltp, /* Qx */
295 : Word32 *synth, /* Qx */
296 : Word32 *A, /* Qx */
297 : const Word16 lpcorder, /* Q0 */
298 : const Word16 gain, /* Q15 */
299 : const Word16 pitch_int, /* Q0 */
300 : const Word16 pitch_fr, /* Q0 */
301 : const Word16 pitres, /* Q0 */
302 : const Word16 filtIdx /* Q0 */
303 : )
304 : {
305 : Word32 buf[TCXLTP_LTP_ORDER];
306 : Word16 alpha, step;
307 : Word32 *x0, *x1;
308 : Word32 *y0, *y1;
309 : Word32 s, s2;
310 : const Word16 *w0, *w1, *v0, *v1;
311 : Word32 i;
312 : Word16 j, k, L;
313 :
314 0 : x0 = &synth_ltp[-pitch_int]; /* Qx */
315 0 : x1 = x0 - 1;
316 0 : y0 = synth; /* Qx */
317 0 : y1 = y0 - 1;
318 :
319 0 : assert( filtIdx >= 0 );
320 :
321 0 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
322 0 : w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr]; /* Q15 */
323 0 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
324 0 : v1 = &tcxLtpFilters[filtIdx].filt[pitres]; /* Q15 */
325 0 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
326 0 : move16();
327 :
328 0 : FOR( j = 0; j < lpcorder; j++ )
329 : {
330 0 : s = L_deposit_l( 0 );
331 0 : s2 = L_deposit_l( 0 );
332 0 : k = 0;
333 0 : move16();
334 0 : FOR( i = 0; i < L; i++ )
335 : {
336 0 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
337 0 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
338 0 : k = k + pitres;
339 : }
340 :
341 : /* s2 *= ALPHA;
342 : buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s ); */
343 0 : i = L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ); /* Qx */
344 0 : buf[j] = L_add_sat( L_sub_sat( synth[j], synth_ltp[j] ), Mpy_32_16_1( i, gain ) ); /* Qx */
345 :
346 0 : move16();
347 :
348 0 : x0++;
349 0 : x1++;
350 0 : y0++;
351 0 : y1++;
352 : }
353 :
354 0 : set32_fx( zir, 0, length );
355 :
356 0 : E_UTIL_synthesis_fx( 0, A, zir, zir, length, buf, 0, lpcorder );
357 :
358 0 : alpha = 0x7FFF; /* 1 in Q15 */
359 0 : move16();
360 : /* step = 1.f/(float)(length/2); */
361 0 : step = shl( 4, norm_s( length ) );
362 0 : if ( s_and( length, sub( length, 1 ) ) != 0 )
363 : {
364 0 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
365 : }
366 0 : if ( EQ_16( length, 240 ) )
367 : {
368 0 : step = 273 /*1.f/120.f Q15*/;
369 0 : move16();
370 : }
371 :
372 0 : FOR( j = shr( length, 1 ); j < length; j++ )
373 : {
374 0 : zir[j] = Mpy_32_16_r( zir[j], alpha ); /* Qx */
375 0 : move32();
376 0 : alpha = sub( alpha, step );
377 : }
378 0 : }
379 :
380 940835 : void predict_signal(
381 : const Word16 excI[], /* i : input excitation buffer Qx*/
382 : Word16 excO[], /* o : output excitation buffer Qx*/
383 : const Word16 T0, /* i : integer pitch lag Q0*/
384 : Word16 frac, /* i : fraction of lag Q0*/
385 : const Word16 frac_max, /* i : max fraction Q0*/
386 : const Word16 L_subfr /* i : subframe size Q0*/
387 : )
388 : {
389 : Word16 j;
390 : Word32 s;
391 : const Word16 *x0, *win;
392 : #ifndef ISSUE_1836_replace_overflow_libcom
393 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
394 : Flag Overflow = 0;
395 : move32();
396 : #endif
397 : #endif
398 940835 : x0 = &excI[-T0 - 1];
399 940835 : frac = negate( frac );
400 :
401 940835 : IF( frac < 0 )
402 : {
403 464636 : frac = add( frac, frac_max );
404 464636 : x0--;
405 : }
406 :
407 940835 : win = &inter4_2tcx2[frac][0]; /* Q15 */
408 940835 : if ( EQ_16( frac_max, 6 ) )
409 201657 : win = &inter6_2tcx2[frac][0]; /* Q15 */
410 :
411 274334771 : FOR( j = 0; j < L_subfr; j++ )
412 : {
413 : #ifdef ISSUE_1836_replace_overflow_libcom
414 273393936 : s = L_mult_sat( win[0], x0[0] ); /* Qx + 16 */
415 273393936 : s = L_mac_sat( s, win[1], x0[1] ); /* Qx + 16 */
416 273393936 : s = L_mac_sat( s, win[2], x0[2] ); /* Qx + 16 */
417 273393936 : excO[j] = mac_r_sat( s, win[3], x0[3] ); /* Qx + 16 */
418 : #else
419 : s = L_mult_o( win[0], x0[0], &Overflow ); /* Qx + 16 */
420 : s = L_mac_o( s, win[1], x0[1], &Overflow ); /* Qx + 16 */
421 : s = L_mac_o( s, win[2], x0[2], &Overflow ); /* Qx + 16 */
422 : excO[j] = mac_ro( s, win[3], x0[3], &Overflow ); /* Qx + 16 */
423 : #endif
424 273393936 : move16();
425 :
426 273393936 : x0++;
427 : }
428 940835 : }
429 :
430 6736 : static void tcx_ltp_synth_filter(
431 : Word16 *synth_ltp, /* Qx */
432 : Word16 *synth, /* Qx */
433 : Word16 length, /* Q0 */
434 : Word16 pitch_int, /* Q0 */
435 : Word16 pitch_fr, /* Q0 */
436 : Word16 gain, /* Q15 */
437 : Word16 pitch_res, /* Q0 */
438 : Word16 *zir, /* can be NULL */
439 : Word16 fade, /* 0=normal, +1=fade-in, -1=fade-out Q0*/
440 : Word16 filtIdx /* Q0 */
441 : )
442 : {
443 : Word16 *x0, *x1;
444 : Word16 *y0, *y1;
445 : Word32 s, s2;
446 : const Word16 *v0, *v1;
447 : const Word16 *w0, *w1;
448 6736 : Word16 alpha, step = 0; /* initialize just to avoid compiler warning */
449 6736 : move16();
450 : Word16 i, j, k, L;
451 :
452 6736 : IF( gain > 0 )
453 : {
454 1440 : x0 = &synth_ltp[-pitch_int]; /* Qx */
455 1440 : x1 = x0 - 1;
456 1440 : y0 = synth; /* Qx */
457 1440 : y1 = y0 - 1;
458 :
459 1440 : assert( filtIdx >= 0 );
460 :
461 1440 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
462 1440 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
463 1440 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
464 1440 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
465 :
466 1440 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
467 1440 : move16();
468 :
469 1440 : alpha = 0;
470 1440 : move16();
471 1440 : IF( fade != 0 )
472 : {
473 168 : if ( fade < 0 )
474 : {
475 84 : alpha = 0x7FFF; /* 1 in Q15 */
476 84 : move16();
477 : }
478 :
479 : /* step = 1.f/(float)(length); */
480 168 : step = shl( 2, norm_s( length ) );
481 168 : if ( s_and( length, sub( length, 1 ) ) != 0 )
482 : {
483 168 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
484 : }
485 168 : if ( EQ_16( length, 240 ) )
486 : {
487 94 : step = 137 /*1.f/240.f Q15*/;
488 94 : move16();
489 : }
490 :
491 168 : if ( fade < 0 )
492 84 : step = negate( step );
493 : }
494 :
495 : #ifdef OPT_TCXLTP_FILTER_LOOP
496 1440 : IF( zir != NULL )
497 : {
498 245 : IF( fade != 0 )
499 : {
500 0 : FOR( j = 0; j < length; j++ )
501 : {
502 0 : s = L_deposit_l( 0 );
503 0 : s2 = L_deposit_l( 0 );
504 0 : k = 0;
505 0 : move16();
506 0 : FOR( i = 0; i < L; i++ )
507 : {
508 0 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
509 0 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
510 0 : k = k + pitch_res;
511 : }
512 :
513 : /* s2 *= ALPHA;
514 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
515 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
516 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
517 0 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
518 0 : k = mult_r( gain, i ); /* Qx */
519 0 : k = mult_r( k, alpha ); /* Qx */
520 0 : k = add_sat( synth[j], k ); /* Qx */
521 0 : k = sub_sat( k, zir[j] ); /* Qx */
522 :
523 0 : synth_ltp[j] = k; /* Qx */
524 0 : move16();
525 :
526 : BASOP_SATURATE_WARNING_OFF_EVS;
527 0 : alpha = add_sat( alpha, step );
528 : BASOP_SATURATE_WARNING_ON_EVS;
529 :
530 0 : x0++;
531 0 : x1++;
532 0 : y0++;
533 0 : y1++;
534 : }
535 : }
536 : ELSE
537 : {
538 51605 : FOR( j = 0; j < length; j++ )
539 : {
540 51360 : s = L_deposit_l( 0 );
541 51360 : s2 = L_deposit_l( 0 );
542 51360 : k = 0;
543 51360 : move16();
544 344640 : FOR( i = 0; i < L; i++ )
545 : {
546 293280 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
547 293280 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
548 293280 : k = k + pitch_res;
549 : }
550 :
551 : /* s2 *= ALPHA;
552 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
553 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
554 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
555 51360 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
556 51360 : k = mult_r( gain, i ); /* Qx */
557 51360 : k = add_sat( synth[j], k ); /* Qx */
558 51360 : k = sub_sat( k, zir[j] ); /* Qx */
559 :
560 51360 : synth_ltp[j] = k; /* Qx */
561 51360 : move16();
562 :
563 51360 : x0++;
564 51360 : x1++;
565 51360 : y0++;
566 51360 : y1++;
567 : }
568 : }
569 : }
570 : ELSE
571 : {
572 1195 : IF( fade != 0 )
573 : {
574 34568 : FOR( j = 0; j < length; j++ )
575 : {
576 34400 : s = L_deposit_l( 0 );
577 34400 : s2 = L_deposit_l( 0 );
578 34400 : k = 0;
579 34400 : move16();
580 228960 : FOR( i = 0; i < L; i++ )
581 : {
582 194560 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
583 194560 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
584 194560 : k = k + pitch_res;
585 : }
586 :
587 : /* s2 *= ALPHA;
588 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
589 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
590 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
591 34400 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
592 34400 : k = mult_r( gain, i ); /* Qx */
593 34400 : k = mult_r( k, alpha );
594 34400 : k = add_sat( synth[j], k ); /* Qx */
595 :
596 34400 : synth_ltp[j] = k; /* Qx */
597 34400 : move16();
598 :
599 : BASOP_SATURATE_WARNING_OFF_EVS;
600 34400 : alpha = add_sat( alpha, step );
601 : BASOP_SATURATE_WARNING_ON_EVS;
602 :
603 34400 : x0++;
604 34400 : x1++;
605 34400 : y0++;
606 34400 : y1++;
607 : }
608 : }
609 : ELSE
610 : {
611 294701 : FOR( j = 0; j < length; j++ )
612 : {
613 293674 : s = L_deposit_l( 0 );
614 293674 : s2 = L_deposit_l( 0 );
615 293674 : k = 0;
616 293674 : move16();
617 1952262 : FOR( i = 0; i < L; i++ )
618 : {
619 1658588 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
620 1658588 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
621 1658588 : k = k + pitch_res;
622 : }
623 :
624 : /* s2 *= ALPHA;
625 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
626 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
627 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
628 293674 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
629 293674 : k = mult_r( gain, i ); /* Qx */
630 293674 : k = add_sat( synth[j], k ); /* Qx */
631 :
632 293674 : synth_ltp[j] = k; /* Qx */
633 293674 : move16();
634 :
635 :
636 293674 : x0++;
637 293674 : x1++;
638 293674 : y0++;
639 293674 : y1++;
640 : }
641 : }
642 : }
643 : #else
644 : FOR( j = 0; j < length; j++ )
645 : {
646 : s = L_deposit_l( 0 );
647 : s2 = L_deposit_l( 0 );
648 : k = 0;
649 : move16();
650 : FOR( i = 0; i < L; i++ )
651 : {
652 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
653 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
654 : k = k + pitch_res;
655 : }
656 :
657 : /* s2 *= ALPHA;
658 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
659 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
660 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
661 : i = sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ); /* Qx */
662 : k = mult_r( gain, i ); /* Qx */
663 : if ( fade != 0 )
664 : k = mult_r( k, alpha ); /* Qx */
665 : k = add_sat( synth[j], k ); /* Qx */
666 : if ( zir != NULL )
667 : {
668 : k = sub_sat( k, zir[j] ); /* Qx */
669 : }
670 :
671 : synth_ltp[j] = k; /* Qx */
672 : move16();
673 :
674 : BASOP_SATURATE_WARNING_OFF_EVS;
675 : if ( fade != 0 )
676 : {
677 : alpha = add_sat( alpha, step );
678 : }
679 : BASOP_SATURATE_WARNING_ON_EVS;
680 :
681 : x0++;
682 : x1++;
683 : y0++;
684 : y1++;
685 : }
686 : #endif
687 : }
688 : ELSE
689 : {
690 5296 : Copy( synth, synth_ltp, length ); /* Qx */
691 : }
692 6736 : }
693 :
694 2270942 : static void tcx_ltp_synth_filter32(
695 : Word32 *synth_ltp, /* Qx */
696 : Word32 *synth, /* Qx */
697 : Word16 length, /* Q0 */
698 : Word16 pitch_int, /* Q0 */
699 : Word16 pitch_fr, /* Q0 */
700 : Word16 gain, /* Q15 */
701 : Word16 pitch_res, /* Q0 */
702 : Word32 *zir, /* can be NULL Qx*/
703 : Word16 fade, /* 0=normal, +1=fade-in, -1=fade-out Q0*/
704 : Word16 filtIdx /* Q0 */
705 : )
706 : {
707 : Word32 *x0, *x1;
708 : Word32 *y0, *y1;
709 : Word32 s, s2;
710 : const Word16 *v0, *v1;
711 : const Word16 *w0, *w1;
712 2270942 : Word16 alpha, step = 0; /* initialize just to avoid compiler warning */
713 : Word16 i, j, k, L;
714 : Word32 L_tmp, L_tmp2;
715 :
716 2270942 : IF( gain > 0 )
717 : {
718 364994 : x0 = &synth_ltp[-pitch_int]; /* Qx */
719 364994 : x1 = x0 - 1;
720 364994 : y0 = synth; /* Qx */
721 364994 : y1 = y0 - 1;
722 :
723 364994 : assert( filtIdx >= 0 );
724 :
725 364994 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
726 364994 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
727 364994 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
728 364994 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
729 :
730 364994 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
731 364994 : move16();
732 364994 : alpha = 0;
733 364994 : move16();
734 364994 : IF( fade != 0 )
735 : {
736 0 : if ( fade < 0 )
737 : {
738 0 : alpha = 0x7FFF; /* 1 in Q15 */
739 0 : move16();
740 : }
741 :
742 : /* step = 1.f/(float)(length); */
743 0 : step = shl( 2, norm_s( length ) );
744 0 : if ( s_and( length, sub( length, 1 ) ) != 0 )
745 : {
746 0 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ ); /* Q15 */
747 : }
748 0 : if ( EQ_16( length, 240 ) )
749 : {
750 0 : step = 137 /*1.f/240.f Q15*/;
751 0 : move16();
752 : }
753 :
754 0 : if ( fade < 0 )
755 0 : step = negate( step );
756 : }
757 :
758 : #ifdef OPT_TCXLTP_FILTER_LOOP
759 364994 : IF( fade != 0 )
760 : {
761 0 : IF( zir != NULL )
762 : {
763 0 : FOR( j = 0; j < length; j++ )
764 : {
765 0 : s = L_deposit_l( 0 );
766 0 : s2 = L_deposit_l( 0 );
767 0 : k = 0;
768 0 : move16();
769 0 : FOR( i = 0; i < L; i++ )
770 : {
771 0 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
772 0 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
773 0 : k = k + pitch_res;
774 : }
775 :
776 : /* s2 *= ALPHA;
777 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
778 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
779 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
780 0 : L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
781 0 : L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */
782 0 : L_tmp2 = Mpy_32_16_r( L_tmp2, alpha ); /* Qx */
783 0 : L_tmp2 = L_sub_sat( L_tmp2, zir[j] ); /* Qx */
784 0 : L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
785 :
786 0 : synth_ltp[j] = L_tmp2; /* Qx */
787 0 : move16();
788 :
789 : BASOP_SATURATE_WARNING_OFF_EVS;
790 0 : alpha = add_sat( alpha, step );
791 : BASOP_SATURATE_WARNING_ON_EVS;
792 :
793 0 : x0++;
794 0 : x1++;
795 0 : y0++;
796 0 : y1++;
797 : }
798 : }
799 : ELSE
800 : {
801 0 : FOR( j = 0; j < length; j++ )
802 : {
803 0 : s = L_deposit_l( 0 );
804 0 : s2 = L_deposit_l( 0 );
805 0 : k = 0;
806 0 : move16();
807 0 : FOR( i = 0; i < L; i++ )
808 : {
809 0 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
810 0 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
811 0 : k = k + pitch_res;
812 : }
813 :
814 : /* s2 *= ALPHA;
815 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
816 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
817 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
818 0 : L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
819 0 : L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */
820 0 : L_tmp2 = Mpy_32_16_r( L_tmp2, alpha ); /* Qx */
821 0 : L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
822 :
823 0 : synth_ltp[j] = L_tmp2; /* Qx */
824 0 : move16();
825 :
826 : BASOP_SATURATE_WARNING_OFF_EVS;
827 0 : alpha = add_sat( alpha, step );
828 : BASOP_SATURATE_WARNING_ON_EVS;
829 :
830 0 : x0++;
831 0 : x1++;
832 0 : y0++;
833 0 : y1++;
834 : }
835 : }
836 : }
837 : ELSE
838 : {
839 364994 : IF( zir != NULL )
840 : {
841 0 : FOR( j = 0; j < length; j++ )
842 : {
843 0 : s = L_deposit_l( 0 );
844 0 : s2 = L_deposit_l( 0 );
845 0 : k = 0;
846 0 : move16();
847 0 : FOR( i = 0; i < L; i++ )
848 : {
849 0 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
850 0 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
851 0 : k = k + pitch_res;
852 : }
853 :
854 : /* s2 *= ALPHA;
855 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
856 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
857 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
858 0 : L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
859 0 : L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */
860 0 : L_tmp2 = L_sub_sat( L_tmp2, zir[j] ); /* Qx */
861 0 : L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
862 :
863 0 : synth_ltp[j] = L_tmp2; /* Qx */
864 0 : move16();
865 :
866 0 : x0++;
867 0 : x1++;
868 0 : y0++;
869 0 : y1++;
870 : }
871 : }
872 : ELSE
873 : {
874 108260784 : FOR( j = 0; j < length; j++ )
875 : {
876 107895790 : s = L_deposit_l( 0 );
877 107895790 : s2 = L_deposit_l( 0 );
878 107895790 : k = 0;
879 107895790 : move16();
880 837594220 : FOR( i = 0; i < L; i++ )
881 : {
882 729698430 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
883 729698430 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
884 729698430 : k = k + pitch_res;
885 : }
886 :
887 : /* s2 *= ALPHA;
888 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
889 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
890 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
891 107895790 : L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
892 107895790 : L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */
893 107895790 : L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
894 :
895 107895790 : synth_ltp[j] = L_tmp2; /* Qx */
896 107895790 : move16();
897 :
898 107895790 : x0++;
899 107895790 : x1++;
900 107895790 : y0++;
901 107895790 : y1++;
902 : }
903 : }
904 : }
905 : #else
906 : FOR( j = 0; j < length; j++ )
907 : {
908 : s = L_deposit_l( 0 );
909 : s2 = L_deposit_l( 0 );
910 : k = 0;
911 : move16();
912 : FOR( i = 0; i < L; i++ )
913 : {
914 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
915 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
916 : k = k + pitch_res;
917 : }
918 :
919 : /* s2 *= ALPHA;
920 : normal: synth_ltp[j] = synth[j] - gain * s2 + gain * s;
921 : zir: synth_ltp[j] = synth[j] - gain * s2 + gain * s - zir[j];
922 : fade-in/out: synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s; */
923 : L_tmp = L_sub_sat( s, Mpy_32_16_r( s2, ALPHA ) ); /* Qx */
924 : L_tmp2 = Mpy_32_16_r( L_tmp, gain ); /* Qx */
925 : IF( fade != 0 )
926 : L_tmp2 = Mpy_32_16_r( L_tmp2, alpha ); /* Qx */
927 : L_tmp2 = L_add_sat( synth[j], L_tmp2 ); /* Qx */
928 : if ( zir != NULL )
929 : {
930 : L_tmp2 = L_sub_sat( L_tmp2, zir[j] ); /* Qx */
931 : }
932 :
933 : synth_ltp[j] = L_tmp2; /* Qx */
934 : move16();
935 :
936 : BASOP_SATURATE_WARNING_OFF_EVS;
937 : if ( fade != 0 )
938 : {
939 : alpha = add_sat( alpha, step );
940 : }
941 : BASOP_SATURATE_WARNING_ON_EVS;
942 :
943 : x0++;
944 : x1++;
945 : y0++;
946 : y1++;
947 : }
948 : #endif
949 : }
950 : ELSE
951 : {
952 1905948 : Copy32( synth, synth_ltp, length ); /* Qx */
953 : }
954 2270942 : }
955 :
956 0 : static void tcx_ltp_synth_filter_10(
957 : Word16 *out, /* Qx */
958 : Word16 *in, /* Qx */
959 : const Word16 length, /* Q0 */
960 : const Word16 pitch_int, /* Q0 */
961 : const Word16 pitch_fr, /* Q0 */
962 : const Word16 gain, /* Q15 */
963 : const Word16 pitch_res, /* Q0 */
964 : const Word16 filtIdx /* Q0 */
965 : )
966 : {
967 : Word16 *x0, *x1;
968 : Word16 *y0, *y1;
969 : Word32 s, s2;
970 : const Word16 *v0, *v1;
971 : const Word16 *w0, *w1;
972 : Word16 i, j, k, L;
973 : Word16 curr_gain, gain_step;
974 :
975 0 : x0 = &out[-pitch_int]; /* Qx */
976 0 : x1 = x0 - 1;
977 0 : y0 = in; /* Qx */
978 0 : y1 = y0 - 1;
979 :
980 0 : assert( GE_16( filtIdx, 0 ) );
981 :
982 0 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
983 0 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
984 0 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
985 0 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
986 0 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
987 :
988 0 : curr_gain = gain;
989 0 : move16();
990 :
991 0 : gain_step = div_s( negate( gain ), length ); /* Q15 */
992 :
993 0 : FOR( j = 0; j < length; j++ )
994 : {
995 0 : s = 0;
996 0 : s2 = 0;
997 0 : move32();
998 0 : move32();
999 0 : k = 0;
1000 0 : move16();
1001 0 : FOR( i = 0; i < L; i++ )
1002 : {
1003 0 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
1004 0 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
1005 0 : k = add( k, pitch_res );
1006 : }
1007 :
1008 0 : out[j] = add_sat( in[j], mult_r_sat( curr_gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
1009 :
1010 0 : x0++;
1011 0 : x1++;
1012 0 : y0++;
1013 0 : y1++;
1014 :
1015 0 : curr_gain = add( curr_gain, gain_step );
1016 : }
1017 :
1018 0 : return;
1019 : }
1020 :
1021 27633 : static void tcx_ltp_synth_filter_10_fx(
1022 : Word32 *out, /* Qx */
1023 : Word32 *in, /* Qx */
1024 : const Word16 length, /* Q0 */
1025 : const Word16 pitch_int, /* Q0 */
1026 : const Word16 pitch_fr, /* Q0 */
1027 : const Word16 gain, /* Q15 */
1028 : const Word16 pitch_res, /* Q0 */
1029 : const Word16 filtIdx /* Q0 */
1030 : )
1031 : {
1032 : Word32 *x0, *x1;
1033 : Word32 *y0, *y1;
1034 : Word32 s, s2;
1035 : const Word16 *v0, *v1;
1036 : const Word16 *w0, *w1;
1037 : Word16 i, j, k, L;
1038 : Word16 curr_gain, gain_step;
1039 :
1040 27633 : x0 = &out[-pitch_int]; /* Qx */
1041 27633 : x1 = x0 - 1;
1042 27633 : y0 = in; /* Qx */
1043 27633 : y1 = y0 - 1;
1044 :
1045 27633 : assert( filtIdx >= 0 );
1046 :
1047 27633 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
1048 27633 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
1049 27633 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
1050 27633 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
1051 27633 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
1052 :
1053 27633 : curr_gain = gain;
1054 27633 : move16();
1055 27633 : gain_step = idiv1616( negate( gain ), length ); // TODO
1056 :
1057 5646513 : FOR( j = 0; j < length; j++ )
1058 : {
1059 5618880 : s = 0;
1060 5618880 : move16();
1061 5618880 : s2 = 0;
1062 5618880 : move16();
1063 5618880 : k = 0;
1064 5618880 : move16();
1065 43352960 : FOR( i = 0; i < L; i++ )
1066 : {
1067 37734080 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
1068 37734080 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
1069 37734080 : k = k + pitch_res;
1070 : }
1071 :
1072 5618880 : out[j] = L_add_sat( in[j], Mpy_32_16_1( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), curr_gain ) ); /* Qx */
1073 5618880 : move32();
1074 5618880 : x0++;
1075 5618880 : x1++;
1076 5618880 : y0++;
1077 5618880 : y1++;
1078 :
1079 5618880 : curr_gain = add( curr_gain, gain_step );
1080 : }
1081 :
1082 27633 : return;
1083 : }
1084 :
1085 0 : static void tcx_ltp_synth_filter_01(
1086 : Word16 *out, /* Qx */
1087 : Word16 *in, /* Qx */
1088 : const Word16 length, /* Q0 */
1089 : const Word16 pitch_int, /* Q0 */
1090 : const Word16 pitch_fr, /* Q0 */
1091 : const Word16 gain, /* Q15 */
1092 : const Word16 pitch_res, /* Q0 */
1093 : const Word16 filtIdx /* Q0 */
1094 : )
1095 : {
1096 : Word16 *x0, *x1;
1097 : Word16 *y0, *y1;
1098 : Word32 s, s2;
1099 : const Word16 *v0, *v1;
1100 : const Word16 *w0, *w1;
1101 : Word16 i, j, k, L;
1102 : Word16 curr_gain, gain_step;
1103 :
1104 0 : x0 = &out[-( pitch_int )]; /* Qx */
1105 0 : x1 = x0 - 1;
1106 0 : y0 = in; /* Qx */
1107 0 : y1 = y0 - 1;
1108 :
1109 0 : assert( filtIdx >= 0 );
1110 :
1111 0 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
1112 0 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
1113 0 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
1114 0 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
1115 0 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
1116 :
1117 0 : curr_gain = 0;
1118 0 : move16();
1119 0 : gain_step = idiv1616( gain, length ); // TODO
1120 :
1121 0 : for ( j = 0; j < length; j++ )
1122 : {
1123 0 : s = 0;
1124 0 : move16();
1125 0 : s2 = 0;
1126 0 : move16();
1127 :
1128 0 : for ( i = 0, k = 0; i < L; i++, k = k + pitch_res )
1129 : {
1130 0 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
1131 0 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
1132 : }
1133 :
1134 0 : out[j] = add_sat( in[j], mult_r_sat( curr_gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
1135 0 : move32();
1136 :
1137 0 : x0++;
1138 0 : x1++;
1139 0 : y0++;
1140 0 : y1++;
1141 :
1142 0 : curr_gain = add( curr_gain, gain_step );
1143 : }
1144 :
1145 0 : return;
1146 : }
1147 :
1148 28847 : static void tcx_ltp_synth_filter_01_fx(
1149 : Word32 *out, /* Qx */
1150 : Word32 *in, /* Qx */
1151 : const Word16 length, /* Q0 */
1152 : const Word16 pitch_int, /* Q0 */
1153 : const Word16 pitch_fr, /* Q0 */
1154 : const Word16 gain, /* Q15 */
1155 : const Word16 pitch_res, /* Q0 */
1156 : const Word16 filtIdx /* Q0 */
1157 : )
1158 : {
1159 : Word32 *x0, *x1;
1160 : Word32 *y0, *y1;
1161 : Word32 s, s2;
1162 : const Word16 *v0, *v1;
1163 : const Word16 *w0, *w1;
1164 : Word16 i, j, k, L;
1165 : Word16 curr_gain, gain_step;
1166 :
1167 28847 : x0 = &out[-( pitch_int )]; /* Qx */
1168 28847 : x1 = x0 - 1;
1169 28847 : y0 = in; /* Qx */
1170 28847 : y1 = y0 - 1;
1171 :
1172 28847 : assert( filtIdx >= 0 );
1173 :
1174 28847 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr]; /* Q15 */
1175 28847 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr]; /* Q15 */
1176 28847 : v0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
1177 28847 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
1178 28847 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
1179 :
1180 28847 : curr_gain = 0;
1181 28847 : move16();
1182 28847 : gain_step = idiv1616( gain, length );
1183 :
1184 5907407 : FOR( j = 0; j < length; j++ )
1185 : {
1186 5878560 : s = 0;
1187 5878560 : move16();
1188 5878560 : s2 = 0;
1189 5878560 : move16();
1190 5878560 : k = 0;
1191 5878560 : move16();
1192 45426880 : FOR( i = 0; i < L; i++ )
1193 : {
1194 39548320 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
1195 39548320 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
1196 39548320 : k = k + pitch_res;
1197 : }
1198 :
1199 5878560 : out[j] = L_add_sat( in[j], Mpy_32_16_r( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), curr_gain ) ); /* Qx */
1200 5878560 : move32();
1201 :
1202 5878560 : x0++;
1203 5878560 : x1++;
1204 5878560 : y0++;
1205 5878560 : y1++;
1206 :
1207 5878560 : curr_gain = add( curr_gain, gain_step );
1208 : }
1209 :
1210 28847 : return;
1211 : }
1212 :
1213 : /*-------------------------------------------------------------------
1214 : *tcx_ltp_synth_filter_11_unequal_pitch_flt()
1215 : *
1216 : * blend between two filters by means of OAO
1217 : * filter the input signal at the initial subinterval with
1218 : * the first filter unit according to parameters associated to
1219 : * the preceding update interval with scaling from non-zero gain towards 0
1220 : * followed by the second filter unit according to parameters associated to
1221 : * the current update interval with scaling from 0 towards non-zero gain
1222 : ---------------------------------------------------------------------*/
1223 :
1224 0 : static void tcx_ltp_synth_filter_11_unequal_pitch(
1225 : Word16 *out, /* Qx */
1226 : Word16 *in, /* Qx */
1227 : const Word16 length, /* Q0 */
1228 : const Word16 cur_pitch_int, /* Q0 */
1229 : const Word16 cur_pitch_fr, /* Q0 */
1230 : const Word16 cur_gain, /* Q15 */
1231 : const Word16 pitch_res, /* Q0 */
1232 : const Word16 filtIdx, /* Q0 */
1233 : const Word16 prev_pitch_int, /* Q0 */
1234 : const Word16 prev_pitch_fr, /* Q0 */
1235 : const Word16 prev_gain, /* Q15 */
1236 : const Word16 prev_pitch_res, /* Q0 */
1237 : const Word16 prev_filtIdx /* Q0 */
1238 : )
1239 : {
1240 : Word16 *x0, *x1;
1241 : Word16 *y0, *y1;
1242 : Word16 *l0, *l1;
1243 : Word16 *m0, *m1;
1244 : Word32 s, s2, s3, s4;
1245 : const Word16 *v0, *v1;
1246 : const Word16 *w0, *w1;
1247 : const Word16 *p0, *p1;
1248 : const Word16 *q0, *q1;
1249 : Word16 i, j, k, L;
1250 : Word16 prev_L;
1251 : Word16 temp_buf[MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN];
1252 : Word16 *temp_ptr;
1253 : Word16 gain, gain_step;
1254 :
1255 0 : x0 = &out[-( prev_pitch_int )];
1256 0 : x1 = x0 - 1;
1257 0 : y0 = in;
1258 0 : y1 = y0 - 1;
1259 :
1260 0 : assert( ( filtIdx >= 0 ) && ( prev_filtIdx >= 0 ) );
1261 :
1262 0 : w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr]; /* Q15 */
1263 0 : w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; /* Q15 */
1264 0 : v0 = &tcxLtpFilters[prev_filtIdx].filt[0]; /* Q15 */
1265 0 : v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res]; /* Q15 */
1266 :
1267 0 : prev_L = tcxLtpFilters[prev_filtIdx].length; /* Q0 */
1268 0 : move16();
1269 :
1270 0 : p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr]; /* Q15 */
1271 0 : p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr]; /* Q15 */
1272 0 : q0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
1273 0 : q1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
1274 :
1275 0 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
1276 0 : move16();
1277 :
1278 : /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */
1279 0 : gain = prev_gain;
1280 0 : move16();
1281 0 : gain_step = idiv1616( negate( prev_gain ), length );
1282 :
1283 0 : FOR( j = 0; j < length; j++ )
1284 : {
1285 0 : s = 0;
1286 0 : move16();
1287 0 : s2 = 0;
1288 0 : move16();
1289 0 : k = 0;
1290 0 : move16();
1291 0 : FOR( i = 0; i < prev_L; i++ )
1292 : {
1293 0 : s = L_mac_sat( L_mac_sat( s, w0[k], x0[i] ), w1[k], x1[-i] ); /* Qx */
1294 0 : s2 = L_mac_sat( L_mac_sat( s2, v0[k], y0[i] ), v1[k], y1[-i] ); /* Qx */
1295 0 : k = k + prev_pitch_res;
1296 : }
1297 :
1298 0 : out[j] = add_sat( in[j], mult_r_sat( gain, sub_sat( round_fx_sat( s ), mult_r_sat( round_fx_sat( s2 ), ALPHA ) ) ) ); /* Qx */
1299 :
1300 0 : x0++;
1301 0 : x1++;
1302 0 : y0++;
1303 0 : y1++;
1304 :
1305 0 : gain = add( gain, gain_step );
1306 : }
1307 :
1308 0 : Copy( out - L, temp_buf, length + L ); /* Qx */
1309 0 : Copy( in + length, temp_buf + length + L, L ); /* Qx */
1310 0 : temp_ptr = &temp_buf[0] + L;
1311 :
1312 0 : m0 = temp_ptr; /* Qx */
1313 0 : m1 = temp_ptr - 1; /* Qx */
1314 0 : l0 = &out[-( cur_pitch_int )]; /* Qx */
1315 0 : l1 = l0 - 1;
1316 :
1317 : /* 2. increasing gain filter. The second filter unit with the parameters associated to the current interval and scaling from 0 towards current gain */
1318 0 : gain = 0;
1319 0 : move16();
1320 0 : gain_step = idiv1616( cur_gain, length );
1321 :
1322 0 : FOR( j = 0; j < length; j++ )
1323 : {
1324 0 : s3 = 0;
1325 0 : move16();
1326 0 : s4 = 0;
1327 0 : move16();
1328 0 : k = 0;
1329 0 : move16();
1330 0 : FOR( i = 0; i < L; i++ )
1331 : {
1332 0 : s3 = L_mac_sat( L_mac_sat( s3, p0[k], l0[i] ), p1[k], l1[-i] ); /* Qx */
1333 0 : s4 = L_mac_sat( L_mac_sat( s4, q0[k], m0[i] ), q1[k], m1[-i] ); /* Qx */
1334 0 : k = k + pitch_res;
1335 : }
1336 :
1337 0 : out[j] = add_sat( *( temp_ptr + j ), mult_r_sat( gain, sub_sat( round_fx_sat( s3 ), mult_r_sat( round_fx_sat( s4 ), ALPHA ) ) ) ); /* Qx */
1338 0 : move32();
1339 :
1340 0 : l0++;
1341 0 : l1++;
1342 0 : m0++;
1343 0 : m1++;
1344 :
1345 0 : gain = add( gain, gain_step );
1346 : }
1347 :
1348 0 : return;
1349 : }
1350 :
1351 120624 : static void tcx_ltp_synth_filter_11_unequal_pitch_fx(
1352 : Word32 *out, /* Qx */
1353 : Word32 *in, /* Qx */
1354 : const Word16 length, /* Q0 */
1355 : const Word16 cur_pitch_int, /* Q0 */
1356 : const Word16 cur_pitch_fr, /* Q0 */
1357 : const Word16 cur_gain, /* Q15 */
1358 : const Word16 pitch_res, /* Q0 */
1359 : const Word16 filtIdx, /* Q0 */
1360 : const Word16 prev_pitch_int, /* Q0 */
1361 : const Word16 prev_pitch_fr, /* Q0 */
1362 : const Word16 prev_gain, /* Q15 */
1363 : const Word16 prev_pitch_res, /* Q0 */
1364 : const Word16 prev_filtIdx /* Q0 */
1365 : )
1366 : {
1367 : Word32 *x0, *x1;
1368 : Word32 *y0, *y1;
1369 : Word32 *l0, *l1;
1370 : Word32 *m0, *m1;
1371 : Word32 s, s2, s3, s4;
1372 : const Word16 *v0, *v1;
1373 : const Word16 *w0, *w1;
1374 : const Word16 *p0, *p1;
1375 : const Word16 *q0, *q1;
1376 : Word16 i, j, k, L;
1377 : Word16 prev_L;
1378 : Word32 temp_buf[MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN];
1379 : Word32 *temp_ptr;
1380 : Word16 gain, gain_step;
1381 :
1382 120624 : x0 = &out[-( prev_pitch_int )]; /* Qx */
1383 120624 : x1 = x0 - 1;
1384 120624 : y0 = in; /* Qx */
1385 120624 : y1 = y0 - 1;
1386 :
1387 120624 : assert( GE_16( filtIdx, 0 ) && GE_16( prev_filtIdx, 0 ) );
1388 :
1389 120624 : w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr]; /* Q15 */
1390 120624 : w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr]; /* Q15 */
1391 120624 : v0 = &tcxLtpFilters[prev_filtIdx].filt[0]; /* Q15 */
1392 120624 : v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res]; /* Q15 */
1393 :
1394 120624 : prev_L = tcxLtpFilters[prev_filtIdx].length; /* Q0 */
1395 120624 : move16();
1396 :
1397 120624 : p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr]; /* Q15 */
1398 120624 : p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr]; /* Q15 */
1399 120624 : q0 = &tcxLtpFilters[filtIdx].filt[0]; /* Q15 */
1400 120624 : q1 = &tcxLtpFilters[filtIdx].filt[pitch_res]; /* Q15 */
1401 :
1402 120624 : L = tcxLtpFilters[filtIdx].length; /* Q0 */
1403 120624 : move16();
1404 :
1405 : /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */
1406 120624 : gain = prev_gain;
1407 120624 : move16();
1408 120624 : gain_step = idiv1616( negate( prev_gain ), length ); // TODOD
1409 :
1410 24648944 : FOR( j = 0; j < length; j++ )
1411 : {
1412 24528320 : s = 0;
1413 24528320 : move16();
1414 24528320 : s2 = 0;
1415 24528320 : move16();
1416 24528320 : k = 0;
1417 24528320 : move16();
1418 191180800 : FOR( i = 0; i < prev_L; i++ )
1419 : {
1420 166652480 : s = Madd_32_16_r( Madd_32_16_r( s, x0[i], w0[k] ), x1[-i], w1[k] ); /* Qx */
1421 166652480 : s2 = Madd_32_16_r( Madd_32_16_r( s2, y0[i], v0[k] ), y1[-i], v1[k] ); /* Qx */
1422 166652480 : k += prev_pitch_res;
1423 : }
1424 :
1425 24528320 : out[j] = L_add_sat( in[j], Mpy_32_16_r( L_sub_sat( s, Mpy_32_16_1( s2, ALPHA ) ), gain ) ); /* Qx */
1426 24528320 : move32();
1427 24528320 : x0++;
1428 24528320 : x1++;
1429 24528320 : y0++;
1430 24528320 : y1++;
1431 :
1432 24528320 : gain = add( gain, gain_step );
1433 : }
1434 :
1435 120624 : Copy32( out - L, temp_buf, length + L ); /* Qx */
1436 120624 : Copy32( in + length, temp_buf + length + L, L ); /* Qx */
1437 120624 : temp_ptr = &temp_buf[0] + L; /* Qx */
1438 :
1439 120624 : m0 = temp_ptr; /* Qx */
1440 120624 : m1 = temp_ptr - 1;
1441 120624 : l0 = &out[-( cur_pitch_int )]; /* Qx */
1442 120624 : l1 = l0 - 1;
1443 :
1444 : /* 2. increasing gain filter. The second filter unit with the parameters associated to the current interval and scaling from 0 towards current gain */
1445 120624 : gain = 0;
1446 120624 : move16();
1447 120624 : gain_step = idiv1616( cur_gain, length );
1448 :
1449 24648944 : FOR( j = 0; j < length; j++ )
1450 : {
1451 24528320 : s3 = 0;
1452 24528320 : move16();
1453 24528320 : s4 = 0;
1454 24528320 : move16();
1455 24528320 : k = 0;
1456 191180800 : FOR( i = 0; i < L; i++ )
1457 : {
1458 166652480 : s3 = Madd_32_16_r( Madd_32_16_r( s3, l0[i], p0[k] ), l1[-i], p1[k] ); /* Qx */
1459 166652480 : s4 = Madd_32_16_r( Madd_32_16_r( s4, m0[i], q0[k] ), m1[-i], q1[k] ); /* Qx */
1460 166652480 : k = add( k, pitch_res );
1461 : }
1462 :
1463 24528320 : out[j] = L_add_sat( *( temp_ptr + j ), Mpy_32_16_r( L_sub_sat( s3, Mpy_32_16_1( s4, ALPHA ) ), gain ) ); /* Qx */
1464 24528320 : move32();
1465 :
1466 24528320 : l0++;
1467 24528320 : l1++;
1468 24528320 : m0++;
1469 24528320 : m1++;
1470 :
1471 24528320 : gain = add( gain, gain_step );
1472 : }
1473 :
1474 120624 : return;
1475 : }
1476 :
1477 832050 : Word16 tcx_ltp_decode_params(
1478 : Word16 *ltp_param, /* Q0 */
1479 : Word16 *pitch_int, /* Q0 */
1480 : Word16 *pitch_fr, /* Q0 */
1481 : Word16 *gain, /* Q13 */
1482 : const Word16 pitmin, /* Q0 */
1483 : const Word16 pitfr1, /* Q0 */
1484 : const Word16 pitfr2, /* Q0 */
1485 : const Word16 pitmax, /* Q0 */
1486 : const Word16 pitres /* Q0 */
1487 : )
1488 : {
1489 : Word16 tmp, tmp2;
1490 :
1491 :
1492 : /* Decode Pitch and Gain */
1493 832050 : test();
1494 832050 : IF( ltp_param != 0 && ltp_param[0] != 0 )
1495 : {
1496 557525 : tmp = imult1616( sub( pitfr2, pitmin ), pitres ); /* Q0 */
1497 :
1498 557525 : IF( LT_16( ltp_param[1], tmp ) )
1499 : {
1500 376748 : tmp2 = idiv1616U( ltp_param[1], pitres );
1501 :
1502 376748 : *pitch_int = add( pitmin, tmp2 ); /* Q0 */
1503 376748 : move16();
1504 376748 : tmp2 = sub( *pitch_int, pitmin ); /* Q0 */
1505 376748 : *pitch_fr = sub( ltp_param[1], imult1616( tmp2, pitres ) ); /* Q0 */
1506 376748 : move16();
1507 : }
1508 : ELSE
1509 : {
1510 180777 : tmp2 = imult1616( sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ); /* Q0 */
1511 :
1512 180777 : IF( LT_16( ltp_param[1], add( tmp, tmp2 ) ) )
1513 : {
1514 54381 : tmp2 = idiv1616U( sub( ltp_param[1], tmp ), shr( pitres, 1 ) ); /* Q0 */
1515 :
1516 54381 : *pitch_int = add( pitfr2, tmp2 ); /* Q0 */
1517 54381 : move16();
1518 54381 : *pitch_fr = shl( sub( sub( ltp_param[1], tmp ), imult1616( tmp2, shr( pitres, 1 ) ) ), 1 ); /* Q0 */
1519 54381 : move16();
1520 : }
1521 : ELSE
1522 : {
1523 126396 : *pitch_int = sub( add( ltp_param[1], pitfr1 ), add( tmp, tmp2 ) ); /* Q0 */
1524 126396 : move16();
1525 126396 : *pitch_fr = 0;
1526 126396 : move16();
1527 : }
1528 : }
1529 :
1530 557525 : *gain = imult1616( add( ltp_param[2], 1 ), 0x1400 /* 0.625 in Q13 */ ); /* Q13 */
1531 557525 : move16();
1532 :
1533 557525 : IF( LT_16( *pitch_int, PIT_MIN_SHORTER ) )
1534 : {
1535 : /*pitch out of range due to bit error */
1536 0 : *pitch_int = PIT_MIN_SHORTER; /* Q0 */
1537 0 : move16();
1538 0 : return 1;
1539 : }
1540 :
1541 557525 : IF( GT_16( *pitch_int, PIT_MAX_MAX ) )
1542 : {
1543 : /*pitch out of range due to bit error */
1544 0 : *pitch_int = PIT_MAX_MAX; /* Q0 */
1545 0 : move16();
1546 0 : return 1;
1547 : }
1548 : }
1549 : ELSE
1550 : {
1551 274525 : *pitch_int = pitmax; /* Q0 */
1552 274525 : move16();
1553 274525 : *pitch_fr = 0;
1554 274525 : move16();
1555 274525 : *gain = 0;
1556 274525 : move16();
1557 : }
1558 :
1559 832050 : return 0;
1560 : }
1561 :
1562 3100 : void tcx_ltp_post_fx(
1563 : Decoder_State *st,
1564 : TCX_LTP_DEC_HANDLE hTcxLtpDec,
1565 : Word16 core, /* Q0 */
1566 : Word16 output_frame, /* Q0 */
1567 : Word16 delay, /* Q0 */
1568 : Word16 *sig, /* Qx */
1569 : Word16 *tcx_buf /* Qx */
1570 : )
1571 : {
1572 : Word16 tmp, L_transition, lpcorder, filtIdx;
1573 : Word16 gain, gain2;
1574 : Word32 tmp32;
1575 : Word16 zir[L_FRAME_PLUS / 4], A[TCXLTP_LTP_ORDER + 1];
1576 : Word16 buf_in[TCXLTP_MAX_DELAY + L_FRAME48k + TCXLTP_MAX_DELAY], buf_out[2 * L_FRAME48k];
1577 : Word16 *sig_in, *sig_out;
1578 : Word16 pitch_int, pitch_fr;
1579 : Word16 tcx_buf_len, bfi, L_frame_core, SideInfoOnly;
1580 : Word32 total_brate;
1581 :
1582 3100 : total_brate = st->total_brate; /* Q0 */
1583 3100 : move32();
1584 3100 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
1585 : {
1586 0 : total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); /* Q0 */
1587 0 : move32();
1588 : }
1589 :
1590 3100 : filtIdx = 0; /* just to avoid comilation warnings */
1591 3100 : move16();
1592 3100 : tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
1593 3100 : SideInfoOnly = 0;
1594 3100 : move16();
1595 3100 : if ( GE_32( total_brate, HQ_96k ) )
1596 : {
1597 0 : SideInfoOnly = 1;
1598 0 : move16();
1599 : }
1600 :
1601 3100 : L_frame_core = st->L_frame; /* Q0 */
1602 3100 : move16();
1603 :
1604 3100 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
1605 : {
1606 0 : L_frame_core = L_FRAME; /* Q0 */
1607 0 : move16();
1608 : }
1609 :
1610 3100 : IF( EQ_16( core, ACELP_CORE ) )
1611 : {
1612 2466 : bfi = 0;
1613 2466 : move16();
1614 2466 : pitch_int = 0;
1615 2466 : move16();
1616 2466 : pitch_fr = 0;
1617 2466 : move16();
1618 2466 : gain = 0;
1619 2466 : move16();
1620 2466 : L_frame_core = st->L_frame_past; /* Q0 */
1621 2466 : move16();
1622 : }
1623 : ELSE
1624 : {
1625 634 : bfi = st->bfi; /* Q0 */
1626 634 : pitch_int = hTcxLtpDec->tcxltp_pitch_int; /* Q0 */
1627 634 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr; /* Q0 */
1628 634 : gain = hTcxLtpDec->tcxltp_gain; /* Q15 */
1629 634 : move16();
1630 634 : move16();
1631 634 : move16();
1632 634 : move16();
1633 : }
1634 : /******** Init ********/
1635 :
1636 :
1637 : /* Parameters */
1638 3100 : L_transition = shr( output_frame, 2 ); /* Q0 */
1639 3100 : lpcorder = TCXLTP_LTP_ORDER;
1640 3100 : move16();
1641 :
1642 : /* Input buffer */
1643 3100 : sig_in = buf_in + tcx_buf_len;
1644 3100 : Copy( hTcxLtpDec->tcxltp_mem_in, buf_in, tcx_buf_len ); /* exp(exp_tcxltp_mem_in) */
1645 3100 : Copy( sig, buf_in + tcx_buf_len, output_frame ); /* Qx */
1646 3100 : IF( GT_16( core, ACELP_CORE ) )
1647 : {
1648 634 : Copy( tcx_buf, sig_in + output_frame, tcx_buf_len ); /* Qx */
1649 : }
1650 3100 : Copy( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in, tcx_buf_len ); /* Qx */
1651 :
1652 : /* Output buffer */
1653 3100 : sig_out = buf_out + output_frame;
1654 3100 : Copy( hTcxLtpDec->tcxltp_mem_out, buf_out, output_frame ); /* exp(exp_tcxltp_mem_out) */
1655 :
1656 : /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
1657 3100 : test();
1658 3100 : test();
1659 3100 : IF( !( SideInfoOnly != 0 || hTcxLtpDec->tcxltp != 0 ) || EQ_16( core, ACELP_CORE ) )
1660 : {
1661 : /* No LTP */
1662 2466 : pitch_int = 0;
1663 2466 : move16();
1664 2466 : pitch_fr = 0;
1665 2466 : move16();
1666 2466 : gain = 0;
1667 2466 : move16();
1668 : }
1669 634 : ELSE IF( bfi == 0 )
1670 : {
1671 : /* LTP and good frame */
1672 634 : test();
1673 634 : IF( EQ_16( st->element_mode, EVS_MONO ) ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
1674 : {
1675 634 : IF( NE_16( output_frame, L_frame_core ) )
1676 : {
1677 634 : tmp = div_s( output_frame, shl( L_frame_core, 2 ) ); /* Q13 */
1678 634 : tmp32 = L_mult0( add( imult1616( pitch_int, st->pit_res_max ), pitch_fr ), tmp ); /* Q13 */
1679 634 : tmp = round_fx( L_shl( tmp32, 3 ) ); /* Q0 */
1680 634 : pitch_int = idiv1616U( tmp, st->pit_res_max );
1681 634 : pitch_fr = sub( tmp, imult1616( pitch_int, st->pit_res_max ) ); /* Q0 */
1682 : }
1683 634 : test();
1684 634 : test();
1685 634 : IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, L_FRAME16k ) )
1686 : {
1687 0 : gain = mult_r( gain, 10486 /*0.32f Q15*/ ); /* Q15 */
1688 : }
1689 634 : ELSE IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, 512 ) )
1690 : {
1691 0 : gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
1692 : }
1693 : ELSE
1694 : {
1695 634 : gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
1696 : }
1697 : }
1698 0 : ELSE IF( GT_16( st->element_mode, IVAS_SCE ) && GE_32( total_brate, IVAS_96k ) )
1699 : {
1700 0 : gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
1701 : }
1702 : ELSE
1703 : {
1704 0 : gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
1705 : }
1706 : }
1707 : ELSE
1708 : {
1709 : /* PLC: [TCX: Fade-out]
1710 : * PLC: LTP and bad frame (concealment) */
1711 0 : IF( EQ_16( st->pit_res_max, st->pit_res_max_past ) ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
1712 : {
1713 0 : pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev;
1714 0 : move16();
1715 0 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev;
1716 0 : move16();
1717 0 : gain = shl( mult_r( hTcxLtpDec->tcxltp_gain_post_prev, st->hTcxDec->damping ), 1 );
1718 : }
1719 : ELSE
1720 : {
1721 0 : gain = 0;
1722 0 : move16();
1723 : }
1724 : }
1725 :
1726 :
1727 3100 : IF( SideInfoOnly != 0 )
1728 : {
1729 0 : gain = 0;
1730 0 : move16();
1731 0 : if ( bfi != 0 )
1732 : {
1733 0 : hTcxLtpDec->tcxltp_gain_post_prev = 0;
1734 0 : move16();
1735 : }
1736 : }
1737 3100 : gain2 = gain;
1738 3100 : move16();
1739 :
1740 3100 : IF( EQ_16( L_frame_core, L_FRAME ) )
1741 : {
1742 2046 : SWITCH( output_frame )
1743 : {
1744 0 : case L_FRAME8k:
1745 0 : filtIdx = 0;
1746 0 : move16();
1747 0 : BREAK;
1748 0 : case L_FRAME16k:
1749 0 : filtIdx = 1;
1750 0 : move16();
1751 0 : BREAK;
1752 1046 : case L_FRAME32k:
1753 1046 : filtIdx = 2;
1754 1046 : move16();
1755 1046 : BREAK;
1756 1000 : case L_FRAME48k:
1757 1000 : filtIdx = 3;
1758 1000 : move16();
1759 1000 : BREAK;
1760 0 : default:
1761 0 : assert( 0 );
1762 : }
1763 : }
1764 1054 : ELSE IF( EQ_16( L_frame_core, L_FRAME16k ) )
1765 : {
1766 1037 : SWITCH( output_frame )
1767 : {
1768 0 : case L_FRAME8k:
1769 0 : filtIdx = 4;
1770 0 : move16();
1771 0 : BREAK;
1772 0 : case L_FRAME16k:
1773 0 : filtIdx = 5;
1774 0 : move16();
1775 0 : BREAK;
1776 4 : case L_FRAME32k:
1777 4 : filtIdx = 6;
1778 4 : move16();
1779 4 : BREAK;
1780 1033 : case L_FRAME48k:
1781 1033 : filtIdx = 7;
1782 1033 : move16();
1783 1033 : BREAK;
1784 0 : default:
1785 0 : assert( 0 );
1786 : }
1787 : }
1788 17 : ELSE IF( EQ_16( L_frame_core, 512 ) )
1789 : {
1790 0 : SWITCH( output_frame )
1791 : {
1792 0 : case L_FRAME8k:
1793 0 : filtIdx = 8;
1794 0 : move16();
1795 0 : BREAK;
1796 0 : case L_FRAME16k:
1797 0 : filtIdx = 9;
1798 0 : move16();
1799 0 : BREAK;
1800 0 : case L_FRAME32k:
1801 0 : filtIdx = 10;
1802 0 : move16();
1803 0 : BREAK;
1804 0 : case L_FRAME48k:
1805 0 : filtIdx = 11;
1806 0 : move16();
1807 0 : BREAK;
1808 0 : default:
1809 0 : assert( 0 );
1810 : }
1811 : }
1812 : ELSE
1813 : {
1814 17 : filtIdx = -1;
1815 17 : move16();
1816 : }
1817 :
1818 :
1819 : /******** Previous-frame part ********/
1820 :
1821 3100 : tcx_ltp_synth_filter( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev,
1822 3100 : st->pit_res_max_past, NULL, 0, hTcxLtpDec->tcxltp_filt_idx_prev );
1823 :
1824 : /******** Transition part ********/
1825 :
1826 3100 : test();
1827 3100 : test();
1828 3100 : test();
1829 : // #ifdef IVAS_CODE_TCX_LTP
1830 3100 : IF( NE_16( st->element_mode, EVS_MONO ) )
1831 : {
1832 0 : test();
1833 0 : test();
1834 0 : test();
1835 0 : test();
1836 0 : test();
1837 0 : test();
1838 0 : test();
1839 0 : IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
1840 : {
1841 : /* The filtering is deactivated, just copy input to the output */
1842 0 : Copy( sig_in + delay, sig_out + delay, L_transition ); /* Qx */
1843 : }
1844 0 : ELSE IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev != 0 )
1845 : {
1846 : /* Filtering with the first filter unit */
1847 0 : tcx_ltp_synth_filter_10( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1848 : }
1849 0 : ELSE IF( gain != 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
1850 : {
1851 : /* Filtering with the second filter unit */
1852 0 : tcx_ltp_synth_filter_01( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1853 : }
1854 0 : ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) && EQ_16( st->pit_res_max, st->pit_res_max_past ) && EQ_16( filtIdx, hTcxLtpDec->tcxltp_filt_idx_prev ) )
1855 : {
1856 0 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
1857 : }
1858 : ELSE
1859 : {
1860 : /* Filtering with the first filter unit, followed by the filtering with the second filter unit */
1861 0 : tcx_ltp_synth_filter_11_unequal_pitch( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx,
1862 0 : hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1863 : }
1864 : }
1865 : ELSE
1866 : {
1867 3100 : test();
1868 3100 : test();
1869 3100 : test();
1870 3100 : test();
1871 3100 : IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
1872 : {
1873 2564 : Copy( sig_in + delay, sig_out + delay, L_transition ); /* Qx */
1874 : }
1875 536 : ELSE IF( hTcxLtpDec->tcxltp_gain_post_prev == 0 )
1876 : {
1877 84 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int,
1878 84 : pitch_fr, gain, st->pit_res_max, NULL, 1, filtIdx );
1879 : }
1880 452 : ELSE IF( gain == 0 )
1881 : {
1882 84 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev,
1883 84 : hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, NULL, -1, hTcxLtpDec->tcxltp_filt_idx_prev );
1884 : }
1885 368 : ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) )
1886 : {
1887 123 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
1888 : }
1889 : ELSE
1890 : {
1891 245 : tcx_ltp_get_lpc( sig_out + delay - output_frame, output_frame, A, lpcorder );
1892 :
1893 245 : tcx_ltp_get_zir( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx );
1894 :
1895 245 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, 0, filtIdx );
1896 : }
1897 : }
1898 :
1899 : /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/
1900 :
1901 3100 : tcx_ltp_synth_filter( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
1902 :
1903 :
1904 : /******** Output ********/
1905 :
1906 :
1907 : /* copy to output */
1908 :
1909 3100 : Copy( sig_out, sig, output_frame ); /* Qx */
1910 :
1911 : /* Update */
1912 3100 : hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
1913 3100 : move16();
1914 3100 : hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
1915 3100 : move16();
1916 3100 : hTcxLtpDec->tcxltp_gain_post_prev = gain2;
1917 3100 : move16();
1918 3100 : hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
1919 3100 : move16();
1920 3100 : st->pit_res_max_past = st->pit_res_max;
1921 3100 : move16();
1922 3100 : Copy( sig_out, hTcxLtpDec->tcxltp_mem_out, output_frame ); /* Qx */
1923 3100 : }
1924 :
1925 :
1926 : /* IVAS 32-bit variant */
1927 1124260 : void tcx_ltp_post_fx32(
1928 : Decoder_State *st,
1929 : TCX_LTP_DEC_HANDLE hTcxLtpDec,
1930 : Word16 core, /* Q0 */
1931 : Word16 output_frame, /* Q0 */
1932 : Word16 delay, /* Q0 */
1933 : Word32 *sig, /* sig_q */
1934 : Word32 *tcx_buf, /* sig_q */
1935 : Word16 sig_q )
1936 : {
1937 : Word16 tmp, L_transition, lpcorder, filtIdx;
1938 : Word16 gain, gain2;
1939 : Word32 tmp32;
1940 : Word32 zir[L_FRAME_PLUS / 4], A[TCXLTP_LTP_ORDER + 1];
1941 : Word32 buf_in[TCXLTP_MAX_DELAY + L_FRAME48k + TCXLTP_MAX_DELAY], buf_out[2 * L_FRAME48k];
1942 : Word32 *sig_in, *sig_out;
1943 : Word16 pitch_int, pitch_fr;
1944 : Word16 tcx_buf_len, bfi, L_frame_core, SideInfoOnly;
1945 : Word32 total_brate;
1946 :
1947 1124260 : total_brate = st->total_brate;
1948 1124260 : move32();
1949 1124260 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
1950 : {
1951 698688 : total_brate = L_mult0( st->bits_frame_nominal, FRAMES_PER_SEC ); // TDO
1952 698688 : move32();
1953 : }
1954 :
1955 1124260 : filtIdx = 0; /* just to avoid comilation warnings */
1956 1124260 : move16();
1957 1124260 : tcx_buf_len = NS2SA_FX2( st->output_Fs, TCXLTP_DELAY_NS ); /* Q0 */
1958 1124260 : move16();
1959 1124260 : SideInfoOnly = 0;
1960 1124260 : move16();
1961 1124260 : if ( GE_32( total_brate, HQ_96k ) )
1962 : {
1963 400596 : SideInfoOnly = 1;
1964 400596 : move16();
1965 : }
1966 :
1967 1124260 : L_frame_core = st->L_frame; /* Q0 */
1968 1124260 : move16();
1969 :
1970 1124260 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
1971 : {
1972 698688 : L_frame_core = L_FRAME;
1973 698688 : move16();
1974 : }
1975 :
1976 1124260 : IF( EQ_16( core, ACELP_CORE ) )
1977 : {
1978 204274 : bfi = 0;
1979 204274 : pitch_int = 0;
1980 204274 : pitch_fr = 0;
1981 204274 : gain = 0;
1982 204274 : L_frame_core = st->L_frame_past; /* Q0 */
1983 204274 : move16();
1984 204274 : move16();
1985 204274 : move16();
1986 204274 : move16();
1987 : }
1988 : ELSE
1989 : {
1990 919986 : bfi = st->bfi; /* Q0 */
1991 919986 : pitch_int = hTcxLtpDec->tcxltp_pitch_int; /* Q0 */
1992 919986 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr; /* Q0 */
1993 919986 : gain = hTcxLtpDec->tcxltp_gain; /* Q15 */
1994 919986 : move16();
1995 919986 : move16();
1996 919986 : move16();
1997 919986 : move16();
1998 : }
1999 : /******** Init ********/
2000 :
2001 :
2002 : /* Parameters */
2003 1124260 : L_transition = shr( output_frame, 2 ); /* Q0 */
2004 1124260 : lpcorder = TCXLTP_LTP_ORDER;
2005 1124260 : move16();
2006 :
2007 : /* Input buffer */
2008 1124260 : sig_in = buf_in + tcx_buf_len;
2009 1124260 : Copy32( hTcxLtpDec->tcxltp_mem_in_32, buf_in, tcx_buf_len ); /* exp(exp_tcxltp_mem_in)*/
2010 1124260 : scale_sig32( buf_in, tcx_buf_len, sub( hTcxLtpDec->exp_tcxltp_mem_in, sub( 31, sig_q ) ) );
2011 1124260 : Copy32( sig, buf_in + tcx_buf_len, output_frame ); /* sig_q */
2012 1124260 : IF( core > ACELP_CORE )
2013 : {
2014 919986 : Copy32( tcx_buf, sig_in + output_frame, tcx_buf_len ); /* sig_q */
2015 : }
2016 1124260 : Copy32( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in_32, tcx_buf_len ); /* sig_q */
2017 1124260 : hTcxLtpDec->exp_tcxltp_mem_in = sub( 31, sig_q );
2018 1124260 : move16();
2019 : /* Output buffer */
2020 1124260 : sig_out = buf_out + output_frame;
2021 1124260 : Copy32( hTcxLtpDec->tcxltp_mem_out_32, buf_out, output_frame ); /* exp(exp_tcxltp_mem_out) */
2022 1124260 : scale_sig32( buf_out, output_frame, sub( hTcxLtpDec->exp_tcxltp_mem_out, sub( 31, sig_q ) ) );
2023 :
2024 : /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
2025 1124260 : test();
2026 1124260 : test();
2027 1124260 : IF( !( SideInfoOnly != 0 || hTcxLtpDec->tcxltp != 0 ) || EQ_16( core, ACELP_CORE ) )
2028 : {
2029 : /* No LTP */
2030 500717 : pitch_int = 0;
2031 500717 : move16();
2032 500717 : pitch_fr = 0;
2033 500717 : move16();
2034 500717 : gain = 0;
2035 500717 : move16();
2036 : }
2037 623543 : ELSE IF( bfi == 0 )
2038 : {
2039 : /* LTP and good frame */
2040 619131 : IF( NE_16( output_frame, L_frame_core ) )
2041 : {
2042 610356 : tmp = div_s( output_frame, shl( L_frame_core, 2 ) ); /* Q13 */
2043 610356 : tmp32 = L_mult0( add( imult1616( pitch_int, st->pit_res_max ), pitch_fr ), tmp ); /* Q13 */
2044 610356 : tmp = round_fx( L_shl( tmp32, 3 ) ); /* Q0 */
2045 610356 : pitch_int = idiv1616U( tmp, st->pit_res_max );
2046 610356 : pitch_fr = sub( tmp, imult1616( pitch_int, st->pit_res_max ) ); /* Q0 */
2047 : }
2048 619131 : IF( st->element_mode == EVS_MONO ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
2049 : {
2050 0 : test();
2051 0 : test();
2052 0 : IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, L_FRAME16k ) )
2053 : {
2054 0 : gain = mult_r( gain, 10486 /*0.32f Q15*/ ); /* Q15 */
2055 : }
2056 0 : ELSE IF( EQ_32( total_brate, 48000 ) && EQ_16( L_frame_core, 512 ) )
2057 : {
2058 0 : gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
2059 : }
2060 : ELSE
2061 : {
2062 0 : gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
2063 : }
2064 : }
2065 619131 : ELSE IF( GT_16( st->element_mode, IVAS_SCE ) && GE_32( total_brate, IVAS_96k ) )
2066 : {
2067 382830 : gain = mult_r( gain, 13107 /*0.40f Q15*/ ); /* Q15 */
2068 : }
2069 : ELSE
2070 : {
2071 236301 : gain = mult_r( gain, 20972 /*0.64f Q15*/ ); /* Q15 */
2072 : }
2073 : }
2074 : ELSE
2075 : {
2076 : /* PLC: [TCX: Fade-out]
2077 : * PLC: LTP and bad frame (concealment) */
2078 4412 : IF( st->pit_res_max == st->pit_res_max_past ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
2079 : {
2080 4412 : pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev; /* Q0 */
2081 4412 : move16();
2082 4412 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev; /* Q0 */
2083 4412 : move16();
2084 4412 : gain = shl( mult_r( hTcxLtpDec->tcxltp_gain_post_prev, st->hTcxDec->damping ), 1 ); /* Q15 */
2085 : }
2086 : ELSE
2087 : {
2088 0 : gain = 0;
2089 0 : move16();
2090 : }
2091 : }
2092 :
2093 :
2094 1124260 : IF( SideInfoOnly != 0 )
2095 : {
2096 400596 : gain = 0;
2097 400596 : move16();
2098 400596 : if ( bfi != 0 )
2099 : {
2100 2839 : hTcxLtpDec->tcxltp_gain_post_prev = 0;
2101 2839 : move16();
2102 : }
2103 : }
2104 1124260 : gain2 = gain;
2105 1124260 : move16();
2106 :
2107 1124260 : IF( EQ_16( L_frame_core, L_FRAME ) )
2108 : {
2109 811781 : SWITCH( output_frame )
2110 : {
2111 0 : case L_FRAME8k:
2112 0 : filtIdx = 0;
2113 0 : move16();
2114 0 : BREAK;
2115 80253 : case L_FRAME16k:
2116 80253 : filtIdx = 1;
2117 80253 : move16();
2118 80253 : BREAK;
2119 186039 : case L_FRAME32k:
2120 186039 : filtIdx = 2;
2121 186039 : move16();
2122 186039 : BREAK;
2123 545489 : case L_FRAME48k:
2124 545489 : filtIdx = 3;
2125 545489 : move16();
2126 545489 : BREAK;
2127 0 : default:
2128 0 : assert( 0 );
2129 : }
2130 : }
2131 312479 : ELSE IF( EQ_16( L_frame_core, L_FRAME16k ) )
2132 : {
2133 180898 : SWITCH( output_frame )
2134 : {
2135 0 : case L_FRAME8k:
2136 0 : filtIdx = 4;
2137 0 : move16();
2138 0 : BREAK;
2139 19031 : case L_FRAME16k:
2140 19031 : filtIdx = 5;
2141 19031 : move16();
2142 19031 : BREAK;
2143 46738 : case L_FRAME32k:
2144 46738 : filtIdx = 6;
2145 46738 : move16();
2146 46738 : BREAK;
2147 115129 : case L_FRAME48k:
2148 115129 : filtIdx = 7;
2149 115129 : move16();
2150 115129 : BREAK;
2151 0 : default:
2152 0 : assert( 0 );
2153 : }
2154 : }
2155 131581 : ELSE IF( EQ_16( L_frame_core, 512 ) )
2156 : {
2157 13935 : SWITCH( output_frame )
2158 : {
2159 0 : case L_FRAME8k:
2160 0 : filtIdx = 8;
2161 0 : move16();
2162 0 : BREAK;
2163 133 : case L_FRAME16k:
2164 133 : filtIdx = 9;
2165 133 : move16();
2166 133 : BREAK;
2167 2685 : case L_FRAME32k:
2168 2685 : filtIdx = 10;
2169 2685 : move16();
2170 2685 : BREAK;
2171 11117 : case L_FRAME48k:
2172 11117 : filtIdx = 11;
2173 11117 : move16();
2174 11117 : BREAK;
2175 0 : default:
2176 0 : assert( 0 );
2177 : }
2178 : }
2179 : ELSE
2180 : {
2181 117646 : filtIdx = -1;
2182 117646 : move16();
2183 : }
2184 :
2185 :
2186 : /******** Previous-frame part ********/
2187 :
2188 1124260 : tcx_ltp_synth_filter32( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev,
2189 1124260 : st->pit_res_max_past, NULL, 0, hTcxLtpDec->tcxltp_filt_idx_prev );
2190 :
2191 : /******** Transition part ********/
2192 1124260 : IF( NE_16( st->element_mode, EVS_MONO ) )
2193 : {
2194 1124260 : test();
2195 1124260 : test();
2196 1124260 : test();
2197 1124260 : test();
2198 1124260 : test();
2199 1124260 : test();
2200 1124260 : test();
2201 1124260 : test();
2202 1124260 : IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
2203 : {
2204 : /* The filtering is deactivated, just copy input to the output */
2205 924734 : Copy32( sig_in + delay, sig_out + delay, L_transition ); /* sig_q */
2206 : }
2207 199526 : ELSE IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev != 0 )
2208 : {
2209 : /* Filtering with the first filter unit */
2210 27633 : tcx_ltp_synth_filter_10_fx( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
2211 : }
2212 171893 : ELSE IF( gain != 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
2213 : {
2214 : /* Filtering with the second filter unit */
2215 28847 : tcx_ltp_synth_filter_01_fx( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
2216 : }
2217 143046 : ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) && EQ_16( st->pit_res_max, st->pit_res_max_past ) && EQ_16( filtIdx, hTcxLtpDec->tcxltp_filt_idx_prev ) )
2218 : {
2219 22422 : tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
2220 : }
2221 : ELSE
2222 : {
2223 : /* Filtering with the first filter unit, followed by the filtering with the second filter unit */
2224 120624 : tcx_ltp_synth_filter_11_unequal_pitch_fx( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx,
2225 120624 : hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
2226 : }
2227 : }
2228 : ELSE
2229 : {
2230 0 : test();
2231 0 : test();
2232 0 : test();
2233 0 : IF( gain == 0 && hTcxLtpDec->tcxltp_gain_post_prev == 0 )
2234 : {
2235 0 : Copy32( sig_in + delay, sig_out + delay, L_transition ); /* sig_q */
2236 : }
2237 0 : ELSE IF( hTcxLtpDec->tcxltp_gain_post_prev == 0 )
2238 : {
2239 0 : tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int,
2240 0 : pitch_fr, gain, st->pit_res_max, NULL, 1, filtIdx );
2241 : }
2242 0 : ELSE IF( gain == 0 )
2243 : {
2244 0 : tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev,
2245 0 : hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, NULL, -1, hTcxLtpDec->tcxltp_filt_idx_prev );
2246 : }
2247 0 : ELSE IF( EQ_16( gain, hTcxLtpDec->tcxltp_gain_post_prev ) && EQ_16( pitch_int, hTcxLtpDec->tcxltp_pitch_int_post_prev ) && EQ_16( pitch_fr, hTcxLtpDec->tcxltp_pitch_fr_post_prev ) )
2248 : {
2249 0 : tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
2250 : }
2251 : ELSE
2252 : {
2253 0 : tcx_ltp_get_lpc_fx( sig_out + delay - output_frame, output_frame, A, lpcorder );
2254 :
2255 0 : tcx_ltp_get_zir_fx( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx );
2256 :
2257 0 : tcx_ltp_synth_filter32( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, 0, filtIdx );
2258 : }
2259 : }
2260 :
2261 : /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/
2262 :
2263 1124260 : tcx_ltp_synth_filter32( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, NULL, 0, filtIdx );
2264 :
2265 :
2266 : /******** Output ********/
2267 :
2268 :
2269 : /* copy to output */
2270 :
2271 1124260 : Copy32( sig_out, sig, output_frame ); /* sig_q */
2272 :
2273 : /* Update */
2274 1124260 : hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
2275 1124260 : move16();
2276 1124260 : hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
2277 1124260 : move16();
2278 1124260 : hTcxLtpDec->tcxltp_gain_post_prev = gain2;
2279 1124260 : move16();
2280 1124260 : hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
2281 1124260 : move16();
2282 1124260 : st->pit_res_max_past = st->pit_res_max;
2283 1124260 : Copy32( sig_out, hTcxLtpDec->tcxltp_mem_out_32, output_frame ); /* sig_q */
2284 1124260 : hTcxLtpDec->exp_tcxltp_mem_out = sub( 31, sig_q );
2285 1124260 : move16();
2286 1124260 : }
|