Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <assert.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h"
10 : #include "stl.h"
11 :
12 2345880677 : static Word32 syn_kern_2( Word32 L_tmp, const Word16 a[], const Word16 y[] )
13 : {
14 : #ifndef ISSUE_1836_replace_overflow_libcom
15 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
16 : Flag Overflow = 0;
17 : #endif
18 : L_tmp = L_msu_o( L_tmp, y[-1], a[1], &Overflow );
19 : return L_msu_o( L_tmp, y[-2], a[2], &Overflow );
20 : #else
21 2345880677 : L_tmp = L_msu_sat( L_tmp, y[-1], a[1] );
22 2345880677 : return L_msu_sat( L_tmp, y[-2], a[2] );
23 : #endif
24 : }
25 :
26 1126283402 : static Word32 syn_kern_4( Word32 L_tmp, const Word16 a[], const Word16 y[] )
27 : {
28 1126283402 : L_tmp = syn_kern_2( L_tmp, a, y );
29 1126283402 : return syn_kern_2( L_tmp, a + 2, y - 2 );
30 : }
31 :
32 1111050 : static Word32 syn_kern_6( Word32 L_tmp, const Word16 a[], const Word16 y[] )
33 : {
34 1111050 : L_tmp = syn_kern_4( L_tmp, a, y );
35 1111050 : return syn_kern_2( L_tmp, a + 4, y - 4 );
36 : }
37 :
38 562586176 : static Word32 syn_kern_8( Word32 L_tmp, const Word16 a[], const Word16 y[] )
39 : {
40 562586176 : L_tmp = syn_kern_4( L_tmp, a, y );
41 562586176 : return syn_kern_4( L_tmp, a + 4, y - 4 );
42 : }
43 :
44 92202823 : static Word32 syn_kern_10( Word32 L_tmp, const Word16 a[], const Word16 y[] )
45 : {
46 92202823 : L_tmp = syn_kern_8( L_tmp, a, y );
47 92202823 : return syn_kern_2( L_tmp, a + 8, y - 8 );
48 : }
49 :
50 235168814 : Word32 syn_kern_16( Word32 L_tmp, const Word16 a[], const Word16 y[] )
51 : {
52 235168814 : L_tmp = syn_kern_8( L_tmp, a, y );
53 235168814 : return syn_kern_8( L_tmp, a + 8, y - 8 );
54 : }
55 :
56 45725 : static Word32 syn_kern_24( Word32 L_tmp, const Word16 a[], const Word16 y[] )
57 : {
58 45725 : L_tmp = syn_kern_16( L_tmp, a, y );
59 45725 : return syn_kern_8( L_tmp, a + 16, y - 16 );
60 : }
61 :
62 :
63 13600030 : static Word32 syn_kern_2_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
64 : {
65 13600030 : L_tmp = Msub_32_32_r( L_tmp, y[-1], a[1] );
66 13600030 : return Msub_32_32_r( L_tmp, y[-2], a[2] );
67 : }
68 :
69 5440012 : static Word32 syn_kern_4_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
70 : {
71 5440012 : L_tmp = syn_kern_2_fx( L_tmp, a, y );
72 5440012 : return syn_kern_2_fx( L_tmp, a + 2, y - 2 );
73 : }
74 :
75 0 : static Word32 syn_kern_6_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
76 : {
77 0 : L_tmp = syn_kern_4_fx( L_tmp, a, y );
78 0 : return syn_kern_2_fx( L_tmp, a + 4, y - 4 );
79 : }
80 :
81 2720006 : static Word32 syn_kern_8_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
82 : {
83 2720006 : L_tmp = syn_kern_4_fx( L_tmp, a, y );
84 2720006 : return syn_kern_4_fx( L_tmp, a + 4, y - 4 );
85 : }
86 :
87 2720006 : static Word32 syn_kern_10_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
88 : {
89 2720006 : L_tmp = syn_kern_8_fx( L_tmp, a, y );
90 2720006 : return syn_kern_2_fx( L_tmp, a + 8, y - 8 );
91 : }
92 :
93 0 : static Word32 syn_kern_16_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
94 : {
95 0 : L_tmp = syn_kern_8_fx( L_tmp, a, y );
96 0 : return syn_kern_8_fx( L_tmp, a + 8, y - 8 );
97 : }
98 :
99 0 : static Word32 syn_kern_24_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
100 : {
101 0 : L_tmp = syn_kern_16_fx( L_tmp, a, y );
102 0 : return syn_kern_8_fx( L_tmp, a + 16, y - 16 );
103 : }
104 :
105 :
106 : /*------------------------------------------------------------------*
107 : * Syn_filt_s_lc:
108 : *
109 : * perform the synthesis filtering 1/A(z).
110 : * Optimized Version when No Memory, Past is Set to 0
111 : *------------------------------------------------------------------*/
112 2186859 : void syn_filt_s_lc_fx(
113 : const Word16 shift, /* i : scaling to apply Q0 */
114 : const Word16 a[], /* i : LP filter coefficients Q12 */
115 : const Word16 x[], /* i : input signal Qx */
116 : Word16 y[], /* o : output signal Qx-s */
117 : const Word16 lg /* i : size of filtering Q0 */
118 : )
119 : {
120 : Word16 i, j;
121 : Word32 L_tmp;
122 : Word16 a0;
123 : Word16 q;
124 :
125 :
126 2186859 : q = add( norm_s( a[0] ), 1 );
127 2186859 : a0 = shr( a[0], shift ); /* input / 2^shift */
128 :
129 : /*-----------------------------------------------------------------------*
130 : * Do the filtering
131 : *-----------------------------------------------------------------------*/
132 37176603 : FOR( i = 0; i < M; i++ )
133 : {
134 34989744 : L_tmp = L_mult( *x++, a0 );
135 : /* Stop at i to Avoid Mults with Zeros */
136 297412824 : FOR( j = 1; j <= i; j++ )
137 : {
138 262423080 : L_tmp = L_msu_sat( L_tmp, y[-j], a[j] );
139 : }
140 :
141 34989744 : L_tmp = L_shl_sat( L_tmp, q );
142 34989744 : *y++ = round_fx_sat( L_tmp );
143 34989744 : move16();
144 : }
145 :
146 87593979 : FOR( ; i < lg; i++ )
147 : {
148 85407120 : L_tmp = syn_kern_16( L_mult( *x++, a0 ), a, y );
149 85407120 : L_tmp = L_shl_sat( L_tmp, q );
150 85407120 : *y++ = round_fx_sat( L_tmp );
151 85407120 : move16();
152 : }
153 2186859 : }
154 :
155 : /*------------------------------------------------------------------*
156 : * Syn_filt_s:
157 : *
158 : * perform the synthesis filtering 1/A(z).
159 : *------------------------------------------------------------------*/
160 3002330 : void Syn_filt_s(
161 : const Word16 shift, /* i : scaling to apply Q0 */
162 : const Word16 a[], /* i : LP filter coefficients Q12 */
163 : const Word16 m, /* i : order of LP filter Q0 */
164 : const Word16 x[], /* i : input signal Qx */
165 : Word16 y[], /* o : output signal Qx-s */
166 : const Word16 lg, /* i : size of filtering Q0 */
167 : Word16 mem[], /* i/o: memory associated with this filtering. Qx-s */
168 : const Word16 update /* i : 0=no update, 1=update of memory. Q0 */
169 : )
170 : {
171 3002330 : E_UTIL_synthesis( shift, a, x, y, lg, mem, update, m );
172 3002330 : }
173 :
174 :
175 : /*------------------------------------------------------------------*
176 : * syn_filt_fx:
177 : *
178 : * perform the synthesis filtering 1/A(z).
179 : *------------------------------------------------------------------*/
180 2397485 : void syn_filt_fx(
181 : const Word16 shift, /* i : scaling to apply Q0 */
182 : const Word16 a[], /* i : LP filter coefficients Q12 */
183 : const Word16 m, /* i : order of LP filter Q0 */
184 : const Word16 x[], /* i : input signal Qx */
185 : Word16 y[], /* o : output signal Qx-s */
186 : const Word16 l, /* i : size of filtering Q0 */
187 : Word16 mem[], /* i/o: initial filter states Qx-s */
188 : const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */
189 : ) /* 1 --> update of memory */
190 : {
191 : Word16 i, j;
192 : Word16 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */
193 : Word16 *yy;
194 : Word32 s;
195 : Word16 q;
196 : Word16 a0;
197 :
198 2397485 : yy = &buf[0];
199 2397485 : q = add( norm_s( a[0] ), 1 );
200 :
201 2397485 : a0 = shr_sat( a[0], shift ); /* input / 2^shift */
202 :
203 : /*------------------------------------------------------------------*
204 : * copy initial filter states into synthesis buffer and do synthesis
205 : *------------------------------------------------------------------*/
206 :
207 33397903 : FOR( i = 0; i < m; i++ )
208 : {
209 31000418 : *yy++ = mem[i];
210 31000418 : move16();
211 : }
212 :
213 : /*-----------------------------------------------------------------------*
214 : * Do the filtering
215 : *-----------------------------------------------------------------------*/
216 :
217 183177757 : FOR( i = 0; i < l; i++ )
218 : {
219 180780272 : s = L_mult( a0, x[i] ); // Qx + Qa - shift + 1
220 2451284944 : FOR( j = 1; j <= m; j++ )
221 : {
222 2270504672 : s = L_msu_sat( s, a[j], yy[i - j] ); // Qa + Qx - shift + 1
223 : }
224 :
225 180780272 : s = L_shl_sat( s, q ); // Qx + (Qa + q)Q15 - shift + 1 = Qx - shift + Q16
226 180780272 : yy[i] = extract_h( s ); // Qx - shift
227 180780272 : move16();
228 180780272 : y[i] = extract_h( s );
229 180780272 : move16();
230 : }
231 :
232 : /*------------------------------------------------------------------*
233 : * Update memory if required
234 : *------------------------------------------------------------------*/
235 :
236 2397485 : IF( update_m )
237 : {
238 17681837 : FOR( i = 0; i < m; i++ )
239 : {
240 16366186 : mem[i] = yy[l - m + i];
241 16366186 : move16();
242 : }
243 : }
244 :
245 2397485 : return;
246 : }
247 :
248 :
249 12735 : void syn_filt_fx32(
250 : const Word16 a_e, /* i : exp of LP coeffs Q0 */
251 : const Word32 a[], /* i : LP filter coefficients Q12 */
252 : const Word16 m, /* i : order of LP filter Q0 */
253 : const Word32 x[], /* i : input signal Qx */
254 : const Word16 x_e, /* i : input signal Qx */
255 : Word32 y[], /* o : output signal Qx */
256 : Word16 *y_e, /* o : output signal Qx */
257 : const Word16 l, /* i : size of filtering Q0 */
258 : Word32 mem[], /* i/o: initial filter states Qx */
259 : Word16 *mem_e, /* i/o: initial filter states Qx */
260 : const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */
261 : ) /* 1 --> update of memory */
262 : {
263 : Word16 i, j;
264 : Word64 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */
265 : Word64 s, *yy;
266 :
267 12735 : yy = &buf[0];
268 :
269 : /*------------------------------------------------------------------*
270 : * copy initial filter states into synthesis buffer and do synthesis
271 : *------------------------------------------------------------------*/
272 :
273 140085 : FOR( i = 0; i < m; i++ )
274 : {
275 127350 : *yy++ = W_deposit32_l( mem[i] );
276 127350 : move32();
277 : }
278 :
279 : /*-----------------------------------------------------------------------*
280 : * Do the filtering
281 : *-----------------------------------------------------------------------*/
282 12735 : Word64 max_val = 1;
283 4087935 : FOR( i = 0; i < l; i++ )
284 : {
285 4075200 : s = W_deposit32_l( x[i] );
286 44827200 : FOR( j = 1; j <= m; j++ )
287 : {
288 40752000 : s = W_sub( s, W_mult0_32_32( a[j], W_extract_l( W_shr( yy[i - j], sub( 31, a_e ) ) ) ) );
289 : }
290 :
291 4075200 : yy[i] = s;
292 4075200 : move32();
293 4075200 : if ( GT_64( W_abs( s ), max_val ) )
294 : {
295 80366 : max_val = W_abs( s );
296 : }
297 : }
298 :
299 12735 : Word16 norm = W_norm( max_val );
300 :
301 4087935 : FOR( i = 0; i < l; i++ )
302 : {
303 4075200 : y[i] = W_extract_l( W_shr( yy[i], sub( 32, norm ) ) );
304 : }
305 12735 : *y_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
306 : /*------------------------------------------------------------------*
307 : * Update memory if required
308 : *------------------------------------------------------------------*/
309 :
310 12735 : IF( update_m )
311 : {
312 140085 : FOR( i = 0; i < m; i++ )
313 : {
314 127350 : mem[i] = W_extract_l( W_shr( yy[l - m + i], sub( 32, norm ) ) );
315 : }
316 12735 : *mem_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
317 : }
318 :
319 12735 : return;
320 : }
321 :
322 :
323 : /*
324 : * E_UTIL_synthesis
325 : *
326 : * Parameters:
327 : * shift i : scaling to apply for a[0] Q0
328 : * a[] i : LP filter coefficients Qx
329 : * x[] i : input signal Qx
330 : * y[] o : output signal Qx-s
331 : * lg i : size of filtering Q0
332 : * mem[] i/o: memory associated with this filtering. Qx-s
333 : * update i : 0=no update, 1=update of memory. Q0
334 : * m i : order of LP filter Q0
335 : *
336 : * Function:
337 : * Perform the synthesis filtering 1/A(z).
338 : * Memory size is always M.
339 : *
340 : * Returns:
341 : * void
342 : */
343 4672632 : void E_UTIL_synthesis( const Word16 shift, const Word16 a[], const Word16 x[], Word16 y[], const Word16 lg, Word16 mem[], const Word16 update, const Word16 m )
344 : {
345 : Word16 i, j, a0;
346 : Word32 L_tmp;
347 : Word16 q;
348 4672632 : Word32 ( *syn_kern )( Word32 L_tmp, const Word16 a[], const Word16 y[] ) = NULL;
349 : #ifndef ISSUE_1836_replace_overflow_libcom
350 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
351 : Flag Overflow = 0;
352 : move32();
353 : #endif
354 : #endif
355 :
356 4672632 : if ( EQ_16( m, 6 ) )
357 : {
358 14814 : syn_kern = syn_kern_6;
359 : }
360 4672632 : if ( EQ_16( m, 10 ) )
361 : {
362 1159856 : syn_kern = syn_kern_10;
363 : }
364 4672632 : if ( EQ_16( m, 16 ) )
365 : {
366 3497717 : syn_kern = syn_kern_16;
367 : }
368 4672632 : if ( EQ_16( m, 24 ) )
369 : {
370 245 : syn_kern = syn_kern_24;
371 : }
372 4672632 : assert( syn_kern != NULL );
373 4672632 : q = add( norm_s( a[0] ), 1 );
374 :
375 :
376 : /*-----------------------------------------------------------------------*
377 : * Set Memory Pointer at End for Backward Access
378 : *-----------------------------------------------------------------------*/
379 4672632 : mem += m; /*move16();*/
380 :
381 4672632 : a0 = shr_sat( a[0], shift ); /* input / 2^shift */
382 : /*-----------------------------------------------------------------------*
383 : * Do the filtering
384 : *-----------------------------------------------------------------------*/
385 : /* Filtering Only from Input + Memory */
386 4672632 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, mem );
387 : #ifdef ISSUE_1836_replace_overflow_libcom
388 4672632 : L_tmp = L_shl_sat( L_tmp, q );
389 4672632 : *y++ = round_fx_sat( L_tmp );
390 : #else
391 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
392 : *y++ = round_fx_o( L_tmp, &Overflow );
393 : #endif
394 4672632 : move16();
395 :
396 : /* Filtering from Input + Mix of Memory & Output Signal Past */
397 67656796 : FOR( i = 1; i < m; i++ )
398 : {
399 62984164 : L_tmp = L_mult( a0, *x++ );
400 : /* Process Output Signal Past */
401 535193554 : FOR( j = 1; j <= i; j++ )
402 : {
403 : #ifdef ISSUE_1836_replace_overflow_libcom
404 472209390 : L_tmp = L_msu_sat( L_tmp, a[j], y[-j] );
405 : #else
406 : L_tmp = L_msu_o( L_tmp, a[j], y[-j], &Overflow );
407 : #endif
408 : }
409 : /* Process Memory */
410 535193554 : FOR( ; j <= m; j++ )
411 : {
412 472209390 : L_tmp = L_msu_sat( L_tmp, a[j], mem[i - j] );
413 : }
414 : #ifdef ISSUE_1836_replace_overflow_libcom
415 62984164 : L_tmp = L_shl_sat( L_tmp, q );
416 62984164 : *y++ = round_fx_sat( L_tmp );
417 : #else
418 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
419 : *y++ = round_fx_o( L_tmp, &Overflow );
420 : #endif
421 62984164 : move16();
422 : }
423 :
424 : /* Filtering from Input + Output Signal Past */
425 243075567 : FOR( ; i < lg; i++ )
426 : {
427 238402935 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, y );
428 : #ifdef ISSUE_1836_replace_overflow_libcom
429 238402935 : L_tmp = L_shl_sat( L_tmp, q );
430 238402935 : *y++ = round_fx_sat( L_tmp );
431 : #else
432 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
433 : *y++ = round_fx_o( L_tmp, &Overflow );
434 : #endif
435 238402935 : move16();
436 : }
437 :
438 : /*-----------------------------------------------------------------------*
439 : * Update memory if required
440 : *-----------------------------------------------------------------------*/
441 4672632 : IF( update != 0 )
442 : {
443 39005928 : FOR( i = 0; i < m; i++ )
444 : {
445 36444762 : *--mem = *--y;
446 36444762 : move16();
447 : }
448 : }
449 :
450 4672632 : return;
451 : }
452 :
453 :
454 : /*
455 : * E_UTIL_synthesis_fx
456 : *
457 : * Parameters:
458 : * shift i : scaling to apply for a[0] Q0
459 : * a[] i : LP filter coefficients Qx
460 : * x[] i : input signal Qx
461 : * y[] o : output signal Qx-s
462 : * lg i : size of filtering Q0
463 : * mem[] i/o: memory associated with this filtering. Qx-s
464 : * update i : 0=no update, 1=update of memory. Q0
465 : * m i : order of LP filter Q0
466 : *
467 : * Function:
468 : * Perform the synthesis filtering 1/A(z).
469 : * Memory size is always M.
470 : *
471 : * Returns:
472 : * void
473 : */
474 8746 : void E_UTIL_synthesis_fx( const Word16 shift, const Word32 a[], const Word32 x[], Word32 y[], const Word16 lg, Word32 mem[], const Word16 update, const Word16 m )
475 : {
476 : Word16 i, j;
477 : Word32 a0;
478 : Word32 L_tmp;
479 : Word16 q;
480 8746 : Word32 ( *syn_kern )( Word32 L_tmp, const Word32 a[], const Word32 y[] ) = NULL;
481 : #ifndef ISSUE_1836_replace_overflow_libcom
482 : Flag Overflow = 0;
483 : move32();
484 : #endif
485 :
486 8746 : if ( EQ_16( m, 6 ) )
487 : {
488 0 : syn_kern = syn_kern_6_fx;
489 : }
490 8746 : if ( EQ_16( m, 10 ) )
491 : {
492 8746 : syn_kern = syn_kern_10_fx;
493 : }
494 8746 : if ( EQ_16( m, 16 ) )
495 : {
496 0 : syn_kern = syn_kern_16_fx;
497 : }
498 8746 : if ( EQ_16( m, 24 ) )
499 : {
500 0 : syn_kern = syn_kern_24_fx;
501 : }
502 8746 : assert( syn_kern != NULL );
503 8746 : q = add( norm_l( a[0] ), 1 );
504 :
505 :
506 : /*-----------------------------------------------------------------------*
507 : * Set Memory Pointer at End for Backward Access
508 : *-----------------------------------------------------------------------*/
509 8746 : mem += m; /*move32();*/
510 :
511 : #ifdef ISSUE_1836_replace_overflow_libcom
512 8746 : a0 = L_shr_sat( a[0], shift ); /* input / 2^shift */
513 : #else
514 : a0 = L_shr_o( a[0], shift, &Overflow ); /* input / 2^shift */
515 : #endif
516 :
517 : /*-----------------------------------------------------------------------*
518 : * Do the filtering
519 : *-----------------------------------------------------------------------*/
520 : /* Filtering Only from Input + Memory */
521 8746 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, mem );
522 : #ifdef ISSUE_1836_replace_overflow_libcom
523 8746 : L_tmp = L_shl_sat( L_tmp, q );
524 : #else
525 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
526 : #endif
527 8746 : *y++ = L_tmp;
528 8746 : move32();
529 :
530 : /* Filtering from Input + Mix of Memory & Output Signal Past */
531 87460 : FOR( i = 1; i < m; i++ )
532 : {
533 78714 : L_tmp = Mpy_32_32( a0, *x++ );
534 : /* Process Output Signal Past */
535 472284 : FOR( j = 1; j <= i; j++ )
536 : {
537 393570 : L_tmp = Msub_32_32_r( L_tmp, a[j], y[-j] );
538 : }
539 : /* Process Memory */
540 472284 : FOR( ; j <= m; j++ )
541 : {
542 393570 : L_tmp = Msub_32_32_r( L_tmp, a[j], mem[i - j] );
543 : }
544 : #ifdef ISSUE_1836_replace_overflow_libcom
545 78714 : L_tmp = L_shl_sat( L_tmp, q );
546 : #else
547 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
548 : #endif
549 78714 : *y++ = L_tmp;
550 78714 : move32();
551 : }
552 :
553 : /* Filtering from Input + Output Signal Past */
554 2720006 : FOR( ; i < lg; i++ )
555 : {
556 2711260 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, y );
557 : #ifdef ISSUE_1836_replace_overflow_libcom
558 2711260 : L_tmp = L_shl_sat( L_tmp, q );
559 : #else
560 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
561 : #endif
562 2711260 : *y++ = L_tmp;
563 2711260 : move32();
564 : }
565 :
566 : /*-----------------------------------------------------------------------*
567 : * Update memory if required
568 : *-----------------------------------------------------------------------*/
569 8746 : IF( update != 0 )
570 : {
571 96206 : FOR( i = 0; i < m; i++ )
572 : {
573 87460 : *--mem = *--y;
574 87460 : move32();
575 : }
576 : }
577 :
578 8746 : return;
579 : }
580 :
581 :
582 : /*-------------------------------------------------------------------*
583 : * synth_mem_updt2()
584 : *
585 : * Update of synthesis filter memories in case of ACELP@12k8 <-> ACELP@16k switching
586 : *--------------------------------------------------------------------*/
587 :
588 1216 : void ivas_synth_mem_updt2_fx(
589 : const Word16 L_frame, /* i : frame length */
590 : const Word16 last_L_frame, /* i : frame length */
591 : Word16 old_exc[], /* i/o: excitation buffer st->Q_syn */
592 : Word16 mem_syn_r[], /* i/o: synthesis filter memory st->Q_syn */
593 : Word16 mem_syn2[], /* o : synthesis filter memory for find_target st->Q_syn */
594 : Word16 mem_syn[], /* o : synthesis filter memory for find_target st->Q_syn */
595 : const Word16 dec )
596 : {
597 : Word16 mem_syn_r_size_old, mem_syn_r_size_new;
598 : Word32 en1, en2;
599 : Word16 en1_e, en2_e, loc_rat, tmp, i;
600 : Word32 tmp1, tmp2;
601 :
602 : /* Residual and update old_exc */
603 1216 : IF( GE_16( dec, DEC ) )
604 : {
605 1216 : lerp( old_exc + L_EXC_MEM_DEC - ( last_L_frame + last_L_frame / 2 ), old_exc + L_EXC_MEM_DEC - ( L_frame + L_frame / 2 ), L_frame + L_frame / 2, last_L_frame + last_L_frame / 2 );
606 : }
607 : ELSE
608 : {
609 0 : lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame );
610 : }
611 :
612 : /*Resamp memory*/
613 : /*Size of LPC syn memory*/
614 : /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */
615 1216 : mem_syn_r_size_old = shr( last_L_frame, 4 );
616 1216 : mem_syn_r_size_new = shr( L_frame, 4 );
617 :
618 1216 : lerp( mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old );
619 1216 : IF( EQ_16( dec, DEC_IVAS ) )
620 : {
621 691 : IF( EQ_16( L_frame, L_FRAME16k ) )
622 : {
623 : /* find scaling factor */
624 : // en1 = 1.25f * sum2_f( mem_syn2, M );
625 420 : en1 = Mpy_32_32( 1342177280 /*1.25f in Q30*/, sum2_f_16_fx( mem_syn2, M ) ); /* 2 * Q - 1 */
626 420 : en2 = L_shr( sum2_f_16_fx( mem_syn_r + L_SYN_MEM - M, M ), 1 ); /* 2 * Q - 1 */
627 :
628 : // loc_rat = sqrtf( en2 ) / ( sqrtf( en1 ) + 0.01f );
629 420 : IF( EQ_32( en2, 0 ) )
630 : {
631 1 : loc_rat = 0;
632 1 : move16();
633 : }
634 : ELSE
635 : {
636 :
637 419 : en1 = L_max( en1, 1 );
638 419 : en2_e = norm_l( en2 );
639 419 : en1_e = sub( norm_l( en1 ), 1 );
640 419 : tmp = div_l( L_shl( en1, en1_e ), extract_h( L_shl( en2, en2_e ) ) );
641 419 : en1_e = sub( en2_e, en1_e );
642 419 : tmp1 = L_shl_sat( tmp, sub( 16 + 1, en1_e ) ); /* Q14 because of norm - 1 for the num */
643 419 : tmp2 = Isqrt( tmp1 ); /* Q16 */
644 419 : loc_rat = round_fx_sat( L_shl_sat( tmp2, sub( 16, en1_e ) ) ); /* loc_rat in Q15 */
645 : }
646 :
647 : /* scale synthesis filter memory */
648 7140 : FOR( i = 0; i < M; i++ )
649 : {
650 : // mem_syn_r[L_SYN_MEM - M + i] *= loc_rat;
651 6720 : mem_syn_r[L_SYN_MEM - M + i] = mult_r( mem_syn_r[L_SYN_MEM - M + i], loc_rat );
652 6720 : move16();
653 : }
654 : }
655 : }
656 1216 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
657 :
658 1216 : IF( mem_syn != NULL )
659 : {
660 0 : Copy( mem_syn2, mem_syn, M );
661 : }
662 1216 : }
663 1296 : void synth_mem_updt2(
664 : const Word16 L_frame, /* i : frame length */
665 : const Word16 last_L_frame, /* i : frame length */
666 : Word16 old_exc[], /* i/o: excitation buffer st->Q_syn */
667 : Word16 mem_syn_r[], /* i/o: synthesis filter memory st->Q_syn */
668 : Word16 mem_syn2[], /* o : synthesis filter memory for find_target st->Q_syn */
669 : Word16 mem_syn[], /* o : synthesis filter memory for find_target st->Q_syn */
670 : const Word16 dec /* i : flag for decoder indication */
671 : )
672 : {
673 : Word16 mem_syn_r_size_old, mem_syn_r_size_new;
674 :
675 : /* Residual and update old_exc */
676 1296 : IF( GE_16( dec, DEC ) )
677 : {
678 2 : lerp( old_exc + L_EXC_MEM_DEC - ( last_L_frame + last_L_frame / 2 ), old_exc + L_EXC_MEM_DEC - ( L_frame + L_frame / 2 ), L_frame + L_frame / 2, last_L_frame + last_L_frame / 2 );
679 : }
680 : ELSE
681 : {
682 1294 : lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame );
683 : }
684 :
685 : /*Resamp memory*/
686 : /*Size of LPC syn memory*/
687 : /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */
688 1296 : mem_syn_r_size_old = shr( last_L_frame, 4 );
689 1296 : mem_syn_r_size_new = shr( L_frame, 4 );
690 :
691 1296 : lerp( mem_syn_r + L_SYN_MEM - mem_syn_r_size_old, mem_syn_r + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old );
692 :
693 1296 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
694 :
695 1296 : IF( mem_syn != NULL )
696 : {
697 1294 : Copy( mem_syn2, mem_syn, M );
698 : }
699 1296 : }
|