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