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 2309515606 : static Word32 syn_kern_2( Word32 L_tmp, const Word16 a[], const Word16 y[] )
13 : {
14 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
15 2309515606 : Flag Overflow = 0;
16 : #endif
17 2309515606 : L_tmp = L_msu_o( L_tmp, y[-1], a[1], &Overflow );
18 2309515606 : return L_msu_o( L_tmp, y[-2], a[2], &Overflow );
19 : }
20 :
21 1109087845 : static Word32 syn_kern_4( Word32 L_tmp, const Word16 a[], const Word16 y[] )
22 : {
23 1109087845 : L_tmp = syn_kern_2( L_tmp, a, y );
24 1109087845 : return syn_kern_2( L_tmp, a + 2, y - 2 );
25 : }
26 :
27 1065975 : static Word32 syn_kern_6( Word32 L_tmp, const Word16 a[], const Word16 y[] )
28 : {
29 1065975 : L_tmp = syn_kern_4( L_tmp, a, y );
30 1065975 : return syn_kern_2( L_tmp, a + 4, y - 4 );
31 : }
32 :
33 554010935 : static Word32 syn_kern_8( Word32 L_tmp, const Word16 a[], const Word16 y[] )
34 : {
35 554010935 : L_tmp = syn_kern_4( L_tmp, a, y );
36 554010935 : return syn_kern_4( L_tmp, a + 4, y - 4 );
37 : }
38 :
39 90273941 : static Word32 syn_kern_10( Word32 L_tmp, const Word16 a[], const Word16 y[] )
40 : {
41 90273941 : L_tmp = syn_kern_8( L_tmp, a, y );
42 90273941 : return syn_kern_2( L_tmp, a + 8, y - 8 );
43 : }
44 :
45 231844658 : Word32 syn_kern_16( Word32 L_tmp, const Word16 a[], const Word16 y[] )
46 : {
47 231844658 : L_tmp = syn_kern_8( L_tmp, a, y );
48 231844658 : 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 2153671 : 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 2153671 : q = add( norm_s( a[0] ), 1 );
122 2153671 : a0 = shr( a[0], shift ); /* input / 2^shift */
123 :
124 : /*-----------------------------------------------------------------------*
125 : * Do the filtering
126 : *-----------------------------------------------------------------------*/
127 36612407 : FOR( i = 0; i < M; i++ )
128 : {
129 34458736 : L_tmp = L_mult( *x++, a0 );
130 : /* Stop at i to Avoid Mults with Zeros */
131 292899256 : FOR( j = 1; j <= i; j++ )
132 : {
133 258440520 : L_tmp = L_msu_sat( L_tmp, y[-j], a[j] );
134 : }
135 :
136 34458736 : L_tmp = L_shl_sat( L_tmp, q );
137 34458736 : *y++ = round_fx_sat( L_tmp );
138 34458736 : move16();
139 : }
140 :
141 84989783 : FOR( ; i < lg; i++ )
142 : {
143 82836112 : L_tmp = syn_kern_16( L_mult( *x++, a0 ), a, y );
144 82836112 : L_tmp = L_shl_sat( L_tmp, q );
145 82836112 : *y++ = round_fx_sat( L_tmp );
146 82836112 : move16();
147 : }
148 2153671 : }
149 :
150 : /*------------------------------------------------------------------*
151 : * Syn_filt_s:
152 : *
153 : * perform the synthesis filtering 1/A(z).
154 : *------------------------------------------------------------------*/
155 2979527 : 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 2979527 : E_UTIL_synthesis( shift, a, x, y, lg, mem, update, m );
167 2979527 : }
168 :
169 :
170 : /*------------------------------------------------------------------*
171 : * syn_filt_fx:
172 : *
173 : * perform the synthesis filtering 1/A(z).
174 : *------------------------------------------------------------------*/
175 2385782 : 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 2385782 : Flag Overflow = 0;
192 2385782 : move16();
193 : Word16 a0;
194 :
195 2385782 : yy = &buf[0];
196 2385782 : q = add( norm_s( a[0] ), 1 );
197 :
198 2385782 : a0 = shr_o( a[0], shift, &Overflow ); /* input / 2^shift */
199 :
200 : /*------------------------------------------------------------------*
201 : * copy initial filter states into synthesis buffer and do synthesis
202 : *------------------------------------------------------------------*/
203 :
204 33233644 : FOR( i = 0; i < m; i++ )
205 : {
206 30847862 : *yy++ = mem[i];
207 30847862 : move16();
208 : }
209 :
210 : /*-----------------------------------------------------------------------*
211 : * Do the filtering
212 : *-----------------------------------------------------------------------*/
213 :
214 182286102 : FOR( i = 0; i < l; i++ )
215 : {
216 179900320 : s = L_mult( a0, x[i] ); // Qx + Qa - shift + 1
217 2439390560 : FOR( j = 1; j <= m; j++ )
218 : {
219 2259490240 : s = L_msu_sat( s, a[j], yy[i - j] ); // Qa + Qx - shift + 1
220 : }
221 :
222 179900320 : s = L_shl_sat( s, q ); // Qx + (Qa + q)Q15 - shift + 1 = Qx - shift + Q16
223 179900320 : yy[i] = extract_h( s ); // Qx - shift
224 179900320 : move16();
225 179900320 : y[i] = extract_h( s );
226 179900320 : move16();
227 : }
228 :
229 : /*------------------------------------------------------------------*
230 : * Update memory if required
231 : *------------------------------------------------------------------*/
232 :
233 2385782 : IF( update_m )
234 : {
235 17604256 : FOR( i = 0; i < m; i++ )
236 : {
237 16294310 : mem[i] = yy[l - m + i];
238 16294310 : move16();
239 : }
240 : }
241 :
242 2385782 : return;
243 : }
244 :
245 :
246 12632 : void syn_filt_fx32(
247 : const Word16 a_e, /* i : exp of LP coeffs Q0 */
248 : const Word32 a[], /* i : LP filter coefficients Q12 */
249 : const Word16 m, /* i : order of LP filter Q0 */
250 : const Word32 x[], /* i : input signal Qx */
251 : const Word16 x_e, /* i : input signal Qx */
252 : Word32 y[], /* o : output signal Qx */
253 : Word16 *y_e, /* o : output signal Qx */
254 : const Word16 l, /* i : size of filtering Q0 */
255 : Word32 mem[], /* i/o: initial filter states Qx */
256 : Word16 *mem_e, /* i/o: initial filter states Qx */
257 : const Word16 update_m /* i : update memory flag Q0 : 0 --> no memory update */
258 : ) /* 1 --> update of memory */
259 : {
260 : Word16 i, j;
261 : Word64 buf[L_FRAME48k + L_FRAME48k / 2 + TCXLTP_LTP_ORDER]; /* temporary synthesis buffer */
262 : Word64 s, *yy;
263 :
264 12632 : yy = &buf[0];
265 :
266 : /*------------------------------------------------------------------*
267 : * copy initial filter states into synthesis buffer and do synthesis
268 : *------------------------------------------------------------------*/
269 :
270 138952 : FOR( i = 0; i < m; i++ )
271 : {
272 126320 : *yy++ = W_deposit32_l( mem[i] );
273 126320 : move32();
274 : }
275 :
276 : /*-----------------------------------------------------------------------*
277 : * Do the filtering
278 : *-----------------------------------------------------------------------*/
279 12632 : Word64 max_val = 1;
280 4054872 : FOR( i = 0; i < l; i++ )
281 : {
282 4042240 : s = W_deposit32_l( x[i] );
283 44464640 : FOR( j = 1; j <= m; j++ )
284 : {
285 40422400 : s = W_sub( s, W_mult0_32_32( a[j], W_extract_l( W_shr( yy[i - j], sub( 31, a_e ) ) ) ) );
286 : }
287 :
288 4042240 : yy[i] = s;
289 4042240 : move32();
290 4042240 : if ( GT_64( W_abs( s ), max_val ) )
291 : {
292 79732 : max_val = W_abs( s );
293 : }
294 : }
295 :
296 12632 : Word16 norm = W_norm( max_val );
297 :
298 4054872 : FOR( i = 0; i < l; i++ )
299 : {
300 4042240 : y[i] = W_extract_l( W_shr( yy[i], sub( 32, norm ) ) );
301 : }
302 12632 : *y_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
303 : /*------------------------------------------------------------------*
304 : * Update memory if required
305 : *------------------------------------------------------------------*/
306 :
307 12632 : IF( update_m )
308 : {
309 138952 : FOR( i = 0; i < m; i++ )
310 : {
311 126320 : mem[i] = W_extract_l( W_shr( yy[l - m + i], sub( 32, norm ) ) );
312 : }
313 12632 : *mem_e = sub( 31, add( sub( 31, x_e ), sub( norm, 32 ) ) );
314 : }
315 :
316 12632 : return;
317 : }
318 :
319 :
320 : /*
321 : * E_UTIL_synthesis
322 : *
323 : * Parameters:
324 : * shift i : scaling to apply for a[0] Q0
325 : * a[] i : LP filter coefficients Qx
326 : * x[] i : input signal Qx
327 : * y[] o : output signal Qx-s
328 : * lg i : size of filtering Q0
329 : * mem[] i/o: memory associated with this filtering. Qx-s
330 : * update i : 0=no update, 1=update of memory. Q0
331 : * m i : order of LP filter Q0
332 : *
333 : * Function:
334 : * Perform the synthesis filtering 1/A(z).
335 : * Memory size is always M.
336 : *
337 : * Returns:
338 : * void
339 : */
340 4625348 : 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 )
341 : {
342 : Word16 i, j, a0;
343 : Word32 L_tmp;
344 : Word16 q;
345 4625348 : Word32 ( *syn_kern )( Word32 L_tmp, const Word16 a[], const Word16 y[] ) = NULL;
346 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
347 4625348 : Flag Overflow = 0;
348 4625348 : move32();
349 : #endif
350 :
351 4625348 : if ( EQ_16( m, 6 ) )
352 : {
353 14213 : syn_kern = syn_kern_6;
354 : }
355 4625348 : if ( EQ_16( m, 10 ) )
356 : {
357 1131277 : syn_kern = syn_kern_10;
358 : }
359 4625348 : if ( EQ_16( m, 16 ) )
360 : {
361 3479604 : syn_kern = syn_kern_16;
362 : }
363 4625348 : if ( EQ_16( m, 24 ) )
364 : {
365 254 : syn_kern = syn_kern_24;
366 : }
367 4625348 : assert( syn_kern != NULL );
368 4625348 : q = add( norm_s( a[0] ), 1 );
369 :
370 :
371 : /*-----------------------------------------------------------------------*
372 : * Set Memory Pointer at End for Backward Access
373 : *-----------------------------------------------------------------------*/
374 4625348 : mem += m; /*move16();*/
375 :
376 4625348 : a0 = shr_o( a[0], shift, &Overflow ); /* input / 2^shift */
377 : /*-----------------------------------------------------------------------*
378 : * Do the filtering
379 : *-----------------------------------------------------------------------*/
380 : /* Filtering Only from Input + Memory */
381 4625348 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, mem );
382 4625348 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
383 4625348 : *y++ = round_fx_o( L_tmp, &Overflow );
384 4625348 : move16();
385 :
386 : /* Filtering from Input + Mix of Memory & Output Signal Past */
387 67077808 : FOR( i = 1; i < m; i++ )
388 : {
389 62452460 : L_tmp = L_mult( a0, *x++ );
390 : /* Process Output Signal Past */
391 531195704 : FOR( j = 1; j <= i; j++ )
392 : {
393 468743244 : L_tmp = L_msu_o( L_tmp, a[j], y[-j], &Overflow );
394 : }
395 : /* Process Memory */
396 531195704 : FOR( ; j <= m; j++ )
397 : {
398 468743244 : L_tmp = L_msu_sat( L_tmp, a[j], mem[i - j] );
399 : }
400 62452460 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
401 62452460 : *y++ = round_fx_o( L_tmp, &Overflow );
402 62452460 : move16();
403 : }
404 :
405 : /* Filtering from Input + Output Signal Past */
406 240348462 : FOR( ; i < lg; i++ )
407 : {
408 235723114 : L_tmp = syn_kern( L_mult( a0, *x++ ), a, y );
409 235723114 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
410 235723114 : *y++ = round_fx_o( L_tmp, &Overflow );
411 235723114 : move16();
412 : }
413 :
414 : /*-----------------------------------------------------------------------*
415 : * Update memory if required
416 : *-----------------------------------------------------------------------*/
417 4625348 : IF( update != 0 )
418 : {
419 38892292 : FOR( i = 0; i < m; i++ )
420 : {
421 36345214 : *--mem = *--y;
422 36345214 : move16();
423 : }
424 : }
425 :
426 4625348 : return;
427 : }
428 :
429 :
430 : /*
431 : * E_UTIL_synthesis_fx
432 : *
433 : * Parameters:
434 : * shift i : scaling to apply for a[0] Q0
435 : * a[] i : LP filter coefficients Qx
436 : * x[] i : input signal Qx
437 : * y[] o : output signal Qx-s
438 : * lg i : size of filtering Q0
439 : * mem[] i/o: memory associated with this filtering. Qx-s
440 : * update i : 0=no update, 1=update of memory. Q0
441 : * m i : order of LP filter Q0
442 : *
443 : * Function:
444 : * Perform the synthesis filtering 1/A(z).
445 : * Memory size is always M.
446 : *
447 : * Returns:
448 : * void
449 : */
450 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 )
451 : {
452 : Word16 i, j;
453 : Word32 a0;
454 : Word32 L_tmp;
455 : Word16 q;
456 8556 : Word32 ( *syn_kern )( Word32 L_tmp, const Word32 a[], const Word32 y[] ) = NULL;
457 8556 : Flag Overflow = 0;
458 8556 : move32();
459 :
460 8556 : if ( EQ_16( m, 6 ) )
461 : {
462 0 : syn_kern = syn_kern_6_fx;
463 : }
464 8556 : if ( EQ_16( m, 10 ) )
465 : {
466 8556 : syn_kern = syn_kern_10_fx;
467 : }
468 8556 : if ( EQ_16( m, 16 ) )
469 : {
470 0 : syn_kern = syn_kern_16_fx;
471 : }
472 8556 : if ( EQ_16( m, 24 ) )
473 : {
474 0 : syn_kern = syn_kern_24_fx;
475 : }
476 8556 : assert( syn_kern != NULL );
477 8556 : q = add( norm_l( a[0] ), 1 );
478 :
479 :
480 : /*-----------------------------------------------------------------------*
481 : * Set Memory Pointer at End for Backward Access
482 : *-----------------------------------------------------------------------*/
483 8556 : mem += m; /*move32();*/
484 :
485 8556 : a0 = L_shr_o( a[0], shift, &Overflow ); /* input / 2^shift */
486 :
487 : /*-----------------------------------------------------------------------*
488 : * Do the filtering
489 : *-----------------------------------------------------------------------*/
490 : /* Filtering Only from Input + Memory */
491 8556 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, mem );
492 8556 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
493 8556 : *y++ = L_tmp;
494 8556 : move32();
495 :
496 : /* Filtering from Input + Mix of Memory & Output Signal Past */
497 85560 : FOR( i = 1; i < m; i++ )
498 : {
499 77004 : L_tmp = Mpy_32_32( a0, *x++ );
500 : /* Process Output Signal Past */
501 462024 : FOR( j = 1; j <= i; j++ )
502 : {
503 385020 : L_tmp = Msub_32_32_r( L_tmp, a[j], y[-j] );
504 : }
505 : /* Process Memory */
506 462024 : FOR( ; j <= m; j++ )
507 : {
508 385020 : L_tmp = Msub_32_32_r( L_tmp, a[j], mem[i - j] );
509 : }
510 77004 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
511 77004 : *y++ = L_tmp;
512 77004 : move32();
513 : }
514 :
515 : /* Filtering from Input + Output Signal Past */
516 2660916 : FOR( ; i < lg; i++ )
517 : {
518 2652360 : L_tmp = syn_kern( Mpy_32_32( a0, *x++ ), a, y );
519 2652360 : L_tmp = L_shl_o( L_tmp, q, &Overflow );
520 2652360 : *y++ = L_tmp;
521 2652360 : move32();
522 : }
523 :
524 : /*-----------------------------------------------------------------------*
525 : * Update memory if required
526 : *-----------------------------------------------------------------------*/
527 8556 : IF( update != 0 )
528 : {
529 94116 : FOR( i = 0; i < m; i++ )
530 : {
531 85560 : *--mem = *--y;
532 85560 : move32();
533 : }
534 : }
535 :
536 8556 : return;
537 : }
538 :
539 :
540 : /*-------------------------------------------------------------------*
541 : * synth_mem_updt2()
542 : *
543 : * Update of synthesis filter memories in case of ACELP@12k8 <-> ACELP@16k switching
544 : *--------------------------------------------------------------------*/
545 :
546 1188 : void ivas_synth_mem_updt2_fx(
547 : const Word16 L_frame, /* i : frame length */
548 : const Word16 last_L_frame, /* i : frame length */
549 : Word16 old_exc[], /* i/o: excitation buffer st->Q_syn */
550 : Word16 mem_syn_r[], /* i/o: synthesis filter memory st->Q_syn */
551 : Word16 mem_syn2[], /* o : synthesis filter memory for find_target st->Q_syn */
552 : Word16 mem_syn[], /* o : synthesis filter memory for find_target st->Q_syn */
553 : const Word16 dec )
554 : {
555 : Word16 mem_syn_r_size_old, mem_syn_r_size_new;
556 : Word32 en1, en2;
557 : Word16 en1_e, en2_e, loc_rat, tmp, i;
558 : Word32 tmp1, tmp2;
559 :
560 : /* Residual and update old_exc */
561 1188 : IF( GE_16( dec, DEC ) )
562 : {
563 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 );
564 : }
565 : ELSE
566 : {
567 0 : lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame );
568 : }
569 :
570 : /*Resamp memory*/
571 : /*Size of LPC syn memory*/
572 : /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */
573 1188 : mem_syn_r_size_old = shr( last_L_frame, 4 );
574 1188 : mem_syn_r_size_new = shr( L_frame, 4 );
575 :
576 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 );
577 1188 : IF( EQ_16( dec, DEC_IVAS ) )
578 : {
579 690 : IF( EQ_16( L_frame, L_FRAME16k ) )
580 : {
581 : /* find scaling factor */
582 : // en1 = 1.25f * sum2_f( mem_syn2, M );
583 414 : en1 = Mpy_32_32( 1342177280 /*1.25f in Q30*/, sum2_f_16_fx( mem_syn2, M ) ); /* 2 * Q - 1 */
584 414 : en2 = L_shr( sum2_f_16_fx( mem_syn_r + L_SYN_MEM - M, M ), 1 ); /* 2 * Q - 1 */
585 :
586 : // loc_rat = sqrtf( en2 ) / ( sqrtf( en1 ) + 0.01f );
587 414 : IF( EQ_32( en2, 0 ) )
588 : {
589 3 : loc_rat = 0;
590 3 : move16();
591 : }
592 : ELSE
593 : {
594 :
595 411 : en1 = L_max( en1, 1 );
596 411 : en2_e = norm_l( en2 );
597 411 : en1_e = sub( norm_l( en1 ), 1 );
598 411 : tmp = div_l( L_shl( en1, en1_e ), extract_h( L_shl( en2, en2_e ) ) );
599 411 : en1_e = sub( en2_e, en1_e );
600 411 : tmp1 = L_shl_sat( tmp, sub( 16 + 1, en1_e ) ); /* Q14 because of norm - 1 for the num */
601 411 : tmp2 = Isqrt( tmp1 ); /* Q16 */
602 411 : loc_rat = round_fx_sat( L_shl_sat( tmp2, sub( 16, en1_e ) ) ); /* loc_rat in Q15 */
603 : }
604 :
605 : /* scale synthesis filter memory */
606 7038 : FOR( i = 0; i < M; i++ )
607 : {
608 : // mem_syn_r[L_SYN_MEM - M + i] *= loc_rat;
609 6624 : mem_syn_r[L_SYN_MEM - M + i] = mult_r( mem_syn_r[L_SYN_MEM - M + i], loc_rat );
610 6624 : move16();
611 : }
612 : }
613 : }
614 1188 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
615 :
616 1188 : IF( mem_syn != NULL )
617 : {
618 0 : Copy( mem_syn2, mem_syn, M );
619 : }
620 1188 : }
621 1293 : void synth_mem_updt2(
622 : const Word16 L_frame, /* i : frame length */
623 : const Word16 last_L_frame, /* i : frame length */
624 : Word16 old_exc[], /* i/o: excitation buffer st->Q_syn */
625 : Word16 mem_syn_r[], /* i/o: synthesis filter memory st->Q_syn */
626 : Word16 mem_syn2[], /* o : synthesis filter memory for find_target st->Q_syn */
627 : Word16 mem_syn[], /* o : synthesis filter memory for find_target st->Q_syn */
628 : const Word16 dec /* i : flag for decoder indication */
629 : )
630 : {
631 : Word16 mem_syn_r_size_old, mem_syn_r_size_new;
632 :
633 : /* Residual and update old_exc */
634 1293 : IF( GE_16( dec, DEC ) )
635 : {
636 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 );
637 : }
638 : ELSE
639 : {
640 1292 : lerp( old_exc + L_EXC_MEM - last_L_frame, old_exc + L_EXC_MEM - L_frame, L_frame, last_L_frame );
641 : }
642 :
643 : /*Resamp memory*/
644 : /*Size of LPC syn memory*/
645 : /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */
646 1293 : mem_syn_r_size_old = shr( last_L_frame, 4 );
647 1293 : mem_syn_r_size_new = shr( L_frame, 4 );
648 :
649 1293 : 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 );
650 :
651 1293 : Copy( mem_syn_r + L_SYN_MEM - M, mem_syn2, M );
652 :
653 1293 : IF( mem_syn != NULL )
654 : {
655 1292 : Copy( mem_syn2, mem_syn, M );
656 : }
657 1293 : }
|