Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <stdint.h>
34 : #include "options.h"
35 : #include "prot_fx.h"
36 : #include "ivas_rom_com.h"
37 : #include <math.h>
38 : #include "wmc_auto.h"
39 : #include "ivas_prot_fx.h"
40 : #include "ivas_rom_com_fx.h"
41 :
42 : /*------------------------------------------------------------------------------------------*
43 : * Local constants
44 : *------------------------------------------------------------------------------------------*/
45 :
46 : #define LFE_PLC_DSF ( 48000 / LFE_PLC_FS )
47 : #define LFE_PLC_LPCORD ( MAX_LP_FILTER_ORDER )
48 : #define LFE_PLC_MAXITER ( 10 )
49 : #define LFE_PLC_RECLEN_48K ( ( IVAS_LFE_NUM_COEFFS_IN_SUBGRP + 1 ) * L_FRAME48k / IVAS_LFE_NUM_COEFFS_IN_SUBGRP + LFE_PLC_FDEL )
50 : #define LFE_PLC_RECLEN ( ( LFE_PLC_RECLEN_48K / LFE_PLC_DSF ) )
51 : #define LFE_PLC_MUTE_THR ( 10 )
52 : #define MAX_LEN_LP 960
53 : #define POW_THR_Q50 ( 11258999 )
54 : #define EPS_STOP_Q31 ( 21475 )
55 : #define LFE_PLC_BURST_ATT_Q31 ( 2124429696 )
56 :
57 : /*------------------------------------------------------------------------------------------*
58 : * Static function declarations
59 : *
60 : * Note (DLB): the local double precision functions defined below are replica of corresponding
61 : * float functions defined in tools.c, lpc_tools.c and syn_filt.c.
62 : * Double precision arithmetic is required for proper functioning of the lfe_plc.
63 : *------------------------------------------------------------------------------------------*/
64 : /*---------------------------------------------------------------------*
65 : * autocorr_fx()
66 : *
67 : * Compute autocorrelations of input signal
68 : *---------------------------------------------------------------------*/
69 :
70 151 : static void d_autocorr_fx(
71 : const Word32 *x_fx, /* i : input signal */
72 : Word16 x_q_fx,
73 : Word32 *r_fx, /* o : autocorrelations vector */
74 : Word16 *r_q_fx,
75 : const Word16 m, /* i : order of LP filter */
76 : const Word16 len, /* i : window size */
77 : const UWord32 *wind_fx, /* i : window */
78 : const Word16 rev_flag, /* i : flag to reverse window */
79 : const Word16 sym_flag, /* i : symmetric window flag */
80 : const Word16 no_thr /* i : flag to avoid thresholding */
81 : )
82 : {
83 : Word16 i, j;
84 : Word32 t_fx[MAX_LEN_LP];
85 : Word64 s_fx;
86 : Word32 temp;
87 : Word16 tmp_q, exp1, exp2;
88 :
89 : /* Windowing of signal */
90 151 : IF( EQ_16( rev_flag, 1 ) )
91 : {
92 : /* time reversed window */
93 0 : FOR( i = 0; i < len; i++ )
94 : {
95 0 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - i - 1] ); // Q = x_q_fx
96 0 : move32();
97 : }
98 : }
99 151 : ELSE IF( EQ_16( sym_flag, 1 ) )
100 : {
101 : /* symmetric window of even length */
102 18271 : FOR( i = 0; i < len / 2; i++ )
103 : {
104 18120 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
105 18120 : move32();
106 : }
107 :
108 18271 : FOR( ; i < len; i++ )
109 : {
110 18120 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx
111 18120 : move32();
112 : }
113 : }
114 : ELSE /* assymetric window */
115 : {
116 0 : FOR( i = 0; i < len; i++ )
117 : {
118 0 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
119 0 : move32();
120 : }
121 : }
122 :
123 : /* Compute r[1] to r[m] */
124 3322 : FOR( i = 0; i <= m; i++ )
125 : {
126 3171 : exp1 = norm_l( t_fx[0] );
127 3171 : exp2 = norm_l( t_fx[i] );
128 3171 : s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) );
129 3171 : r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
130 3171 : move16();
131 729330 : FOR( j = 1; j < len - i; j++ )
132 : {
133 726159 : exp1 = norm_l( t_fx[j] );
134 726159 : exp2 = norm_l( t_fx[i + j] );
135 726159 : temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) );
136 726159 : tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
137 :
138 726159 : IF( LT_16( tmp_q, r_q_fx[i] ) )
139 : {
140 3050 : s_fx = W_add( W_shr( s_fx, sub( r_q_fx[i], tmp_q ) ), W_deposit32_l( temp ) );
141 3050 : r_q_fx[i] = tmp_q;
142 3050 : move16();
143 : }
144 : ELSE
145 : {
146 723109 : s_fx = W_add( s_fx, W_shr( temp, sub( tmp_q, r_q_fx[i] ) ) );
147 : }
148 : }
149 3171 : exp1 = W_norm( s_fx );
150 3171 : r_fx[i] = W_extract_h( W_shl( s_fx, exp1 ) );
151 3171 : move32();
152 3171 : r_q_fx[i] = sub( add( r_q_fx[i], exp1 ), 32 );
153 3171 : move16();
154 : }
155 :
156 : // 2097152000 = 1000 in Q21
157 151 : IF( LT_16( r_q_fx[0], Q21 ) )
158 : {
159 151 : IF( L_and( LT_32( r_fx[0], L_shr( 2097152000, sub( Q21, r_q_fx[0] ) ) ), EQ_16( no_thr, 0 ) ) )
160 : {
161 0 : r_fx[0] = 2097152000;
162 0 : move32();
163 0 : r_q_fx[0] = Q21;
164 0 : move16();
165 : }
166 : }
167 : ELSE
168 : {
169 0 : IF( L_and( LT_32( L_shr( r_fx[0], sub( r_q_fx[0], Q21 ) ), 2097152000 ), EQ_16( no_thr, 0 ) ) )
170 : {
171 0 : r_fx[0] = 2097152000;
172 0 : move32();
173 0 : r_q_fx[0] = Q21;
174 0 : move16();
175 : }
176 : }
177 :
178 151 : return;
179 : }
180 :
181 : /*---------------------------------------------------------------------*
182 : * lfeplc_lev_dur()
183 : *
184 : * Wiener-Levinson-Durbin algorithm to compute LP parameters from the autocorrelations
185 : * of input signal
186 : *---------------------------------------------------------------------*/
187 :
188 : /*! r: stability flag */
189 24 : static Word16 lfeplc_lev_dur_fx(
190 : Word32 *a_out_fx, /* o : LP coefficients (a[0] = 1.0) */
191 : Word16 *a_out_q_fx,
192 : Word32 *r_fx, /* i : vector of autocorrelations */
193 : Word16 *r_q_fx,
194 : const Word16 m )
195 : {
196 : Word16 i, j, l;
197 : Word32 buf_fx[TCXLTP_LTP_ORDER];
198 : Word16 rc_q_fx[TCXLTP_LTP_ORDER];
199 : Word32 *rc_fx; /* reflection coefficients 0,...,m-1 */
200 : Word32 temp1, temp2, err_fx, at_fx, s;
201 : Word16 temp_q1, temp_q2, s_q_fx, err_q_fx, exp1, exp2;
202 : Word64 s_fx;
203 : Word32 a_fx[LFE_PLC_LPCORD + 1];
204 : Word16 a_q_fx[LFE_PLC_LPCORD + 1];
205 :
206 24 : set32_fx( a_fx, 0, LFE_PLC_LPCORD + 1 );
207 24 : set16_fx( a_q_fx, 31, LFE_PLC_LPCORD + 1 );
208 24 : set32_fx( a_out_fx, 0, LFE_PLC_LPCORD + 1 );
209 24 : set16_fx( a_out_q_fx, 31, LFE_PLC_LPCORD + 1 );
210 :
211 24 : s_q_fx = 0;
212 24 : move16();
213 :
214 24 : rc_fx = &buf_fx[0];
215 24 : a_fx[0] = ONE_IN_Q30;
216 24 : move32();
217 24 : a_q_fx[0] = 30;
218 24 : move16();
219 24 : err_fx = r_fx[0];
220 24 : move32();
221 24 : err_q_fx = r_q_fx[0];
222 24 : move16();
223 24 : a_out_fx[0] = a_fx[0];
224 24 : move32();
225 24 : a_out_q_fx[0] = 30;
226 24 : move16();
227 :
228 24 : rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 );
229 24 : move32();
230 24 : rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) );
231 24 : move16();
232 :
233 24 : s = r_fx[1];
234 24 : s_q_fx = r_q_fx[1];
235 24 : move32();
236 24 : move16();
237 :
238 24 : a_fx[1] = rc_fx[0];
239 24 : move32();
240 24 : a_q_fx[1] = rc_q_fx[0];
241 24 : move32();
242 :
243 24 : a_out_fx[1] = a_fx[1];
244 24 : move32();
245 24 : a_out_q_fx[1] = a_q_fx[1];
246 24 : move32();
247 :
248 24 : i = 1;
249 24 : move16();
250 480 : WHILE( LT_16( i, m ) )
251 : {
252 2616 : FOR( j = 1; j <= i / 2; j++ )
253 : {
254 2160 : l = sub( i, j );
255 2160 : exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
256 2160 : exp2 = sub( norm_l( a_fx[l] ), 1 );
257 2160 : rc_fx[i - 1] = L_shl( rc_fx[i - 1], exp1 );
258 2160 : move32();
259 2160 : rc_q_fx[i - 1] = add( rc_q_fx[i - 1], exp1 );
260 2160 : move16();
261 2160 : a_fx[l] = L_shl( a_fx[l], exp2 );
262 2160 : move32();
263 2160 : a_q_fx[l] = add( a_q_fx[l], exp2 );
264 2160 : move16();
265 :
266 2160 : exp2 = sub( norm_l( a_fx[j] ), 1 );
267 2160 : a_fx[j] = L_shl( a_fx[j], exp2 );
268 2160 : move32();
269 2160 : a_q_fx[j] = add( a_q_fx[j], exp2 );
270 2160 : move16();
271 :
272 2160 : temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[l] );
273 2160 : temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[l] ), 31 );
274 2160 : if ( temp2 == 0 )
275 : {
276 0 : temp_q2 = 31;
277 0 : move16();
278 : }
279 :
280 2160 : IF( LT_16( temp_q2, a_q_fx[j] ) )
281 : {
282 72 : at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2)
283 72 : temp_q1 = temp_q2;
284 72 : move16();
285 : }
286 : ELSE
287 : {
288 2088 : at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx)
289 2088 : temp_q1 = a_q_fx[j];
290 2088 : move16();
291 : }
292 :
293 2160 : temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] );
294 2160 : temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 );
295 2160 : if ( temp2 == 0 )
296 : {
297 0 : temp_q2 = 31;
298 0 : move16();
299 : }
300 :
301 2160 : IF( LT_16( temp_q2, a_q_fx[l] ) )
302 : {
303 1076 : a_fx[l] = L_add( L_shr( a_fx[l], sub( a_q_fx[l], temp_q2 ) ), temp2 );
304 1076 : move32();
305 1076 : a_q_fx[l] = temp_q2;
306 1076 : move16();
307 : }
308 : ELSE
309 : {
310 1084 : a_fx[l] = L_add( a_fx[l], L_shr( temp2, sub( temp_q2, a_q_fx[l] ) ) );
311 1084 : move16();
312 : }
313 2160 : a_fx[j] = at_fx;
314 2160 : move32();
315 2160 : a_q_fx[j] = temp_q1;
316 2160 : move16();
317 : }
318 :
319 456 : a_fx[i] = rc_fx[i - 1];
320 456 : move32();
321 456 : a_q_fx[i] = rc_q_fx[i - 1];
322 456 : move16();
323 :
324 456 : exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
325 456 : exp2 = norm_l( s );
326 456 : temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) );
327 456 : temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 );
328 456 : if ( temp1 == 0 )
329 : {
330 0 : temp_q1 = 31;
331 0 : move16();
332 : }
333 :
334 456 : IF( LT_16( temp_q1, err_q_fx ) )
335 : {
336 18 : err_fx = L_add( L_shr( err_fx, sub( err_q_fx, temp_q1 ) ), temp1 );
337 18 : err_q_fx = temp_q1;
338 18 : move16();
339 : }
340 : ELSE
341 : {
342 438 : err_fx = L_add( err_fx, L_shr( temp1, sub( temp_q1, err_q_fx ) ) );
343 : }
344 :
345 456 : s_fx = 0;
346 456 : move32();
347 456 : s_q_fx = 0;
348 456 : move16();
349 456 : i = add( i, 1 );
350 456 : s_fx = 0;
351 456 : move64();
352 :
353 5472 : FOR( j = 0; j < i; j++ )
354 : {
355 5016 : exp1 = norm_l( r_fx[i - j] );
356 5016 : exp2 = norm_l( a_fx[j] );
357 5016 : temp1 = Mpy_32_32( L_shl( r_fx[i - j], exp1 ), L_shl( a_fx[j], exp2 ) );
358 5016 : temp_q1 = sub( add( add( r_q_fx[i - j], exp1 ), add( a_q_fx[j], exp2 ) ), 31 );
359 5016 : if ( temp1 == 0 )
360 : {
361 0 : temp_q1 = 31;
362 0 : move16();
363 : }
364 :
365 5016 : IF( j == 0 )
366 : {
367 456 : s_fx = W_deposit32_l( temp1 );
368 456 : s_q_fx = temp_q1;
369 456 : move16();
370 : }
371 : ELSE
372 : {
373 4560 : IF( LT_16( temp_q1, s_q_fx ) )
374 : {
375 520 : s_fx = W_add( W_shr( s_fx, sub( s_q_fx, temp_q1 ) ), W_deposit32_l( temp1 ) );
376 520 : s_q_fx = temp_q1;
377 520 : move16();
378 : }
379 : ELSE
380 : {
381 4040 : s_fx = W_add( s_fx, W_shr( W_deposit32_l( temp1 ), sub( temp_q1, s_q_fx ) ) );
382 : }
383 : }
384 : }
385 :
386 456 : exp1 = W_norm( s_fx );
387 456 : s = W_extract_h( W_shl( s_fx, exp1 ) );
388 456 : s_q_fx = sub( add( s_q_fx, exp1 ), 32 );
389 :
390 456 : rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 );
391 456 : move32();
392 456 : rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 );
393 456 : move16();
394 :
395 456 : IF( LT_16( rc_q_fx[i - 1], 31 ) )
396 : {
397 :
398 94 : IF( GT_32( L_abs( rc_fx[i - 1] ), L_shr( 2146302532, sub( 31, rc_q_fx[i - 1] ) ) ) ) // 2146302532 = 0.99945f in Q31
399 : {
400 0 : return 1;
401 : }
402 : ELSE
403 : {
404 2068 : FOR( j = 0; j <= m; j++ )
405 : {
406 1974 : a_out_fx[j] = a_fx[j];
407 1974 : a_out_q_fx[j] = a_q_fx[j];
408 1974 : move32();
409 1974 : move32();
410 : }
411 : }
412 : }
413 : ELSE
414 : {
415 362 : IF( GT_32( L_abs( L_shr( rc_fx[i - 1], sub( rc_q_fx[i - 1], 31 ) ) ), 2146302532 ) ) // 2146302532 = 0.00045f in Q31
416 : {
417 0 : return 1;
418 : }
419 : ELSE
420 : {
421 7964 : FOR( j = 0; j <= m; j++ )
422 : {
423 7602 : a_out_fx[j] = a_fx[j];
424 7602 : a_out_q_fx[j] = a_q_fx[j];
425 7602 : move32();
426 7602 : move32();
427 : }
428 : }
429 : }
430 : }
431 24 : return 0;
432 : }
433 : /*-------------------------------------------------------------------*
434 : * a2rc_fx()
435 : *
436 : * Convert from LPC to reflection coeff
437 : *-------------------------------------------------------------------*/
438 :
439 306 : static Word16 d_a2rc_fx(
440 : const Word32 *a_fx, /* i : LPC coefficients */
441 : Word16 *a_q_fx,
442 : Word32 *refl_fx, /* o : Reflection co-efficients */
443 : const Word16 lpcorder /* i : LPC order */
444 : )
445 : {
446 : Word16 m, j, n;
447 : Word32 ff_fx[LFE_PLC_LPCORD];
448 : Word32 km_fx, denom_fx, temp1, temp2, temp;
449 : Word16 ff_q_fx[LFE_PLC_LPCORD], temp_q1, temp_q2, denom_q_fx, km_q_fx, temp_q;
450 : Word16 exp1, exp2;
451 :
452 6426 : FOR( m = 0; m < lpcorder; m++ )
453 : {
454 6120 : ff_fx[m] = L_negate( a_fx[m] );
455 6120 : move32();
456 6120 : ff_q_fx[m] = a_q_fx[m];
457 6120 : move32();
458 : }
459 :
460 : /* Initialization */
461 6024 : FOR( m = lpcorder - 1; m >= 0; m-- )
462 : {
463 5877 : km_fx = ff_fx[m];
464 5877 : move32();
465 5877 : km_q_fx = ff_q_fx[m];
466 5877 : move16();
467 5877 : IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) )
468 : {
469 3339 : FOR( j = 0; j < lpcorder; j++ )
470 : {
471 3180 : refl_fx[j] = 0;
472 3180 : move32();
473 : }
474 159 : return 0;
475 : }
476 :
477 5718 : refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx)
478 5718 : move32();
479 :
480 5718 : exp1 = norm_l( km_fx );
481 5718 : temp1 = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( km_fx, exp1 ) );
482 5718 : temp_q1 = sub( add( add( km_q_fx, exp1 ), add( km_q_fx, exp1 ) ), 31 );
483 5718 : temp1 = L_sub( ONE_IN_Q30, L_shr( temp1, sub( temp_q1, 30 ) ) );
484 5718 : denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) );
485 5718 : denom_q_fx = sub( 15, temp_q1 );
486 :
487 33057 : FOR( j = 0; j < m / 2; j++ )
488 : {
489 27339 : n = sub( sub( m, 1 ), j );
490 :
491 27339 : exp1 = norm_l( denom_fx );
492 27339 : exp2 = sub( norm_l( ff_fx[j] ), 1 );
493 27339 : temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
494 27339 : temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
495 :
496 27339 : exp2 = sub( norm_l( ff_fx[n] ), 1 );
497 27339 : temp2 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[n], exp2 ) );
498 27339 : temp_q2 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[n], exp2 ) ), 31 );
499 :
500 27339 : exp1 = norm_l( km_fx );
501 27339 : exp2 = sub( norm_l( temp2 ), 1 );
502 27339 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp2, exp2 ) );
503 27339 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q2, exp2 ) ), 31 );
504 27339 : if ( temp == 0 )
505 : {
506 2754 : temp_q = 31;
507 2754 : move16();
508 : }
509 27339 : IF( LT_16( temp_q, temp_q1 ) )
510 : {
511 594 : ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
512 594 : move32();
513 594 : ff_q_fx[j] = temp_q;
514 594 : move16();
515 : }
516 : ELSE
517 : {
518 26745 : ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
519 26745 : move32();
520 26745 : ff_q_fx[j] = temp_q1;
521 26745 : move16();
522 : }
523 :
524 27339 : exp1 = norm_l( km_fx );
525 27339 : exp2 = sub( norm_l( temp1 ), 1 );
526 27339 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
527 27339 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
528 27339 : if ( temp == 0 )
529 : {
530 2754 : temp_q = 31;
531 2754 : move16();
532 : }
533 27339 : IF( LT_16( temp_q, temp_q2 ) )
534 : {
535 6299 : ff_fx[n] = L_add( L_shr( temp2, sub( temp_q2, temp_q ) ), temp );
536 6299 : move32();
537 6299 : ff_q_fx[n] = temp_q;
538 6299 : move16();
539 : }
540 : ELSE
541 : {
542 21040 : ff_fx[n] = L_add( temp2, L_shr( temp, sub( temp_q, temp_q2 ) ) );
543 21040 : move32();
544 21040 : ff_q_fx[n] = temp_q2;
545 21040 : move16();
546 : }
547 : }
548 :
549 5718 : IF( s_and( m, 1 ) )
550 : {
551 2879 : exp1 = norm_l( denom_fx );
552 2879 : exp2 = sub( norm_l( ff_fx[j] ), 1 );
553 2879 : temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
554 2879 : temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
555 :
556 2879 : exp1 = norm_l( km_fx );
557 2879 : exp2 = sub( norm_l( temp1 ), 1 );
558 2879 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
559 2879 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
560 2879 : if ( temp == 0 )
561 : {
562 306 : temp_q = 31;
563 306 : move16();
564 : }
565 2879 : IF( LT_16( temp_q, temp_q1 ) )
566 : {
567 168 : ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
568 168 : move32();
569 168 : ff_q_fx[j] = temp_q;
570 168 : move16();
571 : }
572 : ELSE
573 : {
574 2711 : ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
575 2711 : move32();
576 2711 : ff_q_fx[j] = temp_q1;
577 2711 : move16();
578 : }
579 : }
580 : }
581 :
582 147 : return 1;
583 : }
584 :
585 24 : static void d_syn_filt_fx(
586 : const Word32 *a_fx, /* i : LP filter coefficients */
587 : Word16 *a_q_fx,
588 : const Word16 m, /* i : order of LP filter */
589 : const Word32 *x_fx, /* i : input signal */
590 : Word32 *y_fx, /* o : output signal */
591 : Word16 *y_q_fx,
592 : const Word16 l, /* i : size of filtering */
593 : const Word32 *mem_fx, /* i : initial filter states */
594 : Word16 mem_q_fx )
595 : {
596 : Word16 i, j;
597 : Word32 buf_fx[LFE_PLC_LPCORD + LFE_PLC_RECLEN]; /* temporary synthesis buffer */
598 : Word32 *yy_fx, temp;
599 : Word64 s_fx;
600 : Word16 tmp;
601 : Word16 yy_q_fx[LFE_PLC_LPCORD + LFE_PLC_RECLEN], exp1, exp2, s_q_fx, temp_q;
602 :
603 24 : yy_fx = &buf_fx[0];
604 :
605 : /*------------------------------------------------------------------*
606 : * copy initial filter states into synthesis buffer and do synthesis
607 : *------------------------------------------------------------------*/
608 504 : FOR( i = 0; i < m; i++ )
609 : {
610 480 : *yy_fx++ = mem_fx[i];
611 480 : move32();
612 480 : yy_q_fx[i] = mem_q_fx;
613 480 : move16();
614 : }
615 :
616 : /*-----------------------------------------------------------------------*
617 : * Do the filtering
618 : *-----------------------------------------------------------------------*/
619 :
620 1416 : FOR( i = 0; i < l; i++ )
621 : {
622 1392 : s_fx = x_fx[i];
623 1392 : move64();
624 1392 : s_q_fx = Q31;
625 1392 : move16();
626 29232 : FOR( j = 1; j <= m; j++ )
627 : {
628 27840 : exp1 = sub( norm_l( a_fx[j] ), 1 );
629 27840 : exp2 = sub( norm_l( yy_fx[i - j] ), 1 );
630 27840 : IF( GT_16( j, i ) )
631 : {
632 5040 : temp_q = mem_q_fx;
633 5040 : move16();
634 : }
635 : ELSE
636 : {
637 22800 : temp_q = yy_q_fx[i - j];
638 22800 : move16();
639 : }
640 27840 : temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) );
641 27840 : temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 );
642 :
643 27840 : IF( LT_16( s_q_fx, temp_q ) )
644 : {
645 24530 : s_fx = W_sub( s_fx, L_shr( temp, sub( temp_q, s_q_fx ) ) );
646 : }
647 : ELSE
648 : {
649 : #ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
650 3310 : s_fx = W_sub( W_shr( s_fx, s_min( 63, sub( s_q_fx, temp_q ) ) ), temp );
651 : #else
652 : s_fx = W_sub( W_shr( s_fx, sub( s_q_fx, temp_q ) ), temp );
653 : #endif
654 3310 : s_q_fx = temp_q;
655 3310 : move16();
656 : }
657 : }
658 1392 : tmp = W_norm( s_fx );
659 1392 : s_fx = W_shl( s_fx, tmp );
660 1392 : s_q_fx = add( s_q_fx, tmp );
661 1392 : yy_fx[i] = W_extract_h( s_fx );
662 1392 : move32();
663 1392 : yy_q_fx[i] = sub( s_q_fx, 32 );
664 1392 : move16();
665 1392 : y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) );
666 1392 : move32();
667 : }
668 24 : *y_q_fx = Q5;
669 24 : move16();
670 :
671 24 : return;
672 : }
673 :
674 : /*-----------------------------------------------------------------------------------------*
675 : * Function check_stab_fx()
676 : *
677 : * LPC filter stability check applying given sharpening value delta
678 : *-----------------------------------------------------------------------------------------*/
679 :
680 306 : static Word16 check_stab_fx(
681 : Word32 *a_fx,
682 : Word16 *a_q_fx,
683 : Word32 delta_fx,
684 : Word16 delta_q_fx )
685 : {
686 : Word16 i;
687 : Word16 stable;
688 :
689 : Word32 amod_fx[LFE_PLC_LPCORD], refl_fx[LFE_PLC_LPCORD];
690 : Word16 fac_q_fx, fac1_q_fx, amod_q_fx[LFE_PLC_LPCORD];
691 : Word16 exp1, exp2;
692 : Word32 fac_fx, fac1_fx;
693 :
694 306 : exp1 = norm_l( delta_fx );
695 306 : delta_fx = L_shl( delta_fx, exp1 );
696 306 : delta_q_fx = add( delta_q_fx, exp1 );
697 :
698 306 : IF( LT_16( delta_q_fx, 29 ) )
699 : {
700 0 : fac_fx = L_add( L_shr( ONE_IN_Q29, sub( 29, delta_q_fx ) ), delta_fx );
701 0 : fac_q_fx = delta_q_fx;
702 0 : move16();
703 : }
704 : ELSE
705 : {
706 306 : fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, 29 ) ) );
707 306 : fac_q_fx = Q29;
708 306 : move16();
709 : }
710 306 : fac1_fx = fac_fx;
711 306 : move32();
712 306 : fac1_q_fx = fac_q_fx;
713 306 : move16();
714 :
715 6426 : FOR( i = 0; i < LFE_PLC_LPCORD; i++ )
716 : {
717 6120 : exp1 = norm_l( a_fx[i] );
718 6120 : exp2 = norm_l( fac_fx );
719 6120 : amod_fx[i] = Mpy_32_32( L_shl( a_fx[i], exp1 ), L_shl( fac_fx, exp2 ) );
720 6120 : move32();
721 6120 : amod_q_fx[i] = sub( add( add( a_q_fx[i], exp1 ), add( fac_q_fx, exp2 ) ), 31 );
722 6120 : move16();
723 6120 : if ( amod_fx[i] == 0 )
724 : {
725 306 : amod_q_fx[i] = 31;
726 306 : move16();
727 : }
728 6120 : exp1 = norm_l( fac_fx );
729 6120 : exp2 = norm_l( fac1_fx );
730 6120 : fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( fac1_fx, exp2 ) );
731 6120 : fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( fac1_q_fx, exp2 ) ), 31 );
732 6120 : if ( fac_fx == 0 )
733 : {
734 0 : fac_q_fx = 0;
735 0 : move16();
736 : }
737 : }
738 306 : stable = d_a2rc_fx( amod_fx, amod_q_fx, refl_fx, LFE_PLC_LPCORD );
739 :
740 306 : return stable;
741 : }
742 :
743 : /*-----------------------------------------------------------------------------------------*
744 : * Function find_max_delta_fx()
745 : *
746 : * Find maximum LPC filter sharpening by iteration to get a filter that is almost instable
747 : *-----------------------------------------------------------------------------------------*/
748 :
749 24 : static Word32 find_max_delta_fx(
750 : Word32 *a_fx,
751 : Word16 *a_q_fx,
752 : Word16 *delta_q_fx )
753 : {
754 : Word16 stable;
755 : Word16 eps_q_fx, fac_q_fx, exp1, exp2;
756 : Word32 delta_fx, fac_fx, eps_fx, temp;
757 :
758 24 : delta_fx = 0;
759 24 : move32();
760 24 : eps_fx = 21474836; // 0.01 in Q31
761 24 : move32();
762 24 : fac_fx = 1073741824; // 2 in Q29
763 24 : move32();
764 24 : eps_q_fx = Q31;
765 24 : move16();
766 24 : fac_q_fx = Q29;
767 24 : move16();
768 :
769 24 : stable = FALSE;
770 24 : move16();
771 :
772 44 : WHILE( check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx ) )
773 : {
774 20 : exp1 = norm_l( eps_fx );
775 20 : exp2 = norm_l( fac_fx );
776 20 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
777 20 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
778 20 : stable = TRUE;
779 20 : move16();
780 : }
781 24 : fac_fx = 1073741824; // 0.5 in Q31
782 24 : move32();
783 24 : fac_q_fx = Q31;
784 24 : move16();
785 :
786 24 : IF( stable )
787 : {
788 10 : exp1 = norm_l( eps_fx );
789 10 : exp2 = norm_l( fac_fx );
790 10 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
791 10 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
792 : }
793 :
794 48 : WHILE( !stable )
795 : {
796 24 : exp1 = norm_l( eps_fx );
797 24 : exp2 = norm_l( fac_fx );
798 24 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
799 24 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
800 :
801 24 : stable = check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx );
802 : }
803 :
804 : /* must be stable with current eps */
805 24 : *delta_q_fx = sub( norm_l( eps_fx ), 1 );
806 24 : delta_fx = L_shl( eps_fx, *delta_q_fx );
807 24 : *delta_q_fx = add( eps_q_fx, *delta_q_fx );
808 24 : move16();
809 24 : move16();
810 :
811 24 : exp1 = norm_l( eps_fx );
812 24 : exp2 = norm_l( fac_fx );
813 24 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
814 24 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
815 :
816 : WHILE( 1 )
817 : {
818 238 : IF( LT_16( *delta_q_fx, eps_q_fx ) )
819 : {
820 238 : delta_fx = L_add( delta_fx, L_shr( eps_fx, sub( eps_q_fx, *delta_q_fx ) ) );
821 : }
822 : ELSE
823 : {
824 0 : delta_fx = L_add( L_shr( delta_fx, sub( *delta_q_fx, eps_q_fx ) ), eps_fx );
825 0 : *delta_q_fx = eps_q_fx;
826 0 : move16();
827 : }
828 238 : stable = check_stab_fx( a_fx, a_q_fx, delta_fx, *delta_q_fx );
829 :
830 238 : IF( !stable )
831 : {
832 125 : temp = L_abs( eps_fx );
833 125 : IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
834 : {
835 113 : exp1 = norm_l( -temp );
836 113 : exp2 = norm_l( fac_fx );
837 113 : eps_fx = Mpy_32_32( L_shl( -temp, exp1 ), L_shl( fac_fx, exp2 ) );
838 113 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
839 : }
840 : ELSE
841 : {
842 12 : eps_fx = L_negate( L_abs( eps_fx ) );
843 : }
844 : }
845 : ELSE
846 : {
847 113 : temp = L_abs( eps_fx );
848 113 : if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
849 : {
850 24 : BREAK;
851 : }
852 :
853 89 : exp1 = norm_l( temp );
854 89 : exp1 = norm_l( fac_fx );
855 89 : eps_fx = Mpy_32_32( L_shl( temp, exp1 ), L_shl( fac_fx, exp2 ) );
856 89 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
857 : }
858 : }
859 :
860 24 : return delta_fx;
861 : }
862 :
863 : /*-----------------------------------------------------------------------------------------*
864 : * Function recover_samples_fx()
865 : *
866 : * recover lost samples by extrapolation of signal buffer
867 : *-----------------------------------------------------------------------------------------*/
868 :
869 151 : static void recover_samples_fx(
870 : const Word16 bfi_count,
871 : const Word32 *outbuf_fx,
872 : Word16 outbuf_q_fx,
873 : Word32 *rec_frame_fx,
874 : Word16 *rec_frame_q_fx )
875 : {
876 : Word16 i;
877 : Word32 d_outbuf_fx[LFE_PLC_BUFLEN], d_a_fx[LFE_PLC_LPCORD + 1];
878 : Word16 d_r_q_fx[LFE_PLC_LPCORD + 1], d_a_q_fx[LFE_PLC_LPCORD + 1];
879 : Word32 d_r_fx[LFE_PLC_LPCORD + 1], zeroes_fx[LFE_PLC_RECLEN];
880 : Word32 delta_fx, fac_fx, att_fx, temp;
881 : Word16 delta_q_fx, fac_q_fx, temp_q, exp1, exp2;
882 :
883 151 : Copy32( outbuf_fx, d_outbuf_fx, LFE_PLC_BUFLEN );
884 :
885 151 : d_autocorr_fx( d_outbuf_fx, outbuf_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD, LFE_PLC_BUFLEN, d_hamm_lfe_plc_fx, 0, 1, 1 );
886 :
887 151 : IF( LT_64( W_shr( d_r_fx[0], sub( d_r_q_fx[0], Q19 ) ), W_deposit32_l( Mpy_32_32( POW_THR_Q50, LFE_PLC_BUFLEN ) ) ) )
888 : {
889 127 : set_zero_fx( rec_frame_fx, LFE_PLC_RECLEN );
890 127 : return;
891 : }
892 :
893 24 : lfeplc_lev_dur_fx( d_a_fx, d_a_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD );
894 :
895 24 : delta_fx = find_max_delta_fx( d_a_fx + 1, d_a_q_fx + 1, &delta_q_fx );
896 :
897 24 : IF( LT_16( delta_q_fx, Q29 ) )
898 : {
899 0 : fac_fx = L_add( L_shr( ONE_IN_Q29, sub( Q29, delta_q_fx ) ), delta_fx );
900 0 : fac_q_fx = delta_q_fx;
901 0 : move16();
902 : }
903 : ELSE
904 : {
905 24 : fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, Q29 ) ) );
906 24 : fac_q_fx = Q29;
907 24 : move16();
908 : }
909 24 : att_fx = ONE_IN_Q31;
910 24 : move32();
911 :
912 24 : IF( GE_16( bfi_count, LFE_PLC_MUTE_THR ) )
913 : {
914 0 : att_fx = LFE_PLC_BURST_ATT_Q31;
915 0 : move32();
916 0 : fac_fx = Mpy_32_32( fac_fx, att_fx );
917 : }
918 :
919 504 : FOR( i = 1; i <= LFE_PLC_LPCORD; i++ )
920 : {
921 480 : d_a_fx[i] = Mpy_32_32( d_a_fx[i], fac_fx );
922 480 : move32();
923 480 : d_a_q_fx[i] = sub( add( d_a_q_fx[i], fac_q_fx ), 31 );
924 480 : move16();
925 480 : if ( d_a_fx[i] == 0 )
926 : {
927 24 : d_a_q_fx[i] = 31;
928 24 : move16();
929 : }
930 480 : IF( LT_16( delta_q_fx, Q30 ) )
931 : {
932 0 : temp = L_add( L_shr( ONE_IN_Q30, sub( Q30, delta_q_fx ) ), delta_fx );
933 0 : temp_q = delta_q_fx;
934 0 : move16();
935 : }
936 : ELSE
937 : {
938 480 : temp = L_add( ONE_IN_Q30, L_shr( delta_fx, sub( delta_q_fx, Q30 ) ) );
939 480 : temp_q = Q30;
940 480 : move16();
941 : }
942 480 : exp2 = norm_l( temp );
943 480 : temp = Mpy_32_32( att_fx, L_shl( temp, exp2 ) );
944 480 : temp_q = add( temp_q, exp2 );
945 :
946 480 : exp1 = norm_l( fac_fx );
947 480 : exp2 = norm_l( temp );
948 480 : fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( temp, exp2 ) );
949 480 : fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( temp_q, exp2 ) ), 31 );
950 : }
951 :
952 24 : set_zero_fx( zeroes_fx, LFE_PLC_RECLEN );
953 :
954 24 : d_syn_filt_fx( d_a_fx, d_a_q_fx, LFE_PLC_LPCORD, zeroes_fx, rec_frame_fx, rec_frame_q_fx, LFE_PLC_RECLEN, outbuf_fx + LFE_PLC_BUFLEN - LFE_PLC_LPCORD, outbuf_q_fx );
955 :
956 24 : return;
957 : }
958 : /*-----------------------------------------------------------------------------------------*
959 : * Function ivas_lfe_tdplc_fx()
960 : *
961 : * MDCT interface recover lost samples by extrapolation of signal buffer
962 : *-----------------------------------------------------------------------------------------*/
963 :
964 151 : void ivas_lfe_tdplc_fx(
965 : LFE_DEC_HANDLE hLFE, /* i/o: LFE decoder handle */
966 : const Word32 *prevsynth, /* i : previous frame synthesis */
967 : Word32 *ytda, /* o : output time-domain buffer */
968 : const Word16 output_frame /* i : output frame length */
969 : )
970 : {
971 : Word32 rec_frame_us_fx[LFE_PLC_RECLEN_48K], input_tda_fx[L_FRAME48k];
972 : Word32 rec_frame_fx[LFE_PLC_RECLEN], prevsynth_fx[LFE_PLC_BUFLEN];
973 : Word16 rec_frame_us_16_fx[LFE_PLC_RECLEN_48K], mem_fx[2 * LFE_PLC_FDEL / LFE_PLC_DSF], rec_frame_16_fx[LFE_PLC_RECLEN];
974 : Word16 prevsynth_16_fx[LFE_PLC_BUFLEN];
975 : const Word32 *pWindow_coeffs_fx;
976 : Word32 output_Fs;
977 : Word16 i, fade_len, full_len, dct_len, zero_pad_len, plc_fdel, rec_frame_len;
978 : Word16 prevsynth_q_fx, rec_frame_q, temp_q, idx, exp;
979 :
980 151 : output_Fs = L_mult0( output_frame, FRAMES_PER_SEC );
981 151 : fade_len = hLFE->pWindow_state->fade_len;
982 151 : move16();
983 151 : full_len = hLFE->pWindow_state->full_len;
984 151 : move16();
985 151 : dct_len = hLFE->pWindow_state->dct_len;
986 151 : move16();
987 151 : zero_pad_len = hLFE->pWindow_state->zero_pad_len;
988 151 : move16();
989 151 : pWindow_coeffs_fx = hLFE->pWindow_state->pWindow_coeffs_fx;
990 :
991 : /* plc_fdel = (int16_t) ( LFE_PLC_FDEL * output_Fs / 48000 ); */
992 151 : plc_fdel = extract_l( Mpy_32_32( output_Fs, 13421773 /* ( LFE_PLC_FDEL / 48000 ) in Q31 */ ) );
993 : /* rec_frame_len = (int16_t) ( LFE_PLC_RECLEN_48K * output_Fs / 48000 ); */
994 151 : rec_frame_len = extract_l( Mpy_32_32_r( output_Fs, 77846282 /* LFE_PLC_RECLEN_48K / 48000 in Q31 */ ) );
995 :
996 151 : Copy32( prevsynth, prevsynth_fx, LFE_PLC_BUFLEN );
997 151 : exp = L_norm_arr( prevsynth_fx, LFE_PLC_BUFLEN );
998 151 : scale_sig32( prevsynth_fx, LFE_PLC_BUFLEN, exp );
999 151 : prevsynth_q_fx = add( Q9, exp );
1000 151 : move16();
1001 :
1002 151 : recover_samples_fx( hLFE->bfi_count, prevsynth_fx, prevsynth_q_fx, rec_frame_fx, &rec_frame_q );
1003 :
1004 151 : set16_fx( mem_fx, 0, 2 * LFE_PLC_FDEL / LFE_PLC_DSF );
1005 :
1006 151 : Copy_Scale_sig_32_16( prevsynth_fx, prevsynth_16_fx, LFE_PLC_BUFLEN, -prevsynth_q_fx ); // Q0
1007 151 : Copy_Scale_sig_32_16( rec_frame_fx, rec_frame_16_fx, LFE_PLC_RECLEN, -Q5 ); // Q0
1008 :
1009 : Word16 Q_new_inp, mem_decim_size, size_modified;
1010 151 : size_modified = modify_Fs_ivas_fx( prevsynth_16_fx + LFE_PLC_BUFLEN - LFE_PLC_FDEL / LFE_PLC_DSF, LFE_PLC_FDEL / LFE_PLC_DSF, LFE_PLC_FS, rec_frame_us_16_fx, 48000, mem_fx, 0, &Q_new_inp, &mem_decim_size );
1011 151 : Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
1012 :
1013 151 : size_modified = modify_Fs_ivas_fx( rec_frame_16_fx, LFE_PLC_RECLEN, LFE_PLC_FS, rec_frame_us_16_fx, 48000, mem_fx, 0, &Q_new_inp, &mem_decim_size );
1014 151 : Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
1015 :
1016 : /*samples are generated with 48k sampling rate
1017 : and then converted to required sampling rate by simple decimation
1018 : as signal is already bandlimited*/
1019 :
1020 : /*decimation to correct sampling rate*/
1021 151 : IF( NE_32( output_Fs, 48000 ) )
1022 : {
1023 5805 : FOR( i = 0; i < rec_frame_len; i++ )
1024 : {
1025 5800 : idx = BASOP_Util_Divide3232_Scale( Mpy_32_32( L_shl( i, 16 ), L_shl( 44100, 15 ) ), output_Fs, &temp_q );
1026 5800 : idx = shr( idx, add( sub( 15, temp_q ), 1 ) );
1027 5800 : rec_frame_us_16_fx[i] = rec_frame_us_16_fx[idx];
1028 5800 : move16();
1029 : }
1030 : }
1031 :
1032 151 : Copy_Scale_sig_16_32_DEPREC( rec_frame_us_16_fx, rec_frame_us_fx, LFE_PLC_RECLEN_48K, 10 ); // Q10 = rec_frame_q + 5
1033 :
1034 453 : FOR( i = 0; i < 2; i++ )
1035 : {
1036 302 : ivas_dct_windowing_fx( fade_len, full_len, dct_len, zero_pad_len, pWindow_coeffs_fx, output_frame, input_tda_fx, rec_frame_us_fx + plc_fdel, rec_frame_us_fx + add( add( plc_fdel, fade_len ), i_mult( i, dct_len ) ) );
1037 302 : ivas_tda_fx( input_tda_fx, ytda + imult1616( i, dct_len ), dct_len );
1038 : }
1039 :
1040 151 : return;
1041 : }
|