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 126 : 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 126 : 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 126 : ELSE IF( EQ_16( sym_flag, 1 ) )
100 : {
101 : /* symmetric window of even length */
102 15246 : FOR( i = 0; i < len / 2; i++ )
103 : {
104 15120 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[i] ); // Q = x_q_fx
105 15120 : move32();
106 : }
107 :
108 15246 : FOR( ; i < len; i++ )
109 : {
110 15120 : t_fx[i] = Mpy_32_32( x_fx[i], wind_fx[len - 1 - i] ); // Q = x_q_fx
111 15120 : 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 2772 : FOR( i = 0; i <= m; i++ )
125 : {
126 2646 : exp1 = norm_l( t_fx[0] );
127 2646 : exp2 = norm_l( t_fx[i] );
128 2646 : s_fx = W_deposit32_l( Mpy_32_32( L_shl( t_fx[0], exp1 ), L_shl( t_fx[i], exp2 ) ) );
129 2646 : r_q_fx[i] = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
130 2646 : move16();
131 608580 : FOR( j = 1; j < len - i; j++ )
132 : {
133 605934 : exp1 = norm_l( t_fx[j] );
134 605934 : exp2 = norm_l( t_fx[i + j] );
135 605934 : temp = Mpy_32_32( L_shl( t_fx[j], exp1 ), L_shl( t_fx[i + j], exp2 ) );
136 605934 : tmp_q = sub( add( add( x_q_fx, exp1 ), add( x_q_fx, exp2 ) ), 31 );
137 :
138 605934 : IF( LT_16( tmp_q, r_q_fx[i] ) )
139 : {
140 2735 : s_fx = W_add( W_shr( s_fx, sub( r_q_fx[i], tmp_q ) ), W_deposit32_l( temp ) );
141 2735 : r_q_fx[i] = tmp_q;
142 2735 : move16();
143 : }
144 : ELSE
145 : {
146 603199 : s_fx = W_add( s_fx, W_shr( temp, sub( tmp_q, r_q_fx[i] ) ) );
147 : }
148 : }
149 2646 : exp1 = W_norm( s_fx );
150 2646 : r_fx[i] = W_extract_h( W_shl( s_fx, exp1 ) );
151 2646 : move32();
152 2646 : r_q_fx[i] = sub( add( r_q_fx[i], exp1 ), 32 );
153 2646 : move16();
154 : }
155 :
156 : // 2097152000 = 1000 in Q21
157 126 : IF( LT_16( r_q_fx[0], Q21 ) )
158 : {
159 126 : 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 126 : 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 20 : 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 20 : set32_fx( a_fx, 0, LFE_PLC_LPCORD + 1 );
207 20 : set16_fx( a_q_fx, 31, LFE_PLC_LPCORD + 1 );
208 20 : set32_fx( a_out_fx, 0, LFE_PLC_LPCORD + 1 );
209 20 : set16_fx( a_out_q_fx, 31, LFE_PLC_LPCORD + 1 );
210 :
211 20 : s_q_fx = 0;
212 20 : move16();
213 :
214 20 : rc_fx = &buf_fx[0];
215 20 : a_fx[0] = ONE_IN_Q30;
216 20 : move32();
217 20 : a_q_fx[0] = 30;
218 20 : move16();
219 20 : err_fx = r_fx[0];
220 20 : move32();
221 20 : err_q_fx = r_q_fx[0];
222 20 : move16();
223 20 : a_out_fx[0] = a_fx[0];
224 20 : move32();
225 20 : a_out_q_fx[0] = 30;
226 20 : move16();
227 :
228 20 : rc_fx[0] = BASOP_Util_Divide3232_Scale_newton( -r_fx[1], r_fx[0], &temp_q2 );
229 20 : move32();
230 20 : rc_q_fx[0] = add( sub( r_q_fx[1], r_q_fx[0] ), sub( 31, temp_q2 ) );
231 20 : move16();
232 :
233 20 : s = r_fx[1];
234 20 : s_q_fx = r_q_fx[1];
235 20 : move32();
236 20 : move16();
237 :
238 20 : a_fx[1] = rc_fx[0];
239 20 : move32();
240 20 : a_q_fx[1] = rc_q_fx[0];
241 20 : move32();
242 :
243 20 : a_out_fx[1] = a_fx[1];
244 20 : move32();
245 20 : a_out_q_fx[1] = a_q_fx[1];
246 20 : move32();
247 :
248 20 : i = 1;
249 20 : move16();
250 400 : WHILE( LT_16( i, m ) )
251 : {
252 2180 : FOR( j = 1; j <= i / 2; j++ )
253 : {
254 1800 : l = sub( i, j );
255 1800 : exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
256 1800 : exp2 = sub( norm_l( a_fx[l] ), 1 );
257 1800 : rc_fx[i - 1] = L_shl( rc_fx[i - 1], exp1 );
258 1800 : move32();
259 1800 : rc_q_fx[i - 1] = add( rc_q_fx[i - 1], exp1 );
260 1800 : move16();
261 1800 : a_fx[l] = L_shl( a_fx[l], exp2 );
262 1800 : move32();
263 1800 : a_q_fx[l] = add( a_q_fx[l], exp2 );
264 1800 : move16();
265 :
266 1800 : exp2 = sub( norm_l( a_fx[j] ), 1 );
267 1800 : a_fx[j] = L_shl( a_fx[j], exp2 );
268 1800 : move32();
269 1800 : a_q_fx[j] = add( a_q_fx[j], exp2 );
270 1800 : move16();
271 :
272 1800 : temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[l] );
273 1800 : temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[l] ), 31 );
274 1800 : if ( temp2 == 0 )
275 : {
276 0 : temp_q2 = 31;
277 0 : move16();
278 : }
279 :
280 1800 : IF( LT_16( temp_q2, a_q_fx[j] ) )
281 : {
282 58 : at_fx = L_add( L_shr( a_fx[j], sub( a_q_fx[j], temp_q2 ) ), temp2 ); // Q(temp_q2)
283 58 : temp_q1 = temp_q2;
284 58 : move16();
285 : }
286 : ELSE
287 : {
288 1742 : at_fx = L_add( a_fx[j], L_shr( temp2, sub( temp_q2, a_q_fx[j] ) ) ); // Q(a_q_fx)
289 1742 : temp_q1 = a_q_fx[j];
290 1742 : move16();
291 : }
292 :
293 1800 : temp2 = Mpy_32_32( rc_fx[i - 1], a_fx[j] );
294 1800 : temp_q2 = sub( add( rc_q_fx[i - 1], a_q_fx[j] ), 31 );
295 1800 : if ( temp2 == 0 )
296 : {
297 0 : temp_q2 = 31;
298 0 : move16();
299 : }
300 :
301 1800 : IF( LT_16( temp_q2, a_q_fx[l] ) )
302 : {
303 908 : a_fx[l] = L_add( L_shr( a_fx[l], sub( a_q_fx[l], temp_q2 ) ), temp2 );
304 908 : move32();
305 908 : a_q_fx[l] = temp_q2;
306 908 : move16();
307 : }
308 : ELSE
309 : {
310 892 : a_fx[l] = L_add( a_fx[l], L_shr( temp2, sub( temp_q2, a_q_fx[l] ) ) );
311 892 : move16();
312 : }
313 1800 : a_fx[j] = at_fx;
314 1800 : move32();
315 1800 : a_q_fx[j] = temp_q1;
316 1800 : move16();
317 : }
318 :
319 380 : a_fx[i] = rc_fx[i - 1];
320 380 : move32();
321 380 : a_q_fx[i] = rc_q_fx[i - 1];
322 380 : move16();
323 :
324 380 : exp1 = sub( norm_l( rc_fx[i - 1] ), 1 );
325 380 : exp2 = norm_l( s );
326 380 : temp1 = Mpy_32_32( L_shl( rc_fx[i - 1], exp1 ), L_shl( s, exp2 ) );
327 380 : temp_q1 = sub( add( add( rc_q_fx[i - 1], exp1 ), add( s_q_fx, exp2 ) ), 31 );
328 380 : if ( temp1 == 0 )
329 : {
330 0 : temp_q1 = 31;
331 0 : move16();
332 : }
333 :
334 380 : IF( LT_16( temp_q1, err_q_fx ) )
335 : {
336 14 : err_fx = L_add( L_shr( err_fx, sub( err_q_fx, temp_q1 ) ), temp1 );
337 14 : err_q_fx = temp_q1;
338 14 : move16();
339 : }
340 : ELSE
341 : {
342 366 : err_fx = L_add( err_fx, L_shr( temp1, sub( temp_q1, err_q_fx ) ) );
343 : }
344 :
345 380 : s_fx = 0;
346 380 : move32();
347 380 : s_q_fx = 0;
348 380 : move16();
349 380 : i = add( i, 1 );
350 380 : s_fx = 0;
351 380 : move64();
352 :
353 4560 : FOR( j = 0; j < i; j++ )
354 : {
355 4180 : exp1 = norm_l( r_fx[i - j] );
356 4180 : exp2 = norm_l( a_fx[j] );
357 4180 : temp1 = Mpy_32_32( L_shl( r_fx[i - j], exp1 ), L_shl( a_fx[j], exp2 ) );
358 4180 : temp_q1 = sub( add( add( r_q_fx[i - j], exp1 ), add( a_q_fx[j], exp2 ) ), 31 );
359 4180 : if ( temp1 == 0 )
360 : {
361 0 : temp_q1 = 31;
362 0 : move16();
363 : }
364 :
365 4180 : IF( j == 0 )
366 : {
367 380 : s_fx = W_deposit32_l( temp1 );
368 380 : s_q_fx = temp_q1;
369 380 : move16();
370 : }
371 : ELSE
372 : {
373 3800 : IF( LT_16( temp_q1, s_q_fx ) )
374 : {
375 442 : s_fx = W_add( W_shr( s_fx, sub( s_q_fx, temp_q1 ) ), W_deposit32_l( temp1 ) );
376 442 : s_q_fx = temp_q1;
377 442 : move16();
378 : }
379 : ELSE
380 : {
381 3358 : s_fx = W_add( s_fx, W_shr( W_deposit32_l( temp1 ), sub( temp_q1, s_q_fx ) ) );
382 : }
383 : }
384 : }
385 :
386 380 : exp1 = W_norm( s_fx );
387 380 : s = W_extract_h( W_shl( s_fx, exp1 ) );
388 380 : s_q_fx = sub( add( s_q_fx, exp1 ), 32 );
389 :
390 380 : rc_fx[i - 1] = L_shr( BASOP_Util_Divide3232_Scale_newton( L_negate( s ), err_fx, &temp_q2 ), 1 );
391 380 : move32();
392 380 : rc_q_fx[i - 1] = sub( add( sub( s_q_fx, err_q_fx ), sub( 31, temp_q2 ) ), 1 );
393 380 : move16();
394 :
395 380 : IF( LT_16( rc_q_fx[i - 1], 31 ) )
396 : {
397 :
398 82 : 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 1804 : FOR( j = 0; j <= m; j++ )
405 : {
406 1722 : a_out_fx[j] = a_fx[j];
407 1722 : a_out_q_fx[j] = a_q_fx[j];
408 1722 : move32();
409 1722 : move32();
410 : }
411 : }
412 : }
413 : ELSE
414 : {
415 298 : 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 6556 : FOR( j = 0; j <= m; j++ )
422 : {
423 6258 : a_out_fx[j] = a_fx[j];
424 6258 : a_out_q_fx[j] = a_q_fx[j];
425 6258 : move32();
426 6258 : move32();
427 : }
428 : }
429 : }
430 : }
431 20 : return 0;
432 : }
433 : /*-------------------------------------------------------------------*
434 : * a2rc_fx()
435 : *
436 : * Convert from LPC to reflection coeff
437 : *-------------------------------------------------------------------*/
438 :
439 254 : 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 5334 : FOR( m = 0; m < lpcorder; m++ )
453 : {
454 5080 : ff_fx[m] = L_negate( a_fx[m] );
455 5080 : move32();
456 5080 : ff_q_fx[m] = a_q_fx[m];
457 5080 : move32();
458 : }
459 :
460 : /* Initialization */
461 4979 : FOR( m = lpcorder - 1; m >= 0; m-- )
462 : {
463 4859 : km_fx = ff_fx[m];
464 4859 : move32();
465 4859 : km_q_fx = ff_q_fx[m];
466 4859 : move16();
467 4859 : IF( GE_64( W_shr( L_abs( km_fx ), sub( ff_q_fx[m], Q30 ) ), W_deposit32_l( ONE_IN_Q30 ) ) )
468 : {
469 2814 : FOR( j = 0; j < lpcorder; j++ )
470 : {
471 2680 : refl_fx[j] = 0;
472 2680 : move32();
473 : }
474 134 : return 0;
475 : }
476 :
477 4725 : refl_fx[m] = L_negate( km_fx ); // Q(km_q_Fx)
478 4725 : move32();
479 :
480 4725 : exp1 = norm_l( km_fx );
481 4725 : temp1 = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( km_fx, exp1 ) );
482 4725 : temp_q1 = sub( add( add( km_q_fx, exp1 ), add( km_q_fx, exp1 ) ), 31 );
483 4725 : temp1 = L_sub( ONE_IN_Q30, L_shr( temp1, sub( temp_q1, 30 ) ) );
484 4725 : denom_fx = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q30, temp1, &temp_q1 ) );
485 4725 : denom_q_fx = sub( 15, temp_q1 );
486 :
487 27390 : FOR( j = 0; j < m / 2; j++ )
488 : {
489 22665 : n = sub( sub( m, 1 ), j );
490 :
491 22665 : exp1 = norm_l( denom_fx );
492 22665 : exp2 = sub( norm_l( ff_fx[j] ), 1 );
493 22665 : temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
494 22665 : temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
495 :
496 22665 : exp2 = sub( norm_l( ff_fx[n] ), 1 );
497 22665 : temp2 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[n], exp2 ) );
498 22665 : temp_q2 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[n], exp2 ) ), 31 );
499 :
500 22665 : exp1 = norm_l( km_fx );
501 22665 : exp2 = sub( norm_l( temp2 ), 1 );
502 22665 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp2, exp2 ) );
503 22665 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q2, exp2 ) ), 31 );
504 22665 : if ( temp == 0 )
505 : {
506 2286 : temp_q = 31;
507 2286 : move16();
508 : }
509 22665 : IF( LT_16( temp_q, temp_q1 ) )
510 : {
511 482 : ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
512 482 : move32();
513 482 : ff_q_fx[j] = temp_q;
514 482 : move16();
515 : }
516 : ELSE
517 : {
518 22183 : ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
519 22183 : move32();
520 22183 : ff_q_fx[j] = temp_q1;
521 22183 : move16();
522 : }
523 :
524 22665 : exp1 = norm_l( km_fx );
525 22665 : exp2 = sub( norm_l( temp1 ), 1 );
526 22665 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
527 22665 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
528 22665 : if ( temp == 0 )
529 : {
530 2286 : temp_q = 31;
531 2286 : move16();
532 : }
533 22665 : IF( LT_16( temp_q, temp_q2 ) )
534 : {
535 5119 : ff_fx[n] = L_add( L_shr( temp2, sub( temp_q2, temp_q ) ), temp );
536 5119 : move32();
537 5119 : ff_q_fx[n] = temp_q;
538 5119 : move16();
539 : }
540 : ELSE
541 : {
542 17546 : ff_fx[n] = L_add( temp2, L_shr( temp, sub( temp_q, temp_q2 ) ) );
543 17546 : move32();
544 17546 : ff_q_fx[n] = temp_q2;
545 17546 : move16();
546 : }
547 : }
548 :
549 4725 : IF( s_and( m, 1 ) )
550 : {
551 2379 : exp1 = norm_l( denom_fx );
552 2379 : exp2 = sub( norm_l( ff_fx[j] ), 1 );
553 2379 : temp1 = Mpy_32_32( L_shl( denom_fx, exp1 ), L_shl( ff_fx[j], exp2 ) );
554 2379 : temp_q1 = sub( add( add( denom_q_fx, exp1 ), add( ff_q_fx[j], exp2 ) ), 31 );
555 :
556 2379 : exp1 = norm_l( km_fx );
557 2379 : exp2 = sub( norm_l( temp1 ), 1 );
558 2379 : temp = Mpy_32_32( L_shl( km_fx, exp1 ), L_shl( temp1, exp2 ) );
559 2379 : temp_q = sub( add( add( km_q_fx, exp1 ), add( temp_q1, exp2 ) ), 31 );
560 2379 : if ( temp == 0 )
561 : {
562 254 : temp_q = 31;
563 254 : move16();
564 : }
565 2379 : IF( LT_16( temp_q, temp_q1 ) )
566 : {
567 153 : ff_fx[j] = L_add( L_shr( temp1, sub( temp_q1, temp_q ) ), temp );
568 153 : move32();
569 153 : ff_q_fx[j] = temp_q;
570 153 : move16();
571 : }
572 : ELSE
573 : {
574 2226 : ff_fx[j] = L_add( temp1, L_shr( temp, sub( temp_q, temp_q1 ) ) );
575 2226 : move32();
576 2226 : ff_q_fx[j] = temp_q1;
577 2226 : move16();
578 : }
579 : }
580 : }
581 :
582 120 : return 1;
583 : }
584 :
585 20 : 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 20 : yy_fx = &buf_fx[0];
604 :
605 : /*------------------------------------------------------------------*
606 : * copy initial filter states into synthesis buffer and do synthesis
607 : *------------------------------------------------------------------*/
608 420 : FOR( i = 0; i < m; i++ )
609 : {
610 400 : *yy_fx++ = mem_fx[i];
611 400 : move32();
612 400 : yy_q_fx[i] = mem_q_fx;
613 400 : move16();
614 : }
615 :
616 : /*-----------------------------------------------------------------------*
617 : * Do the filtering
618 : *-----------------------------------------------------------------------*/
619 :
620 1180 : FOR( i = 0; i < l; i++ )
621 : {
622 1160 : s_fx = x_fx[i];
623 1160 : move64();
624 1160 : s_q_fx = Q31;
625 1160 : move16();
626 24360 : FOR( j = 1; j <= m; j++ )
627 : {
628 23200 : exp1 = sub( norm_l( a_fx[j] ), 1 );
629 23200 : exp2 = sub( norm_l( yy_fx[i - j] ), 1 );
630 23200 : IF( GT_16( j, i ) )
631 : {
632 4200 : temp_q = mem_q_fx;
633 4200 : move16();
634 : }
635 : ELSE
636 : {
637 19000 : temp_q = yy_q_fx[i - j];
638 19000 : move16();
639 : }
640 23200 : temp = Mpy_32_32( L_shl( a_fx[j], exp1 ), L_shl( yy_fx[i - j], exp2 ) );
641 23200 : temp_q = sub( add( add( a_q_fx[j], exp1 ), add( temp_q, exp2 ) ), 31 );
642 :
643 23200 : IF( LT_16( s_q_fx, temp_q ) )
644 : {
645 20434 : s_fx = W_sub( s_fx, L_shr( temp, sub( temp_q, s_q_fx ) ) );
646 : }
647 : ELSE
648 : {
649 2766 : s_fx = W_sub( W_shr( s_fx, sub( s_q_fx, temp_q ) ), temp );
650 2766 : s_q_fx = temp_q;
651 2766 : move16();
652 : }
653 : }
654 1160 : tmp = W_norm( s_fx );
655 1160 : s_fx = W_shl( s_fx, tmp );
656 1160 : s_q_fx = add( s_q_fx, tmp );
657 1160 : yy_fx[i] = W_extract_h( s_fx );
658 1160 : move32();
659 1160 : yy_q_fx[i] = sub( s_q_fx, 32 );
660 1160 : move16();
661 1160 : y_fx[i] = W_extract_l( W_shr( s_fx, sub( s_q_fx, Q5 ) ) );
662 1160 : move32();
663 : }
664 20 : *y_q_fx = Q5;
665 20 : move16();
666 :
667 20 : return;
668 : }
669 :
670 : /*-----------------------------------------------------------------------------------------*
671 : * Function check_stab_fx()
672 : *
673 : * LPC filter stability check applying given sharpening value delta
674 : *-----------------------------------------------------------------------------------------*/
675 :
676 254 : static Word16 check_stab_fx(
677 : Word32 *a_fx,
678 : Word16 *a_q_fx,
679 : Word32 delta_fx,
680 : Word16 delta_q_fx )
681 : {
682 : Word16 i;
683 : Word16 stable;
684 :
685 : Word32 amod_fx[LFE_PLC_LPCORD], refl_fx[LFE_PLC_LPCORD];
686 : Word16 fac_q_fx, fac1_q_fx, amod_q_fx[LFE_PLC_LPCORD];
687 : Word16 exp1, exp2;
688 : Word32 fac_fx, fac1_fx;
689 :
690 254 : exp1 = norm_l( delta_fx );
691 254 : delta_fx = L_shl( delta_fx, exp1 );
692 254 : delta_q_fx = add( delta_q_fx, exp1 );
693 :
694 254 : IF( LT_16( delta_q_fx, 29 ) )
695 : {
696 0 : fac_fx = L_add( L_shr( ONE_IN_Q29, sub( 29, delta_q_fx ) ), delta_fx );
697 0 : fac_q_fx = delta_q_fx;
698 0 : move16();
699 : }
700 : ELSE
701 : {
702 254 : fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, 29 ) ) );
703 254 : fac_q_fx = Q29;
704 254 : move16();
705 : }
706 254 : fac1_fx = fac_fx;
707 254 : move32();
708 254 : fac1_q_fx = fac_q_fx;
709 254 : move16();
710 :
711 5334 : FOR( i = 0; i < LFE_PLC_LPCORD; i++ )
712 : {
713 5080 : exp1 = norm_l( a_fx[i] );
714 5080 : exp2 = norm_l( fac_fx );
715 5080 : amod_fx[i] = Mpy_32_32( L_shl( a_fx[i], exp1 ), L_shl( fac_fx, exp2 ) );
716 5080 : move32();
717 5080 : amod_q_fx[i] = sub( add( add( a_q_fx[i], exp1 ), add( fac_q_fx, exp2 ) ), 31 );
718 5080 : move16();
719 5080 : if ( amod_fx[i] == 0 )
720 : {
721 254 : amod_q_fx[i] = 31;
722 254 : move16();
723 : }
724 5080 : exp1 = norm_l( fac_fx );
725 5080 : exp2 = norm_l( fac1_fx );
726 5080 : fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( fac1_fx, exp2 ) );
727 5080 : fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( fac1_q_fx, exp2 ) ), 31 );
728 5080 : if ( fac_fx == 0 )
729 : {
730 0 : fac_q_fx = 0;
731 0 : move16();
732 : }
733 : }
734 254 : stable = d_a2rc_fx( amod_fx, amod_q_fx, refl_fx, LFE_PLC_LPCORD );
735 :
736 254 : return stable;
737 : }
738 :
739 : /*-----------------------------------------------------------------------------------------*
740 : * Function find_max_delta_fx()
741 : *
742 : * Find maximum LPC filter sharpening by iteration to get a filter that is almost instable
743 : *-----------------------------------------------------------------------------------------*/
744 :
745 20 : static Word32 find_max_delta_fx(
746 : Word32 *a_fx,
747 : Word16 *a_q_fx,
748 : Word16 *delta_q_fx )
749 : {
750 : Word16 stable;
751 : Word16 eps_q_fx, fac_q_fx, exp1, exp2;
752 : Word32 delta_fx, fac_fx, eps_fx, temp;
753 :
754 20 : delta_fx = 0;
755 20 : move32();
756 20 : eps_fx = 21474836; // 0.01 in Q31
757 20 : move32();
758 20 : fac_fx = 1073741824; // 2 in Q29
759 20 : move32();
760 20 : eps_q_fx = Q31;
761 20 : move16();
762 20 : fac_q_fx = Q29;
763 20 : move16();
764 :
765 20 : stable = FALSE;
766 20 : move16();
767 :
768 36 : WHILE( check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx ) )
769 : {
770 16 : exp1 = norm_l( eps_fx );
771 16 : exp2 = norm_l( fac_fx );
772 16 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
773 16 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
774 16 : stable = TRUE;
775 16 : move16();
776 : }
777 20 : fac_fx = 1073741824; // 0.5 in Q31
778 20 : move32();
779 20 : fac_q_fx = Q31;
780 20 : move16();
781 :
782 20 : IF( stable )
783 : {
784 7 : exp1 = norm_l( eps_fx );
785 7 : exp2 = norm_l( fac_fx );
786 7 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
787 7 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
788 : }
789 :
790 43 : WHILE( !stable )
791 : {
792 23 : exp1 = norm_l( eps_fx );
793 23 : exp2 = norm_l( fac_fx );
794 23 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
795 23 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
796 :
797 23 : stable = check_stab_fx( a_fx, a_q_fx, eps_fx, eps_q_fx );
798 : }
799 :
800 : /* must be stable with current eps */
801 20 : *delta_q_fx = sub( norm_l( eps_fx ), 1 );
802 20 : delta_fx = L_shl( eps_fx, *delta_q_fx );
803 20 : *delta_q_fx = add( eps_q_fx, *delta_q_fx );
804 20 : move16();
805 20 : move16();
806 :
807 20 : exp1 = norm_l( eps_fx );
808 20 : exp2 = norm_l( fac_fx );
809 20 : eps_fx = Mpy_32_32( L_shl( eps_fx, exp1 ), L_shl( fac_fx, exp2 ) );
810 20 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
811 :
812 : WHILE( 1 )
813 : {
814 195 : IF( LT_16( *delta_q_fx, eps_q_fx ) )
815 : {
816 195 : delta_fx = L_add( delta_fx, L_shr( eps_fx, sub( eps_q_fx, *delta_q_fx ) ) );
817 : }
818 : ELSE
819 : {
820 0 : delta_fx = L_add( L_shr( delta_fx, sub( *delta_q_fx, eps_q_fx ) ), eps_fx );
821 0 : *delta_q_fx = eps_q_fx;
822 0 : move16();
823 : }
824 195 : stable = check_stab_fx( a_fx, a_q_fx, delta_fx, *delta_q_fx );
825 :
826 195 : IF( !stable )
827 : {
828 104 : temp = L_abs( eps_fx );
829 104 : IF( GT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
830 : {
831 95 : exp1 = norm_l( -temp );
832 95 : exp2 = norm_l( fac_fx );
833 95 : eps_fx = Mpy_32_32( L_shl( -temp, exp1 ), L_shl( fac_fx, exp2 ) );
834 95 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
835 : }
836 : ELSE
837 : {
838 9 : eps_fx = L_negate( L_abs( eps_fx ) );
839 : }
840 : }
841 : ELSE
842 : {
843 91 : temp = L_abs( eps_fx );
844 91 : if ( LT_32( L_shr( temp, sub( eps_q_fx, 31 ) ), EPS_STOP_Q31 ) )
845 : {
846 20 : BREAK;
847 : }
848 :
849 71 : exp1 = norm_l( temp );
850 71 : exp1 = norm_l( fac_fx );
851 71 : eps_fx = Mpy_32_32( L_shl( temp, exp1 ), L_shl( fac_fx, exp2 ) );
852 71 : eps_q_fx = sub( add( add( eps_q_fx, exp1 ), add( fac_q_fx, exp2 ) ), 31 );
853 : }
854 : }
855 :
856 20 : return delta_fx;
857 : }
858 :
859 : /*-----------------------------------------------------------------------------------------*
860 : * Function recover_samples_fx()
861 : *
862 : * recover lost samples by extrapolation of signal buffer
863 : *-----------------------------------------------------------------------------------------*/
864 :
865 126 : static void recover_samples_fx(
866 : const Word16 bfi_count,
867 : const Word32 *outbuf_fx,
868 : Word16 outbuf_q_fx,
869 : Word32 *rec_frame_fx,
870 : Word16 *rec_frame_q_fx )
871 : {
872 : Word16 i;
873 : Word32 d_outbuf_fx[LFE_PLC_BUFLEN], d_a_fx[LFE_PLC_LPCORD + 1];
874 : Word16 d_r_q_fx[LFE_PLC_LPCORD + 1], d_a_q_fx[LFE_PLC_LPCORD + 1];
875 : Word32 d_r_fx[LFE_PLC_LPCORD + 1], zeroes_fx[LFE_PLC_RECLEN];
876 : Word32 delta_fx, fac_fx, att_fx, temp;
877 : Word16 delta_q_fx, fac_q_fx, temp_q, exp1, exp2;
878 :
879 126 : Copy32( outbuf_fx, d_outbuf_fx, LFE_PLC_BUFLEN );
880 :
881 126 : 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 );
882 :
883 126 : 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 ) ) ) )
884 : {
885 106 : set_zero_fx( rec_frame_fx, LFE_PLC_RECLEN );
886 106 : return;
887 : }
888 :
889 20 : lfeplc_lev_dur_fx( d_a_fx, d_a_q_fx, d_r_fx, d_r_q_fx, LFE_PLC_LPCORD );
890 :
891 20 : delta_fx = find_max_delta_fx( d_a_fx + 1, d_a_q_fx + 1, &delta_q_fx );
892 :
893 20 : IF( LT_16( delta_q_fx, Q29 ) )
894 : {
895 0 : fac_fx = L_add( L_shr( ONE_IN_Q29, sub( Q29, delta_q_fx ) ), delta_fx );
896 0 : fac_q_fx = delta_q_fx;
897 0 : move16();
898 : }
899 : ELSE
900 : {
901 20 : fac_fx = L_add( ONE_IN_Q29, L_shr( delta_fx, sub( delta_q_fx, Q29 ) ) );
902 20 : fac_q_fx = Q29;
903 20 : move16();
904 : }
905 20 : att_fx = ONE_IN_Q31;
906 20 : move32();
907 :
908 20 : IF( GE_16( bfi_count, LFE_PLC_MUTE_THR ) )
909 : {
910 0 : att_fx = LFE_PLC_BURST_ATT_Q31;
911 0 : move32();
912 0 : fac_fx = Mpy_32_32( fac_fx, att_fx );
913 : }
914 :
915 420 : FOR( i = 1; i <= LFE_PLC_LPCORD; i++ )
916 : {
917 400 : d_a_fx[i] = Mpy_32_32( d_a_fx[i], fac_fx );
918 400 : move32();
919 400 : d_a_q_fx[i] = sub( add( d_a_q_fx[i], fac_q_fx ), 31 );
920 400 : move16();
921 400 : if ( d_a_fx[i] == 0 )
922 : {
923 20 : d_a_q_fx[i] = 31;
924 20 : move16();
925 : }
926 400 : IF( LT_16( delta_q_fx, Q30 ) )
927 : {
928 0 : temp = L_add( L_shr( ONE_IN_Q30, sub( Q30, delta_q_fx ) ), delta_fx );
929 0 : temp_q = delta_q_fx;
930 0 : move16();
931 : }
932 : ELSE
933 : {
934 400 : temp = L_add( ONE_IN_Q30, L_shr( delta_fx, sub( delta_q_fx, Q30 ) ) );
935 400 : temp_q = Q30;
936 400 : move16();
937 : }
938 400 : exp2 = norm_l( temp );
939 400 : temp = Mpy_32_32( att_fx, L_shl( temp, exp2 ) );
940 400 : temp_q = add( temp_q, exp2 );
941 :
942 400 : exp1 = norm_l( fac_fx );
943 400 : exp2 = norm_l( temp );
944 400 : fac_fx = Mpy_32_32( L_shl( fac_fx, exp1 ), L_shl( temp, exp2 ) );
945 400 : fac_q_fx = sub( add( add( fac_q_fx, exp1 ), add( temp_q, exp2 ) ), 31 );
946 : }
947 :
948 20 : set_zero_fx( zeroes_fx, LFE_PLC_RECLEN );
949 :
950 20 : 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 );
951 :
952 20 : return;
953 : }
954 : /*-----------------------------------------------------------------------------------------*
955 : * Function ivas_lfe_tdplc_fx()
956 : *
957 : * MDCT interface recover lost samples by extrapolation of signal buffer
958 : *-----------------------------------------------------------------------------------------*/
959 :
960 126 : void ivas_lfe_tdplc_fx(
961 : LFE_DEC_HANDLE hLFE, /* i/o: LFE decoder handle */
962 : const Word32 *prevsynth, /* i : previous frame synthesis */
963 : Word32 *ytda, /* o : output time-domain buffer */
964 : const Word16 output_frame /* i : output frame length */
965 : )
966 : {
967 : Word32 rec_frame_us_fx[LFE_PLC_RECLEN_48K], input_tda_fx[L_FRAME48k];
968 : Word32 rec_frame_fx[LFE_PLC_RECLEN], prevsynth_fx[LFE_PLC_BUFLEN];
969 : 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];
970 : Word16 prevsynth_16_fx[LFE_PLC_BUFLEN];
971 : const Word32 *pWindow_coeffs_fx;
972 : Word32 output_Fs;
973 : Word16 i, fade_len, full_len, dct_len, zero_pad_len, plc_fdel, rec_frame_len;
974 : Word16 prevsynth_q_fx, rec_frame_q, temp_q, idx, exp;
975 :
976 126 : output_Fs = L_mult0( output_frame, FRAMES_PER_SEC );
977 126 : fade_len = hLFE->pWindow_state->fade_len;
978 126 : move16();
979 126 : full_len = hLFE->pWindow_state->full_len;
980 126 : move16();
981 126 : dct_len = hLFE->pWindow_state->dct_len;
982 126 : move16();
983 126 : zero_pad_len = hLFE->pWindow_state->zero_pad_len;
984 126 : move16();
985 126 : pWindow_coeffs_fx = hLFE->pWindow_state->pWindow_coeffs_fx;
986 :
987 : /* plc_fdel = (int16_t) ( LFE_PLC_FDEL * output_Fs / 48000 ); */
988 126 : plc_fdel = extract_l( Mpy_32_32( output_Fs, 13421773 /* ( LFE_PLC_FDEL / 48000 ) in Q31 */ ) );
989 : /* rec_frame_len = (int16_t) ( LFE_PLC_RECLEN_48K * output_Fs / 48000 ); */
990 126 : rec_frame_len = extract_l( Mpy_32_32_r( output_Fs, 77846282 /* LFE_PLC_RECLEN_48K / 48000 in Q31 */ ) );
991 :
992 126 : Copy32( prevsynth, prevsynth_fx, LFE_PLC_BUFLEN );
993 126 : exp = L_norm_arr( prevsynth_fx, LFE_PLC_BUFLEN );
994 126 : scale_sig32( prevsynth_fx, LFE_PLC_BUFLEN, exp );
995 126 : prevsynth_q_fx = add( Q9, exp );
996 126 : move16();
997 :
998 126 : recover_samples_fx( hLFE->bfi_count, prevsynth_fx, prevsynth_q_fx, rec_frame_fx, &rec_frame_q );
999 :
1000 126 : set16_fx( mem_fx, 0, 2 * LFE_PLC_FDEL / LFE_PLC_DSF );
1001 :
1002 126 : Copy_Scale_sig_32_16( prevsynth_fx, prevsynth_16_fx, LFE_PLC_BUFLEN, -prevsynth_q_fx ); // Q0
1003 126 : Copy_Scale_sig_32_16( rec_frame_fx, rec_frame_16_fx, LFE_PLC_RECLEN, -Q5 ); // Q0
1004 :
1005 : Word16 Q_new_inp, mem_decim_size, size_modified;
1006 126 : 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 );
1007 126 : Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
1008 :
1009 126 : 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 );
1010 126 : Scale_sig( rec_frame_us_16_fx, size_modified, negate( Q_new_inp ) ); /* scaling back to Q0 */
1011 :
1012 : /*samples are generated with 48k sampling rate
1013 : and then converted to required sampling rate by simple decimation
1014 : as signal is already bandlimited*/
1015 :
1016 : /*decimation to correct sampling rate*/
1017 126 : IF( NE_32( output_Fs, 48000 ) )
1018 : {
1019 1161 : FOR( i = 0; i < rec_frame_len; i++ )
1020 : {
1021 1160 : idx = BASOP_Util_Divide3232_Scale( Mpy_32_32( L_shl( i, 16 ), L_shl( 44100, 15 ) ), output_Fs, &temp_q );
1022 1160 : idx = shr( idx, add( sub( 15, temp_q ), 1 ) );
1023 1160 : rec_frame_us_16_fx[i] = rec_frame_us_16_fx[idx];
1024 1160 : move16();
1025 : }
1026 : }
1027 :
1028 126 : 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
1029 :
1030 378 : FOR( i = 0; i < 2; i++ )
1031 : {
1032 252 : 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 ) ) );
1033 252 : ivas_tda_fx( input_tda_fx, ytda + imult1616( i, dct_len ), dct_len );
1034 : }
1035 :
1036 126 : return;
1037 : }
|