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