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