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 1666821165 : 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 1666821165 : L_tmp = L_msu_sat( L_tmp, y[-1], a[1] );
22 1666821165 : return L_msu_sat( L_tmp, y[-2], a[2] );
23 : #endif
24 : }
25 :
26 790269003 : static Word32 syn_kern_4( Word32 L_tmp, const Word16 a[], const Word16 y[] )
27 : {
28 790269003 : L_tmp = syn_kern_2( L_tmp, a, y );
29 790269003 : return syn_kern_2( L_tmp, a + 2, y - 2 );
30 : }
31 :
32 518175 : static Word32 syn_kern_6( Word32 L_tmp, const Word16 a[], const Word16 y[] )
33 : {
34 518175 : L_tmp = syn_kern_4( L_tmp, a, y );
35 518175 : return syn_kern_2( L_tmp, a + 4, y - 4 );
36 : }
37 :
38 394875414 : static Word32 syn_kern_8( Word32 L_tmp, const Word16 a[], const Word16 y[] )
39 : {
40 394875414 : L_tmp = syn_kern_4( L_tmp, a, y );
41 394875414 : return syn_kern_4( L_tmp, a + 4, y - 4 );
42 : }
43 :
44 85764984 : static Word32 syn_kern_10( Word32 L_tmp, const Word16 a[], const Word16 y[] )
45 : {
46 85764984 : L_tmp = syn_kern_8( L_tmp, a, y );
47 85764984 : return syn_kern_2( L_tmp, a + 8, y - 8 );
48 : }
49 :
50 154530908 : Word32 syn_kern_16( Word32 L_tmp, const Word16 a[], const Word16 y[] )
51 : {
52 154530908 : L_tmp = syn_kern_8( L_tmp, a, y );
53 154530908 : return syn_kern_8( L_tmp, a + 8, y - 8 );
54 : }
55 :
56 48614 : static Word32 syn_kern_24( Word32 L_tmp, const Word16 a[], const Word16 y[] )
57 : {
58 48614 : L_tmp = syn_kern_16( L_tmp, a, y );
59 48614 : return syn_kern_8( L_tmp, a + 16, y - 16 );
60 : }
61 :
62 :
63 13567375 : static Word32 syn_kern_2_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
64 : {
65 13567375 : L_tmp = Msub_32_32_r( L_tmp, y[-1], a[1] );
66 13567375 : return Msub_32_32_r( L_tmp, y[-2], a[2] );
67 : }
68 :
69 5426950 : static Word32 syn_kern_4_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
70 : {
71 5426950 : L_tmp = syn_kern_2_fx( L_tmp, a, y );
72 5426950 : 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 2713475 : static Word32 syn_kern_8_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
82 : {
83 2713475 : L_tmp = syn_kern_4_fx( L_tmp, a, y );
84 2713475 : return syn_kern_4_fx( L_tmp, a + 4, y - 4 );
85 : }
86 :
87 2713475 : static Word32 syn_kern_10_fx( Word32 L_tmp, const Word32 a[], const Word32 y[] )
88 : {
89 2713475 : L_tmp = syn_kern_8_fx( L_tmp, a, y );
90 2713475 : 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 474243 : 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 474243 : q = add( norm_s( a[0] ), 1 );
127 474243 : a0 = shr( a[0], shift ); /* input / 2^shift */
128 :
129 : /*-----------------------------------------------------------------------*
130 : * Do the filtering
131 : *-----------------------------------------------------------------------*/
132 8062131 : FOR( i = 0; i < M; i++ )
133 : {
134 7587888 : L_tmp = L_mult( *x++, a0 );
135 : /* Stop at i to Avoid Mults with Zeros */
136 64497048 : FOR( j = 1; j <= i; j++ )
137 : {
138 56909160 : L_tmp = L_msu_sat( L_tmp, y[-j], a[j] );
139 : }
140 :
141 7587888 : L_tmp = L_shl_sat( L_tmp, q );
142 7587888 : *y++ = round_fx_sat( L_tmp );
143 7587888 : move16();
144 : }
145 :
146 23237907 : FOR( ; i < lg; i++ )
147 : {
148 22763664 : L_tmp = syn_kern_16( L_mult( *x++, a0 ), a, y );
149 22763664 : L_tmp = L_shl_sat( L_tmp, q );
150 22763664 : *y++ = round_fx_sat( L_tmp );
151 22763664 : move16();
152 : }
153 474243 : }
154 :
155 : /*------------------------------------------------------------------*
156 : * Syn_filt_s:
157 : *
158 : * perform the synthesis filtering 1/A(z).
159 : *------------------------------------------------------------------*/
160 2704194 : 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 2704194 : E_UTIL_synthesis( shift, a, x, y, lg, mem, update, m );
172 2704194 : }
173 :
174 :
175 : /*------------------------------------------------------------------*
176 : * syn_filt_fx:
177 : *
178 : * perform the synthesis filtering 1/A(z).
179 : *------------------------------------------------------------------*/
180 0 : 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 0 : yy = &buf[0];
199 0 : q = add( norm_s( a[0] ), 1 );
200 :
201 0 : 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 0 : FOR( i = 0; i < m; i++ )
208 : {
209 0 : *yy++ = mem[i];
210 0 : move16();
211 : }
212 :
213 : /*-----------------------------------------------------------------------*
214 : * Do the filtering
215 : *-----------------------------------------------------------------------*/
216 :
217 0 : FOR( i = 0; i < l; i++ )
218 : {
219 0 : s = L_mult( a0, x[i] ); // Qx + Qa - shift + 1
220 0 : FOR( j = 1; j <= m; j++ )
221 : {
222 0 : s = L_msu_sat( s, a[j], yy[i - j] ); // Qa + Qx - shift + 1
223 : }
224 :
225 0 : s = L_shl_sat( s, q ); // Qx + (Qa + q)Q15 - shift + 1 = Qx - shift + Q16
226 0 : yy[i] = extract_h( s ); // Qx - shift
227 0 : move16();
228 0 : y[i] = extract_h( s );
229 0 : move16();
230 : }
231 :
232 : /*------------------------------------------------------------------*
233 : * Update memory if required
234 : *------------------------------------------------------------------*/
235 :
236 0 : IF( update_m )
237 : {
238 0 : FOR( i = 0; i < m; i++ )
239 : {
240 0 : mem[i] = yy[l - m + i];
241 0 : move16();
242 : }
243 : }
244 :
245 0 : return;
246 : }
247 :
248 :
249 0 : 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 0 : yy = &buf[0];
268 :
269 : /*------------------------------------------------------------------*
270 : * copy initial filter states into synthesis buffer and do synthesis
271 : *------------------------------------------------------------------*/
272 :
273 0 : FOR( i = 0; i < m; i++ )
274 : {
275 0 : *yy++ = W_deposit32_l( mem[i] );
276 0 : move32();
277 : }
278 :
279 : /*-----------------------------------------------------------------------*
280 : * Do the filtering
281 : *-----------------------------------------------------------------------*/
282 0 : Word64 max_val = 1;
283 0 : FOR( i = 0; i < l; i++ )
284 : {
285 0 : s = W_deposit32_l( x[i] );
286 0 : FOR( j = 1; j <= m; j++ )
287 : {
288 0 : 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 0 : yy[i] = s;
292 0 : move32();
293 0 : if ( GT_64( W_abs( s ), max_val ) )
294 : {
295 0 : max_val = W_abs( s );
296 : }
297 : }
298 :
299 0 : Word16 norm = W_norm( max_val );
300 :
301 0 : FOR( i = 0; i < l; i++ )
302 : {
303 0 : y[i] = W_extract_l( W_shr( yy[i], sub( 32, norm ) ) );
304 : }
305 0 : *y_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
306 : /*------------------------------------------------------------------*
307 : * Update memory if required
308 : *------------------------------------------------------------------*/
309 :
310 0 : IF( update_m )
311 : {
312 0 : FOR( i = 0; i < m; i++ )
313 : {
314 0 : mem[i] = W_extract_l( W_shr( yy[l - m + i], sub( 32, norm ) ) );
315 : }
316 0 : *mem_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
317 : }
318 :
319 0 : 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 4317581 : 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 4317581 : 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 4317581 : if ( EQ_16( m, 6 ) )
357 : {
358 6909 : syn_kern = syn_kern_6;
359 : }
360 4317581 : if ( EQ_16( m, 10 ) )
361 : {
362 1130424 : syn_kern = syn_kern_10;
363 : }
364 4317581 : if ( EQ_16( m, 16 ) )
365 : {
366 3179986 : syn_kern = syn_kern_16;
367 : }
368 4317581 : if ( EQ_16( m, 24 ) )
369 : {
370 262 : syn_kern = syn_kern_24;
371 : }
372 4317581 : assert( syn_kern != NULL );
373 4317581 : q = add( norm_s( a[0] ), 1 );
374 :
375 :
376 : /*-----------------------------------------------------------------------*
377 : * Set Memory Pointer at End for Backward Access
378 : *-----------------------------------------------------------------------*/
379 4317581 : mem += m; /*move16();*/
380 :
381 4317581 : a0 = shr_sat( a[0], shift ); /* input / 2^shift */
382 : /*-----------------------------------------------------------------------*
383 : * Do the filtering
384 : *-----------------------------------------------------------------------*/
385 : /* Filtering Only from Input + Memory */
386 4317581 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, mem );
387 : #ifdef ISSUE_1836_replace_overflow_libcom
388 4317581 : L_tmp = L_shl_sat( L_tmp, q );
389 4317581 : *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 4317581 : move16();
395 :
396 : /* Filtering from Input + Mix of Memory & Output Signal Past */
397 62231758 : FOR( i = 1; i < m; i++ )
398 : {
399 57914177 : L_tmp = L_mult( a0, *x++ );
400 : /* Process Output Signal Past */
401 490557524 : FOR( j = 1; j <= i; j++ )
402 : {
403 : #ifdef ISSUE_1836_replace_overflow_libcom
404 432643347 : 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 490557524 : FOR( ; j <= m; j++ )
411 : {
412 432643347 : L_tmp = L_msu_sat( L_tmp, a[j], mem[i - j] );
413 : }
414 : #ifdef ISSUE_1836_replace_overflow_libcom
415 57914177 : L_tmp = L_shl_sat( L_tmp, q );
416 57914177 : *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 57914177 : move16();
422 : }
423 :
424 : /* Filtering from Input + Output Signal Past */
425 218050403 : FOR( ; i < lg; i++ )
426 : {
427 213732822 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, y );
428 : #ifdef ISSUE_1836_replace_overflow_libcom
429 213732822 : L_tmp = L_shl_sat( L_tmp, q );
430 213732822 : *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 213732822 : move16();
436 : }
437 :
438 : /*-----------------------------------------------------------------------*
439 : * Update memory if required
440 : *-----------------------------------------------------------------------*/
441 4317581 : IF( update != 0 )
442 : {
443 34759969 : FOR( i = 0; i < m; i++ )
444 : {
445 32456294 : *--mem = *--y;
446 32456294 : move16();
447 : }
448 : }
449 :
450 4317581 : 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 8725 : 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 8725 : 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 8725 : if ( EQ_16( m, 6 ) )
487 : {
488 0 : syn_kern = syn_kern_6_fx;
489 : }
490 8725 : if ( EQ_16( m, 10 ) )
491 : {
492 8725 : syn_kern = syn_kern_10_fx;
493 : }
494 8725 : if ( EQ_16( m, 16 ) )
495 : {
496 0 : syn_kern = syn_kern_16_fx;
497 : }
498 8725 : if ( EQ_16( m, 24 ) )
499 : {
500 0 : syn_kern = syn_kern_24_fx;
501 : }
502 8725 : assert( syn_kern != NULL );
503 8725 : q = add( norm_l( a[0] ), 1 );
504 :
505 :
506 : /*-----------------------------------------------------------------------*
507 : * Set Memory Pointer at End for Backward Access
508 : *-----------------------------------------------------------------------*/
509 8725 : mem += m; /*move32();*/
510 :
511 : #ifdef ISSUE_1836_replace_overflow_libcom
512 8725 : 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 8725 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, mem );
522 : #ifdef ISSUE_1836_replace_overflow_libcom
523 8725 : L_tmp = L_shl_sat( L_tmp, q );
524 : #else
525 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
526 : #endif
527 8725 : *y++ = L_tmp;
528 8725 : move32();
529 :
530 : /* Filtering from Input + Mix of Memory & Output Signal Past */
531 87250 : FOR( i = 1; i < m; i++ )
532 : {
533 78525 : L_tmp = Mpy_32_32( a0, *x++ );
534 : /* Process Output Signal Past */
535 471150 : FOR( j = 1; j <= i; j++ )
536 : {
537 392625 : L_tmp = Msub_32_32_r( L_tmp, a[j], y[-j] );
538 : }
539 : /* Process Memory */
540 471150 : FOR( ; j <= m; j++ )
541 : {
542 392625 : L_tmp = Msub_32_32_r( L_tmp, a[j], mem[i - j] );
543 : }
544 : #ifdef ISSUE_1836_replace_overflow_libcom
545 78525 : L_tmp = L_shl_sat( L_tmp, q );
546 : #else
547 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
548 : #endif
549 78525 : *y++ = L_tmp;
550 78525 : move32();
551 : }
552 :
553 : /* Filtering from Input + Output Signal Past */
554 2713475 : FOR( ; i < lg; i++ )
555 : {
556 2704750 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, y );
557 : #ifdef ISSUE_1836_replace_overflow_libcom
558 2704750 : L_tmp = L_shl_sat( L_tmp, q );
559 : #else
560 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
561 : #endif
562 2704750 : *y++ = L_tmp;
563 2704750 : move32();
564 : }
565 :
566 : /*-----------------------------------------------------------------------*
567 : * Update memory if required
568 : *-----------------------------------------------------------------------*/
569 8725 : IF( update != 0 )
570 : {
571 95975 : FOR( i = 0; i < m; i++ )
572 : {
573 87250 : *--mem = *--y;
574 87250 : move32();
575 : }
576 : }
577 :
578 8725 : 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 1218 : 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 1218 : IF( GE_16( dec, DEC ) )
604 : {
605 1218 : 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 1218 : mem_syn_r_size_old = shr( last_L_frame, 4 );
616 1218 : mem_syn_r_size_new = shr( L_frame, 4 );
617 :
618 1218 : 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 1218 : IF( EQ_16( dec, DEC_IVAS ) )
620 : {
621 707 : IF( EQ_16( L_frame, L_FRAME16k ) )
622 : {
623 : /* find scaling factor */
624 : // en1 = 1.25f * sum2_f( mem_syn2, M );
625 430 : en1 = Mpy_32_32( 1342177280 /*1.25f in Q30*/, sum2_f_16_fx( mem_syn2, M ) ); /* 2 * Q - 1 */
626 430 : 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 430 : IF( EQ_32( en2, 0 ) )
630 : {
631 1 : loc_rat = 0;
632 1 : move16();
633 : }
634 : ELSE
635 : {
636 :
637 429 : en1 = L_max( en1, 1 );
638 429 : en2_e = norm_l( en2 );
639 429 : en1_e = sub( norm_l( en1 ), 1 );
640 429 : tmp = div_l( L_shl( en1, en1_e ), extract_h( L_shl( en2, en2_e ) ) );
641 429 : en1_e = sub( en2_e, en1_e );
642 429 : tmp1 = L_shl_sat( tmp, sub( 16 + 1, en1_e ) ); /* Q14 because of norm - 1 for the num */
643 429 : tmp2 = Isqrt( tmp1 ); /* Q16 */
644 429 : 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 7310 : FOR( i = 0; i < M; i++ )
649 : {
650 : // mem_syn_r[L_SYN_MEM - M + i] *= loc_rat;
651 6880 : mem_syn_r[L_SYN_MEM - M + i] = mult_r( mem_syn_r[L_SYN_MEM - M + i], loc_rat );
652 6880 : move16();
653 : }
654 : }
655 : }
656 1218 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
657 :
658 1218 : IF( mem_syn != NULL )
659 : {
660 0 : Copy( mem_syn2, mem_syn, M );
661 : }
662 1218 : }
663 2 : 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 2 : 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 0 : 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 2 : mem_syn_r_size_old = shr( last_L_frame, 4 );
689 2 : mem_syn_r_size_new = shr( L_frame, 4 );
690 :
691 2 : 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 2 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
694 :
695 2 : IF( mem_syn != NULL )
696 : {
697 0 : Copy( mem_syn2, mem_syn, M );
698 : }
699 2 : }
|