Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <stdio.h>
7 : #include <assert.h>
8 : #include "prot_fx.h"
9 : #include "options.h"
10 : #include "basop_util.h"
11 : #include "stl.h"
12 : #include "math.h"
13 : #include "ivas_prot_fx.h"
14 : #include "rom_com.h"
15 : #include "ivas_rom_com.h"
16 : #include "ivas_rom_com_fx.h"
17 : extern const Word16 T_DIV_L_Frame[]; /*0Q15 * 2^-7 */
18 :
19 : static Word32 CalculateAbsEnergy_fx( /* o : normalized result Q31 */
20 : const Word32 L_off, /* i : initial sum value Qn */
21 : const Word16 x[], /* i : x vector Qn */
22 : const Word16 lg, /* i : vector length, range [0..7FFF] Q0 */
23 : Word16 *exp /* o : exponent of result in [-32,31] Q0 */
24 : );
25 :
26 646 : void decoder_tcx_fx(
27 : TCX_CONFIG_HANDLE hTcxCfg,
28 : Word16 prm[], /* input: parameters */
29 : Word16 A[], /* input: coefficients NxAz[M+1] */
30 : Word16 Aind[], /* input: frame-independent coefficients Az[M+1] */
31 : Word16 L_frame_glob, /* input: frame length */
32 : Word16 L_frameTCX_glob,
33 : Word16 L_spec,
34 : Word16 synth[], /* in/out: synth[-M-LFAC..L_frame] */
35 : Word16 synthFB[],
36 : Decoder_State *st,
37 : Word16 coder_type, /* input : coder type */
38 : Word16 bfi, /* input: Bad frame indicator */
39 : Word16 frame_cnt, /* input: frame counter in the super frame */
40 : Word16 stab_fac /* input: stability of isf (1Q14) */
41 : )
42 : {
43 : Word16 i, index, L_frame, tcx_offset;
44 : Word16 L_frameTCX, tcx_offsetFB;
45 : Word16 firstLine;
46 : Word16 gain_tcx, gain_tcx_e, fac_ns;
47 : Word16 Ap[M + 2];
48 : Word32 x[N_MAX];
49 : Word16 x_e;
50 : Word16 *xn_buf;
51 : Word16 xn_bufFB[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
52 : Word32 xn_buf32[N_MAX];
53 : Word16 overlap;
54 : Word16 overlapFB;
55 : Word16 noiseFillingSize;
56 : Word16 noiseTransWidth;
57 : Word16 tnsSize; /* number of tns parameters put into prm */
58 : Word8 fUseTns; /* flag that is set if TNS data is present */
59 : STnsData tnsData;
60 : Word16 left_rect;
61 : Word16 gainlpc2[FDNS_NPTS];
62 : Word16 gainlpc2_e[FDNS_NPTS];
63 : Word16 noiseTiltFactor;
64 : Word16 nf_seed;
65 : Word16 tmp1, tmp2, s, *tmpP16;
66 : Word8 tmp8;
67 : Word32 tmp32;
68 : Word16 gamma1;
69 : Word16 gamma;
70 : Word16 gainCompensate, gainCompensate_e;
71 : Word16 h1[L_FRAME_MAX / 4 + 1];
72 : Word16 mem[M];
73 : Word16 temp_concealment_method;
74 : Word16 arith_bits, signaling_bits;
75 : Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target;
76 : Word16 *pInfoTCXNoise;
77 : Word16 acelp_zir[L_FRAME_MAX / 2];
78 : Word16 noise_filling_index;
79 : Word16 infoIGFStartLine;
80 : Word16 L_spec_con;
81 : TCX_LTP_DEC_HANDLE hTcxLtpDec;
82 : TCX_DEC_HANDLE hTcxDec;
83 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
84 646 : Flag Overflow = 0;
85 646 : Flag Carry = 0;
86 646 : move32();
87 646 : move32();
88 : #endif
89 646 : temp_concealment_method = 0;
90 646 : move16();
91 :
92 646 : hTcxLtpDec = st->hTcxLtpDec;
93 646 : hTcxDec = st->hTcxDec;
94 :
95 646 : prm_target = NULL; /* just to suppress MSVC warnigs */
96 :
97 :
98 646 : x_e = 0; /* to avoid compilation warnings */
99 646 : move16();
100 646 : nf_seed = 0; /* to avoid compilation warnings */
101 646 : move16();
102 :
103 : /* Overlay xn_buf32 with xn_buf */
104 646 : xn_buf = (Word16 *) xn_buf32;
105 :
106 646 : noiseTransWidth = MIN_NOISE_FILLING_HOLE;
107 646 : move16();
108 646 : tnsSize = 0;
109 646 : move16();
110 646 : fUseTns = 0;
111 646 : move16();
112 646 : gainCompensate = 32768 / 2;
113 646 : move16();
114 646 : gainCompensate_e = 1;
115 646 : move16();
116 659566 : FOR( i = 0; i < ( L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2; i++ )
117 : {
118 658920 : xn_buf32[i] = L_deposit_l( 0 );
119 658920 : move32();
120 : }
121 :
122 :
123 : /* Init lengths */
124 :
125 646 : overlap = hTcxCfg->tcx_mdct_window_length;
126 646 : move16();
127 646 : overlapFB = hTcxCfg->tcx_mdct_window_lengthFB;
128 646 : move16();
129 : /* Modified the overlap to the delay in case of short blocks*/
130 646 : tcx_offset = hTcxCfg->tcx_offset;
131 646 : move16();
132 646 : tcx_offsetFB = hTcxCfg->tcx_offsetFB;
133 646 : move16();
134 646 : L_spec_con = L_spec;
135 646 : move16();
136 646 : gamma1 = st->gamma;
137 646 : move16();
138 :
139 646 : if ( hTcxDec->enableTcxLpc != 0 )
140 : {
141 0 : gamma1 = 0x7FFF;
142 0 : move16();
143 : }
144 :
145 646 : IF( bfi != 0 )
146 : {
147 : /* PLC: [TCX: Memory update]
148 : * PLC: Init buffers */
149 :
150 0 : assert( st->L_frame_past > 0 );
151 0 : L_frame = st->L_frame_past;
152 0 : move16();
153 0 : L_frameTCX = st->L_frameTCX_past;
154 0 : move16();
155 :
156 0 : left_rect = hTcxDec->prev_widow_left_rect;
157 0 : move16();
158 :
159 0 : IF( left_rect != 0 )
160 : {
161 0 : tcx_offset = hTcxCfg->lfacNext;
162 0 : move16();
163 0 : tcx_offsetFB = hTcxCfg->lfacNextFB;
164 0 : move16();
165 0 : L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
166 0 : L_spec_con = add( L_spec_con, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
167 : }
168 : }
169 : ELSE
170 : {
171 646 : test();
172 646 : IF( frame_cnt == 0 && st->last_core == ACELP_CORE )
173 : {
174 38 : if ( st->prev_bfi == 0 )
175 : {
176 38 : hTcxCfg->last_aldo = 0;
177 38 : move16();
178 : }
179 :
180 : /* if past frame is ACELP */
181 38 : L_frame = add( L_frame_glob, tcx_offset );
182 38 : L_frameTCX = add( L_frameTCX_glob, tcx_offsetFB );
183 38 : L_spec_con = add( L_spec_con, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
184 38 : assert( hTcxCfg->lfacNext <= 0 );
185 38 : L_frame = sub( L_frame, hTcxCfg->lfacNext );
186 38 : L_frameTCX = sub( L_frameTCX, hTcxCfg->lfacNextFB );
187 38 : tcx_offset = hTcxCfg->lfacNext;
188 38 : move16();
189 38 : tcx_offsetFB = hTcxCfg->lfacNextFB;
190 38 : move16();
191 38 : left_rect = 1;
192 38 : move16();
193 38 : hTcxDec->prev_widow_left_rect = 1;
194 38 : move16();
195 : }
196 : ELSE
197 : {
198 :
199 608 : L_frame = L_frame_glob;
200 608 : move16();
201 608 : L_frameTCX = L_frameTCX_glob;
202 608 : move16();
203 608 : left_rect = 0;
204 608 : move16();
205 608 : hTcxDec->prev_widow_left_rect = 0;
206 608 : move16();
207 : }
208 :
209 646 : IF( frame_cnt == 0 && EQ_16( st->last_core_from_bs, ACELP_CORE ) )
210 : {
211 38 : L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
212 : }
213 :
214 646 : st->L_frame_past = L_frame;
215 646 : move16();
216 646 : st->L_frameTCX_past = L_frameTCX;
217 646 : move16();
218 : }
219 :
220 646 : test();
221 646 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
222 : {
223 0 : IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_SHORT );
224 : }
225 : ELSE
226 : {
227 646 : test();
228 646 : test();
229 646 : IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && st->bfi ) )
230 : {
231 38 : IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_TRAN );
232 : }
233 : ELSE
234 : {
235 608 : IGFDecUpdateInfo( st->hIGFDec, IGF_GRID_LB_NORM );
236 : }
237 : }
238 :
239 646 : IF( 0 == st->igf )
240 : {
241 0 : IF( st->narrowBand == 0 )
242 : {
243 : /* minimum needed for output with sampling rates lower then the
244 : nominal sampling rate */
245 0 : infoIGFStartLine = s_min( L_frameTCX, L_frame );
246 : }
247 : ELSE
248 : {
249 0 : infoIGFStartLine = L_frameTCX;
250 0 : move16();
251 : }
252 : }
253 : ELSE
254 : {
255 646 : infoIGFStartLine = s_min( st->hIGFDec->infoIGFStartLine, L_frameTCX );
256 : }
257 :
258 646 : noiseFillingSize = L_spec;
259 646 : move16();
260 646 : if ( st->igf != 0 )
261 : {
262 646 : noiseFillingSize = st->hIGFDec->infoIGFStartLine;
263 646 : move16();
264 : }
265 :
266 :
267 646 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
268 646 : prm_tns = prm_ltp + LTPSIZE;
269 :
270 : /*-----------------------------------------------------------*
271 : * Read TCX parameters *
272 : *-----------------------------------------------------------*/
273 :
274 646 : index = 0;
275 646 : move16();
276 :
277 646 : IF( bfi == 0 )
278 : {
279 :
280 646 : index = prm[0];
281 646 : move16();
282 :
283 : /* read noise level (fac_ns) */
284 :
285 646 : noise_filling_index = prm[1];
286 646 : move16();
287 :
288 646 : fac_ns = extract_l( L_shr( L_mult0( noise_filling_index, 0x6000 ), NBITS_NOISE_FILL_LEVEL ) );
289 : }
290 : ELSE
291 : {
292 0 : fac_ns = 0;
293 0 : move16();
294 : }
295 :
296 : /* read TNS data */
297 646 : test();
298 646 : IF( ( bfi == 0 ) && ( hTcxCfg->fIsTNSAllowed != 0 ) )
299 : {
300 371 : cast16();
301 :
302 371 : fUseTns = (Word8) DecodeTnsData( hTcxCfg->pCurrentTnsConfig,
303 : prm_tns,
304 : &tnsSize,
305 : &tnsData );
306 : }
307 : ELSE
308 : {
309 275 : fUseTns = 0;
310 275 : move16();
311 : }
312 :
313 646 : prm_hm = prm_tns + tnsSize;
314 646 : prm_sqQ = prm_hm + NPRM_CTX_HM;
315 :
316 : /*-----------------------------------------------------------*
317 : * Spectrum data *
318 : *-----------------------------------------------------------*/
319 :
320 646 : IF( bfi == 0 )
321 : {
322 :
323 : /*-----------------------------------------------------------*
324 : * Context HM *
325 : *-----------------------------------------------------------*/
326 646 : test();
327 646 : test();
328 646 : IF( hTcxCfg->ctx_hm != 0 && ( ( st->last_core_from_bs != ACELP_CORE ) || ( frame_cnt > 0 ) ) )
329 : {
330 608 : st->last_ctx_hm_enabled = prm_hm[0];
331 608 : move16();
332 : {
333 389728 : FOR( i = 0; i < L_spec; i++ ) /* no context harmonic model, copy MDCT coefficients to x */
334 : {
335 :
336 389120 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
337 389120 : move32();
338 : }
339 : }
340 608 : x_e = SPEC_EXP_DEC;
341 608 : move16();
342 : }
343 : ELSE /* hTcxCfg->ctx_hm == 0 */
344 : {
345 :
346 38 : IF( hTcxDec->tcx_lpc_shaped_ari != 0 ) /* low rates: new arithmetic coder */
347 : {
348 0 : prm_target = prm_sqQ;
349 0 : move16();
350 0 : prm_sqQ = prm_target + 1;
351 0 : move16();
352 :
353 0 : tmp8 = 1;
354 0 : move16();
355 0 : if ( EQ_16( st->last_core_from_bs, ACELP_CORE ) )
356 : {
357 0 : tmp8 = 0;
358 0 : move16();
359 : }
360 :
361 0 : tcx_arith_decode_envelope_fx(
362 : x, &x_e,
363 : L_frame,
364 : L_spec,
365 : st,
366 : Aind,
367 0 : *prm_target,
368 : prm_sqQ,
369 : tmp8,
370 : prm_hm, /* HM parameter area */
371 0 : hTcxDec->tcx_hm_LtpPitchLag,
372 : &arith_bits,
373 : &signaling_bits,
374 : &nf_seed,
375 0 : shr( st->bwidth, 1 ) /* equivalent to: (st->bwidth > WB)?1:0 */
376 : );
377 :
378 0 : hTcxDec->resQBits[frame_cnt] = sub( *prm_target, arith_bits );
379 0 : move16();
380 : }
381 : ELSE /* TCX-only: old arithmetic coder */
382 : {
383 30438 : FOR( i = 0; i < L_spec; i++ )
384 : {
385 :
386 30400 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
387 30400 : move32();
388 : }
389 :
390 38 : set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
391 :
392 38 : x_e = SPEC_EXP_DEC;
393 38 : move16();
394 : }
395 :
396 : } /* else of if hTcxCfg->ctx_hm */
397 646 : tmp1 = s_max( L_frame, L_frameTCX );
398 646 : tmp1 = s_max( tmp1, L_spec_con );
399 646 : set32_fx( x + L_spec, 0, sub( tmp1, L_spec ) );
400 :
401 :
402 : /*-----------------------------------------------------------*
403 : * adaptive low frequency deemphasis. *
404 : *-----------------------------------------------------------*/
405 :
406 646 : weight_a_fx( A, Ap, gamma1, M );
407 :
408 646 : lpc2mdct( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0 );
409 :
410 :
411 : /* initialize LF deemphasis factors in xn_buf */
412 646 : tmp1 = s_max( L_spec, L_frameTCX );
413 646 : set16_fx( xn_buf, 0x4000, tmp1 );
414 :
415 646 : IF( st->tcxonly == 0 )
416 : {
417 646 : AdaptLowFreqDeemph( x, x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e,
418 : L_frame, xn_buf /* LF deemphasis factors */ );
419 : }
420 : }
421 :
422 : /* Global Gain */
423 646 : hTcxDec->damping = 0;
424 646 : move16();
425 646 : IF( bfi == 0 )
426 : {
427 : /*-----------------------------------------------------------*
428 : * Compute global gain *
429 : *-----------------------------------------------------------*/
430 :
431 646 : tmp32 = L_shl( L_mult0( index, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
432 646 : gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
433 646 : gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) );
434 :
435 646 : tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
436 646 : s = 15 - 5 - 7;
437 646 : move16();
438 646 : IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/
439 : {
440 0 : tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
441 0 : s = 15 - 4 - 7;
442 0 : move16();
443 : }
444 646 : tmp1 = ISqrt16( tmp1, &s );
445 :
446 646 : gain_tcx = mult( gain_tcx, tmp1 );
447 646 : gain_tcx_e = add( gain_tcx_e, s );
448 :
449 646 : hTcxDec->old_gaintcx_bfi = gain_tcx;
450 646 : move16();
451 646 : hTcxDec->old_gaintcx_bfi_e = gain_tcx_e;
452 646 : move16();
453 :
454 646 : hTcxDec->cummulative_damping_tcx = 32767 /*1.0f Q15*/;
455 646 : move16();
456 : }
457 : ELSE /* bfi = 1 */
458 : {
459 : /* PLC: [TCX: Fade-out]
460 : * derivation of damping factor */
461 :
462 :
463 0 : IF( st->use_partial_copy != 0 )
464 : {
465 0 : IF( EQ_16( st->rf_frame_type, RF_TCXFD ) )
466 : {
467 0 : tmp32 = L_shl( L_mult0( hTcxDec->old_gaintcx_bfi, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
468 0 : gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
469 0 : gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
470 :
471 0 : tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
472 0 : s = 15 - 5 - 7;
473 0 : move16();
474 0 : tmp1 = ISqrt16( tmp1, &s );
475 :
476 0 : gain_tcx = mult( gain_tcx, tmp1 );
477 0 : gain_tcx_e = add( gain_tcx_e, s );
478 :
479 0 : hTcxDec->old_gaintcx_bfi = gain_tcx;
480 0 : move16();
481 0 : hTcxDec->old_gaintcx_bfi_e = gain_tcx_e;
482 0 : move16();
483 : }
484 : ELSE
485 : {
486 0 : gain_tcx = hTcxDec->old_gaintcx_bfi;
487 0 : move16();
488 0 : gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
489 0 : move16();
490 : }
491 :
492 0 : hTcxDec->damping = 16384 /*1.f Q14*/; /*Q14*/
493 0 : move16();
494 : }
495 : ELSE
496 : {
497 0 : hTcxDec->damping = Damping_fact_fx( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->Mode2_lp_gainp ), st->last_core );
498 0 : move16();
499 0 : gain_tcx = hTcxDec->old_gaintcx_bfi;
500 0 : move16();
501 0 : gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
502 0 : move16();
503 : }
504 :
505 0 : hTcxDec->cummulative_damping_tcx = shl( mult( hTcxDec->cummulative_damping_tcx, hTcxDec->damping ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
506 0 : move16();
507 : }
508 : {
509 646 : IF( bfi )
510 : {
511 0 : gamma = gamma1;
512 0 : move16();
513 0 : if ( hTcxDec->envWeighted )
514 : {
515 0 : gamma = st->gamma;
516 0 : move16();
517 : }
518 :
519 : /* PLC: [TCX: Fade-out]
520 : * PLC: invert LPC weighting in case of PLC */
521 0 : IF( hTcxDec->enableTcxLpc != 0 )
522 : {
523 0 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( st->gamma, 32767 /*1.0f Q15*/ ) ), 32767 /*1.0f Q15*/ );
524 : }
525 : ELSE
526 : {
527 0 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( gamma1, 32767 /*1.0f Q15*/ ) ), 32767 /*1.0f Q15*/ );
528 : }
529 0 : weight_a_fx( A, Ap, gamma, M );
530 :
531 0 : lpc2mdct( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS, 0 );
532 : }
533 646 : tmp2 = 0;
534 646 : move16();
535 :
536 646 : set16_fx( h1, 0, add( L_SUBFR, 1 ) );
537 646 : set16_fx( mem, 0, M );
538 646 : h1[0] = 32768 / 32;
539 646 : move16();
540 646 : E_UTIL_synthesis( 0, Ap, h1, h1, L_SUBFR, mem, 0, M );
541 646 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp2 );
542 : /* impulse response level = gain introduced by synthesis+deemphasis */
543 646 : IF( bfi == 0 )
544 : {
545 : /* st->last_gain_syn_deemph = (float)sqrt(dot_product( h1, h1, L_SUBFR)); */
546 646 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ) /*Q15, st->last_gain_syn_deemph_e*/;
547 646 : st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
548 646 : move16();
549 646 : tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e );
550 : #ifdef ISSUE_1866_replace_overflow_libdec
551 646 : st->last_gain_syn_deemph = round_fx_sat( tmp32 );
552 : #else
553 : st->last_gain_syn_deemph = round_fx_o( tmp32, &Overflow );
554 : #endif
555 646 : move16();
556 : /*for avoiding compiler warnings*/
557 646 : hTcxDec->gainHelper = 32768 / 2;
558 646 : move16();
559 646 : hTcxDec->gainHelper_e = 1;
560 646 : move16();
561 646 : hTcxDec->stepCompensate = 0;
562 646 : move16();
563 646 : hTcxDec->stepCompensate_e = 0;
564 646 : move16();
565 : }
566 : /* not instrumenting the additional test() here seems to be common practice */
567 0 : ELSE IF( EQ_16( TCX_20_CORE, st->core ) || EQ_16( frame_cnt, 1 ) )
568 : {
569 : /* gainCompensate = st->last_gain_syn_deemph/(float)sqrt(dot_product( h1, h1, L_SUBFR)); */
570 0 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/;
571 0 : gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ );
572 0 : gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/;
573 0 : BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph,
574 0 : st->last_gain_syn_deemph_e,
575 : gainCompensate,
576 : gainCompensate_e,
577 : &gainCompensate,
578 : &gainCompensate_e );
579 :
580 0 : tmp1 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )];
581 :
582 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
583 : {
584 : /* stepCompensate = (1.f - gainCompensate)/st->L_frame; */
585 0 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
586 : tmp1,
587 : -7,
588 0 : negate( mult( gainCompensate, tmp1 ) ),
589 0 : add( -7, gainCompensate_e ),
590 : &hTcxDec->stepCompensate );
591 0 : move16();
592 :
593 0 : hTcxDec->gainHelper = 32768 / 2;
594 0 : move16();
595 0 : hTcxDec->gainHelper_e = 1;
596 0 : move16();
597 : }
598 : ELSE
599 : {
600 : /* stepCompensate = (st->last_concealed_gain_syn_deemph - gainCompensate)/st->L_frame; */
601 0 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
602 0 : mult( tmp1, st->last_concealed_gain_syn_deemph ),
603 0 : add( -7, st->last_concealed_gain_syn_deemph_e ),
604 0 : negate( mult( tmp1, gainCompensate ) ),
605 0 : add( -7, gainCompensate_e ),
606 : &hTcxDec->stepCompensate );
607 0 : move16();
608 0 : move16();
609 0 : hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph;
610 0 : hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e;
611 0 : move16();
612 : }
613 0 : move16();
614 0 : move16();
615 0 : st->last_concealed_gain_syn_deemph = gainCompensate;
616 0 : st->last_concealed_gain_syn_deemph_e = gainCompensate_e;
617 : }
618 : }
619 :
620 :
621 : /*-----------------------------------------------------------*
622 : * Residual inv. Q. *
623 : *-----------------------------------------------------------*/
624 646 : test();
625 646 : IF( ( bfi == 0 ) && ( hTcxCfg->resq != 0 ) )
626 : {
627 :
628 646 : IF( hTcxDec->tcx_lpc_shaped_ari != 0 ) /* new arithmetic coder */
629 : {
630 :
631 : Word16 *prm_resq;
632 :
633 0 : prm_resq = prm_sqQ + sub( *prm_target /* = targetBits */
634 : ,
635 0 : hTcxDec->resQBits[frame_cnt] );
636 :
637 0 : i = tcx_ari_res_invQ_spec( x, x_e, L_spec,
638 : prm_resq,
639 0 : hTcxDec->resQBits[frame_cnt],
640 : 0,
641 0 : hTcxCfg->sq_rounding,
642 : xn_buf /* LF deemphasis factors */ );
643 : }
644 : ELSE /* old arithmetic coder */
645 : {
646 646 : i = tcx_res_invQ_gain( &gain_tcx, &gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] );
647 :
648 646 : tmpP16 = xn_buf;
649 646 : if ( st->tcxonly != 0 )
650 0 : tmpP16 = NULL;
651 :
652 646 : tcx_res_invQ_spec( x, x_e, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding, tmpP16 /* LF deemphasis factors */ );
653 : }
654 : }
655 646 : test();
656 646 : IF( bfi == 0 && st->tcxonly != 0 )
657 : {
658 0 : test();
659 0 : test();
660 0 : IF( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain > 0 ) && !fUseTns )
661 : {
662 :
663 0 : PsychAdaptLowFreqDeemph( x, gainlpc2, gainlpc2_e, NULL );
664 : }
665 : }
666 :
667 : /* for FAC */
668 :
669 646 : test();
670 646 : IF( bfi == 0 && st->tcxonly == 0 )
671 : {
672 : /* Replication of ACELP formant enhancement for low rates */
673 646 : test();
674 646 : IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_flag != 0 )
675 : {
676 0 : tcxFormantEnhancement( xn_buf, gainlpc2, gainlpc2_e, x, &x_e, L_frame, L_frameTCX );
677 : }
678 : }
679 :
680 : /*-----------------------------------------------------------*
681 : * Add gain to the lpc gains *
682 : *-----------------------------------------------------------*/
683 :
684 646 : IF( st->VAD == 0 )
685 : {
686 9 : gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale );
687 : }
688 :
689 646 : i = norm_s( gain_tcx );
690 646 : gain_tcx = shl( gain_tcx, i );
691 646 : gain_tcx_e = sub( gain_tcx_e, i );
692 41990 : FOR( i = 0; i < FDNS_NPTS; i++ )
693 : {
694 41344 : gainlpc2[i] = mult_r( gainlpc2[i], gain_tcx );
695 41344 : move16();
696 : }
697 :
698 :
699 : /*-----------------------------------------------------------*
700 : * Noise filling. *
701 : *-----------------------------------------------------------*/
702 :
703 646 : test();
704 646 : IF( bfi == 0 && ( fac_ns > 0 ) )
705 : {
706 :
707 645 : tmp1 = 0;
708 645 : move16();
709 645 : test();
710 645 : if ( GE_16( st->bits_frame, 256 ) && st->rf_flag == 0 )
711 : {
712 645 : tmp1 = 1;
713 645 : move16();
714 : }
715 :
716 645 : firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, tmp1, &noiseTiltFactor );
717 :
718 645 : IF( st->tcxonly != 0 )
719 : {
720 0 : tmp1 = 0;
721 0 : move16();
722 0 : test();
723 0 : test();
724 0 : if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( st->last_ctx_hm_enabled != 0 ) )
725 : {
726 0 : tmp1 = 10240 /*0.3125f Q15*/;
727 0 : move16();
728 : }
729 0 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxLtpDec->tcxltp_gain, tmp1 ) );
730 :
731 0 : if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
732 : {
733 0 : noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */
734 0 : move16();
735 : }
736 : }
737 :
738 :
739 645 : IF( hTcxDec->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
740 : {
741 : /* noise filling seed */
742 645 : tmp32 = L_deposit_l( 0 );
743 419525 : FOR( i = 0; i < L_spec; i++ )
744 : {
745 418880 : tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow );
746 : }
747 645 : nf_seed = extract_l( tmp32 );
748 : }
749 :
750 645 : tmp1 = nf_seed;
751 645 : move16();
752 :
753 645 : pInfoTCXNoise = NULL;
754 645 : if ( st->igf )
755 : {
756 645 : pInfoTCXNoise = st->hIGFDec->infoTCXNoise_evs;
757 : }
758 645 : tcx_noise_filling( x, x_e, tmp1 /* seed */, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor,
759 645 : fac_ns, pInfoTCXNoise, st->element_mode );
760 645 : st->seed_tcx_plc = tmp1;
761 645 : move16();
762 : }
763 :
764 646 : IF( st->enablePlcWaveadjust )
765 : {
766 0 : IF( bfi )
767 : {
768 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
769 : {
770 0 : st->hPlcInfo->concealment_method = TCX_NONTONAL;
771 0 : move16();
772 : /* tonal/non-tonal decision */
773 0 : test();
774 0 : test();
775 0 : IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) )
776 : {
777 0 : Word16 sum_word16 = 0;
778 0 : move16();
779 :
780 0 : FOR( i = 9; i >= 0; i-- )
781 : {
782 0 : sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] );
783 : }
784 :
785 0 : if ( GE_16( sum_word16, 6 ) )
786 : {
787 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
788 0 : move16();
789 : }
790 : }
791 :
792 0 : if ( st->tonal_mdct_plc_active )
793 : {
794 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
795 0 : move16();
796 : }
797 : }
798 :
799 0 : if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) )
800 : {
801 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
802 0 : move16();
803 : }
804 :
805 0 : temp_concealment_method = st->hPlcInfo->concealment_method;
806 0 : move16();
807 :
808 0 : if ( EQ_16( st->core, TCX_10_CORE ) )
809 : {
810 0 : temp_concealment_method = TCX_TONAL;
811 0 : move16();
812 : }
813 : }
814 : /* get the starting location of the subframe in the frame */
815 0 : IF( EQ_16( st->core, TCX_10_CORE ) )
816 : {
817 0 : st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) );
818 0 : move16();
819 : }
820 : }
821 :
822 : /* PLC: [TCX: Tonal Concealment] */
823 : /* PLC: [TCX: Fade-out]
824 : * PLC: Fade out to white noise */
825 :
826 646 : IF( bfi == 0 )
827 : {
828 646 : TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e );
829 : }
830 : ELSE
831 : {
832 0 : test();
833 0 : IF( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) )
834 : {
835 : Word16 f, tmp;
836 :
837 : /* set f to 1 to not fade out */
838 : /* set f to 0 to immediately switch to white noise */
839 0 : f = hTcxDec->cummulative_damping_tcx;
840 0 : move16();
841 0 : if ( 0 != st->tcxonly )
842 : {
843 0 : f = 32767 /*1.0f Q15*/;
844 0 : move16();
845 : }
846 :
847 0 : test();
848 0 : test();
849 0 : test();
850 0 : test();
851 0 : test();
852 0 : test();
853 0 : IF( ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
854 : {
855 : Word16 exp1, exp2;
856 : Word32 E_2ndlast, E_last;
857 :
858 0 : E_2ndlast = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[0] ), infoIGFStartLine, &exp2 );
859 0 : E_last = CalculateAbsEnergy_fx( 1, &( st->hTonalMDCTConc->lastBlockData.spectralData[1] ), infoIGFStartLine, &exp1 );
860 :
861 0 : BASOP_Util_Divide_MantExp( extract_h( E_2ndlast ), exp2, extract_h( E_last ), exp1, &tmp1, &tmp2 );
862 :
863 0 : tmp1 = shr( tmp1, 2 ); /*Q13*/
864 0 : tmp1 = shl_sat( tmp1, tmp2 );
865 : /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
866 0 : IF( GT_16( tmp1, 16384 /*2 in Q13*/ ) )
867 : {
868 0 : FOR( i = 0; i < infoIGFStartLine; i += 2 )
869 : {
870 0 : move32();
871 0 : st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
872 : }
873 : }
874 0 : ELSE IF( LT_16( tmp1, 4096 /*0.5 in Q13*/ ) )
875 : {
876 0 : FOR( i = 0; i < infoIGFStartLine; i += 2 )
877 : {
878 0 : move32();
879 0 : st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
880 : }
881 : }
882 : }
883 :
884 0 : noiseTiltFactor = 32767 /*1.0f Q15*/;
885 0 : move16();
886 :
887 0 : tmp = 0;
888 0 : move16();
889 0 : test();
890 0 : if ( GE_16( st->bits_frame, 256 ) && st->rf_flag == 0 )
891 : {
892 0 : tmp = 1;
893 0 : move16();
894 : }
895 :
896 0 : tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor );
897 :
898 0 : TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, &x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc,
899 : noiseTiltFactor, f,
900 : infoIGFStartLine );
901 : }
902 : }
903 :
904 :
905 646 : IF( LT_16( L_spec, L_frame ) )
906 : {
907 0 : set32_fx( x + L_spec, 0, sub( L_frame, L_spec ) );
908 : }
909 646 : ELSE IF( GT_16( L_spec, L_frameTCX ) )
910 : {
911 0 : set32_fx( x + L_frameTCX, 0, sub( L_spec, L_frameTCX ) );
912 : }
913 :
914 646 : test();
915 646 : test();
916 646 : test();
917 646 : test();
918 646 : test();
919 646 : test();
920 646 : test();
921 646 : test();
922 646 : test();
923 646 : test();
924 646 : IF( bfi && ( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) ) && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
925 : {
926 0 : IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT );
927 0 : Copy( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB );
928 : }
929 :
930 : /*-----------------------------------------------------------*
931 : * Noise shaping in frequency domain (1/Wz) *
932 : *-----------------------------------------------------------*/
933 646 : test();
934 646 : IF( st->igf && !bfi )
935 : {
936 646 : test();
937 646 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
938 : {
939 0 : IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_SHORT );
940 : }
941 : ELSE
942 : {
943 646 : IF( st->last_core == ACELP_CORE )
944 : {
945 38 : IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_TRAN );
946 : }
947 : ELSE
948 : {
949 608 : IGFDecCopyLPCFlatSpectrum( st->hIGFDec, x, x_e, IGF_GRID_LB_NORM );
950 : }
951 : }
952 : }
953 :
954 : /* LPC gains already available */
955 646 : test();
956 646 : test();
957 646 : IF( !st->enablePlcWaveadjust || !bfi || ( EQ_16( temp_concealment_method, TCX_TONAL ) ) )
958 : {
959 646 : x_e = add( x_e, gain_tcx_e );
960 646 : mdct_shaping( x, L_frame, gainlpc2, gainlpc2_e );
961 646 : IF( bfi == 0 )
962 : {
963 228262 : FOR( i = L_frame; i < L_spec; i++ )
964 : {
965 227616 : x[i] = L_shl( Mpy_32_16_1( x[i], gainlpc2[FDNS_NPTS - 1] ), gainlpc2_e[FDNS_NPTS - 1] );
966 227616 : move32();
967 : }
968 : }
969 :
970 646 : set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
971 646 : test();
972 646 : test();
973 646 : IF( ( bfi != 0 ) && ( !st->enablePlcWaveadjust || EQ_16( temp_concealment_method, TCX_TONAL ) ) )
974 : {
975 0 : scale_sig32( x + infoIGFStartLine, sub( L_spec, infoIGFStartLine ), negate( gain_tcx_e ) );
976 : }
977 : }
978 :
979 : /* PLC: [TCX: Tonal Concealment] */
980 646 : test();
981 646 : IF( bfi && st->tonal_mdct_plc_active )
982 : {
983 0 : TonalMDCTConceal_Apply( st->hTonalMDCTConc, x, &x_e );
984 : }
985 :
986 646 : tmp32 = L_deposit_h( 0 );
987 646 : if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
988 : {
989 469 : tmp32 = L_add( st->old_fpitch, 0 );
990 : }
991 646 : tmp8 = 0;
992 646 : move16();
993 646 : test();
994 646 : if ( bfi && st->tonal_mdct_plc_active )
995 : {
996 0 : tmp8 = 1;
997 0 : move16();
998 : }
999 :
1000 646 : TonalMDCTConceal_UpdateState( st->hTonalMDCTConc, L_frameTCX, tmp32, bfi, tmp8 );
1001 :
1002 646 : IF( st->enablePlcWaveadjust )
1003 : {
1004 : Word16 core;
1005 0 : core = st->core;
1006 0 : move16();
1007 : /* spectrum concealment */
1008 0 : IF( bfi && ( EQ_16( temp_concealment_method, TCX_NONTONAL ) ) )
1009 : {
1010 : /* x_e =31-x_scale; */
1011 0 : concealment_decode_fix( core, x, &x_e, st->hPlcInfo );
1012 : }
1013 :
1014 : /* update spectrum buffer, tonality flag, etc. */
1015 0 : concealment_update_x( bfi, core, st->tonality_flag, x, &x_e, st->hPlcInfo );
1016 : }
1017 :
1018 : /*-----------------------------------------------------------*
1019 : * IGF *
1020 : *-----------------------------------------------------------*/
1021 646 : test();
1022 646 : test();
1023 646 : IF( st->igf && !( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
1024 : {
1025 : Word16 igfGridIdx;
1026 :
1027 646 : test();
1028 646 : IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && bfi ) )
1029 : {
1030 : /* packet loss after first TCX must be handled like transition frame */
1031 38 : igfGridIdx = IGF_GRID_LB_TRAN;
1032 38 : move16();
1033 : }
1034 : ELSE
1035 : {
1036 608 : igfGridIdx = IGF_GRID_LB_NORM;
1037 608 : move16();
1038 : }
1039 :
1040 646 : *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_mac0( 13849L, nf_seed, 31821 ) );
1041 646 : move16();
1042 646 : IGFDecApplyMono( st->hIGFDec, x, &x_e, igfGridIdx, bfi );
1043 : }
1044 646 : test();
1045 646 : test();
1046 646 : IF( st->igf && ( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
1047 : {
1048 0 : *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_mac0( 13849L, nf_seed, 31821 ) );
1049 0 : move16();
1050 0 : IGFDecApplyMono( st->hIGFDec, x, &x_e, IGF_GRID_LB_SHORT, bfi );
1051 : }
1052 :
1053 646 : index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
1054 646 : move16();
1055 :
1056 : /* normalize spectrum to minimize IMDCT_fx noise */
1057 646 : tmp1 = s_max( s_max( L_frame, L_frameTCX ), L_spec );
1058 646 : s = s_max( 0, sub( getScaleFactor32( x, tmp1 ), 4 ) ); /* Keep 4 bits headroom for TNS */
1059 646 : Scale_sig32( x, tmp1, s );
1060 646 : x_e = sub( x_e, s );
1061 :
1062 646 : IF( st->igf )
1063 : {
1064 646 : test();
1065 646 : IF( st->hIGFDec->flatteningTrigger != 0 && fUseTns == 0 )
1066 : {
1067 : Word16 startLine, endLine;
1068 538 : startLine = st->hIGFDec->infoIGFStartLine;
1069 538 : move16();
1070 538 : endLine = st->hIGFDec->infoIGFStopLine;
1071 538 : move16();
1072 : Word32 x_itf[N_MAX_TCX - IGF_START_MN];
1073 : Word16 j;
1074 :
1075 538 : const Word16 *chk_sparse = st->hIGFDec->flag_sparseBuf;
1076 538 : const Word32 *virtualSpec = st->hIGFDec->virtualSpec;
1077 :
1078 538 : const Word16 maxOrder = 8;
1079 538 : move16();
1080 : Word16 curr_order; /* not counted */
1081 538 : curr_order = 0;
1082 538 : move16();
1083 : Word16 A_itf[ITF_MAX_FILTER_ORDER + 1];
1084 : Word16 Q_A_itf;
1085 : Word16 predictionGain; /* not counted */
1086 538 : predictionGain = 0;
1087 538 : move16();
1088 :
1089 193072 : FOR( j = startLine; j < endLine; j++ )
1090 : {
1091 192534 : IF( EQ_16( chk_sparse[j - IGF_START_MN], 2 ) )
1092 : {
1093 27 : x_itf[j - IGF_START_MN] = x[j];
1094 27 : move32();
1095 27 : x[j] = virtualSpec[j - IGF_START_MN];
1096 27 : move32();
1097 : }
1098 : }
1099 538 : ITF_Detect_fx( x + IGF_START_MN, startLine, endLine, maxOrder, A_itf, &Q_A_itf, &predictionGain, &curr_order, shl( x_e, 1 ) );
1100 538 : s = getScaleFactor32( &x[startLine], sub( endLine, startLine ) );
1101 538 : s = sub( s, 2 );
1102 193072 : FOR( j = startLine; j < endLine; j++ )
1103 : {
1104 192534 : x[j] = L_shl( x[j], s );
1105 192534 : move32();
1106 : }
1107 :
1108 538 : ITF_Apply_fx( x, startLine, endLine, A_itf, Q_A_itf, curr_order );
1109 :
1110 193072 : FOR( j = startLine; j < endLine; j++ )
1111 : {
1112 192534 : x[j] = L_shr( x[j], s );
1113 192534 : move32();
1114 : }
1115 :
1116 193072 : FOR( j = startLine; j < endLine; j++ )
1117 : {
1118 192534 : IF( EQ_16( chk_sparse[j - IGF_START_MN], 2 ) )
1119 : {
1120 27 : x[j] = x_itf[j - IGF_START_MN];
1121 27 : move32();
1122 : }
1123 : }
1124 : }
1125 : }
1126 :
1127 646 : test();
1128 646 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
1129 : {
1130 : Word16 L;
1131 0 : L = L_frameTCX;
1132 0 : move16();
1133 :
1134 0 : test();
1135 0 : test();
1136 0 : test();
1137 0 : if ( ( hTcxCfg->fIsTNSAllowed != 0 && fUseTns != 0 && bfi == 0 ) || ( GT_16( L_spec, L_frameTCX ) ) )
1138 : {
1139 0 : L = L_spec;
1140 0 : move16();
1141 : }
1142 :
1143 0 : tcxInvertWindowGrouping( hTcxCfg,
1144 : xn_buf32,
1145 : x,
1146 : L,
1147 : fUseTns,
1148 0 : st->last_core,
1149 : index,
1150 : frame_cnt,
1151 : bfi );
1152 : }
1153 :
1154 :
1155 : /*-----------------------------------------------------------*
1156 : * Temporal Noise Shaping Synthesis *
1157 : *-----------------------------------------------------------*/
1158 :
1159 646 : test();
1160 646 : test();
1161 646 : IF( ( hTcxCfg->fIsTNSAllowed != 0 ) && ( fUseTns != 0 ) && bfi == 0 )
1162 : {
1163 : /* Apply TNS to get the reconstructed signal */
1164 1 : test();
1165 1 : SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
1166 1 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, &tnsData, x, 0 );
1167 :
1168 1 : test();
1169 1 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
1170 : {
1171 :
1172 0 : test();
1173 0 : test();
1174 0 : test();
1175 0 : IF( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
1176 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) )
1177 : {
1178 0 : tmp1 = shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 );
1179 : /* undo rearrangement of LF sub-window lines for TNS synthesis filtering */
1180 0 : IF( GT_16( s_max( L_frameTCX, L_spec ), hTcxCfg->tnsConfig[0][0].iFilterBorders[0] ) )
1181 : {
1182 0 : tmp2 = shr( s_max( L_frameTCX, L_spec ), 1 );
1183 0 : Copy32( x + add( tmp1, 8 ), x + add( tmp2, 8 ), sub( tmp1, 8 ) );
1184 0 : Copy32( x + 8, x + tmp2, 8 );
1185 0 : Copy32( x + 16, x + 8, sub( tmp1, 8 ) );
1186 0 : set32_fx( x + tmp1, 0, sub( tmp2, tmp1 ) );
1187 0 : set32_fx( x + add( tmp2, tmp1 ), 0, sub( tmp2, tmp1 ) );
1188 : }
1189 : ELSE
1190 : {
1191 0 : Copy32( x + 8, xn_buf32, 8 );
1192 0 : Copy32( x + 16, x + 8, sub( tmp1, 8 ) );
1193 0 : Copy32( xn_buf32, x + tmp1, 8 );
1194 : }
1195 : }
1196 : }
1197 : }
1198 :
1199 :
1200 : /*-----------------------------------------------------------*
1201 : * Compute inverse MDCT of x[]. *
1202 : *-----------------------------------------------------------*/
1203 :
1204 :
1205 646 : Copy32( x, xn_buf32, s_max( s_max( L_frame, L_frameTCX ), L_spec ) );
1206 :
1207 646 : IF( st->igf != 0 )
1208 : {
1209 646 : set32_fx( xn_buf32 + st->hIGFDec->infoIGFStartLine, 0, sub( L_frameTCX, st->hIGFDec->infoIGFStartLine ) );
1210 : }
1211 1292 : IMDCT_fx( xn_buf32, x_e, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, xn_buf, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2,
1212 646 : st->hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_trans, st->hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length,
1213 646 : index, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx,
1214 646 : &st->hHQ_core->Q_old_wtda_LB, st, 0, acelp_zir );
1215 : /* Generate additional comfort noise to mask potential coding artefacts */
1216 646 : IF( st->flag_cna != 0 )
1217 : {
1218 275 : generate_masking_noise_mdct_fx( x, &x_e, st->hFdCngDec->hFdCngCom, s_max( s_max( L_frame, L_frameTCX ), L_spec ) );
1219 : }
1220 :
1221 1292 : IMDCT_fx( x, x_e, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, xn_bufFB, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB,
1222 646 : hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB,
1223 646 : index, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob,
1224 646 : frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, st, div_l( L_mult( FSCALE_DENOM, L_frameTCX_glob ), L_frame_glob ), acelp_zir );
1225 :
1226 : /* PLC: [TCX: Tonal Concealment] */
1227 :
1228 646 : IF( !bfi )
1229 : {
1230 646 : st->second_last_tns_active = st->last_tns_active;
1231 646 : move16();
1232 646 : st->last_tns_active = 0;
1233 646 : move16();
1234 646 : test();
1235 646 : if ( hTcxCfg->fIsTNSAllowed && fUseTns )
1236 : {
1237 1 : st->last_tns_active = 1;
1238 1 : move16();
1239 : }
1240 :
1241 646 : hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
1242 646 : move32();
1243 646 : hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
1244 646 : move32();
1245 646 : st->old_fpitch = L_add( L_deposit_h( hTcxLtpDec->tcxltp_pitch_int ), L_mult( hTcxLtpDec->tcxltp_pitch_fr, div_s( 1, st->pit_res_max ) /*Q16*/ ) );
1246 646 : move32();
1247 646 : st->old_fpitchFB = Mpy_32_16_1( st->old_fpitch /*Q16*/, mult_r( L_frameTCX /*Q0*/, getInvFrameLen( L_frame ) /*Q21*/ ) /*Q6*/ ) /*Q7*/;
1248 646 : move32();
1249 646 : st->old_fpitchFB = L_shr( st->old_fpitchFB, 7 - 16 ); /*->Q16*/
1250 646 : move32();
1251 : }
1252 :
1253 :
1254 : /* Update old_syn_overl */
1255 646 : IF( st->hTcxCfg->last_aldo == 0 )
1256 : {
1257 0 : Copy( xn_buf + L_frame, hTcxDec->syn_Overl, overlap );
1258 0 : Copy( xn_bufFB + L_frameTCX, hTcxDec->syn_OverlFB, overlapFB );
1259 : }
1260 :
1261 : /* Output */
1262 646 : Copy( xn_buf + sub( shr( overlap, 1 ), tcx_offset ), synth, L_frame_glob );
1263 646 : Copy( xn_bufFB + sub( shr( overlapFB, 1 ), tcx_offsetFB ), synthFB, L_frameTCX_glob );
1264 646 : }
1265 :
1266 :
1267 646 : void decoder_tcx_post_fx( Decoder_State *st_fx,
1268 : Word16 *synth,
1269 : Word16 *synthFB,
1270 : Word16 *A,
1271 : Word16 bfi )
1272 : {
1273 : Word16 i;
1274 : Word16 level_syn;
1275 : Word16 level_syn_e;
1276 : Word32 step;
1277 : Word16 gainCNG, gainCNG_e;
1278 : Word16 xn_buf[L_FRAME_MAX];
1279 : Word16 tmp1, tmp2, s;
1280 : Word32 tmp32;
1281 : Word32 tmp32_1, tmp32_2;
1282 : TCX_DEC_HANDLE hTcxDec;
1283 : #ifndef ISSUE_1866_replace_overflow_libdec
1284 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1285 : Flag Overflow = 0;
1286 : move32();
1287 : #endif
1288 : #endif
1289 :
1290 646 : hTcxDec = st_fx->hTcxDec;
1291 :
1292 : /* TCX output */
1293 646 : Copy( synth, xn_buf, st_fx->L_frame );
1294 :
1295 : /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */
1296 646 : test();
1297 646 : test();
1298 646 : if ( !st_fx->bfi && st_fx->prev_bfi && st_fx->last_core == ACELP_CORE )
1299 : {
1300 0 : hTcxDec->tcxltp_last_gain_unmodified = 0;
1301 0 : move16();
1302 : }
1303 646 : test();
1304 646 : IF( bfi != 0 && st_fx->use_partial_copy == 0 )
1305 : {
1306 0 : test();
1307 : /* run lpc gain compensation not for waveform adjustment */
1308 0 : IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
1309 : {
1310 : UWord32 dmy;
1311 0 : tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1312 0 : tmp32_2 /*stepCompensateFB*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1313 :
1314 0 : Mpy_32_32_ss( tmp32_2 /*Q28*/,
1315 0 : L_shl( L_mult0( st_fx->L_frame,
1316 0 : getInvFrameLen( hTcxDec->L_frameTCX ) /*Q21*/ ) /*Q21*/,
1317 : 8 ) /*Q29*/,
1318 : &tmp32_2,
1319 : &dmy ); /*Q26*/
1320 :
1321 0 : tmp32_2 = L_shl( tmp32_2, 3 - 1 ); /*Q28*/
1322 :
1323 0 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1324 : {
1325 0 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1326 0 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) );
1327 0 : move16();
1328 0 : tmp32_1 = L_sub( tmp32_1, tmp32_2 );
1329 : }
1330 : }
1331 0 : tmp32_1 /*gainHelper*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1332 0 : tmp32_2 /*stepCompensate*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1333 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
1334 : {
1335 0 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1336 0 : xn_buf[i] = extract_l( Mpy_32_16_1( tmp32, xn_buf[i] ) );
1337 0 : move16();
1338 0 : tmp32_1 = L_sub( tmp32_1, tmp32_2 );
1339 : }
1340 : }
1341 :
1342 : /* PLC: [TCX: Fade-out]
1343 : * PLC: estimate and update CNG energy */
1344 :
1345 : /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */
1346 646 : s = sub( getScaleFactor16( synthFB, hTcxDec->L_frameTCX ), 4 );
1347 : {
1348 : Word64 tmp64;
1349 646 : tmp64 = 0;
1350 646 : move64();
1351 532806 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1352 : {
1353 532160 : tmp1 = shl( synthFB[i], s );
1354 532160 : tmp64 = W_mac0_16_16( tmp64, tmp1, tmp1 );
1355 : }
1356 646 : tmp32 = W_sat_l( tmp64 );
1357 : }
1358 646 : tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) );
1359 646 : tmp2 = norm_l( tmp32 );
1360 : #ifdef ISSUE_1866_replace_overflow_libdec
1361 646 : tmp1 = round_fx_sat( L_shl( tmp32, tmp2 ) );
1362 : #else
1363 : tmp1 = round_fx_o( L_shl( tmp32, tmp2 ), &Overflow );
1364 : #endif
1365 646 : s = sub( sub( sub( 1, shl( s, 1 ) ), 6 /*table lookup for inverse framelength*/ ), tmp2 );
1366 646 : tmp1 = Sqrt16( tmp1, &s );
1367 646 : move16();
1368 646 : level_syn = tmp1; /*Q0*/
1369 :
1370 : /* PLC: [TCX: Fade-out]
1371 : * PLC: estimate and update CNG energy */
1372 :
1373 646 : level_syn_e = add( s, 15 );
1374 646 : test();
1375 646 : test();
1376 646 : IF( bfi == 0 && st_fx->tcxonly != 0 && EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) )
1377 : {
1378 :
1379 : Word16 Qnew_levelBackgroundTrace;
1380 0 : Qnew_levelBackgroundTrace = 0;
1381 0 : move16();
1382 0 : minimumStatistics_fx( hTcxDec->conNoiseLevelMemory, /*Q15*/
1383 : &hTcxDec->conNoiseLevelIndex, /*Q0 */
1384 : &hTcxDec->conCurrLevelIndex, /*Q0 */
1385 : &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/
1386 : &hTcxDec->conLastFrameLevel, /*Q15*/
1387 : level_syn, /*Q15*/
1388 0 : hTcxDec->conNoiseLevelMemory_e,
1389 0 : hTcxDec->conCngLevelBackgroundTrace_e,
1390 : &Qnew_levelBackgroundTrace,
1391 : &hTcxDec->conLastFrameLevel_e,
1392 : level_syn_e /*scaling of level_syn*/
1393 : );
1394 :
1395 : /*note: All parameters being different from Q0 have to have the same Q-format*/
1396 :
1397 0 : hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace;
1398 0 : move16();
1399 : }
1400 :
1401 : /* PLC: [TCX: Fade-out]
1402 : * PLC: fade-out in time domain */
1403 646 : IF( bfi != 0 )
1404 : {
1405 : Word32 conceal_eof_gain32;
1406 : Word32 conceal_eof_gainFB;
1407 0 : move16();
1408 0 : move16();
1409 0 : gainCNG = 1;
1410 0 : gainCNG_e = 14 + 15 + 6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */
1411 0 : IF( st_fx->tcxonly != 0 )
1412 : {
1413 : /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/
1414 :
1415 0 : IF( level_syn != 0 )
1416 : {
1417 0 : BASOP_Util_Divide_MantExp(
1418 0 : hTcxDec->conCngLevelBackgroundTrace,
1419 0 : hTcxDec->conCngLevelBackgroundTrace_e,
1420 : level_syn,
1421 : level_syn_e,
1422 : &gainCNG,
1423 : &gainCNG_e );
1424 : }
1425 : }
1426 : ELSE
1427 : {
1428 : /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/
1429 0 : IF( level_syn != 0 )
1430 : {
1431 0 : BASOP_Util_Divide_MantExp(
1432 0 : st_fx->cngTDLevel,
1433 0 : st_fx->cngTDLevel_e,
1434 : level_syn,
1435 : level_syn_e,
1436 : &gainCNG,
1437 : &gainCNG_e );
1438 : }
1439 : }
1440 :
1441 0 : if ( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) )
1442 : {
1443 0 : hTcxDec->conceal_eof_gain = 16384 /*1.0f Q14*/; /*Q14*/
1444 0 : move16();
1445 : }
1446 :
1447 : /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */
1448 0 : tmp2 = BASOP_Util_Add_MantExp(
1449 0 : mult_r( hTcxDec->conceal_eof_gain /*Q14*/,
1450 0 : hTcxDec->damping /*Q14*/ ),
1451 : 15 - 13 /*->Q15*/,
1452 0 : mult_r( gainCNG /*Q15*/, sub( 0x4000, hTcxDec->damping /*Q14*/ ) ) /*Q14*/,
1453 0 : add( gainCNG_e, 15 - 14 ) /*->Q15*/,
1454 : &tmp1 );
1455 0 : tmp2 = BASOP_Util_Add_MantExp( hTcxDec->conceal_eof_gain, 15 - 14, negate( tmp1 ), tmp2, &tmp1 );
1456 :
1457 : #ifdef ISSUE_1866_replace_overflow_libdec
1458 0 : step = L_shl_sat( L_mult( tmp1, getInvFrameLen( st_fx->L_frame ) ), sub( tmp2, 6 /*scaling from table lookup*/ + 1 /*go to Q30*/ ) ); /*Q30*/
1459 : #else
1460 : step = L_shl_o( L_mult( tmp1, getInvFrameLen( st_fx->L_frame ) ), sub( tmp2, 6 /*scaling from table lookup*/ + 1 /*go to Q30*/ ), &Overflow ); /*Q30*/
1461 : #endif
1462 : {
1463 : Word32 stepFB;
1464 : UWord32 dmy;
1465 0 : conceal_eof_gainFB = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/
1466 0 : Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy );
1467 : #ifdef ISSUE_1866_replace_overflow_libdec
1468 0 : stepFB = L_shl_sat( stepFB, 3 - 1 ); /*Q30*/
1469 : #else
1470 : stepFB = L_shl_o( stepFB, 3 - 1, &Overflow ); /*Q30*/
1471 : #endif
1472 0 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1473 : {
1474 0 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), 1 ) );
1475 0 : move16();
1476 : #ifdef ISSUE_1866_replace_overflow_libdec
1477 0 : conceal_eof_gainFB = L_sub_sat( conceal_eof_gainFB, stepFB );
1478 : #else
1479 : conceal_eof_gainFB = L_sub_o( conceal_eof_gainFB, stepFB, &Overflow );
1480 : #endif
1481 : }
1482 : }
1483 0 : conceal_eof_gain32 = L_deposit_h( hTcxDec->conceal_eof_gain ); /*Q30*/
1484 0 : FOR( i = 0; i < st_fx->L_frame; i++ )
1485 : {
1486 0 : xn_buf[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gain32 /*Q30*/, xn_buf[i] ), 1 ) );
1487 0 : move16();
1488 : #ifdef ISSUE_1866_replace_overflow_libdec
1489 0 : conceal_eof_gain32 = L_sub_sat( conceal_eof_gain32, step );
1490 : #else
1491 : conceal_eof_gain32 = L_sub_o( conceal_eof_gain32, step, &Overflow );
1492 : #endif
1493 : }
1494 : #ifdef ISSUE_1866_replace_overflow_libdec
1495 0 : hTcxDec->conceal_eof_gain = round_fx_sat( conceal_eof_gain32 ); /*Q14*/
1496 : #else
1497 : hTcxDec->conceal_eof_gain = round_fx_o( conceal_eof_gain32, &Overflow ); /*Q14*/
1498 : #endif
1499 0 : move16();
1500 : /* run lpc gain compensation not for waveform adjustment */
1501 0 : test();
1502 0 : IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
1503 : {
1504 : #ifdef ISSUE_1866_replace_overflow_libdec
1505 0 : st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB,
1506 0 : st_fx->last_concealed_gain_syn_deemph ),
1507 0 : st_fx->last_concealed_gain_syn_deemph_e ) );
1508 : /*Q30->Q14*/
1509 : #else
1510 : st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB,
1511 : st_fx->last_concealed_gain_syn_deemph ),
1512 : st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/
1513 : #endif
1514 0 : move16();
1515 : }
1516 : ELSE
1517 : {
1518 0 : st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/
1519 0 : move16();
1520 : }
1521 0 : st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( step ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 3 ) ); /*Q15*/
1522 0 : move16();
1523 : }
1524 :
1525 : /*-----------------------------------------------------------*
1526 : * Memory update *
1527 : *-----------------------------------------------------------*/
1528 :
1529 : /* Update synth, exc and old_Aq */
1530 646 : tcx_decoder_memory_update( xn_buf, /*Q0*/
1531 : synth, /*Q0*/
1532 : A,
1533 : st_fx,
1534 : 0 );
1535 :
1536 :
1537 : /* PLC: [TCX: Memory update] */
1538 :
1539 646 : st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr];
1540 646 : move32();
1541 646 : st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 1];
1542 646 : move32();
1543 646 : Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr );
1544 646 : set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr );
1545 646 : st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 );
1546 646 : move16();
1547 646 : st_fx->bfi_pitch_frame = st_fx->L_frame;
1548 646 : move16();
1549 :
1550 646 : st_fx->mem_pitch_gain[add( shl( st_fx->nb_subfr, 1 ), 1 )] = st_fx->mem_pitch_gain[st_fx->nb_subfr + 1];
1551 646 : move16();
1552 646 : st_fx->mem_pitch_gain[st_fx->nb_subfr * 2] = st_fx->mem_pitch_gain[st_fx->nb_subfr];
1553 646 : move16();
1554 :
1555 3601 : FOR( i = 0; i < st_fx->nb_subfr; i++ )
1556 : {
1557 2955 : st_fx->mem_pitch_gain[sub( sub( shl( st_fx->nb_subfr, 1 ), 1 ), i )] = st_fx->mem_pitch_gain[sub( sub( st_fx->nb_subfr, 1 ), i )];
1558 2955 : move16();
1559 2955 : st_fx->mem_pitch_gain[sub( sub( st_fx->nb_subfr, 1 ), i )] = hTcxDec->tcxltp_last_gain_unmodified;
1560 2955 : move16();
1561 : }
1562 646 : }
1563 :
1564 901241 : void decoder_tcx_post_ivas_fx( Decoder_State *st_fx,
1565 : Word16 *synth, // Q_syn
1566 : Word16 *synthFB, // Q_syn
1567 : Word16 Q_syn,
1568 : Word16 *A, // Q: 14 - norm_s(A[0])
1569 : Word16 bfi,
1570 : Word16 MCT_flag )
1571 : {
1572 : Word16 i;
1573 : Word16 level_syn;
1574 : Word16 level_syn_e;
1575 : Word32 step;
1576 : Word16 step_e;
1577 : Word16 gainCNG, gainCNG_e;
1578 : Word16 xn_buf[L_FRAME_MAX];
1579 : Word16 tmp1, tmp2, s;
1580 : Word32 tmp32;
1581 : Word32 tmp32_1, tmp32_2;
1582 : TCX_DEC_HANDLE hTcxDec;
1583 : #ifndef ISSUE_1866_replace_overflow_libdec
1584 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1585 : Flag Overflow = 0;
1586 : move32();
1587 : #endif
1588 : #endif
1589 :
1590 901241 : hTcxDec = st_fx->hTcxDec;
1591 :
1592 : /* TCX output */
1593 901241 : Copy( synth, xn_buf, st_fx->L_frame );
1594 :
1595 : /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */
1596 901241 : test();
1597 901241 : test();
1598 901241 : if ( !st_fx->bfi && st_fx->prev_bfi && EQ_16( st_fx->last_core, ACELP_CORE ) )
1599 : {
1600 111 : hTcxDec->tcxltp_last_gain_unmodified = 0;
1601 111 : move16();
1602 : }
1603 901241 : test();
1604 901241 : test();
1605 901241 : test();
1606 901241 : IF( st_fx->hTcxLtpDec != NULL && st_fx->element_mode > EVS_MONO && ( EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) || EQ_16( st_fx->clas_dec, INACTIVE_CLAS ) ) )
1607 : {
1608 : /* deactivate TCX LTP for non-voiced frames */
1609 475834 : st_fx->hTcxLtpDec->tcxltp = 0;
1610 475834 : move16();
1611 475834 : st_fx->hTcxLtpDec->tcxltp_gain = 0;
1612 475834 : move16();
1613 : }
1614 901241 : test();
1615 901241 : IF( bfi != 0 && st_fx->use_partial_copy == 0 )
1616 : {
1617 9669 : test();
1618 9669 : test();
1619 : /* run lpc gain compensation not for waveform adjustment */
1620 9669 : IF( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) )
1621 : {
1622 : UWord32 dmy;
1623 9669 : tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1624 9669 : tmp32_2 /*stepCompensateFB*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1625 :
1626 9669 : Mpy_32_32_ss( tmp32_2 /*Q28*/,
1627 9669 : L_shl( L_mult0( st_fx->L_frame,
1628 9669 : getInvFrameLen( hTcxDec->L_frameTCX ) /*Q21*/ ) /*Q21*/,
1629 : 8 ) /*Q29*/,
1630 : &tmp32_2,
1631 : &dmy ); /*Q26*/
1632 :
1633 9669 : tmp32_2 = L_shl( tmp32_2, 3 - 1 ); /*Q28*/
1634 :
1635 6790149 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1636 : {
1637 6780480 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1638 6780480 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); // Q_syn
1639 6780480 : move16();
1640 6780480 : tmp32_1 = L_sub( tmp32_1, tmp32_2 );
1641 : }
1642 : }
1643 9669 : tmp32_1 /*gainHelper*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1644 9669 : tmp32_2 /*stepCompensate*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1645 4599621 : FOR( i = 0; i < st_fx->L_frame; i++ )
1646 : {
1647 4589952 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1648 4589952 : xn_buf[i] = extract_h( L_shl_sat( Mpy_32_16_1( tmp32, xn_buf[i] ), 16 ) ); // Q_syn
1649 4589952 : move16();
1650 4589952 : tmp32_1 = L_sub( tmp32_1, tmp32_2 );
1651 : }
1652 : }
1653 :
1654 : /* PLC: [TCX: Fade-out]
1655 : * PLC: estimate and update CNG energy */
1656 :
1657 : /* level_syn = (float)sqrt(( dot_product(synthFB, synthFB, L_frame)) / L_frame ); */
1658 901241 : s = sub( getScaleFactor16( synthFB, hTcxDec->L_frameTCX ), 4 );
1659 : {
1660 901241 : Word64 tmp64 = 0;
1661 901241 : move64();
1662 755026041 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1663 : {
1664 754124800 : tmp1 = shl( synthFB[i], s );
1665 754124800 : tmp64 = W_mac0_16_16( tmp64, tmp1, tmp1 );
1666 : }
1667 901241 : tmp32 = W_sat_l( tmp64 );
1668 : }
1669 901241 : tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) );
1670 901241 : tmp2 = norm_l( tmp32 );
1671 : #ifdef ISSUE_1866_replace_overflow_libdec
1672 901241 : tmp1 = round_fx_sat( L_shl( tmp32, tmp2 ) );
1673 : #else
1674 : tmp1 = round_fx_o( L_shl( tmp32, tmp2 ), &Overflow );
1675 : #endif
1676 : // s = sub(sub(sub(1, shl(s, 1)), 6/*table lookup for inverse framelength*/), tmp2);
1677 901241 : s = sub( 25, add( shl( add( Q_syn, s ), 1 ), tmp2 ) );
1678 901241 : tmp1 = Sqrt16( tmp1, &s );
1679 901241 : move16();
1680 901241 : level_syn = tmp1; /*Q0*/
1681 :
1682 : /* PLC: [TCX: Fade-out]
1683 : * PLC: estimate and update CNG energy */
1684 :
1685 901241 : level_syn_e = s; // add(s, 15);
1686 901241 : move16();
1687 901241 : test();
1688 901241 : test();
1689 901241 : test();
1690 901241 : test();
1691 901241 : IF( bfi == 0 && st_fx->tcxonly != 0 && ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) || MCT_flag ) && EQ_16( st_fx->clas_dec, UNVOICED_CLAS ) )
1692 : {
1693 :
1694 : Word16 Qnew_levelBackgroundTrace;
1695 351787 : Qnew_levelBackgroundTrace = 0;
1696 351787 : move16();
1697 351787 : minimumStatistics_fx( hTcxDec->conNoiseLevelMemory, /*Q15*/
1698 : &hTcxDec->NoiseLevelIndex_bfi, /*Q0 */
1699 : &hTcxDec->CurrLevelIndex_bfi, /*Q0 */
1700 : &hTcxDec->conCngLevelBackgroundTrace, /*Q15*/
1701 : &hTcxDec->conLastFrameLevel, /*Q15*/
1702 : level_syn, /*Q15*/
1703 351787 : hTcxDec->conNoiseLevelMemory_e,
1704 351787 : hTcxDec->conCngLevelBackgroundTrace_e,
1705 : &Qnew_levelBackgroundTrace,
1706 : &hTcxDec->conLastFrameLevel_e,
1707 : level_syn_e /*scaling of level_syn*/
1708 : );
1709 :
1710 : /*note: All parameters being different from Q0 have to have the same Q-format*/
1711 :
1712 351787 : hTcxDec->conCngLevelBackgroundTrace_e = Qnew_levelBackgroundTrace;
1713 351787 : move16();
1714 : }
1715 :
1716 : /* PLC: [TCX: Fade-out]
1717 : * PLC: fade-out in time domain */
1718 901241 : IF( bfi != 0 )
1719 : {
1720 : Word32 conceal_eof_gainFB;
1721 : Word16 conceal_eof_gainFB_e;
1722 9669 : move16();
1723 9669 : move16();
1724 9669 : gainCNG = 1;
1725 9669 : gainCNG_e = 14 + 15 + 6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */
1726 9669 : IF( st_fx->tcxonly != 0 )
1727 : {
1728 : /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/
1729 8410 : IF( level_syn )
1730 : {
1731 7092 : level_syn_e = BASOP_Util_Add_MantExp( level_syn, level_syn_e, 20992, -6, &level_syn ); /* 0.01 in Q21*/
1732 : }
1733 : ELSE
1734 : {
1735 1318 : level_syn = 328; /* (1 / 0.01) in Q15 */
1736 1318 : level_syn_e = 0;
1737 1318 : move16();
1738 1318 : move16();
1739 : }
1740 :
1741 8410 : IF( level_syn != 0 )
1742 : {
1743 8410 : BASOP_Util_Divide_MantExp(
1744 8410 : hTcxDec->conCngLevelBackgroundTrace,
1745 8410 : hTcxDec->conCngLevelBackgroundTrace_e,
1746 : level_syn,
1747 : level_syn_e,
1748 : &gainCNG,
1749 : &gainCNG_e );
1750 : }
1751 8410 : test();
1752 8410 : IF( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && !MCT_flag )
1753 : {
1754 3083 : IF( GT_16( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) )
1755 : {
1756 0 : gainCNG = 0;
1757 0 : move16();
1758 : }
1759 3083 : ELSE IF( GT_16( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) )
1760 : {
1761 : // gainCNG *= 1.f - (float) sub( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN;
1762 0 : tmp32 = L_sub( ONE_IN_Q31, imult3216( 107374182 /* 1 / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN in Q31*/, sub( st_fx->nbLostCmpt, MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) ) ); /* Q31 */
1763 0 : gainCNG = extract_l( Mpy_32_32( gainCNG, tmp32 ) );
1764 : }
1765 : }
1766 : }
1767 : ELSE
1768 : {
1769 : /*gainCNG = st_fx->cngTDLevel/(tracingLevel+0.01f);*/
1770 1259 : IF( level_syn )
1771 : {
1772 1258 : level_syn_e = BASOP_Util_Add_MantExp( level_syn, level_syn_e, 20992, -6, &level_syn ); /* 0.01 in Q21*/
1773 : }
1774 : ELSE
1775 : {
1776 1 : level_syn = 328; /* (1 / 0.01) in Q15 */
1777 1 : level_syn_e = 0;
1778 1 : move16();
1779 1 : move16();
1780 : }
1781 :
1782 1259 : IF( level_syn != 0 )
1783 : {
1784 1259 : BASOP_Util_Divide_MantExp(
1785 1259 : st_fx->cngTDLevel,
1786 1259 : st_fx->cngTDLevel_e,
1787 : level_syn,
1788 : level_syn_e,
1789 : &gainCNG,
1790 : &gainCNG_e );
1791 : }
1792 : }
1793 :
1794 9669 : IF( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) )
1795 : {
1796 5285 : hTcxDec->conceal_eof_gain32 = ONE_IN_Q30 /*1.0f Q30*/;
1797 5285 : move32();
1798 5285 : hTcxDec->conceal_eof_gain_e = 1;
1799 5285 : move16();
1800 : }
1801 :
1802 : /* step = (st_fx->conceal_eof_gain - ( st_fx->conceal_eof_gain * st_fx->damping + gainCNG * (1 - st_fx->damping) )) / st_fx->L_frame; */
1803 19338 : Word32 L_tmp = BASOP_Util_Add_Mant32Exp(
1804 : Mpy_32_16_1( hTcxDec->conceal_eof_gain32,
1805 9669 : hTcxDec->damping /*Q14*/ ),
1806 9669 : add( 1, hTcxDec->conceal_eof_gain_e ) /*->Q15*/,
1807 9669 : L_mult( gainCNG /*Q15*/, sub( 0x4000, hTcxDec->damping /*Q14*/ ) ) /*Q14*/,
1808 9669 : add( gainCNG_e, 15 - 14 ) /*->Q15*/,
1809 : &tmp2 );
1810 :
1811 9669 : L_tmp = BASOP_Util_Add_Mant32Exp( hTcxDec->conceal_eof_gain32, hTcxDec->conceal_eof_gain_e, L_negate( L_tmp ), tmp2, &tmp2 );
1812 9669 : step = Mpy_32_16_1( L_tmp, getInvFrameLen( st_fx->L_frame ) );
1813 9669 : step_e = sub( tmp2, 6 );
1814 : {
1815 : Word32 stepFB;
1816 : Word16 stepFB_e;
1817 : UWord32 dmy;
1818 : Word16 tmp_shift;
1819 9669 : conceal_eof_gainFB = hTcxDec->conceal_eof_gain32;
1820 9669 : conceal_eof_gainFB_e = hTcxDec->conceal_eof_gain_e;
1821 9669 : move32();
1822 9669 : move16();
1823 9669 : Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy );
1824 9669 : stepFB_e = add( step_e, 2 );
1825 :
1826 6790149 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1827 : {
1828 6780480 : tmp_shift = conceal_eof_gainFB_e;
1829 6780480 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), tmp_shift ) ); // Q_syn
1830 6780480 : move16();
1831 6780480 : conceal_eof_gainFB = BASOP_Util_Add_Mant32Exp( conceal_eof_gainFB, conceal_eof_gainFB_e, L_negate( stepFB ), stepFB_e, &conceal_eof_gainFB_e ); // Q: 31 - conceal_eof_gainFB_e
1832 : }
1833 : }
1834 4599621 : FOR( i = 0; i < st_fx->L_frame; i++ )
1835 : {
1836 4589952 : xn_buf[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( hTcxDec->conceal_eof_gain32, xn_buf[i] ), hTcxDec->conceal_eof_gain_e ) ); // Qx
1837 4589952 : move16();
1838 4589952 : hTcxDec->conceal_eof_gain32 = BASOP_Util_Add_Mant32Exp( hTcxDec->conceal_eof_gain32, hTcxDec->conceal_eof_gain_e, L_negate( step ), step_e, &hTcxDec->conceal_eof_gain_e );
1839 4589952 : move32();
1840 : }
1841 :
1842 : /* run lpc gain compensation not for waveform adjustment */
1843 9669 : IF( st_fx->hPlcInfo != NULL )
1844 : {
1845 0 : test();
1846 0 : IF( 0 == st_fx->enablePlcWaveadjust || EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) )
1847 : {
1848 : #ifdef ISSUE_1866_replace_overflow_libdec
1849 0 : st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e ) ); /*Q30->Q14*/
1850 : #else
1851 : st_fx->hPlcInfo->recovery_gain = extract_h( L_shl_o( Mpy_32_16_1( conceal_eof_gainFB, st_fx->last_concealed_gain_syn_deemph ), st_fx->last_concealed_gain_syn_deemph_e, &Overflow ) ); /*Q30->Q14*/
1852 : #endif
1853 0 : move16();
1854 : }
1855 : ELSE
1856 : {
1857 0 : st_fx->hPlcInfo->recovery_gain = extract_h( conceal_eof_gainFB ); /*Q14*/
1858 0 : move16();
1859 : }
1860 0 : st_fx->hPlcInfo->step_concealgain_fx = round_fx_sat( L_shl_sat( L_mult0( round_fx_sat( L_shr_sat( step, sub( 1, step_e ) ) ), round_fx_sat( L_shl_sat( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ) ) ), 4 ) ); /*Q15*/
1861 0 : move16();
1862 : }
1863 : }
1864 :
1865 : /*-----------------------------------------------------------*
1866 : * Memory update *
1867 : *-----------------------------------------------------------*/
1868 :
1869 : /* Update synth, exc and old_Aq */
1870 901241 : tcx_decoder_memory_update( xn_buf, /*Q0*/
1871 : synth, /*Q0*/
1872 : A,
1873 : st_fx,
1874 : 0 );
1875 :
1876 :
1877 : /* PLC: [TCX: Memory update] */
1878 :
1879 901241 : st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr];
1880 901241 : move32();
1881 901241 : st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 1];
1882 901241 : move32();
1883 901241 : Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr );
1884 901241 : set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr );
1885 901241 : st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 );
1886 901241 : st_fx->bfi_pitch_frame = st_fx->L_frame;
1887 901241 : move16();
1888 :
1889 901241 : st_fx->mem_pitch_gain[st_fx->nb_subfr * 2 + 1] = st_fx->mem_pitch_gain[st_fx->nb_subfr + 1]; // Q14
1890 901241 : move16();
1891 901241 : st_fx->mem_pitch_gain[st_fx->nb_subfr * 2] = st_fx->mem_pitch_gain[st_fx->nb_subfr]; // Q14
1892 901241 : move16();
1893 :
1894 5078619 : FOR( i = 0; i < st_fx->nb_subfr; i++ )
1895 : {
1896 4177378 : st_fx->mem_pitch_gain[( st_fx->nb_subfr * 2 - 1 ) - i] = st_fx->mem_pitch_gain[st_fx->nb_subfr - 1 - i]; // Q14
1897 4177378 : move16();
1898 4177378 : st_fx->mem_pitch_gain[st_fx->nb_subfr - 1 - i] = shr( hTcxDec->tcxltp_last_gain_unmodified, 1 ); /* Q14 */
1899 4177378 : move16();
1900 : }
1901 901241 : }
1902 :
1903 0 : static Word32 CalculateAbsEnergy_fx( /* o : normalized result Q31 */
1904 : const Word32 L_off, /* i : initial sum value Qn */
1905 : const Word16 x[], /* i : x vector Qn */
1906 : const Word16 lg, /* i : vector length, range [0..7FFF] Q0 */
1907 : Word16 *exp /* o : exponent of result in [-32,31] Q0 */
1908 : )
1909 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
1910 : {
1911 : Word16 i;
1912 : Word32 L_sum, L_c;
1913 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1914 : Flag Overflow = 0;
1915 : Flag Carry;
1916 : move32();
1917 : #endif
1918 : /* Clear carry flag and init sum */
1919 : Carry = 0;
1920 : move32();
1921 : L_c = 0;
1922 : move32();
1923 : L_sum = L_macNs_co( L_off, 0, 0, &Carry, &Overflow );
1924 : IF( L_sum > 0 )
1925 : {
1926 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
1927 : }
1928 : IF( L_sum < 0 )
1929 : {
1930 : L_c = L_msuNs_co( L_c, 0, 0, &Carry, &Overflow );
1931 : }
1932 : FOR( i = 0; i < lg; i += 2 )
1933 : {
1934 : Carry = 0;
1935 : move32();
1936 : BASOP_SATURATE_WARNING_OFF_EVS /*multiplication of -32768 * -32768 throws an overflow, but is not critical*/
1937 : L_sum = L_macNs_co( L_sum, x[i], x[i], &Carry, &Overflow );
1938 : BASOP_SATURATE_WARNING_ON_EVS
1939 : Overflow = 0; /* to avoid useless warning in L_macNs calling L_mult */
1940 : move32();
1941 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
1942 : }
1943 : L_sum = norm_llQ31( L_c, L_sum, exp );
1944 : return L_sum;
1945 : }
1946 : #else
1947 : {
1948 : Word16 i;
1949 : Word32 L_sum;
1950 : Word64 L_sum64;
1951 :
1952 0 : L_sum64 = W_deposit32_l( L_off );
1953 :
1954 0 : FOR( i = 0; i < lg; i += 2 )
1955 : {
1956 0 : L_sum64 = W_mac_16_16( L_sum64, x[i], x[i] );
1957 : }
1958 0 : L_sum = w_norm_llQ31( L_sum64, exp ); /*Q31 - *exp */
1959 0 : return L_sum;
1960 : }
1961 : #endif /* FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW */
1962 :
1963 1672 : void IMDCT_fx( Word32 *x, Word16 x_e, Word16 *old_syn_overl, Word16 *syn_Overl_TDAC, Word16 *xn_buf, const Word16 *tcx_aldo_window_1, const PWord16 *tcx_aldo_window_1_trunc, const PWord16 *tcx_aldo_window_2, const PWord16 *tcx_mdct_window_half, const PWord16 *tcx_mdct_window_minimum, const PWord16 *tcx_mdct_window_trans, Word16 tcx_mdct_window_half_length, Word16 tcx_mdct_window_min_length, Word16 index, Word16 left_rect, Word16 tcx_offset, Word16 overlap, Word16 L_frame, Word16 L_frameTCX, Word16 L_spec_TCX5, Word16 L_frame_glob, Word16 frame_cnt, Word16 bfi, Word16 *old_out, Word16 *Q_old_wtda, Decoder_State *st, Word16 fullbandScale, Word16 *acelp_zir )
1964 : {
1965 1672 : const TCX_CONFIG_HANDLE tcx_cfg = st->hTcxCfg;
1966 : Word16 tmp_offset;
1967 : Word16 tmp1, tmp2, tmp3, *tmpP16;
1968 : Word32 tmp32;
1969 : Word8 tmp8;
1970 : Word16 i;
1971 : Word16 nz;
1972 : Word16 aldo;
1973 : TCX_DEC_HANDLE hTcxDec;
1974 1672 : aldo = 0;
1975 1672 : move16();
1976 :
1977 1672 : hTcxDec = st->hTcxDec;
1978 :
1979 : /* number of zero for ALDO windows*/
1980 1672 : tmp32 = L_add( st->sr_core, 0 );
1981 1672 : IF( fullbandScale != 0 )
1982 : {
1983 836 : tmp32 = L_add( st->output_Fs, 0 );
1984 : }
1985 1672 : nz = NS2SA_FX2( tmp32, N_ZERO_MDCT_NS );
1986 :
1987 1672 : tmp_offset = 0;
1988 1672 : move16();
1989 1672 : IF( tcx_offset < 0 )
1990 : {
1991 456 : tmp_offset = negate( tcx_offset );
1992 : }
1993 1672 : test();
1994 1672 : IF( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) )
1995 : {
1996 : /* Mode decision in PLC
1997 :
1998 : last OL curr OL left TCX-10 right TCX-10
1999 : -------------------------------------------------------------
2000 : 0 0 2x TCX-5* 1x TCX-10
2001 : 0 2 1x TCX-10 1x TCX-10
2002 : 0 3 1x TCX-10 1x TCX-10
2003 : 2 0 2x TCX-5 1x TCX-10
2004 : 2 2 2x TCX-5 2x TCX-5
2005 : 2 3 2x TCX-5 2x TCX-5
2006 : 3 0 2x TCX-5 1x TCX-10
2007 : 3 2 2x TCX-5 2x TCX-5
2008 : 3 3 2x TCX-5 2x TCX-5
2009 : */
2010 0 : test();
2011 0 : test();
2012 0 : test();
2013 0 : test();
2014 0 : test();
2015 0 : test();
2016 0 : IF( ( bfi == 0 && tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP ) || ( bfi != 0 && ( tcx_cfg->tcx_last_overlap_mode != FULL_OVERLAP ) && ( tcx_cfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) )
2017 0 : {
2018 : /* minimum or half overlap, two transforms, grouping into one window */
2019 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2020 : Word16 w;
2021 : Word16 L_win, L_ola;
2022 :
2023 0 : L_win = shr( L_frame, 1 );
2024 0 : L_ola = tcx_mdct_window_half_length;
2025 0 : move16();
2026 0 : if ( EQ_16( tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
2027 : {
2028 0 : L_ola = tcx_mdct_window_min_length;
2029 0 : move16();
2030 : }
2031 :
2032 0 : set16_fx( xn_buf, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
2033 0 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
2034 :
2035 0 : FOR( w = 0; w < 2; w++ )
2036 : {
2037 :
2038 0 : TCX_MDCT_Inverse( x + L_mult0( w, L_spec_TCX5 ), sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
2039 :
2040 0 : tmp1 = left_rect;
2041 0 : move16();
2042 0 : tmp2 = tcx_cfg->tcx_last_overlap_mode;
2043 0 : move16();
2044 0 : tmp3 = st->last_core_bfi;
2045 0 : move16();
2046 0 : tmp8 = (Word8) st->last_is_cng;
2047 0 : move16();
2048 0 : IF( w > 0 )
2049 : {
2050 0 : tmp1 = 0;
2051 0 : move16();
2052 0 : tmp2 = MIN_OVERLAP;
2053 0 : move16();
2054 0 : tmp3 = 1;
2055 0 : move16();
2056 0 : tmp8 = (Word8) 0;
2057 0 : move16();
2058 : }
2059 0 : test();
2060 0 : if ( w == 0 && EQ_16( index, 2 ) )
2061 : {
2062 0 : tmp2 = MIN_OVERLAP;
2063 0 : move16();
2064 : }
2065 0 : IF( frame_cnt > 0 )
2066 : {
2067 0 : tmp3 = 1;
2068 0 : move16();
2069 0 : tmp8 = (Word8) 0;
2070 0 : move16();
2071 : }
2072 :
2073 0 : tcx_windowing_synthesis_current_frame( win,
2074 : tcx_aldo_window_2,
2075 : tcx_mdct_window_half,
2076 : tcx_mdct_window_minimum,
2077 : L_ola,
2078 : tcx_mdct_window_half_length,
2079 : tcx_mdct_window_min_length,
2080 : tmp1,
2081 : tmp2,
2082 : acelp_zir,
2083 0 : hTcxDec->old_syn_Overl,
2084 : syn_Overl_TDAC,
2085 0 : st->old_Aq_12_8_fx,
2086 : tcx_mdct_window_trans,
2087 : L_win,
2088 : tmp_offset,
2089 : tmp3,
2090 : tmp8,
2091 : fullbandScale );
2092 :
2093 0 : IF( w > 0 )
2094 : {
2095 0 : tcx_windowing_synthesis_past_frame( xn_buf + tcx_offset - shr( L_ola, 1 ) + imult1616( w, L_win ),
2096 : tcx_aldo_window_1_trunc,
2097 : tcx_mdct_window_half,
2098 : tcx_mdct_window_minimum,
2099 : L_ola,
2100 : tcx_mdct_window_half_length,
2101 : tcx_mdct_window_min_length,
2102 : MIN_OVERLAP );
2103 : }
2104 : /* add part of current sub-window overlapping with previous window */
2105 0 : Vr_add( win,
2106 0 : xn_buf + tcx_offset - shr( L_ola, 1 ) + w * L_win, /*instrumented only shr because in fact, its only L_win+L_win+L_win...*/
2107 0 : xn_buf + tcx_offset - shr( L_ola, 1 ) + w * L_win,
2108 : L_ola );
2109 : /* copy new sub-window region not overlapping with previous window */
2110 0 : Copy(
2111 0 : win + L_ola,
2112 0 : xn_buf + tcx_offset + shr( L_ola, 1 ) + w * L_win,
2113 : L_win );
2114 : }
2115 :
2116 : /* To assure that no garbage values are passed to overlap */
2117 0 : set16_fx( xn_buf + L_frame + tcx_offset + shr( L_ola, 1 ), 0, overlap - tcx_offset - shr( L_ola, 1 ) );
2118 : }
2119 0 : ELSE IF( bfi == 0 && ( frame_cnt == 0 ) && ( tcx_cfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
2120 0 : {
2121 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2122 : Word16 L_win, L_ola, w;
2123 :
2124 : /* special overlap attempt, two transforms, grouping into one window */
2125 0 : L_win = shr( L_frame, 1 );
2126 0 : L_ola = tcx_mdct_window_min_length;
2127 0 : move16();
2128 :
2129 0 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
2130 :
2131 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
2132 :
2133 0 : TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2134 0 : win + L_win,
2135 0 : 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
2136 :
2137 0 : set16_fx( xn_buf, 0, shr( overlap, 1 ) );
2138 : /* copy new sub-window region not overlapping with previous window */
2139 0 : Copy( win + L_win, xn_buf + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
2140 :
2141 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
2142 0 : TCX_MDCT_Inverse( x + L_spec_TCX5, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2143 : win,
2144 0 : L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
2145 :
2146 0 : tcx_windowing_synthesis_current_frame( win,
2147 : tcx_aldo_window_2,
2148 : tcx_mdct_window_half,
2149 : tcx_mdct_window_minimum,
2150 : L_ola,
2151 : tcx_mdct_window_half_length,
2152 : tcx_mdct_window_min_length,
2153 : 0, /* left_rect */
2154 : MIN_OVERLAP, /* left_mode */
2155 : acelp_zir,
2156 0 : hTcxDec->old_syn_Overl,
2157 : syn_Overl_TDAC,
2158 0 : st->old_Aq_12_8_fx,
2159 : tcx_mdct_window_trans,
2160 : L_win,
2161 : tmp_offset,
2162 : 1, /* st->last_core_bfi */
2163 : 0, /* st->last_is_cng */
2164 : fullbandScale );
2165 :
2166 0 : tmpP16 = xn_buf + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
2167 :
2168 0 : tcx_windowing_synthesis_past_frame( tmpP16,
2169 : tcx_aldo_window_1_trunc,
2170 : tcx_mdct_window_half,
2171 : tcx_mdct_window_minimum,
2172 : L_ola,
2173 : tcx_mdct_window_half_length,
2174 : tcx_mdct_window_min_length,
2175 : MIN_OVERLAP );
2176 :
2177 : /* add part of current sub-window overlapping with previous window */
2178 0 : FOR( i = 0; i < L_ola; i++ )
2179 : {
2180 0 : tmpP16[i] = add( tmpP16[i], win[i] );
2181 0 : move16();
2182 : }
2183 :
2184 : /* copy new sub-window region not overlapping with previous window */
2185 0 : Copy( win + L_ola,
2186 0 : xn_buf + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
2187 : L_win );
2188 :
2189 : /* extra folding-out on left side of win, for perfect reconstruction */
2190 0 : FOR( w = ( overlap / 2 ); w < overlap; w++ )
2191 : {
2192 0 : xn_buf[( ( overlap - 1 ) - w )] = negate( xn_buf[w] );
2193 0 : move16();
2194 : }
2195 :
2196 0 : tcx_windowing_synthesis_current_frame( xn_buf,
2197 : tcx_aldo_window_2,
2198 : tcx_mdct_window_half,
2199 : tcx_mdct_window_minimum,
2200 : overlap,
2201 : tcx_mdct_window_half_length,
2202 : tcx_mdct_window_min_length,
2203 : left_rect,
2204 : 0, /* left_mode */
2205 : acelp_zir,
2206 0 : hTcxDec->old_syn_Overl,
2207 : syn_Overl_TDAC,
2208 0 : st->old_Aq_12_8_fx,
2209 : tcx_mdct_window_trans,
2210 0 : shl( L_win, 1 ),
2211 : tmp_offset,
2212 0 : st->last_core_bfi,
2213 0 : (Word8) st->last_is_cng,
2214 : fullbandScale );
2215 : }
2216 : ELSE /* default i.e. maximum overlap, single transform, no grouping */
2217 : {
2218 :
2219 0 : TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), xn_buf, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
2220 :
2221 0 : tmp1 = index;
2222 0 : move16();
2223 0 : test();
2224 0 : test();
2225 0 : test();
2226 0 : if ( bfi == 0 && ( frame_cnt > 0 ) && ( index == 0 ) && ( st->last_core != ACELP_CORE ) )
2227 : {
2228 0 : tmp1 = MIN_OVERLAP;
2229 0 : move16();
2230 : }
2231 :
2232 0 : tmp3 = st->last_core_bfi;
2233 0 : move16();
2234 0 : if ( frame_cnt > 0 )
2235 : {
2236 0 : tmp3 = 1;
2237 0 : move16();
2238 : }
2239 :
2240 0 : tmp8 = (Word8) st->last_is_cng;
2241 0 : move16();
2242 0 : if ( frame_cnt > 0 )
2243 : {
2244 0 : tmp8 = 0;
2245 0 : move16();
2246 : }
2247 :
2248 0 : tcx_windowing_synthesis_current_frame( xn_buf,
2249 : tcx_aldo_window_2,
2250 : tcx_mdct_window_half,
2251 : tcx_mdct_window_minimum,
2252 : overlap,
2253 : tcx_mdct_window_half_length,
2254 : tcx_mdct_window_min_length,
2255 : left_rect,
2256 : tmp1,
2257 : acelp_zir,
2258 0 : hTcxDec->old_syn_Overl,
2259 : syn_Overl_TDAC,
2260 0 : st->old_Aq_12_8_fx,
2261 : tcx_mdct_window_trans,
2262 0 : shr( L_frame_glob, 1 ),
2263 : tmp_offset,
2264 : tmp3,
2265 : tmp8,
2266 : fullbandScale );
2267 : }
2268 : }
2269 : ELSE /* frame is TCX-20 or not TCX-only */
2270 : {
2271 1672 : assert( frame_cnt == 0 );
2272 :
2273 1672 : IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
2274 : {
2275 : Word32 tmp_buf[L_FRAME_PLUS];
2276 : Word16 Q;
2277 :
2278 : /* DCT */
2279 1216 : Q = sub( 31, x_e );
2280 1216 : edct_fx( x, tmp_buf, L_frame, &Q );
2281 :
2282 : /* scale by sqrt(L / NORM_MDCT_FACTOR) */
2283 1216 : tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
2284 1216 : tmp2 = 4;
2285 1216 : move16();
2286 1216 : tmp1 = Sqrt16( tmp1, &tmp2 );
2287 :
2288 680000 : FOR( i = 0; i < L_frame; i++ )
2289 : {
2290 678784 : tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
2291 678784 : move32();
2292 : }
2293 1216 : Q = sub( Q, tmp2 );
2294 :
2295 :
2296 1216 : window_ola_fx( tmp_buf,
2297 : xn_buf,
2298 : &Q,
2299 : old_out,
2300 : Q_old_wtda,
2301 : L_frame,
2302 1216 : tcx_cfg->tcx_last_overlap_mode,
2303 1216 : tcx_cfg->tcx_curr_overlap_mode,
2304 : 0,
2305 : 0,
2306 : NULL );
2307 :
2308 : /* scale output */
2309 1216 : IF( Q <= 0 )
2310 : {
2311 59305 : FOR( i = 0; i < L_frame; i++ )
2312 : {
2313 59200 : xn_buf[i] = shr_sat( xn_buf[i], Q );
2314 59200 : move16();
2315 : }
2316 : }
2317 : ELSE
2318 : {
2319 1111 : tmp1 = shr( 0x4000, sub( Q, 1 ) );
2320 :
2321 620695 : FOR( i = 0; i < L_frame; i++ )
2322 : {
2323 619584 : xn_buf[i] = mult_r( xn_buf[i], tmp1 );
2324 619584 : move16();
2325 : }
2326 : }
2327 :
2328 1216 : aldo = 1;
2329 1216 : move16();
2330 : }
2331 : ELSE
2332 : {
2333 :
2334 456 : TCX_MDCT_Inverse( x, sub( x_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), xn_buf, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
2335 :
2336 :
2337 : /*-----------------------------------------------------------*
2338 : * Windowing, overlap and add *
2339 : *-----------------------------------------------------------*/
2340 :
2341 :
2342 : /* Window current frame */
2343 456 : tmp3 = st->last_core_bfi;
2344 456 : move16();
2345 :
2346 456 : tmp8 = (Word8) st->last_is_cng;
2347 456 : move16();
2348 912 : tcx_windowing_synthesis_current_frame( xn_buf,
2349 : tcx_aldo_window_2,
2350 : tcx_mdct_window_half,
2351 : tcx_mdct_window_minimum,
2352 : overlap,
2353 : tcx_mdct_window_half_length,
2354 : tcx_mdct_window_min_length,
2355 : left_rect,
2356 456 : tcx_cfg->tcx_last_overlap_mode,
2357 : acelp_zir,
2358 456 : hTcxDec->old_syn_Overl,
2359 : syn_Overl_TDAC,
2360 456 : st->old_Aq_12_8_fx,
2361 : tcx_mdct_window_trans,
2362 456 : shr( L_frame_glob, 1 ),
2363 : tmp_offset,
2364 : tmp3,
2365 : tmp8,
2366 : fullbandScale );
2367 : } /* TRANSITION_OVERLAP */
2368 : } /* TCX-20 and TCX-only */
2369 :
2370 : /* Window and overlap-add past frame if past frame is TCX */
2371 1672 : test();
2372 1672 : IF( ( frame_cnt != 0 ) || ( GT_16( st->last_core_bfi, ACELP_CORE ) ) )
2373 : {
2374 1214 : test();
2375 1214 : test();
2376 1214 : IF( ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) )
2377 : {
2378 0 : test();
2379 0 : test();
2380 0 : test();
2381 0 : test();
2382 0 : if ( ( bfi == 0 ) && ( frame_cnt > 0 ) && ( index == 0 ) &&
2383 0 : ( EQ_16( tcx_cfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) && ( st->last_core != ACELP_CORE ) )
2384 : {
2385 0 : index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */
2386 0 : move16();
2387 : }
2388 :
2389 0 : IF( tcx_cfg->last_aldo != 0 )
2390 : {
2391 : Word16 tmp4;
2392 :
2393 0 : tmp2 = add( *Q_old_wtda, TCX_IMDCT_HEADROOM );
2394 0 : tmp4 = sub( shr( overlap, 1 ), tcx_offset );
2395 :
2396 0 : FOR( i = 0; i < tmp4; i++ )
2397 : {
2398 0 : xn_buf[i] = shl( xn_buf[i], TCX_IMDCT_HEADROOM );
2399 0 : move16();
2400 : }
2401 :
2402 0 : tmp1 = sub( overlap, tcx_mdct_window_min_length );
2403 0 : FOR( i = 0; i < tmp1; i++ )
2404 : {
2405 0 : xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], shr_sat( old_out[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
2406 0 : move16();
2407 : }
2408 :
2409 : /* fade truncated ALDO window */
2410 0 : tmp1 = sub( overlap, shr( tcx_mdct_window_min_length, 1 ) );
2411 0 : FOR( ; i < tmp1; i++ )
2412 : {
2413 0 : tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[i - overlap + tcx_mdct_window_min_length].v.re );
2414 0 : xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM );
2415 0 : move16();
2416 : }
2417 0 : FOR( ; i < overlap; i++ )
2418 : {
2419 0 : tmp3 = mult_r( shr( old_out[i + nz], tmp2 ), tcx_mdct_window_minimum[overlap - 1 - i].v.im );
2420 0 : xn_buf[i + tmp4] = shl_sat( add_sat( xn_buf[i + tmp4], tmp3 ), TCX_IMDCT_HEADROOM );
2421 0 : move16();
2422 : }
2423 :
2424 0 : FOR( i = add( i, tmp4 ); i < L_frame; i++ )
2425 : {
2426 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2427 0 : move16();
2428 : }
2429 : }
2430 : ELSE
2431 : {
2432 0 : tmp1 = index;
2433 0 : move16();
2434 0 : test();
2435 0 : if ( ( index == 0 ) || ( EQ_16( tcx_cfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
2436 : {
2437 0 : tmp1 = tcx_cfg->tcx_last_overlap_mode;
2438 0 : move16();
2439 : }
2440 :
2441 0 : tcx_windowing_synthesis_past_frame( old_syn_overl,
2442 : tcx_aldo_window_1_trunc,
2443 : tcx_mdct_window_half,
2444 : tcx_mdct_window_minimum,
2445 : overlap,
2446 : tcx_mdct_window_half_length,
2447 : tcx_mdct_window_min_length,
2448 : tmp1 );
2449 :
2450 : BASOP_SATURATE_WARNING_OFF_EVS;
2451 0 : IF( bfi )
2452 : {
2453 0 : tmp1 = sub( shr( overlap, 1 ), tcx_offset );
2454 0 : tmp3 = shr( tcx_mdct_window_half_length, 1 );
2455 0 : FOR( i = 0; i < tmp1; i++ )
2456 : {
2457 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2458 0 : move16();
2459 : }
2460 0 : FOR( i = 0; i < tmp3; i++ )
2461 : {
2462 0 : tmp2 = add_sat( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[i].v.re ) );
2463 0 : xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM );
2464 0 : move16();
2465 : }
2466 0 : FOR( ; i < tcx_mdct_window_half_length; i++ )
2467 : {
2468 0 : tmp2 = add( xn_buf[i + tmp1], mult_r( old_syn_overl[i], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) );
2469 0 : xn_buf[i + tmp1] = shl_sat( tmp2, TCX_IMDCT_HEADROOM );
2470 0 : move16();
2471 : }
2472 0 : IF( LT_16( add( i, tmp1 ), L_frame ) )
2473 : {
2474 0 : FOR( i = add( i, tmp1 ); i < L_frame; i++ )
2475 : {
2476 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2477 0 : move16();
2478 : }
2479 : }
2480 : }
2481 0 : ELSE IF( left_rect == 0 )
2482 : {
2483 0 : FOR( i = 0; i < overlap; i++ )
2484 : {
2485 :
2486 0 : xn_buf[i] = shl_sat( add_sat( xn_buf[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM );
2487 0 : move16();
2488 : }
2489 :
2490 0 : IF( LT_16( i, L_frame ) )
2491 : {
2492 0 : FOR( ; i < L_frame; i++ )
2493 : {
2494 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2495 0 : move16();
2496 : }
2497 : }
2498 : }
2499 : ELSE
2500 : {
2501 0 : tmp1 = shr( overlap, 1 );
2502 0 : FOR( i = 0; i < tmp1; i++ )
2503 : {
2504 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2505 0 : move16();
2506 : }
2507 :
2508 0 : tmpP16 = xn_buf + tmp1;
2509 0 : FOR( i = 0; i < overlap; i++ )
2510 : {
2511 0 : tmpP16[i] = shl_sat( add( tmpP16[i], old_syn_overl[i] ), TCX_IMDCT_HEADROOM );
2512 0 : move16();
2513 : }
2514 :
2515 0 : IF( LT_16( add( i, tmp1 ), L_frame ) )
2516 : {
2517 0 : FOR( i = add( i, tmp1 ); i < L_frame; i++ )
2518 : {
2519 0 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2520 0 : move16();
2521 : }
2522 : }
2523 : }
2524 : BASOP_SATURATE_WARNING_ON_EVS;
2525 : }
2526 : }
2527 : /* aldo must not become 0 unless for TCX10 and frames after tansistion frames */
2528 1214 : assert( aldo != 0 || ( L_frameTCX == hTcxDec->L_frameTCX >> 1 && st->tcxonly ) || st->hTcxCfg->tcx_last_overlap_mode == TRANSITION_OVERLAP );
2529 : }
2530 : ELSE
2531 : {
2532 458 : IF( aldo == 0 )
2533 : {
2534 : BASOP_SATURATE_WARNING_OFF_EVS;
2535 321176 : FOR( i = 0; i < L_frame; i++ )
2536 : {
2537 320720 : xn_buf[i] = shl_sat( xn_buf[i], TCX_IMDCT_HEADROOM );
2538 320720 : move16();
2539 : }
2540 : BASOP_SATURATE_WARNING_ON_EVS;
2541 : }
2542 : }
2543 :
2544 1672 : test();
2545 1672 : test();
2546 1672 : test();
2547 1672 : IF( ( aldo == 0 ) &&
2548 : ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
2549 : NE_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
2550 : {
2551 : /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
2552 72618 : FOR( i = 0; i < nz; i++ )
2553 : {
2554 72162 : old_out[i] = shr( xn_buf[L_frame - nz + i], TCX_IMDCT_HEADROOM );
2555 72162 : move16();
2556 : }
2557 456 : Copy( xn_buf + L_frame, old_out + nz, overlap );
2558 456 : set16_fx( old_out + nz + overlap, 0, nz );
2559 :
2560 456 : tcx_windowing_synthesis_past_frame( old_out + nz,
2561 : tcx_aldo_window_1_trunc,
2562 : tcx_mdct_window_half,
2563 : tcx_mdct_window_minimum,
2564 : overlap,
2565 : tcx_mdct_window_half_length,
2566 : tcx_mdct_window_min_length,
2567 456 : tcx_cfg->tcx_curr_overlap_mode );
2568 :
2569 : /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
2570 456 : IF( EQ_16( tcx_cfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
2571 : {
2572 72618 : FOR( i = 0; i < nz; i++ )
2573 : {
2574 72162 : old_out[nz + overlap + i] = shr( mult_r( xn_buf[L_frame - 1 - i], tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
2575 72162 : move16();
2576 : }
2577 456 : aldo = 1;
2578 456 : move16();
2579 : }
2580 :
2581 456 : *Q_old_wtda = -TCX_IMDCT_HEADROOM;
2582 456 : move16();
2583 : }
2584 1672 : if ( fullbandScale != 0 )
2585 : {
2586 836 : st->hTcxCfg->last_aldo = aldo;
2587 836 : move16();
2588 : }
2589 :
2590 : /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */
2591 1672 : test();
2592 1672 : test();
2593 1672 : test();
2594 1672 : IF( left_rect && ( frame_cnt == 0 ) && ( st->last_core_bfi == ACELP_CORE ) && st->prev_bfi )
2595 : {
2596 :
2597 0 : IF( fullbandScale )
2598 : {
2599 0 : tmp1 = sub( shr( overlap, 1 ), tcx_offset );
2600 0 : tmp3 = shr( tcx_mdct_window_half_length, 1 );
2601 0 : FOR( i = 0; i < tmp3; i++ )
2602 : {
2603 0 : xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im );
2604 0 : xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) );
2605 0 : move16();
2606 0 : move16();
2607 : }
2608 0 : FOR( ; i < tcx_mdct_window_half_length; i++ )
2609 : {
2610 0 : xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.re );
2611 0 : xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_OverlFB[i], mult_r_sat( tcx_mdct_window_half[( ( tcx_mdct_window_half_length - 1 ) - i )].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) );
2612 0 : move16();
2613 0 : move16();
2614 : }
2615 : }
2616 : ELSE
2617 : {
2618 0 : tmp1 = sub( shr( overlap, 1 ), tcx_offset );
2619 0 : tmp3 = shr( tcx_mdct_window_half_length, 1 );
2620 0 : FOR( i = 0; i < tmp3; i++ )
2621 : {
2622 0 : xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[i].v.im );
2623 0 : xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[i].v.re, tcx_mdct_window_half[i].v.re ) ) );
2624 0 : move16();
2625 0 : move16();
2626 : }
2627 0 : FOR( ; i < tcx_mdct_window_half_length; i++ )
2628 : {
2629 0 : xn_buf[i + tmp1] = mult_r_sat( xn_buf[i + tmp1], tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.re );
2630 0 : xn_buf[i + tmp1] = add_sat( xn_buf[i + tmp1], mult_r_sat( hTcxDec->syn_Overl[i], mult_r_sat( tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im, tcx_mdct_window_half[tcx_mdct_window_half_length - 1 - i].v.im ) ) );
2631 0 : move16();
2632 0 : move16();
2633 : }
2634 : }
2635 : }
2636 1672 : }
2637 :
2638 :
2639 1693434 : static Word16 IMDCT_ivas_fx_calc_qwin(
2640 : Decoder_State *st,
2641 : Word16 *syn_Overl_TDAC,
2642 : Word16 Q_syn_Overl_TDAC,
2643 : Word16 *syn_Overl,
2644 : Word16 Q_syn_Overl,
2645 : Word16 *old_syn_Overl,
2646 : Word16 Q_old_syn_Overl,
2647 : Word16 *old_out_fx,
2648 : Word16 Q_old_out_fx,
2649 : Word16 q_win,
2650 : const Word16 FB_flag )
2651 : {
2652 : Word16 t, old_syn_Overl_len, syn_Overl_TDAC_len;
2653 :
2654 1693434 : t = L_FRAME32k;
2655 1693434 : move16();
2656 1693434 : if ( FB_flag )
2657 : {
2658 846717 : t = L_FRAME48k;
2659 846717 : move16();
2660 : }
2661 :
2662 1693434 : old_syn_Overl_len = st->hTcxCfg->tcx_mdct_window_length;
2663 1693434 : syn_Overl_TDAC_len = s_max( st->hTcxCfg->tcx_mdct_window_length_old, 0 );
2664 :
2665 1693434 : IF( ( st->prev_bfi && EQ_16( st->last_core_bfi, ACELP_CORE ) ) || EQ_16( st->last_core, ACELP_CORE ) )
2666 : {
2667 21588 : old_syn_Overl_len = shr( st->L_frame, 1 );
2668 21588 : syn_Overl_TDAC_len = shr( st->last_L_frame, 1 );
2669 : }
2670 :
2671 1693434 : IF( st->prev_bfi && ( st->last_core_bfi == ACELP_CORE ) )
2672 : {
2673 4934 : syn_Overl_TDAC_len = old_syn_Overl_len;
2674 : }
2675 :
2676 1693434 : q_win = 6;
2677 1693434 : move16();
2678 :
2679 : // q_win == norm + Q_syn_Overl_TDAC
2680 1693434 : q_win = s_min( q_win, norm_arr( syn_Overl_TDAC, syn_Overl_TDAC_len ) + Q_syn_Overl_TDAC );
2681 :
2682 : // q_win = s_min( q_win, norm_arr( syn_Overl, oldLength / 2 ) + Q_syn_Overl );
2683 1693434 : q_win = s_min( q_win, norm_arr( syn_Overl, old_syn_Overl_len ) + Q_syn_Overl );
2684 :
2685 1693434 : q_win = s_min( q_win, norm_arr( old_syn_Overl, old_syn_Overl_len ) + Q_old_syn_Overl );
2686 :
2687 : // q_win = s_min( q_win, norm_arr( old_out_fx, oldLength ) + Q_old_out_fx );
2688 1693434 : q_win = s_min( q_win, norm_arr( old_out_fx, t ) + Q_old_out_fx );
2689 :
2690 : #if 0
2691 : set16_zero_fx(syn_Overl_TDAC + oldLength / 2, (t-oldLength)/2 );
2692 : //set16_zero_fx(syn_Overl + oldLength / 2, (t-oldLength)/2 );
2693 : set16_zero_fx(old_syn_Overl + oldLength / 2, (t-oldLength)/2 );
2694 : //set16_zero_fx(old_out_fx + oldLength, (t-oldLength) );
2695 : #endif
2696 1693434 : q_win = s_max( -3, sub( q_win, 2 ) );
2697 :
2698 1693434 : return q_win;
2699 : }
2700 :
2701 1711870 : static void IMDCT_ivas_fx_rescale(
2702 : Word16 *xn_buf_fx,
2703 : Word16 *q_xn_buf_fx,
2704 : Word16 *syn_Overl_TDAC,
2705 : Word16 *Q_syn_Overl_TDAC,
2706 : Word16 *syn_Overl,
2707 : Word16 *Q_syn_Overl,
2708 : Word16 *old_syn_Overl,
2709 : Word16 *Q_old_syn_Overl,
2710 : Word16 *old_out_fx,
2711 : Word16 *Q_old_out_fx,
2712 : Word16 q_win,
2713 : const Word16 FB_flag )
2714 : {
2715 : Word16 oldLength;
2716 :
2717 1711870 : oldLength = L_FRAME32k;
2718 1711870 : move16();
2719 1711870 : if ( FB_flag )
2720 : {
2721 855935 : oldLength = L_FRAME48k;
2722 855935 : move16();
2723 : }
2724 :
2725 : #if 1
2726 1711870 : IF( xn_buf_fx != NULL )
2727 : {
2728 1710284 : Scale_sig( xn_buf_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX, sub( q_win, *q_xn_buf_fx ) );
2729 1710284 : *q_xn_buf_fx = q_win;
2730 1710284 : move16();
2731 : }
2732 1711870 : Scale_sig( syn_Overl_TDAC, oldLength / 2, sub( q_win, *Q_syn_Overl_TDAC ) ); // st->hTcxDec->Q_syn_Overl_TDAC -> q_win
2733 1711870 : *Q_syn_Overl_TDAC = q_win;
2734 1711870 : move16();
2735 1711870 : Scale_sig( syn_Overl, oldLength / 2, sub( q_win, *Q_syn_Overl ) ); // st->hTcxDec->Q_syn_Overl -> q_win
2736 1711870 : *Q_syn_Overl = q_win;
2737 1711870 : move16();
2738 1711870 : if ( FB_flag == 0 )
2739 : {
2740 855935 : Scale_sig( old_syn_Overl, oldLength / 2, sub( q_win, *Q_old_syn_Overl ) ); // Q(-1 - st->Q_syn) -> q_win
2741 855935 : *Q_old_syn_Overl = q_win;
2742 855935 : move16();
2743 : }
2744 1711870 : Scale_sig( old_out_fx, oldLength, sub( q_win, *Q_old_out_fx ) ); // Q(st->hHQ_core->Q_old_wtda) -> q_win
2745 1711870 : *Q_old_out_fx = q_win;
2746 1711870 : move16();
2747 : #endif
2748 1711870 : }
2749 :
2750 115282 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
2751 : const Word16 L, /* Q0 */
2752 : Word16 *factor_e /* Q0 */
2753 : )
2754 : {
2755 :
2756 : Word16 factor;
2757 :
2758 115282 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
2759 : {
2760 27395 : factor = 32767;
2761 27395 : move16();
2762 27395 : *factor_e = 0;
2763 27395 : move16();
2764 : }
2765 87887 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
2766 : {
2767 14374 : factor = 23170;
2768 14374 : move16();
2769 14374 : *factor_e = 1;
2770 14374 : move16();
2771 : }
2772 73513 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
2773 : {
2774 1065 : factor = 32767;
2775 1065 : move16();
2776 1065 : *factor_e = 1;
2777 1065 : move16();
2778 : }
2779 : ELSE
2780 : {
2781 72448 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
2782 72448 : *factor_e = 4;
2783 72448 : move16();
2784 :
2785 72448 : factor = Sqrt16( factor, factor_e );
2786 : }
2787 :
2788 115282 : return factor;
2789 : }
2790 :
2791 115200 : static void TCX_MDCT_Inverse_qwin_fx(
2792 : Word32 *x, // Q( 31 - x_e )
2793 : Word16 x_e,
2794 : Word16 *y, /* Qy */
2795 : const Word16 l, /* Q0 */
2796 : const Word16 m, /* Q0 */
2797 : const Word16 r, /* Q0 */
2798 : const Word16 element_mode, /* Q0 */
2799 : Word16 *q_win,
2800 : Word16 allow_qwin_change )
2801 : {
2802 :
2803 : Word16 i, fac, negfac, s;
2804 115200 : Word16 L2 = l, R2 = r;
2805 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
2806 : Word16 fac_e;
2807 : (void) element_mode;
2808 115200 : L2 = shr( l, 1 );
2809 115200 : R2 = shr( r, 1 );
2810 :
2811 115200 : x_e = sub( 15, x_e );
2812 115200 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
2813 115200 : x_e = sub( 15, x_e );
2814 :
2815 115200 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
2816 115200 : x_e = add( x_e, fac_e );
2817 :
2818 115200 : negfac = negate( fac );
2819 :
2820 115200 : IF( allow_qwin_change )
2821 : {
2822 : // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
2823 : // q_win = L_norm_arr(tmp_buf, , *q_win ) - x_e;
2824 46950 : s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
2825 46950 : *q_win = s_min( sub( s, x_e ), *q_win );
2826 : }
2827 :
2828 115200 : s = add( x_e, *q_win );
2829 115200 : move16();
2830 :
2831 9344928 : FOR( i = 0; i < R2; i++ )
2832 : {
2833 9229728 : y[l + m + R2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT exp(fac_e)*/
2834 :
2835 9229728 : move16();
2836 : }
2837 :
2838 9015524 : FOR( i = 0; i < L2; i++ )
2839 : {
2840 8900324 : y[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT exp(fac_e)*/
2841 8900324 : move16();
2842 : }
2843 :
2844 17609024 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
2845 : {
2846 : Word16 f;
2847 :
2848 17493824 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
2849 17493824 : y[L2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
2850 17493824 : move16();
2851 17493824 : y[l + m + R2 - 1 - i] = f;
2852 17493824 : move16();
2853 : }
2854 115200 : }
2855 :
2856 20 : static void TCX_MDST_Inverse_qwin_fx(
2857 : Word32 *x, /* exp(x_e) */
2858 : Word16 x_e,
2859 : Word16 *y, /* Qx */
2860 : const Word16 l, /* Q0 */
2861 : const Word16 m, /* Q0 */
2862 : const Word16 r, /* Q0 */
2863 : Word16 *q_win,
2864 : Word16 allow_qwin_change )
2865 : {
2866 :
2867 : Word16 i, fac, negfac, s;
2868 20 : Word16 L2 = l, R2 = r;
2869 20 : move16();
2870 20 : move16();
2871 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
2872 : Word16 fac_e;
2873 :
2874 20 : L2 = shr( l, 1 );
2875 20 : R2 = shr( r, 1 );
2876 :
2877 20 : x_e = sub( 15, x_e );
2878 20 : edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
2879 20 : x_e = sub( 15, x_e );
2880 :
2881 20 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
2882 20 : x_e = add( x_e, fac_e );
2883 :
2884 20 : negfac = negate( fac );
2885 :
2886 20 : IF( allow_qwin_change )
2887 : {
2888 : // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
2889 : // q_win = L_norm_arr(tmp_buf, , *q_win ) - x_e;
2890 8 : s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
2891 8 : *q_win = s_min( sub( s, x_e ), *q_win );
2892 : }
2893 :
2894 20 : s = add( x_e, *q_win );
2895 20 : move16();
2896 :
2897 934 : FOR( i = 0; i < R2; i++ )
2898 : {
2899 914 : y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) ); /* fold out right end of DCT exp(fac_e)*/
2900 914 : move16();
2901 : }
2902 :
2903 934 : FOR( i = 0; i < L2; i++ )
2904 : {
2905 914 : y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], negfac ), s ) ); /* negate, fold out left end of DCT exp(fac_e)*/
2906 914 : move16();
2907 : }
2908 :
2909 1556 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
2910 : {
2911 : Word16 f;
2912 1536 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
2913 :
2914 1536 : y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
2915 1536 : move16();
2916 :
2917 1536 : y[l + m + R2 - 1 - i] = negate( f );
2918 1536 : move16();
2919 : }
2920 20 : }
2921 :
2922 : /*-------------------------------------------------------------------*
2923 : * TCX_MDXT_Inverse_fx()
2924 : *
2925 : *
2926 : *-------------------------------------------------------------------*/
2927 62 : static void TCX_MDXT_Inverse_qwin_fx(
2928 : const Word32 *x, /* exp(x_e) */
2929 : Word16 x_e,
2930 : Word16 *y, /* Qx */
2931 : const Word16 l, /* Q0 */
2932 : const Word16 m, /* Q0 */
2933 : const Word16 r, /* Q0 */
2934 : const UWord16 kernel_type, /* Q0 */
2935 : Word16 *q_win,
2936 : Word16 allow_qwin_change )
2937 : {
2938 : Word16 signLeft;
2939 : Word16 signRight;
2940 : Word16 i, fac, negfac, s, fac_e;
2941 62 : const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
2942 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
2943 : Word16 f;
2944 :
2945 62 : set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
2946 :
2947 62 : edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
2948 :
2949 62 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
2950 62 : x_e = add( x_e, fac_e );
2951 :
2952 62 : negfac = negate( fac );
2953 62 : IF( GE_16( kernel_type, MDCT_II ) )
2954 : {
2955 46 : signLeft = negfac;
2956 : }
2957 : ELSE
2958 : {
2959 16 : signLeft = fac;
2960 : }
2961 : // signRight = ( kernel_type & 1 ? fac : negfac );
2962 62 : IF( L_and( kernel_type, 1 ) )
2963 : {
2964 16 : signRight = fac;
2965 : }
2966 : ELSE
2967 : {
2968 46 : signRight = negfac;
2969 : }
2970 :
2971 62 : IF( allow_qwin_change )
2972 : {
2973 : // x_e + q_win == L_norm_arr(tmp_buf, , *q_win );
2974 : // q_win = L_norm_arr(tmp_buf, , *q_win ) - x_e;
2975 24 : s = L_norm_arr( tmp_buf + L2, m + R2 + L2 );
2976 24 : *q_win = s_min( sub( s, x_e ), *q_win );
2977 : }
2978 :
2979 62 : s = add( x_e, *q_win );
2980 62 : move16();
2981 :
2982 3424 : FOR( i = 0; i < L2; i++ )
2983 : {
2984 3362 : y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], signLeft ), s ) ); /* fold out the left end exp(fac_e)*/
2985 : }
2986 :
2987 3464 : FOR( i = 0; i < R2; i++ )
2988 : {
2989 3402 : y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], signRight ), s ) ); /* ...and right end exp(fac_e)*/
2990 3402 : move16();
2991 : }
2992 :
2993 4750 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
2994 : {
2995 :
2996 4688 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
2997 :
2998 4688 : y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
2999 4688 : move16();
3000 :
3001 4688 : y[l + m + R2 - 1 - i] = f;
3002 4688 : move16();
3003 : }
3004 :
3005 62 : return;
3006 : }
3007 :
3008 1693434 : void IMDCT_ivas_fx(
3009 : Word32 *x_fx, // Q(q_x)
3010 : Word16 q_x,
3011 : Word16 *old_syn_overl_fx, // *Q_old_syn_overl_fx
3012 : Word16 *Q_old_syn_overl_fx,
3013 : Word16 *syn_Overl_TDAC_fx, // *Q_syn_Overl_TDAC_fx
3014 : Word16 *Q_syn_Overl_TDAC_fx,
3015 : Word16 *xn_buf_fx, // Q(-2)
3016 : Word16 q_xn_buf_fx,
3017 : const Word16 *tcx_aldo_window_1_fx, // Q(15)
3018 : const PWord16 *tcx_aldo_window_1_trunc_fx, // Q(15)
3019 : const PWord16 *tcx_aldo_window_2_fx, // Q(15)
3020 : const PWord16 *tcx_mdct_window_half_fx, // Q(15)
3021 : const PWord16 *tcx_mdct_window_minimum_fx, // Q(15)
3022 : const PWord16 *tcx_mdct_window_trans_fx, // Q(15)
3023 : const Word16 tcx_mdct_window_half_length, // Q(15)
3024 : const Word16 tcx_mdct_window_min_length, // Q(15)
3025 : Word16 index,
3026 : const UWord16 kernel_type, /* i : TCX transform kernel type */
3027 : const Word16 left_rect,
3028 : const Word16 tcx_offset,
3029 : const Word16 overlap,
3030 : const Word16 L_frame,
3031 : const Word16 L_frameTCX,
3032 : const Word16 L_spec_TCX5,
3033 : const Word16 L_frame_glob,
3034 : const Word16 frame_cnt,
3035 : const Word16 bfi,
3036 : Word16 *old_out_fx, // Q(-2)
3037 : Word16 *q_old_out_fx,
3038 : const Word16 FB_flag,
3039 : Decoder_State *st,
3040 : const Word16 fullbandScale,
3041 : Word16 *acelp_zir_fx,
3042 : Word16 *q_acelp_zir_fx,
3043 : Word16 *pq_win )
3044 : {
3045 : Word16 i, nz, aldo, w, L_win, L_ola;
3046 : Word16 win_fx[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
3047 1693434 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
3048 1693434 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
3049 : Word16 x_e_hdrm;
3050 : Word32 c;
3051 : Word16 exp;
3052 1693434 : Word16 q_win = *pq_win;
3053 1693434 : Word16 allow_qwin_change = 1;
3054 1693434 : move16();
3055 1693434 : move16();
3056 1693434 : x_e_hdrm = sub( Q16, q_x );
3057 : #if 0
3058 : IF( *pq_win == 0 )
3059 : {
3060 : allow_qwin_change = 0;
3061 : }
3062 : #endif
3063 1693434 : IF( allow_qwin_change )
3064 : {
3065 : // q_win = IMDCT_ivas_fx_adjust_qwin( *Q_syn_Overl_TDAC_fx, *Q_old_syn_overl_fx, hTcxDec->Q_old_syn_Overl, *q_old_out_fx, q_win );
3066 1693434 : q_win = IMDCT_ivas_fx_calc_qwin( st, syn_Overl_TDAC_fx, *Q_syn_Overl_TDAC_fx, old_syn_overl_fx, *Q_old_syn_overl_fx,
3067 1693434 : hTcxDec->old_syn_Overl, hTcxDec->Q_old_syn_Overl, old_out_fx, *q_old_out_fx, q_win, FB_flag );
3068 : }
3069 :
3070 1693434 : aldo = 0;
3071 1693434 : move16();
3072 :
3073 1693434 : c = L_mult0( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), L_frame );
3074 1693434 : exp = 0;
3075 1693434 : move16();
3076 1693434 : nz = BASOP_Util_Divide3216_Scale( c, L_frameTCX, &exp );
3077 1693434 : exp = add( exp, ( 31 - 15 ) );
3078 1693434 : nz = shr( nz, sub( 15, exp ) ); // Q0
3079 :
3080 1693434 : test();
3081 1693434 : test();
3082 1693434 : test();
3083 1693434 : test();
3084 1693434 : test();
3085 1693434 : test();
3086 1693434 : IF( st->element_mode != EVS_MONO && ( frame_cnt == 0 ) && ( bfi == 0 ) && ( st->prev_bfi != 0 ) && ( EQ_16( st->last_core_bfi, TCX_20_CORE ) || EQ_16( st->last_core_bfi, TCX_10_CORE ) ) && ( hTcxCfg->last_aldo == 0 ) )
3087 : {
3088 : Word32 fac;
3089 : // fac = shl_sat( mult_r( extract_h( L_shr_sat( hTcxDec->conceal_eof_gain32, sub( 1, hTcxDec->conceal_eof_gain_e ) ) ), st->last_concealed_gain_syn_deemph ), 1 );
3090 30 : fac = Mpy_32_16_1( hTcxDec->conceal_eof_gain32, st->last_concealed_gain_syn_deemph ); // q = 31 - hTcxDec->conceal_eof_gain_e - last_concealed_gain_syn_deemph_e
3091 30 : Word16 eff_e = add( hTcxDec->conceal_eof_gain_e, st->last_concealed_gain_syn_deemph_e );
3092 6442 : FOR( Word16 ind = 0; ind < overlap; ind++ )
3093 : {
3094 6412 : old_syn_overl_fx[ind] = extract_h( L_shl_sat( Mpy_32_16_1( fac, old_syn_overl_fx[ind] ), eff_e ) ); // Q(-2)
3095 6412 : move16();
3096 : }
3097 : }
3098 :
3099 1693434 : test();
3100 1693434 : IF( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && st->tcxonly )
3101 : {
3102 : /* Mode decision in PLC
3103 :
3104 : last OL curr OL left TCX-10 right TCX-10
3105 : -------------------------------------------------------------
3106 : 0 0 2x TCX-5* 1x TCX-10
3107 : 0 2 1x TCX-10 1x TCX-10
3108 : 0 3 1x TCX-10 1x TCX-10
3109 : 2 0 2x TCX-5 1x TCX-10
3110 : 2 2 2x TCX-5 2x TCX-5
3111 : 2 3 2x TCX-5 2x TCX-5
3112 : 3 0 2x TCX-5 1x TCX-10
3113 : 3 2 2x TCX-5 2x TCX-5
3114 : 3 3 2x TCX-5 2x TCX-5
3115 : */
3116 64528 : test();
3117 64528 : test();
3118 64528 : test();
3119 64528 : test();
3120 64528 : test();
3121 64528 : test();
3122 64528 : IF( ( ( bfi == 0 ) && NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) || ( ( bfi != 0 ) && NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) && NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
3123 18436 : {
3124 : /* minimum or half overlap, two transforms, grouping into one window */
3125 18436 : L_win = shr( L_frame, 1 );
3126 : // L_ola = EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ? tcx_mdct_window_min_length : tcx_mdct_window_half_length;
3127 18436 : IF( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
3128 : {
3129 8046 : L_ola = tcx_mdct_window_min_length;
3130 : }
3131 : ELSE
3132 : {
3133 10390 : L_ola = tcx_mdct_window_half_length;
3134 : }
3135 18436 : move16();
3136 :
3137 18436 : set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 );
3138 18436 : Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) );
3139 18436 : set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */
3140 :
3141 18436 : Word16 L_spec_TCX5_tmp = 0;
3142 18436 : move16();
3143 18436 : IF( allow_qwin_change )
3144 : {
3145 : /* Use fixed q_win to avoid the need to adapt scaling of two TCX5 blocks (less effort with maybe not ideal scaling) */
3146 18436 : q_win = -2;
3147 18436 : move16();
3148 18436 : allow_qwin_change = 0;
3149 18436 : move16();
3150 : }
3151 :
3152 55308 : FOR( w = 0; w < 2; w++ )
3153 : {
3154 36872 : test();
3155 36872 : test();
3156 36872 : L_spec_TCX5_tmp = imult1616( w, L_spec_TCX5 );
3157 : // Assume that xn_buf_fx has no headroom.
3158 36872 : q_win = s_min( q_xn_buf_fx, q_win );
3159 :
3160 36872 : IF( EQ_16( kernel_type, MDST_IV ) || s_and( kernel_type, w ) )
3161 : {
3162 8 : TCX_MDST_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, &q_win, allow_qwin_change );
3163 : }
3164 36864 : ELSE IF( ( kernel_type != 0 ) && ( w == 0 ) ) /* type 1 or 2 */
3165 : {
3166 34 : TCX_MDXT_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, kernel_type, &q_win, allow_qwin_change );
3167 : }
3168 : ELSE
3169 : {
3170 36830 : TCX_MDCT_Inverse_qwin_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode, &q_win, allow_qwin_change );
3171 : }
3172 :
3173 36872 : IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3174 :
3175 36872 : tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : (Word8) st->last_is_cng, fullbandScale );
3176 :
3177 36872 : IF( w > 0 )
3178 : {
3179 : Word16 tmp;
3180 18436 : tmp = add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) );
3181 18436 : tcx_windowing_synthesis_past_frame( xn_buf_fx + tmp, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, MIN_OVERLAP );
3182 : }
3183 :
3184 : /* add part of current sub-window overlapping with previous window */
3185 36872 : v_add_16( win_fx, xn_buf_fx + add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) ), xn_buf_fx + add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) ), L_ola );
3186 :
3187 : /* copy new sub-window region not overlapping with previous window */
3188 36872 : Copy( win_fx + L_ola, xn_buf_fx + add( tcx_offset, add( shr( L_ola, 1 ), imult1616( w, L_win ) ) ), L_win );
3189 : }
3190 :
3191 : /* To assure that no garbage values are passed to overlap */
3192 18436 : set16_fx( xn_buf_fx + add( L_frame, add( tcx_offset, shr( L_ola, 1 ) ) ), 0, sub( overlap, add( tcx_offset, shr( L_ola, 1 ) ) ) );
3193 18436 : test();
3194 18436 : test();
3195 18436 : test();
3196 18436 : IF( ( st->prev_bfi != 0 ) && ( frame_cnt == 0 ) && NE_16( st->last_core, st->last_core_bfi ) && EQ_16( st->last_core_bfi, ACELP_CORE ) )
3197 : {
3198 2 : tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode );
3199 2 : v_add_16( xn_buf_fx, old_syn_overl_fx, xn_buf_fx, overlap );
3200 : }
3201 : }
3202 46092 : ELSE IF( ( bfi == 0 ) && ( frame_cnt == 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
3203 15054 : {
3204 : /* special overlap attempt, two transforms, grouping into one window */
3205 15054 : L_win = shr( L_frame, 1 );
3206 15054 : L_ola = tcx_mdct_window_min_length;
3207 15054 : move16();
3208 :
3209 15054 : set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) );
3210 :
3211 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
3212 : Word16 q_win_prev;
3213 :
3214 : #if 0
3215 : // Assume that xn_buf_fx has no headroom.
3216 : q_win = s_min( q_xn_buf_fx, q_win );
3217 : #endif
3218 15054 : IF( allow_qwin_change )
3219 : {
3220 : /* Use fixed q_win to avoid the need to adapt scaling of two TCX5 blocks (less effort with maybe not ideal scaling) */
3221 15054 : q_win = -2;
3222 15054 : move16();
3223 15054 : allow_qwin_change = 0;
3224 15054 : move16();
3225 : }
3226 :
3227 15054 : IF( EQ_16( kernel_type, MDST_IV ) )
3228 : {
3229 0 : TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, &q_win, allow_qwin_change );
3230 : }
3231 15054 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
3232 : {
3233 4 : TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, kernel_type, &q_win, allow_qwin_change );
3234 : }
3235 : ELSE
3236 : {
3237 15050 : TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode, &q_win, allow_qwin_change );
3238 : }
3239 15054 : q_win_prev = q_win;
3240 :
3241 15054 : set16_fx( xn_buf_fx, 0, shr( overlap, 1 ) );
3242 :
3243 : /* copy new sub-window region not overlapping with previous window */
3244 15054 : Copy( win_fx + L_win, xn_buf_fx + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
3245 :
3246 15054 : q_xn_buf_fx = q_win;
3247 15054 : move16();
3248 :
3249 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
3250 15054 : IF( s_and( kernel_type, 1 ) )
3251 : {
3252 4 : TCX_MDST_Inverse_qwin_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, &q_win, allow_qwin_change );
3253 : }
3254 : ELSE
3255 : {
3256 15050 : TCX_MDCT_Inverse_qwin_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode, &q_win, allow_qwin_change );
3257 : }
3258 :
3259 15054 : assert( q_win_prev == q_win );
3260 :
3261 15054 : IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3262 :
3263 15054 : tcx_windowing_synthesis_current_frame( win_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 0,
3264 15054 : /* left_rect */ MIN_OVERLAP, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, L_win, ( tcx_offset < 0 ) ? -tcx_offset : 0, 1, /* st->last_mode_bfi */ 0, /* st->last_is_cng */ fullbandScale );
3265 :
3266 15054 : tcx_windowing_synthesis_past_frame( xn_buf_fx + shr( overlap, 1 ) + sub( L_win, shr( L_ola, 1 ) ), tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, 2 );
3267 :
3268 : /* add part of current sub-window overlapping with previous window */
3269 15054 : v_add_16( win_fx, xn_buf_fx + add( shr( overlap, 1 ), sub( L_win, shr( L_ola, 1 ) ) ), xn_buf_fx + sub( add( shr( overlap, 1 ), L_win ), shr( L_ola, 1 ) ), L_ola );
3270 :
3271 : /* copy new sub-window region not overlapping with previous window */
3272 15054 : Copy( win_fx + L_ola, xn_buf_fx + add( add( shr( overlap, 1 ), L_win ), shr( L_ola, 1 ) ), L_win );
3273 :
3274 : /* extra folding-out on left side of win, for perfect reconstruction */
3275 15054 : IF( GE_16( kernel_type, MDCT_II ) )
3276 : {
3277 0 : FOR( w = overlap / 2; w < overlap; w++ )
3278 : {
3279 0 : xn_buf_fx[overlap - 1 - w] = xn_buf_fx[w];
3280 0 : move16();
3281 : }
3282 : }
3283 : ELSE
3284 : {
3285 2321162 : FOR( w = overlap / 2; w < overlap; w++ )
3286 : {
3287 2306108 : xn_buf_fx[overlap - 1 - w] = negate( xn_buf_fx[w] );
3288 2306108 : move16();
3289 : }
3290 : }
3291 15054 : tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, 0, /* left_mode */ acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shl( L_win, 1 ), ( tcx_offset < 0 ) ? -tcx_offset : 0, st->last_core_bfi, (Word8) st->last_is_cng, fullbandScale );
3292 : }
3293 : ELSE
3294 : {
3295 : /* default, i.e. maximum overlap, single transform, no grouping */
3296 31038 : IF( allow_qwin_change && fullbandScale )
3297 : {
3298 15519 : q_win = s_min( q_win, norm_arr( acelp_zir_fx, shr( L_frame_glob, 1 ) ) + *q_acelp_zir_fx );
3299 : }
3300 :
3301 31038 : IF( EQ_16( kernel_type, MDST_IV ) )
3302 : {
3303 8 : TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, &q_win, allow_qwin_change );
3304 : }
3305 31030 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
3306 : {
3307 24 : TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, kernel_type, &q_win, allow_qwin_change );
3308 : }
3309 : ELSE
3310 : {
3311 31006 : TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, st->element_mode, &q_win, allow_qwin_change );
3312 : }
3313 : // Because xn_buf_fx is overwritten above.
3314 31038 : q_xn_buf_fx = q_win;
3315 31038 : move16();
3316 :
3317 31038 : IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3318 :
3319 31038 : IF( !fullbandScale )
3320 : {
3321 15519 : *q_acelp_zir_fx = q_xn_buf_fx;
3322 : }
3323 : ELSE
3324 : {
3325 15519 : scale_sig( acelp_zir_fx, shr( L_frame_glob, 1 ), sub( q_xn_buf_fx, *q_acelp_zir_fx ) );
3326 : }
3327 31038 : tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, !bfi && ( frame_cnt > 0 ) && ( index == 0 ) && NE_16( st->last_core, ACELP_CORE ) ? MIN_OVERLAP : index, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr( L_frame_glob, 1 ), ( tcx_offset < 0 ) ? -tcx_offset : 0, ( frame_cnt > 0 /*|| (st->last_con_tcx )*/ ) ? 1 : st->last_core_bfi, ( frame_cnt > 0 ) ? 0 : (Word8) st->last_is_cng, fullbandScale );
3328 :
3329 : } /* tcx_last_overlap_mode != FULL_OVERLAP */
3330 : }
3331 : ELSE
3332 : {
3333 : /* frame is TCX-20 or not TCX-only */
3334 1628906 : assert( frame_cnt == 0 );
3335 1628906 : IF( NE_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
3336 : {
3337 :
3338 : Word16 q_tmp_fx_32, q_xn_buf_fx_32;
3339 1611642 : q_tmp_fx_32 = 15;
3340 1611642 : q_xn_buf_fx_32 = q_x;
3341 1611642 : move16();
3342 1611642 : move16();
3343 : Word32 xn_buf_fx_32[2000], tmp_fx_32[1200], old_out_fx_32[1200];
3344 1611642 : set32_fx( xn_buf_fx_32, 0, 2000 );
3345 1611642 : IF( NE_16( kernel_type, MDCT_IV ) ) /* inverse transform */
3346 : {
3347 1586 : Word16 tmp_a = add( shr( overlap, 1 ), nz );
3348 1586 : IF( EQ_16( kernel_type, MDST_IV ) )
3349 : {
3350 600 : edst_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, &q_xn_buf_fx_32 );
3351 : }
3352 : ELSE /* type 1 or 2 */
3353 : {
3354 986 : edxt_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, kernel_type, TRUE );
3355 : }
3356 :
3357 : Word16 res_m, res_e;
3358 1586 : res_e = 0;
3359 1586 : move16();
3360 1586 : res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
3361 1586 : res_m = Sqrt16( res_m, &res_e );
3362 :
3363 788338 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3364 : {
3365 786752 : tmp_fx_32[ind] = L_shl( Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m ), res_e );
3366 786752 : move32();
3367 : }
3368 1586 : q_tmp_fx_32 = q_xn_buf_fx_32;
3369 1586 : move16();
3370 :
3371 : // q_win < norm + q_tmp_fx_32 - 16
3372 1586 : q_win = s_min( q_win, L_norm_arr( tmp_fx_32, L_frame ) + q_tmp_fx_32 - 16 );
3373 1586 : IMDCT_ivas_fx_rescale( NULL, NULL, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3374 :
3375 1586 : Word16 diff = sub( q_tmp_fx_32, q_win );
3376 1586 : Word16 q_old_out_diff = sub( q_tmp_fx_32, *q_old_out_fx );
3377 1586 : IF( q_old_out_diff < 0 )
3378 : {
3379 0 : Scale_sig( old_out_fx, L_frame, q_old_out_diff );
3380 0 : *q_old_out_fx = add( *q_old_out_fx, q_old_out_diff );
3381 0 : q_old_out_diff = 0;
3382 : }
3383 788338 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3384 : {
3385 786752 : assert( L_shr( L_shl( old_out_fx[ind], q_old_out_diff ), q_old_out_diff ) == old_out_fx[ind] );
3386 786752 : old_out_fx_32[ind] = L_shl( L_deposit_l( old_out_fx[ind] ), q_old_out_diff );
3387 786752 : move32();
3388 : }
3389 :
3390 1586 : window_ola_ext_fx( tmp_fx_32, xn_buf_fx_32, old_out_fx_32, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, kernel_type );
3391 :
3392 788338 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3393 : {
3394 786752 : assert( extract_h( L_shr( old_out_fx_32[ind], q_old_out_diff ) ) == 0 || extract_h( L_shr( old_out_fx_32[ind], q_old_out_diff ) ) == -1 );
3395 786752 : old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], q_old_out_diff ) );
3396 786752 : assert( extract_h( L_shr( xn_buf_fx_32[ind], diff ) ) == 0 || extract_h( L_shr( xn_buf_fx_32[ind], diff ) ) == -1 );
3397 786752 : xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) );
3398 786752 : move16();
3399 786752 : move16();
3400 : }
3401 : }
3402 : ELSE
3403 : {
3404 1610056 : edct_ivas_fx( x_fx, xn_buf_fx_32 + add( shr( overlap, 1 ), nz ), L_frame, &q_xn_buf_fx_32 );
3405 : Word16 res_m, res_e;
3406 1610056 : res_e = 0;
3407 1610056 : move16();
3408 1610056 : res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
3409 1610056 : res_m = Sqrt16( res_m, &res_e );
3410 :
3411 1103394952 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3412 : {
3413 1101784896 : tmp_fx_32[ind] = Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m );
3414 1101784896 : move32();
3415 : }
3416 1610056 : q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e );
3417 : // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame );
3418 :
3419 1610056 : if ( allow_qwin_change )
3420 : {
3421 : // sub( q_xn_buf_fx_32, q_win ) == 16 - L_norm_arr( xn_buf_fx_32, L_frame )
3422 : // q_xn_buf_fx_32 - q_win == 16 - L_norm_arr( xn_buf_fx_32, L_frame )
3423 : // q_win == - 16 + L_norm_arr( xn_buf_fx_32, L_frame ) + q_xn_buf_fx_32
3424 1610056 : q_win = s_min( q_win, add( sub( q_xn_buf_fx_32, 16 ), sub( L_norm_arr( xn_buf_fx_32 + ( overlap / 2 ) + nz, L_frame ), 2 ) ) );
3425 : }
3426 1610056 : IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3427 :
3428 1610056 : Word16 q_diff = sub( q_xn_buf_fx_32, q_win );
3429 1103394952 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3430 : {
3431 1101784896 : assert( extract_h( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ) == 0 || extract_h( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) ) == -1 );
3432 1101784896 : xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) );
3433 1101784896 : move16();
3434 : }
3435 :
3436 1610056 : window_ola_fx( tmp_fx_32, xn_buf_fx, &q_tmp_fx_32, old_out_fx, q_old_out_fx, L_frame, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, 0, 0, NULL );
3437 1610056 : if ( allow_qwin_change )
3438 : {
3439 : // sub( q_tmp_fx_32, q_win ) == -norm_arr( xn_buf_fx, L_frame )
3440 : // q_tmp_fx_32 - q_win == -norm_arr( xn_buf_fx, L_frame )
3441 : // q_win == q_tmp_fx_32 + norm_arr( xn_buf_fx, L_frame )
3442 1610056 : q_win = s_min( q_win, add( q_tmp_fx_32, norm_arr( xn_buf_fx, L_frame ) ) );
3443 : }
3444 1610056 : Word16 diff = sub( q_tmp_fx_32, q_win );
3445 1103394952 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
3446 : {
3447 1101784896 : xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff );
3448 1101784896 : move16();
3449 : }
3450 : }
3451 1611642 : aldo = 1;
3452 1611642 : move16();
3453 : }
3454 : ELSE
3455 : {
3456 : // Word16 acelp_mem_len = tcx_offset < 0 ? -tcx_offset : 0;
3457 : Word16 acelp_mem_len;
3458 :
3459 17264 : IF( tcx_offset < 0 )
3460 : {
3461 17264 : acelp_mem_len = negate( tcx_offset );
3462 : }
3463 : ELSE
3464 : {
3465 0 : acelp_mem_len = 0;
3466 0 : move16();
3467 : }
3468 :
3469 17264 : IF( allow_qwin_change && fullbandScale )
3470 : {
3471 8632 : q_win = s_min( q_win, norm_arr( acelp_zir_fx, shr( L_frame_glob, 1 ) ) + *q_acelp_zir_fx );
3472 : }
3473 17264 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st->last_core_brate, SID_2k40 ) || st->last_core == ACELP_CORE ) && ( fullbandScale == 0 ) )
3474 : {
3475 : /* Increase headroom because if the ACELP ZIR is used below, the synthesis filter gain is unknown. */
3476 1320 : IF( allow_qwin_change )
3477 : {
3478 1320 : allow_qwin_change = 0;
3479 1320 : move16();
3480 1320 : q_win = s_max( -2, sub( q_win, 1 ) );
3481 : }
3482 : }
3483 :
3484 17264 : IF( EQ_16( kernel_type, MDST_IV ) )
3485 : {
3486 0 : TCX_MDST_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, &q_win, allow_qwin_change );
3487 : }
3488 17264 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
3489 : {
3490 0 : TCX_MDXT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, kernel_type, &q_win, allow_qwin_change );
3491 : }
3492 : ELSE
3493 : {
3494 17264 : TCX_MDCT_Inverse_qwin_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, st->element_mode, &q_win, allow_qwin_change );
3495 : }
3496 : // Because xn_buf_fx is overwritten above.
3497 17264 : q_xn_buf_fx = q_win;
3498 17264 : move16();
3499 :
3500 17264 : IMDCT_ivas_fx_rescale( xn_buf_fx, &q_xn_buf_fx, syn_Overl_TDAC_fx, Q_syn_Overl_TDAC_fx, old_syn_overl_fx, Q_old_syn_overl_fx, hTcxDec->old_syn_Overl, &hTcxDec->Q_old_syn_Overl, old_out_fx, q_old_out_fx, q_win, FB_flag );
3501 : /*-----------------------------------------------------------*
3502 : * Windowing, overlap and add *
3503 : *-----------------------------------------------------------*/
3504 17264 : test();
3505 17264 : test();
3506 17264 : test();
3507 17264 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( LE_32( st->last_core_brate, SID_2k40 ) || st->last_core == ACELP_CORE ) && ( fullbandScale == 0 ) )
3508 : {
3509 : /* get LPC from that signal part to use for acelp zir smoothing */
3510 1320 : const Word16 analysis_len = shr( L_frame_glob, 2 );
3511 : Word16 buf_fx[L_FRAME_MAX / 4];
3512 : Word16 window_buf_fx[L_FRAME_MAX / 4];
3513 : Word32 r_fx[M + 1];
3514 : Word16 q_r, q_buf;
3515 :
3516 : /* get the first 5 ms of non-aliased TCX syntesis */
3517 1320 : Copy( xn_buf_fx + add( shr( overlap, 1 ), shl( acelp_mem_len, 1 ) ), &buf_fx[0], analysis_len );
3518 :
3519 1320 : q_buf = q_win;
3520 1320 : move16();
3521 :
3522 1320 : ham_cos_window_ivas( &window_buf_fx[0], shr( analysis_len, 1 ), shr( analysis_len, 1 ) );
3523 1320 : autocorr_fx_32( &buf_fx[0], M, &r_fx[0], &q_r, analysis_len, &window_buf_fx[0], 0, 0 );
3524 1320 : lag_wind_32( r_fx, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG );
3525 1320 : lev_dur_fx( &st->old_Aq_12_8_fx_32[0], &r_fx[0], M, NULL, 28 /*Q(st->q_old_Aq_12_8_fx_32)*/, add( add( shl( q_buf, 1 ), q_r ), 1 ) );
3526 23760 : FOR( Word16 ind = 0; ind <= M; ind++ )
3527 : {
3528 22440 : st->old_Aq_12_8_fx[ind] = (Word16) L_shr( st->old_Aq_12_8_fx_32[ind], 16 ); // Q28 -> Q12
3529 22440 : move16();
3530 : }
3531 : }
3532 17264 : IF( !fullbandScale )
3533 : {
3534 8632 : *q_acelp_zir_fx = q_xn_buf_fx;
3535 : }
3536 : ELSE
3537 : {
3538 8632 : scale_sig( acelp_zir_fx, shr( L_frame_glob, 1 ), sub( q_xn_buf_fx, *q_acelp_zir_fx ) );
3539 : }
3540 : /* Window current frame */
3541 17264 : tcx_windowing_synthesis_current_frame( xn_buf_fx, tcx_aldo_window_2_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, left_rect, hTcxCfg->tcx_last_overlap_mode, acelp_zir_fx, hTcxDec->old_syn_Overl, syn_Overl_TDAC_fx, st->old_Aq_12_8_fx, tcx_mdct_window_trans_fx, shr( L_frame_glob, 1 ), acelp_mem_len, st->last_core_bfi, (Word8) st->last_is_cng, fullbandScale );
3542 : }
3543 : } /* TCX-20 and TCX-only */
3544 1693434 : test();
3545 1693434 : IF( ( frame_cnt != 0 ) || GT_16( st->last_core_bfi, ACELP_CORE ) )
3546 : {
3547 1661590 : test();
3548 1661590 : test();
3549 1661590 : IF( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( st->tcxonly != 0 ) ) ||
3550 : EQ_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
3551 : {
3552 57210 : test();
3553 57210 : test();
3554 57210 : test();
3555 57210 : test();
3556 57210 : if ( ( bfi == 0 ) && ( frame_cnt > 0 ) && ( index == 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && NE_16( st->last_core, ACELP_CORE ) )
3557 : {
3558 15054 : index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */
3559 15054 : move16();
3560 : }
3561 :
3562 57210 : IF( hTcxCfg->last_aldo != 0 )
3563 : {
3564 6063802 : FOR( i = 0; i < sub( overlap, tcx_mdct_window_min_length ); i++ )
3565 : {
3566 6040224 : xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )], old_out_fx[( i + nz )] ); // Q(-2)
3567 6040224 : move16();
3568 : }
3569 :
3570 : /* fade truncated ALDO window */
3571 23578 : test();
3572 23578 : test();
3573 23578 : test();
3574 23578 : IF( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( frame_cnt == 0 ) && EQ_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) )
3575 : {
3576 : // tested
3577 649006 : FOR( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */
3578 : {
3579 634084 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], old_out_fx[( i + nz )] ); // q_win
3580 634084 : move16();
3581 : }
3582 331964 : FOR( i = 0; i < ( tcx_mdct_window_min_length / 2 ); i++ )
3583 : {
3584 317042 : xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[i].v.re ) ); // q_win
3585 317042 : move16();
3586 : }
3587 331964 : FOR( ; i < tcx_mdct_window_min_length; i++ )
3588 : {
3589 317042 : xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )] = add_sat( xn_buf_fx[( ( ( i + ( overlap / 2 ) ) - tcx_offset ) + overlap )], mult_r( old_out_fx[( ( i + nz ) + overlap )], tcx_mdct_window_minimum_fx[( tcx_mdct_window_min_length - ( 1 + i ) )].v.im ) ); // q_win
3590 317042 : move16();
3591 : }
3592 : }
3593 : ELSE
3594 : {
3595 194966 : FOR( ; i < ( overlap - ( tcx_mdct_window_min_length / 2 ) ); i++ )
3596 : {
3597 186310 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( ( tcx_mdct_window_min_length - overlap ) + i )].v.re ) ); // Q(-2)
3598 186310 : move16();
3599 : }
3600 194966 : FOR( ; i < overlap; i++ )
3601 : {
3602 186310 : xn_buf_fx[( i + ( ( overlap / 2 ) - tcx_offset ) )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_out_fx[( i + nz )], tcx_mdct_window_minimum_fx[( overlap - ( 1 + i ) )].v.im ) ); // Q(-2)
3603 186310 : move16();
3604 : }
3605 : }
3606 : }
3607 : ELSE
3608 : {
3609 33632 : tcx_windowing_synthesis_past_frame( old_syn_overl_fx, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( ( index == 0 ) || EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) ? hTcxCfg->tcx_last_overlap_mode : index );
3610 :
3611 33632 : IF( bfi != 0 )
3612 : {
3613 7730 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
3614 : {
3615 7566 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
3616 7566 : move16();
3617 : }
3618 7730 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3619 : {
3620 7566 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( old_syn_overl_fx[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
3621 7566 : move16();
3622 : }
3623 : }
3624 33468 : ELSE IF( left_rect == 0 )
3625 : {
3626 10090368 : FOR( i = 0; i < overlap; i++ )
3627 : {
3628 10056900 : xn_buf_fx[i] = add_sat( xn_buf_fx[i], old_syn_overl_fx[i] ); // Q(-2)
3629 10056900 : move16();
3630 : }
3631 : }
3632 : ELSE
3633 : {
3634 0 : FOR( i = 0; i < overlap; i++ )
3635 : {
3636 0 : xn_buf_fx[( i + ( overlap / 2 ) )] = add_sat( xn_buf_fx[( i + ( overlap / 2 ) )], old_syn_overl_fx[i] ); // Q(-2)
3637 0 : move16();
3638 : }
3639 : }
3640 : }
3641 : }
3642 : }
3643 1693434 : test();
3644 1693434 : test();
3645 1693434 : test();
3646 1693434 : IF( ( aldo == 0 ) && ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( frame_cnt > 0 ) ) || NE_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
3647 : {
3648 : /* Compute windowed synthesis in case of switching to ALDO windows in next frame */
3649 49528 : Copy( xn_buf_fx + sub( L_frame, nz ), old_out_fx, add( nz, overlap ) );
3650 49528 : set16_fx( old_out_fx + add( nz, overlap ), 0, nz );
3651 49528 : *q_old_out_fx = q_win;
3652 49528 : tcx_windowing_synthesis_past_frame( old_out_fx + nz, tcx_aldo_window_1_trunc_fx, tcx_mdct_window_half_fx, tcx_mdct_window_minimum_fx, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_curr_overlap_mode );
3653 :
3654 : /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
3655 49528 : IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
3656 : {
3657 38190 : IF( s_and( kernel_type, 1 ) )
3658 : {
3659 1522 : FOR( i = 0; i < nz; i++ )
3660 : {
3661 1512 : old_out_fx[( ( nz + overlap ) + i )] = negate( mult_r( xn_buf_fx[( L_frame - ( 1 + i ) )], tcx_aldo_window_1_fx[( nz - ( 1 + i ) )] ) ); // Q(-2)
3662 1512 : move16();
3663 : }
3664 : }
3665 : ELSE
3666 : {
3667 6993362 : FOR( i = 0; i < nz; i++ )
3668 : {
3669 6955182 : old_out_fx[( ( nz + overlap ) + i )] = mult_r( xn_buf_fx[( L_frame - ( 1 + i ) )], tcx_aldo_window_1_fx[( nz - ( 1 + i ) )] ); // Q(-2)
3670 6955182 : move16();
3671 : }
3672 : }
3673 38190 : aldo = 1;
3674 38190 : move16();
3675 : }
3676 : }
3677 :
3678 1693434 : if ( FB_flag != 0 )
3679 : {
3680 846717 : hTcxCfg->last_aldo = aldo;
3681 846717 : move16();
3682 : }
3683 :
3684 : /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */
3685 1693434 : test();
3686 1693434 : test();
3687 1693434 : test();
3688 1693434 : IF( ( left_rect != 0 ) && ( frame_cnt == 0 ) && st->last_core_bfi == ACELP_CORE && ( st->prev_bfi != 0 ) ){
3689 194 : IF( FB_flag != 0 ){
3690 6817 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ ){
3691 6720 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[i].v.im ); // Q(-2)
3692 6720 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
3693 6720 : move16();
3694 6720 : move16();
3695 : }
3696 6817 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3697 : {
3698 6720 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.re ); // Q(-2)
3699 6720 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_OverlFB[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
3700 6720 : move16();
3701 6720 : move16();
3702 : }
3703 : }
3704 : ELSE
3705 : {
3706 3757 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
3707 : {
3708 3660 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[i].v.im );
3709 3660 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[i].v.re ), tcx_mdct_window_half_fx[i].v.re ) ); // Q(-2)
3710 3660 : move16();
3711 3660 : move16();
3712 : }
3713 3757 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3714 : {
3715 3660 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = mult_r( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.re );
3716 3660 : xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )] = add_sat( xn_buf_fx[( ( i + ( overlap / 2 ) ) - tcx_offset )], mult_r( mult_r( hTcxDec->syn_Overl[i], tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ), tcx_mdct_window_half_fx[( tcx_mdct_window_half_length - ( 1 + i ) )].v.im ) ); // Q(-2)
3717 3660 : move16();
3718 3660 : move16();
3719 : }
3720 : }
3721 : }
3722 1693434 : *pq_win = q_win;
3723 1693434 : move16();
3724 :
3725 1693434 : return;
3726 : }
3727 :
3728 2512765 : void init_tcx_info_fx(
3729 : Decoder_State *st, /* i/o: coder memory state */
3730 : const Word16 L_frame_glob, /* i : global frame length */
3731 : const Word16 L_frameTCX_glob, /* i : FB global frame length */
3732 : const Word16 frame_cnt, /* i : frame counter in the super_frame */
3733 : const Word16 bfi, /* i : bad frame indicator */
3734 : Word16 *tcx_offset, /* o : folding point offset relative to the end of the previous frame */
3735 : Word16 *tcx_offsetFB, /* o : FB folding point offset relative to the end of the previous frame*/
3736 : Word16 *L_frame, /* o : frame length */
3737 : Word16 *L_frameTCX, /* o : TCX frame length */
3738 : Word16 *left_rect, /* o : left part is rectangular */
3739 : Word16 *L_spec /* o : spectrum length */
3740 : )
3741 : {
3742 2512765 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
3743 2512765 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
3744 :
3745 : /* Init lengths */
3746 2512765 : *tcx_offset = hTcxCfg->tcx_offset;
3747 2512765 : *tcx_offsetFB = hTcxCfg->tcx_offsetFB;
3748 2512765 : move16();
3749 2512765 : move16();
3750 :
3751 2512765 : IF( bfi )
3752 : {
3753 : /* PLC: [TCX: Memory update]
3754 : * PLC: Init buffers */
3755 :
3756 27565 : assert( st->L_frame_past > 0 );
3757 27565 : *L_frame = st->L_frame_past;
3758 27565 : move16();
3759 27565 : *L_frameTCX = st->L_frameTCX_past;
3760 27565 : move16();
3761 :
3762 27565 : *left_rect = hTcxDec->prev_widow_left_rect;
3763 27565 : move16();
3764 :
3765 27565 : IF( *left_rect )
3766 : {
3767 430 : *tcx_offset = hTcxCfg->lfacNext;
3768 430 : move16();
3769 430 : *tcx_offsetFB = hTcxCfg->lfacNextFB;
3770 430 : move16();
3771 430 : *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
3772 : }
3773 : }
3774 : ELSE
3775 : {
3776 2485200 : test();
3777 2485200 : IF( frame_cnt == 0 && st->last_core == ACELP_CORE )
3778 : {
3779 12580 : if ( !st->prev_bfi )
3780 : {
3781 12355 : hTcxCfg->last_aldo = 0;
3782 12355 : move16();
3783 : }
3784 :
3785 : /* if past frame is ACELP */
3786 12580 : *L_frame = add( L_frame_glob, *tcx_offset );
3787 12580 : *L_frameTCX = add( L_frameTCX_glob, *tcx_offsetFB );
3788 12580 : move16();
3789 12580 : move16();
3790 12580 : IF( EQ_16( st->last_core, st->last_core_from_bs ) )
3791 : {
3792 : /* case: last frame was lost and concealed as CNG */
3793 : /* using the longer transition spec length causes reading of uninitialized data */
3794 12470 : *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
3795 12470 : move16();
3796 : }
3797 :
3798 12580 : assert( hTcxCfg->lfacNext <= 0 );
3799 12580 : *L_frame = sub( *L_frame, hTcxCfg->lfacNext );
3800 12580 : *L_frameTCX = sub( *L_frameTCX, hTcxCfg->lfacNextFB );
3801 12580 : *tcx_offset = hTcxCfg->lfacNext;
3802 12580 : move16();
3803 12580 : move16();
3804 12580 : move16();
3805 12580 : *tcx_offsetFB = hTcxCfg->lfacNextFB;
3806 12580 : move16();
3807 :
3808 12580 : *left_rect = 1;
3809 12580 : move16();
3810 12580 : hTcxDec->prev_widow_left_rect = 1;
3811 12580 : move16();
3812 : }
3813 : ELSE
3814 : {
3815 2472620 : *L_frame = L_frame_glob;
3816 2472620 : move16();
3817 2472620 : *L_frameTCX = L_frameTCX_glob;
3818 2472620 : move16();
3819 2472620 : *left_rect = 0;
3820 2472620 : move16();
3821 2472620 : hTcxDec->prev_widow_left_rect = 0;
3822 2472620 : move16();
3823 : }
3824 :
3825 2485200 : st->L_frame_past = *L_frame;
3826 2485200 : move16();
3827 2485200 : st->L_frameTCX_past = *L_frameTCX;
3828 2485200 : move16();
3829 : }
3830 :
3831 2512765 : IF( st->igf )
3832 : {
3833 1645121 : test();
3834 1645121 : IF( EQ_16( *L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
3835 : {
3836 75542 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_SHORT );
3837 : }
3838 : ELSE
3839 : {
3840 1569579 : test();
3841 1569579 : test();
3842 1569579 : IF( st->last_core == ACELP_CORE || ( *left_rect && st->bfi ) )
3843 : {
3844 11096 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_TRAN );
3845 : }
3846 : ELSE
3847 : {
3848 1558483 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_NORM );
3849 : }
3850 : }
3851 : }
3852 2512765 : }
3853 :
3854 :
3855 : /*-------------------------------------------------------------------*
3856 : * decoder_tcx_IGF_mono_fx()
3857 : *
3858 : * TCX: apply mono IGF
3859 : *-------------------------------------------------------------------*/
3860 :
3861 188837 : void decoder_tcx_IGF_mono_fx(
3862 : Decoder_State *st, /* i/o: coder memory state */
3863 : Word32 x_fx[], /* o : de-quatized coefficients */
3864 : Word16 *x_e, /* o : de-quatized coefficients exponent */
3865 : Word16 *x_len, /* o : de-quatized coefficients length */
3866 : const Word16 L_frame, /* i : frame length */
3867 : const Word16 left_rect, /* i : left part is rectangular */
3868 : const Word16 bfi, /* i : bad frame indicator */
3869 : const Word16 frame_cnt /* i : frame counter in the super_frame */
3870 : )
3871 : {
3872 : Word16 igfGridIdx;
3873 :
3874 188837 : test();
3875 188837 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
3876 : {
3877 9708 : igfGridIdx = IGF_GRID_LB_SHORT;
3878 9708 : move16();
3879 : }
3880 : ELSE
3881 : {
3882 179129 : test();
3883 179129 : IF( ( EQ_16( st->last_core, ACELP_CORE ) || left_rect ) )
3884 : {
3885 1056 : igfGridIdx = IGF_GRID_LB_TRAN;
3886 1056 : move16();
3887 : }
3888 : ELSE
3889 : {
3890 178073 : igfGridIdx = IGF_GRID_LB_NORM;
3891 178073 : move16();
3892 : }
3893 : }
3894 :
3895 188837 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, igfGridIdx );
3896 :
3897 188837 : IF( st->igf )
3898 : {
3899 188837 : igfGridIdx = IGF_GRID_LB_SHORT;
3900 188837 : move16();
3901 : /*st->hIGFDec.igfData.igfInfo.nfSeed = (int16_t)(*nf_seed * 31821L + 13849L);*/
3902 :
3903 188837 : test();
3904 188837 : IF( NE_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
3905 : {
3906 179129 : test();
3907 179129 : test();
3908 179129 : IF( EQ_16( st->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
3909 : {
3910 1056 : igfGridIdx = IGF_GRID_LB_TRAN;
3911 1056 : move16();
3912 : }
3913 : ELSE
3914 : {
3915 178073 : igfGridIdx = IGF_GRID_LB_NORM;
3916 178073 : move16();
3917 : }
3918 : }
3919 :
3920 188837 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
3921 :
3922 188837 : *x_len = st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
3923 188837 : move16();
3924 : }
3925 :
3926 188837 : return;
3927 : }
3928 :
3929 :
3930 86760 : void decoder_tcx_IGF_stereo_fx(
3931 : Decoder_State **sts, /* i/o: coder memory states */
3932 : STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo structure */
3933 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */
3934 : Word32 *x_fx[CPE_CHANNELS][NB_DIV], /* i/o: de-quatized coefficients */
3935 : Word16 x_e[CPE_CHANNELS][NB_DIV], /* i/o: de-quatized coefficients exponents */
3936 : Word16 x_len[CPE_CHANNELS][NB_DIV], /* o : length of de-quantized coefficients */
3937 : const Word16 L_frame, /* i : frame length */
3938 : const Word16 left_rect, /* i : left part is rectangular */
3939 : const Word16 k, /* i : Subframe index */
3940 : const Word16 bfi, /* i : bad frame indicator */
3941 : const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */
3942 : )
3943 : {
3944 : Word16 coreMsMask[N_MAX];
3945 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
3946 : Word16 core, sfb, igfGridIdx, restrict_hopsize;
3947 :
3948 86760 : core = sts[0]->core;
3949 86760 : move16();
3950 :
3951 : /* assumptions: stereo filling was already done on the flattened spectra
3952 : * IGF region is always coded M/S, never L/R (to be done in the encoder)
3953 : * for residual bands with stereo filling infoTcxNoise is set to zero
3954 : * both channels have the same IGF configuration
3955 : */
3956 :
3957 :
3958 : /* initialization */
3959 86760 : IF( EQ_16( core, TCX_20_CORE ) )
3960 : {
3961 82276 : sfbConf = &hStereoMdct->stbParamsTCX20;
3962 : }
3963 : ELSE
3964 : {
3965 4484 : sfbConf = &hStereoMdct->stbParamsTCX10;
3966 : }
3967 :
3968 86760 : if ( EQ_16( sts[0]->last_core, ACELP_CORE ) )
3969 : {
3970 8 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
3971 : }
3972 :
3973 : /* create line wise ms mask for the core bands */
3974 86760 : set16_fx( coreMsMask, 0, N_MAX );
3975 :
3976 3680155 : FOR( sfb = 0; sfb < sfbConf->sfbCnt; sfb++ )
3977 : {
3978 3593395 : set16_fx( &coreMsMask[sfbConf->sfbOffset[sfb]], ms_mask[k][sfb], sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ) );
3979 : }
3980 :
3981 86760 : test();
3982 86760 : IF( EQ_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
3983 : {
3984 4484 : igfGridIdx = IGF_GRID_LB_SHORT;
3985 4484 : move16();
3986 : }
3987 : ELSE
3988 : {
3989 82276 : test();
3990 82276 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || left_rect )
3991 : {
3992 8 : igfGridIdx = IGF_GRID_LB_TRAN;
3993 8 : move16();
3994 : }
3995 : ELSE
3996 : {
3997 82268 : igfGridIdx = IGF_GRID_LB_NORM;
3998 82268 : move16();
3999 : }
4000 : }
4001 86760 : IGFDecUpdateInfo_ivas_fx( sts[0]->hIGFDec, k, igfGridIdx );
4002 :
4003 86760 : test();
4004 86760 : IF( EQ_16( L_frame, shr( sts[1]->L_frame, 1 ) ) && ( sts[1]->tcxonly ) )
4005 : {
4006 4484 : igfGridIdx = IGF_GRID_LB_SHORT;
4007 4484 : move16();
4008 : }
4009 : ELSE
4010 : {
4011 82276 : test();
4012 82276 : IF( EQ_16( sts[1]->last_core, ACELP_CORE ) || left_rect )
4013 : {
4014 8 : igfGridIdx = IGF_GRID_LB_TRAN;
4015 8 : move16();
4016 : }
4017 : ELSE
4018 : {
4019 82268 : igfGridIdx = IGF_GRID_LB_NORM;
4020 82268 : move16();
4021 : }
4022 : }
4023 86760 : IGFDecUpdateInfo_ivas_fx( sts[1]->hIGFDec, k, igfGridIdx );
4024 :
4025 :
4026 86760 : IF( sts[0]->igf )
4027 : {
4028 86760 : igfGridIdx = IGF_GRID_LB_SHORT;
4029 86760 : move16();
4030 86760 : test();
4031 86760 : IF( NE_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
4032 : {
4033 82276 : test();
4034 82276 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
4035 : {
4036 8 : igfGridIdx = IGF_GRID_LB_TRAN;
4037 8 : move16();
4038 : }
4039 : ELSE
4040 : {
4041 82268 : igfGridIdx = IGF_GRID_LB_NORM;
4042 82268 : move16();
4043 : }
4044 : }
4045 :
4046 86760 : restrict_hopsize = 0;
4047 86760 : move16();
4048 86760 : if ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
4049 : {
4050 13917 : restrict_hopsize = 1;
4051 13917 : move16();
4052 : }
4053 :
4054 86760 : IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x_fx[0][k], &x_e[0][k], x_fx[1][k], &x_e[1][k], igfGridIdx, coreMsMask, restrict_hopsize, bfi, MCT_flag );
4055 :
4056 86760 : x_len[0][k] = sts[0]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
4057 86760 : move16();
4058 86760 : x_len[1][k] = sts[1]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
4059 86760 : move16();
4060 : }
4061 :
4062 86760 : return;
4063 : }
4064 :
4065 :
4066 220416 : void decoder_tcx_ivas_fx(
4067 : Decoder_State *st,
4068 : Word16 prm[],
4069 : Word16 A_fx[], // Q: 14 - norm_s(A_fx[0])
4070 : Word16 Aind[], // Q: 14 - norm_s(Aind[0])
4071 : Word16 synth_fx[], // Q_syn
4072 : Word16 synthFB_fx[], // Q_syn
4073 : const Word16 bfi,
4074 : const Word16 frame_cnt,
4075 : const Word16 sba_dirac_stereo_flag )
4076 : {
4077 : Word32 x_fx[N_MAX];
4078 : Word16 x_e;
4079 : Word16 gainlpc2_fx[FDNS_NPTS];
4080 : Word16 gainlpc2_e[FDNS_NPTS];
4081 : Word16 gain_tcx_e, gain_tcx_fx;
4082 : Word16 fUseTns, L_frame_glob, L_frameTCX_glob;
4083 : STnsData tnsData;
4084 : Word16 tcx_offset, tcx_offsetFB, L_frame, L_frameTCX;
4085 : Word16 left_rect, L_spec, tmp_concealment_method, nf_seed;
4086 : const Word16 *prm_sqQ;
4087 : Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* Q14 */
4088 : Word16 shift;
4089 : Word16 x_len;
4090 : Word16 q_x;
4091 220416 : q_x = Q11;
4092 220416 : move16();
4093 220416 : x_e = 30;
4094 220416 : move16();
4095 220416 : gain_tcx_e = 0;
4096 220416 : gain_tcx_fx = 0;
4097 220416 : move16();
4098 220416 : move16();
4099 220416 : set32_fx( x_fx, 0, N_MAX );
4100 220416 : set16_fx( gainlpc2_fx, 0, FDNS_NPTS );
4101 220416 : set16_fx( gainlpc2_e, 0, FDNS_NPTS );
4102 :
4103 220416 : L_spec = st->hTcxCfg->tcx_coded_lines;
4104 220416 : move16();
4105 220416 : L_frame_glob = st->L_frame;
4106 220416 : move16();
4107 220416 : L_frameTCX_glob = st->hTcxDec->L_frameTCX;
4108 220416 : move16();
4109 220416 : IF( EQ_16( st->core, TCX_10_CORE ) )
4110 : {
4111 3928 : L_spec = shr( L_spec, 1 );
4112 3928 : L_frame_glob = shr( L_frame_glob, 1 );
4113 3928 : L_frameTCX_glob = shr( L_frameTCX_glob, 1 );
4114 : }
4115 :
4116 220416 : tmp_concealment_method = 0;
4117 220416 : move16();
4118 220416 : nf_seed = 0;
4119 220416 : move16();
4120 220416 : fUseTns = 0; /* flag that is set if TNS data is present */
4121 220416 : move16();
4122 :
4123 220416 : set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX );
4124 :
4125 220416 : init_tcx_info_fx( st, L_frame_glob, L_frameTCX_glob, frame_cnt, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec );
4126 :
4127 220416 : decoder_tcx_invQ_fx( st, prm, A_fx, Aind, L_spec, L_frame, L_frameTCX, x_fx, &x_e, gainlpc2_fx, gainlpc2_e, &xn_buf_fx[0], &fUseTns, &tnsData, &gain_tcx_fx, &gain_tcx_e, &prm_sqQ, &nf_seed, bfi, frame_cnt );
4128 :
4129 220416 : shift = Find_Max_Norm32( x_fx, N_MAX );
4130 220416 : Scale_sig32( x_fx, N_MAX, shift );
4131 220416 : x_e = sub( x_e, shift );
4132 :
4133 220416 : decoder_tcx_noisefilling_fx( st, NULL, 0, A_fx, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, x_fx, &x_e, gainlpc2_fx, gainlpc2_e, &tmp_concealment_method, gain_tcx_fx, gain_tcx_e, prm_sqQ, nf_seed, bfi, 0, frame_cnt );
4134 :
4135 220416 : decoder_tcx_noiseshaping_igf_fx( st, L_spec, L_frame, L_frameTCX, left_rect, x_fx, &x_e, &x_len, gainlpc2_fx, gainlpc2_e, &tmp_concealment_method, bfi );
4136 :
4137 220416 : shift = sub( Find_Max_Norm32( x_fx, N_MAX ), 6 ); // 6 -> guardbits//
4138 220416 : Scale_sig32( x_fx, N_MAX, shift );
4139 220416 : x_e = sub( x_e, shift );
4140 :
4141 220416 : decoder_tcx_tns_fx( st, L_frame_glob, L_spec, L_frame, L_frameTCX, x_fx, fUseTns, &tnsData, bfi, frame_cnt, 0, NULL );
4142 :
4143 220416 : Scale_sig32( x_fx, N_MAX, sub( x_e, 20 ) ); // Scaling x_fx to Q11
4144 220416 : Scale_sig( xn_buf_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX, sub( st->Q_syn, 14 ) ); // Scaling xn_buf_fx to Q_syn
4145 220416 : x_e = sub( 31, 11 );
4146 :
4147 220416 : IF( st->igf != 0 )
4148 : {
4149 210257 : Scale_sig32( st->hIGFDec->virtualSpec, ( N_MAX_TCX - IGF_START_MN ), ( sub( st->hIGFDec->virtualSpec_e, x_e ) ) );
4150 210257 : st->hIGFDec->virtualSpec_e = x_e;
4151 210257 : move16();
4152 : }
4153 :
4154 220416 : Copy_Scale_sig_16_32_no_sat( st->old_Aq_12_8_fx, st->old_Aq_12_8_fx_32, M + 1, ( sub( 28, ( sub( 15, norm_s( sub( st->old_Aq_12_8_fx[0], 1 ) ) ) ) ) ) );
4155 :
4156 : Word16 q_win, q_winFB;
4157 :
4158 220416 : q_win = st->Q_syn;
4159 220416 : move16();
4160 220416 : q_winFB = st->Q_syn;
4161 220416 : move16();
4162 :
4163 220416 : assert( q_win == 0 );
4164 :
4165 220416 : Scale_sig( synth_fx, L_frame_glob, sub( q_win, st->Q_syn ) ); // Scaling to Q_syn
4166 220416 : Scale_sig( synthFB_fx, L_frameTCX_glob, sub( q_winFB, st->Q_syn ) ); // Scaling to Q_syn
4167 :
4168 220416 : decoder_tcx_imdct_fx( st, L_frame_glob, L_frameTCX_glob, L_spec, tcx_offset, tcx_offsetFB, L_frame, L_frameTCX, left_rect, &x_fx[0], q_x, xn_buf_fx, &q_win, &q_winFB, MDCT_IV,
4169 : fUseTns, &synth_fx[0], &synthFB_fx[0], bfi, frame_cnt, sba_dirac_stereo_flag );
4170 :
4171 : /* Scaling up again */
4172 220416 : Scale_sig( synth_fx, L_frame_glob, sub( st->Q_syn, q_win ) );
4173 220416 : Scale_sig( synthFB_fx, L_frameTCX_glob, sub( st->Q_syn, q_winFB ) );
4174 : // Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, 1 );
4175 :
4176 220416 : Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2
4177 220416 : st->hTcxDec->Q_old_syn_Overl = -2;
4178 220416 : }
4179 :
4180 : /*-------------------------------------------------------------------*
4181 : * decoder_tcx_invQ_fx
4182 : *
4183 : * TCX: inverse quantization
4184 : *-------------------------------------------------------------------*/
4185 850462 : void decoder_tcx_invQ_fx(
4186 : Decoder_State *st, /* i/o: coder memory state */
4187 : int16_t prm[], /* i : parameters */
4188 : Word16 A[], /* i : coefficients NxAz[M+1] */
4189 : Word16 Aind[], /* i : frame-independent coefficients Az[M+1] */
4190 : const Word16 L_spec,
4191 : const Word16 L_frame,
4192 : const Word16 L_frameTCX,
4193 : Word32 x[],
4194 : Word16 *x_e,
4195 : Word16 gainlpc2[],
4196 : Word16 gainlpc2_e[],
4197 : Word16 xn_buf[], /* Q14 */
4198 : Word16 *fUseTns, /* o : flag that is set if TNS data is present */
4199 : STnsData *tnsData,
4200 : Word16 *gain_tcx,
4201 : Word16 *gain_tcx_e,
4202 : const Word16 **prm_sqQ1,
4203 : Word16 *nf_seed,
4204 : const Word16 bfi, /* i : Bad frame indicator */
4205 : const Word16 frame_cnt /* i : frame counter in the super frame */
4206 : )
4207 : {
4208 : Word16 i, index;
4209 : Word16 start_zeroing;
4210 : Word16 Ap[M + 2];
4211 :
4212 : Word16 noiseFillingSize;
4213 : Word16 tnsSize; /* number of tns parameters put into prm */
4214 :
4215 : Word16 gamma1; /* Q15 */
4216 : Word16 gamma; /* Q15 */
4217 : Word16 mem[M];
4218 : Word16 gainCompensate, gainCompensate_e;
4219 : Word16 h1[L_SUBFR + 1];
4220 : Word16 tmp1, tmp2;
4221 : Word32 tmp32;
4222 : Word16 s;
4223 :
4224 : Word16 arith_bits, signaling_bits;
4225 : Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target;
4226 850462 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
4227 850462 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
4228 850462 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
4229 :
4230 850462 : gainCompensate = 0;
4231 850462 : gainCompensate_e = 0;
4232 850462 : move16();
4233 850462 : move16();
4234 :
4235 : #ifndef ISSUE_1866_replace_overflow_libdec
4236 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
4237 : Flag Overflow = 0;
4238 : move32();
4239 : #endif
4240 : #endif
4241 :
4242 850462 : tnsSize = 0;
4243 850462 : move16();
4244 : /* just to suppress MSVC warnigs */
4245 850462 : prm_target = NULL;
4246 850462 : prm_ltp = NULL;
4247 850462 : prm_tns = NULL;
4248 850462 : prm_sqQ = NULL;
4249 :
4250 : /*-----------------------------------------------------------------*
4251 : * Initializations
4252 : *-----------------------------------------------------------------*/
4253 :
4254 : /* Init lengths */
4255 850462 : gamma1 = st->gamma;
4256 850462 : move16();
4257 :
4258 850462 : if ( hTcxDec->enableTcxLpc != 0 )
4259 : {
4260 14170 : gamma1 = MAX16B;
4261 14170 : move16();
4262 : }
4263 :
4264 850462 : noiseFillingSize = L_spec;
4265 850462 : move16();
4266 850462 : if ( st->igf != 0 )
4267 : {
4268 572614 : noiseFillingSize = st->hIGFDec->infoIGFStartLine;
4269 572614 : move16();
4270 : }
4271 :
4272 :
4273 850462 : gainCompensate = ONE_IN_Q14;
4274 850462 : move16();
4275 850462 : gainCompensate_e = 1;
4276 850462 : move16();
4277 :
4278 : /*-----------------------------------------------------------*
4279 : * Read TCX parameters *
4280 : *-----------------------------------------------------------*/
4281 :
4282 850462 : index = 0;
4283 850462 : move16();
4284 :
4285 850462 : IF( !bfi )
4286 : {
4287 841729 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
4288 841729 : prm_tns = prm_ltp + LTPSIZE;
4289 841729 : index = prm[0];
4290 841729 : move16();
4291 :
4292 : /* read noise level (fac_ns) */
4293 841729 : st->hTcxDec->noise_filling_index[frame_cnt] = prm[1];
4294 841729 : move16();
4295 : }
4296 :
4297 : /* read TNS data */
4298 850462 : test();
4299 850462 : IF( !bfi && hTcxCfg->fIsTNSAllowed )
4300 : {
4301 775575 : *fUseTns = DecodeTnsData_ivas_fx( hTcxCfg->pCurrentTnsConfig, prm_tns, &tnsSize, tnsData );
4302 775575 : move16();
4303 : }
4304 : ELSE
4305 : {
4306 74887 : *fUseTns = 0;
4307 74887 : move16();
4308 : }
4309 :
4310 :
4311 : /*-----------------------------------------------------------*
4312 : * Spectrum data *
4313 : *-----------------------------------------------------------*/
4314 :
4315 850462 : IF( !bfi )
4316 : {
4317 841729 : prm_hm = prm_tns + tnsSize;
4318 841729 : prm_sqQ = prm_hm + NPRM_CTX_HM;
4319 841729 : *prm_sqQ1 = prm_sqQ;
4320 : /*-----------------------------------------------------------*
4321 : * Context HM *
4322 : *-----------------------------------------------------------*/
4323 841729 : test();
4324 841729 : test();
4325 841729 : IF( hTcxCfg->ctx_hm && ( ( st->last_core_from_bs != ACELP_CORE ) || ( frame_cnt > 0 ) ) )
4326 : {
4327 170340 : st->last_ctx_hm_enabled = prm_hm[0];
4328 170340 : move16();
4329 :
4330 144521380 : FOR( i = 0; i < L_spec; i++ )
4331 : {
4332 : /* no context harmonic model, copy MDCT coefficients to x */
4333 144351040 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
4334 144351040 : move32();
4335 : }
4336 170340 : *x_e = SPEC_EXP_DEC;
4337 170340 : move16();
4338 : }
4339 : ELSE /* hTcxCfg->ctx_hm == 0 */
4340 : {
4341 671389 : IF( hTcxDec->tcx_lpc_shaped_ari ) /* low rates: envelope based arithmetic coder */
4342 : {
4343 14024 : prm_target = prm_sqQ;
4344 14024 : move16();
4345 14024 : prm_sqQ = prm_target + 1;
4346 14024 : move16();
4347 :
4348 14024 : IF( GT_32( st->bwidth, WB ) )
4349 : {
4350 12648 : tcx_arith_decode_envelope_ivas_fx( st, x, x_e, L_frame, L_spec, Aind, *prm_target, prm_sqQ, (Word16) NE_16( st->last_core_from_bs, ACELP_CORE ), prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, 1 );
4351 : }
4352 : ELSE
4353 : {
4354 1376 : tcx_arith_decode_envelope_ivas_fx( st, x, x_e, L_frame, L_spec, Aind, *prm_target, prm_sqQ, (Word16) NE_16( st->last_core_from_bs, ACELP_CORE ), prm_hm, /* HM parameter area */ hTcxDec->tcx_hm_LtpPitchLag, &arith_bits, &signaling_bits, 0 );
4355 : }
4356 :
4357 14024 : hTcxDec->resQBits[frame_cnt] = sub( *prm_target, arith_bits );
4358 14024 : move16();
4359 :
4360 : /* Noise filling seed */
4361 2943512 : FOR( i = 0; i < noiseFillingSize; ++i )
4362 : {
4363 2929488 : tmp32 = L_shr( x[i], sub( 31, *x_e ) );
4364 : #ifdef ISSUE_1866_replace_overflow_libdec
4365 2929488 : *nf_seed = add_sat( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ) ); // abs( tmp32 ) * i * 2
4366 : #else
4367 : *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2
4368 : #endif
4369 2929488 : move16();
4370 : }
4371 : }
4372 : ELSE /* TCX-only: context based arithmetic coder */
4373 : {
4374 526935525 : FOR( i = 0; i < L_spec; i++ )
4375 : {
4376 526278160 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
4377 526278160 : move32();
4378 : }
4379 :
4380 657365 : set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
4381 :
4382 657365 : *x_e = SPEC_EXP_DEC;
4383 657365 : move16();
4384 : }
4385 :
4386 : } /* else of if hTcxCfg->ctx_hm */
4387 :
4388 : // start_zeroing = ( st->last_core != st->last_core_from_bs ) ? min( L_spec, L_frame ) : L_spec;
4389 841729 : IF( NE_16( st->last_core, st->last_core_from_bs ) )
4390 : {
4391 80 : start_zeroing = s_min( L_spec, L_frame );
4392 : }
4393 : ELSE
4394 : {
4395 841649 : start_zeroing = L_spec;
4396 841649 : move16();
4397 : }
4398 841729 : test();
4399 841729 : test();
4400 841729 : IF( frame_cnt == 0 && EQ_16( st->last_core, ACELP_CORE ) && NE_16( st->last_core_from_bs, ACELP_CORE ) )
4401 : {
4402 : Word16 L_spec_con;
4403 26 : L_spec_con = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
4404 :
4405 12346 : FOR( i = start_zeroing; i < L_spec_con; i++ )
4406 : {
4407 12320 : x[i] = 0;
4408 12320 : move32();
4409 : }
4410 :
4411 26 : start_zeroing = L_spec_con;
4412 26 : move16();
4413 : }
4414 :
4415 42083857 : FOR( i = start_zeroing; i < s_max( L_frame, L_frameTCX ); i++ )
4416 : {
4417 41242128 : x[i] = 0;
4418 41242128 : move32();
4419 : }
4420 :
4421 : /*-----------------------------------------------------------*
4422 : * adaptive low frequency deemphasis. *
4423 : *-----------------------------------------------------------*/
4424 :
4425 841729 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4426 : {
4427 218592 : weight_a_fx( A, Ap, gamma1, M );
4428 218592 : lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
4429 : }
4430 :
4431 : /* initialize LF deemphasis factors in xn_buf */
4432 841729 : test();
4433 841729 : test();
4434 841729 : IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) )
4435 : {
4436 115083 : Word16 len = s_max( L_spec, L_frameTCX );
4437 103435003 : FOR( i = 0; i < len; i++ )
4438 : {
4439 103319920 : xn_buf[i] = ONE_IN_Q14;
4440 103319920 : move16();
4441 : }
4442 : }
4443 841729 : IF( !st->tcxonly )
4444 : {
4445 115083 : AdaptLowFreqDeemph( x, *x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e, L_frame, xn_buf /* LF deemphasis factors */ );
4446 : }
4447 : }
4448 :
4449 850462 : hTcxDec->damping = 0;
4450 850462 : move16();
4451 :
4452 850462 : IF( bfi == 0 )
4453 : {
4454 : /*-----------------------------------------------------------*
4455 : * Compute global gain *
4456 : *-----------------------------------------------------------*/
4457 :
4458 841729 : tmp32 = L_shl( L_mult0( index, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
4459 841729 : *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
4460 841729 : *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) );
4461 841729 : move16();
4462 841729 : move16();
4463 :
4464 841729 : tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
4465 841729 : s = 15 - 5 - 7;
4466 841729 : move16();
4467 841729 : IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/
4468 : {
4469 3783 : tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
4470 3783 : s = 15 - 4 - 7;
4471 3783 : move16();
4472 : }
4473 841729 : tmp1 = ISqrt16( tmp1, &s );
4474 :
4475 841729 : *gain_tcx = mult( *gain_tcx, tmp1 );
4476 841729 : *gain_tcx_e = add( *gain_tcx_e, s );
4477 841729 : move16();
4478 841729 : move16();
4479 :
4480 841729 : hTcxDec->old_gaintcx_bfi = *gain_tcx;
4481 841729 : move16();
4482 841729 : hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
4483 841729 : move16();
4484 :
4485 841729 : hTcxDec->cummulative_damping_tcx = MAX16B; // 1 in Q15
4486 841729 : move16();
4487 : }
4488 : ELSE /* bfi = 1 */
4489 : {
4490 : /* PLC: [TCX: Fade-out]
4491 : * derivation of damping factor */
4492 8733 : IF( st->use_partial_copy )
4493 : {
4494 0 : IF( EQ_16( st->rf_frame_type, RF_TCXFD ) )
4495 : {
4496 0 : tmp32 = L_shl( L_mult0( hTcxDec->old_gaintcx_bfi, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
4497 0 : *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
4498 0 : *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
4499 0 : move16();
4500 0 : move16();
4501 :
4502 0 : tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
4503 0 : s = 15 - 5 - 7;
4504 0 : move16();
4505 0 : tmp1 = ISqrt16( tmp1, &s );
4506 :
4507 0 : *gain_tcx = mult( *gain_tcx, tmp1 );
4508 0 : *gain_tcx_e = add( *gain_tcx_e, s );
4509 0 : move16();
4510 0 : move16();
4511 :
4512 0 : hTcxDec->old_gaintcx_bfi = *gain_tcx;
4513 0 : move16();
4514 0 : hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
4515 0 : move16();
4516 : }
4517 : ELSE
4518 : {
4519 0 : *gain_tcx = hTcxDec->old_gaintcx_bfi;
4520 0 : move16();
4521 0 : *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
4522 0 : move16();
4523 : }
4524 :
4525 0 : hTcxDec->damping = ONE_IN_Q14; // Q14
4526 0 : move16();
4527 : }
4528 : ELSE
4529 : {
4530 8733 : *gain_tcx = hTcxDec->old_gaintcx_bfi;
4531 8733 : move16();
4532 8733 : *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
4533 8733 : move16();
4534 :
4535 17466 : hTcxDec->damping = Damping_fact_fx( st->coder_type, st->nbLostCmpt, st->last_good,
4536 8733 : st->stab_fac_fx,
4537 : &st->Mode2_lp_gainp,
4538 8733 : st->last_core );
4539 8733 : move16();
4540 : }
4541 :
4542 8733 : hTcxDec->cummulative_damping_tcx = shl( mult( hTcxDec->cummulative_damping_tcx, hTcxDec->damping ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
4543 8733 : move16();
4544 : }
4545 :
4546 850462 : IF( bfi )
4547 : {
4548 8733 : IF( hTcxDec->envWeighted )
4549 : {
4550 0 : gamma = st->gamma;
4551 0 : move16();
4552 : }
4553 : ELSE
4554 : {
4555 8733 : gamma = gamma1;
4556 8733 : move16();
4557 : }
4558 :
4559 : /* PLC: [TCX: Fade-out]
4560 : * PLC: invert LPC weighting in case of PLC */
4561 :
4562 8733 : IF( hTcxDec->enableTcxLpc )
4563 : {
4564 146 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( st->gamma, MAX16B ) ), MAX16B );
4565 : }
4566 : ELSE
4567 : {
4568 8587 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( gamma1, MAX16B ) ), MAX16B );
4569 : }
4570 :
4571 8733 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4572 : {
4573 1824 : weight_a_fx( A, Ap, gamma, M );
4574 1824 : lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
4575 : }
4576 : }
4577 :
4578 850462 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4579 : {
4580 220416 : set16_fx( h1, 0, L_SUBFR + 1 );
4581 220416 : set16_fx( mem, 0, M );
4582 220416 : h1[0] = ONE_IN_Q10;
4583 220416 : move16();
4584 220416 : E_UTIL_synthesis( 0, Ap, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC */
4585 :
4586 220416 : tmp2 = 0;
4587 220416 : move16();
4588 220416 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp2 ); /* tmp2 in Q10 */
4589 : }
4590 :
4591 : /* impulse response level = gain introduced by synthesis+deemphasis */
4592 850462 : test();
4593 850462 : IF( !bfi )
4594 : {
4595 841729 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4596 : {
4597 623137 : st->last_gain_syn_deemph = 0;
4598 623137 : move16();
4599 623137 : st->last_gain_syn_deemph_e = 0;
4600 623137 : move16();
4601 : }
4602 : ELSE
4603 : {
4604 218592 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ) /*Q15, st->last_gain_syn_deemph_e*/;
4605 218592 : st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
4606 218592 : move16();
4607 218592 : tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e );
4608 : #ifdef ISSUE_1866_replace_overflow_libdec
4609 218592 : st->last_gain_syn_deemph = round_fx_sat( tmp32 ); // Q15
4610 : #else
4611 : st->last_gain_syn_deemph = round_fx_o( tmp32, &Overflow ); // Q15
4612 : #endif
4613 218592 : move16();
4614 : }
4615 :
4616 : /*for avoiding compiler warnings*/
4617 841729 : hTcxDec->gainHelper = ONE_IN_Q14;
4618 841729 : move16();
4619 841729 : hTcxDec->gainHelper_e = 1;
4620 841729 : move16();
4621 841729 : hTcxDec->stepCompensate = 0;
4622 841729 : move16();
4623 841729 : hTcxDec->stepCompensate_e = 0;
4624 841729 : move16();
4625 : }
4626 : /* not instrumenting the additional test() here seems to be common practice */
4627 8733 : ELSE IF( EQ_16( TCX_20_CORE, st->core ) || EQ_16( frame_cnt, 1 ) )
4628 : {
4629 8674 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4630 : {
4631 6858 : gainCompensate = ONE_IN_Q14;
4632 6858 : move16();
4633 6858 : gainCompensate_e = 1;
4634 6858 : move16();
4635 : }
4636 : ELSE
4637 : {
4638 1816 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/;
4639 1816 : gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ );
4640 1816 : gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/;
4641 1816 : BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph,
4642 1816 : st->last_gain_syn_deemph_e,
4643 : gainCompensate,
4644 : gainCompensate_e,
4645 : &gainCompensate,
4646 : &gainCompensate_e );
4647 : }
4648 :
4649 8674 : tmp1 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )]; /* indexing for lookup table */
4650 :
4651 8674 : IF( EQ_16( st->nbLostCmpt, 1 ) )
4652 : {
4653 4773 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
4654 : tmp1,
4655 : -7,
4656 4773 : negate( mult( gainCompensate, tmp1 ) ),
4657 4773 : add( -7, gainCompensate_e ),
4658 : &hTcxDec->stepCompensate );
4659 4773 : hTcxDec->gainHelper = ONE_IN_Q14;
4660 4773 : move16();
4661 4773 : hTcxDec->gainHelper_e = 1;
4662 4773 : move16();
4663 : }
4664 : ELSE
4665 : {
4666 3901 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
4667 3901 : mult( tmp1, st->last_concealed_gain_syn_deemph ),
4668 3901 : add( -7, st->last_concealed_gain_syn_deemph_e ),
4669 3901 : negate( mult( tmp1, gainCompensate ) ),
4670 3901 : add( -7, gainCompensate_e ),
4671 : &hTcxDec->stepCompensate );
4672 :
4673 3901 : hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph;
4674 3901 : move16();
4675 3901 : hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e;
4676 3901 : move16();
4677 : }
4678 :
4679 8674 : st->last_concealed_gain_syn_deemph = gainCompensate;
4680 8674 : move16();
4681 8674 : st->last_concealed_gain_syn_deemph_e = gainCompensate_e;
4682 8674 : move16();
4683 : }
4684 :
4685 : /*-----------------------------------------------------------*
4686 : * Residual inv. Q. *
4687 : *-----------------------------------------------------------*/
4688 850462 : test();
4689 850462 : IF( !bfi && hTcxCfg->resq )
4690 : {
4691 370942 : IF( hTcxDec->tcx_lpc_shaped_ari )
4692 : {
4693 : /* envelope based arithmetic coder */
4694 : const Word16 *prm_resq;
4695 14024 : prm_resq = prm_sqQ + sub( *prm_target /* = targetBits */, hTcxDec->resQBits[frame_cnt] );
4696 :
4697 14024 : i = tcx_ari_res_invQ_spec( x, *x_e, L_spec,
4698 : prm_resq,
4699 14024 : hTcxDec->resQBits[frame_cnt],
4700 : 0,
4701 14024 : hTcxCfg->sq_rounding,
4702 : xn_buf /* LF deemphasis factors */ );
4703 : }
4704 : ELSE
4705 : {
4706 : /* context based arithmetic coder */
4707 356918 : i = tcx_res_invQ_gain( gain_tcx, gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] );
4708 :
4709 356918 : Word16 *tmpP16 = xn_buf;
4710 356918 : if ( st->tcxonly != 0 )
4711 255859 : tmpP16 = NULL;
4712 356918 : tcx_res_invQ_spec( x, *x_e, L_spec, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt], i, hTcxCfg->sq_rounding, tmpP16 /* LF deemphasis factors */ );
4713 : }
4714 : }
4715 :
4716 850462 : test();
4717 850462 : test();
4718 850462 : IF( !bfi && st->tcxonly && st->element_mode != IVAS_CPE_MDCT )
4719 : {
4720 103509 : test();
4721 103509 : test();
4722 103509 : IF( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain > 0 ) && !( *fUseTns ) )
4723 : {
4724 3675 : PsychAdaptLowFreqDeemph( x, gainlpc2, gainlpc2_e, NULL );
4725 : }
4726 : }
4727 850462 : test();
4728 850462 : IF( !bfi && !st->tcxonly )
4729 : {
4730 : /* Replication of ACELP formant enhancement for low rates */
4731 115083 : IF( LT_32( st->total_brate, ACELP_13k20 ) )
4732 : {
4733 26443 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4734 : {
4735 0 : assert( !"Not adapted to warped scale" );
4736 : }
4737 :
4738 : Word16 xn_buf_e;
4739 26443 : tcxFormantEnhancement_with_shift( xn_buf, &xn_buf_e, gainlpc2, gainlpc2_e, x, x_e, L_frame, L_frameTCX );
4740 1718795 : FOR( i = 0; i < FDNS_NPTS; i++ )
4741 : {
4742 1692352 : xn_buf[i] = shl( xn_buf[i], xn_buf_e - 1 );
4743 1692352 : move16();
4744 : }
4745 : }
4746 : }
4747 :
4748 : /*-----------------------------------------------------------*
4749 : * Add gain to the lpc gains *
4750 : *-----------------------------------------------------------*/
4751 :
4752 850462 : IF( st->VAD == 0 )
4753 : {
4754 579999 : *gain_tcx = mult_r( *gain_tcx, hTcxCfg->na_scale );
4755 579999 : move16();
4756 : }
4757 :
4758 850462 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4759 : {
4760 220416 : i = norm_s( *gain_tcx );
4761 220416 : *gain_tcx = shl( *gain_tcx, i );
4762 220416 : *gain_tcx_e = sub( *gain_tcx_e, i );
4763 220416 : move16();
4764 220416 : move16();
4765 14327040 : FOR( i = 0; i < FDNS_NPTS; i++ )
4766 : {
4767 14106624 : gainlpc2[i] = mult( gainlpc2[i], *gain_tcx );
4768 14106624 : move16();
4769 14106624 : gainlpc2_e[i] = add( gainlpc2_e[i], *gain_tcx_e );
4770 14106624 : move16();
4771 : }
4772 : }
4773 :
4774 850462 : return;
4775 : }
4776 :
4777 : /*-------------------------------------------------------------------*
4778 : * decoder_tcx_noisefilling()
4779 : *
4780 : * TCX: core noise filling, IGF updates
4781 : *-------------------------------------------------------------------*/
4782 :
4783 850462 : void decoder_tcx_noisefilling_fx(
4784 : Decoder_State *st, /* i/o: coder memory state */
4785 : const Word32 concealment_noise[L_FRAME48k],
4786 : const Word16 concealment_noise_exp,
4787 : const Word16 A[], /* i : coefficients NxAz[M+1] */
4788 : const Word16 L_frameTCX_glob,
4789 : const Word16 L_spec,
4790 : const Word16 L_frame,
4791 : const Word16 L_frameTCX,
4792 : Word32 x[],
4793 : Word16 *x_e,
4794 : Word16 *gainlpc2,
4795 : Word16 *gainlpc2_e,
4796 : Word16 *temp_concealment_method,
4797 : const Word16 gain_tcx,
4798 : const Word16 gain_tcx_e,
4799 : const Word16 *prm_sqQ,
4800 : Word16 nf_seed,
4801 : const Word16 bfi, /* i : Bad frame indicator */
4802 : const Word16 MCT_flag,
4803 : const Word16 frame_cnt /* i : frame counter in the super frame*/
4804 : )
4805 : {
4806 : Word16 i;
4807 : Word16 firstLine;
4808 : Word16 fac_ns;
4809 : Word16 noiseFillingSize;
4810 850462 : Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
4811 850462 : move16();
4812 : Word16 tmp, tmp1, tmp2;
4813 : Word16 sum_word16;
4814 : Word16 infoIGFStartLine;
4815 : Word16 f, noiseTiltFactor;
4816 : Word32 smooth_gain;
4817 850462 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
4818 850462 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
4819 850462 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
4820 : Word32 total_brate;
4821 : Word32 tmp32;
4822 : Word16 *pInfoTCXNoise;
4823 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
4824 850462 : Flag Overflow = 0;
4825 850462 : move32();
4826 850462 : Flag Carry = 0;
4827 850462 : move32();
4828 : #endif
4829 850462 : total_brate = ( (Word16) EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? st->element_brate : st->total_brate );
4830 850462 : move32();
4831 : /*-----------------------------------------------------------------*
4832 : * Initializations
4833 : *-----------------------------------------------------------------*/
4834 :
4835 : /* Init lengths */
4836 850462 : infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX );
4837 :
4838 850462 : noiseFillingSize = L_spec;
4839 850462 : move16();
4840 850462 : if ( st->igf != 0 )
4841 : {
4842 572614 : noiseFillingSize = st->hIGFDec->infoIGFStartLine;
4843 572614 : move16();
4844 : }
4845 :
4846 850462 : IF( bfi == 0 )
4847 : {
4848 841729 : fac_ns = extract_l( L_shr( L_mult0( hTcxDec->noise_filling_index[frame_cnt], 0x6000 /* 0.75f in Q15 */ ), NBITS_NOISE_FILL_LEVEL ) );
4849 : }
4850 : ELSE
4851 : {
4852 8733 : fac_ns = 0;
4853 8733 : move16();
4854 : }
4855 :
4856 : /*-----------------------------------------------------------*
4857 : * Noise filling. *
4858 : *-----------------------------------------------------------*/
4859 :
4860 850462 : test();
4861 850462 : IF( bfi == 0 && ( fac_ns > 0 ) )
4862 : {
4863 803199 : firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, ( GE_32( total_brate, ACELP_13k20 ) && !st->rf_flag ), &noiseTiltFactor );
4864 :
4865 803199 : IF( st->tcxonly != 0 )
4866 : {
4867 688474 : tmp1 = 0;
4868 688474 : move16();
4869 688474 : test();
4870 688474 : test();
4871 688474 : if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( st->last_ctx_hm_enabled != 0 ) )
4872 : {
4873 4386 : tmp1 = 10240 /*0.3125f Q15*/;
4874 4386 : move16();
4875 : }
4876 688474 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4877 : {
4878 598573 : IF( frame_cnt == 0 )
4879 : {
4880 584949 : Copy( hTcxDec->ltpGainMemory_fx, &hTcxDec->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
4881 584949 : hTcxDec->ltpGainMemory_fx[0] = hTcxLtpDec->tcxltp_gain; /* Q15 */
4882 584949 : move16();
4883 : }
4884 598573 : smooth_gain = Dot_product( hTcxDec->ltpGainMemory_fx, nf_tw_smoothing_coeffs_fx, N_LTP_GAIN_MEMS ); /* Q31 */
4885 598573 : noiseTransWidth = HOLE_SIZE_FROM_LTP32( L_max( smooth_gain, L_deposit_h( tmp1 ) ) ); /* using 32-bit for increased precision. */
4886 : }
4887 : ELSE
4888 : {
4889 89901 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxLtpDec->tcxltp_gain, tmp1 ) );
4890 : }
4891 :
4892 688474 : if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
4893 : {
4894 27662 : noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */
4895 27662 : move16();
4896 : }
4897 : }
4898 :
4899 803199 : IF( hTcxDec->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
4900 : {
4901 : /* noise filling seed */
4902 789350 : tmp32 = L_deposit_l( 0 );
4903 644395670 : FOR( i = 0; i < L_spec; i++ )
4904 : {
4905 643606320 : tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow );
4906 : }
4907 789350 : nf_seed = extract_l( tmp32 );
4908 : }
4909 803199 : pInfoTCXNoise = NULL;
4910 803199 : if ( st->igf )
4911 : {
4912 551993 : pInfoTCXNoise = st->hIGFDec->infoTCXNoise_ptr;
4913 : }
4914 803199 : tcx_noise_filling_with_shift( x, x_e, nf_seed, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, fac_ns, pInfoTCXNoise, st->element_mode );
4915 803199 : st->seed_tcx_plc = nf_seed;
4916 803199 : move16();
4917 : }
4918 :
4919 850462 : IF( st->enablePlcWaveadjust )
4920 : {
4921 0 : IF( bfi )
4922 : {
4923 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
4924 : {
4925 0 : st->hPlcInfo->concealment_method = TCX_NONTONAL;
4926 0 : move16();
4927 :
4928 : /* tonal/non-tonal decision */
4929 0 : test();
4930 0 : test();
4931 0 : IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) )
4932 : {
4933 0 : sum_word16 = 0;
4934 0 : move16();
4935 :
4936 0 : FOR( i = 9; i >= 0; i-- )
4937 : {
4938 0 : sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] );
4939 : }
4940 :
4941 0 : if ( GE_16( sum_word16, 6 ) )
4942 : {
4943 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4944 0 : move16();
4945 : }
4946 : }
4947 :
4948 0 : if ( st->tonal_mdct_plc_active )
4949 : {
4950 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4951 0 : move16();
4952 : }
4953 : }
4954 :
4955 0 : if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) )
4956 : {
4957 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4958 0 : move16();
4959 : }
4960 :
4961 0 : *temp_concealment_method = st->hPlcInfo->concealment_method;
4962 0 : move16();
4963 :
4964 0 : if ( EQ_16( st->core, TCX_10_CORE ) )
4965 : {
4966 0 : *temp_concealment_method = TCX_TONAL;
4967 0 : move16();
4968 : }
4969 : }
4970 :
4971 : /* get the starting location of the subframe in the frame */
4972 0 : IF( EQ_16( st->core, TCX_10_CORE ) )
4973 : {
4974 0 : st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) );
4975 0 : move16();
4976 : }
4977 : }
4978 :
4979 : /* PLC: [TCX: Tonal Concealment] */
4980 : /* PLC: [TCX: Fade-out]
4981 : * PLC: Fade out to white noise */
4982 850462 : IF( st->hTonalMDCTConc != NULL )
4983 : {
4984 850462 : test();
4985 850462 : IF( bfi == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4986 : {
4987 218592 : TonalMDCTConceal_SaveFreqSignal_ivas_fx( st->hTonalMDCTConc, x, *x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e, infoIGFStartLine );
4988 : }
4989 631870 : ELSE IF( bfi )
4990 : {
4991 8733 : test();
4992 8733 : IF( !st->enablePlcWaveadjust || EQ_16( *temp_concealment_method, TCX_TONAL ) )
4993 : {
4994 : /* set f to 1 to not fade out */
4995 : /* set f to 0 to immediately switch to white noise */
4996 8733 : test();
4997 8733 : test();
4998 8733 : IF( st->tcxonly && ( NE_16( st->element_mode, IVAS_CPE_MDCT ) || MCT_flag ) )
4999 : {
5000 4366 : f = MAX16B;
5001 4366 : move16();
5002 : }
5003 : ELSE
5004 : {
5005 4367 : f = hTcxDec->cummulative_damping_tcx;
5006 4367 : move16();
5007 : }
5008 :
5009 8733 : test();
5010 8733 : test();
5011 8733 : test();
5012 8733 : test();
5013 8733 : test();
5014 8733 : test();
5015 8733 : IF( ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
5016 : {
5017 : Word16 exp1, exp2;
5018 15 : exp1 = 0;
5019 15 : exp2 = 0;
5020 : Word64 E_2ndlast, E_last;
5021 15 : E_2ndlast = E_last = EPSILON_FX;
5022 15 : move16();
5023 15 : move16();
5024 15 : move64();
5025 15 : move64();
5026 :
5027 : Word16 tmp_len;
5028 15 : IF( st->element_mode > EVS_MONO )
5029 : {
5030 15 : tmp_len = L_frameTCX;
5031 15 : move16();
5032 : }
5033 : ELSE
5034 : {
5035 0 : tmp_len = infoIGFStartLine;
5036 0 : move16();
5037 : }
5038 :
5039 2015 : FOR( i = 0; i < tmp_len; i = i + 2 )
5040 : {
5041 2000 : E_2ndlast = W_mac_16_16( E_2ndlast, st->hTonalMDCTConc->lastBlockData.spectralData[i], st->hTonalMDCTConc->lastBlockData.spectralData[i] ); /* Q(31 - 2 * st->hTonalMDCTConc->lastBlockData.spectralData_exp) */
5042 2000 : E_last = W_mac_16_16( E_last, st->hTonalMDCTConc->lastBlockData.spectralData[i + 1], st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] ); /* Q(31 - 2 * st->hTonalMDCTConc->lastBlockData.spectralData_exp) */
5043 : }
5044 :
5045 15 : exp2 = W_norm( E_2ndlast );
5046 15 : E_2ndlast = W_shl( E_2ndlast, exp2 );
5047 15 : exp2 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp2 ) );
5048 :
5049 15 : exp1 = W_norm( E_last );
5050 15 : E_last = W_shl( E_last, exp1 );
5051 15 : exp1 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp1 ) );
5052 :
5053 15 : tmp1 = BASOP_Util_Divide3232_Scale( W_extract_h( E_2ndlast ), W_extract_h( E_last ), &tmp2 );
5054 15 : tmp2 = add( tmp2, sub( exp2, exp1 ) );
5055 :
5056 15 : tmp1 = shl_sat( tmp1, sub( tmp2, 2 ) );
5057 :
5058 : /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
5059 15 : IF( st->element_mode > EVS_MONO )
5060 : {
5061 15 : tmp_len = L_frameTCX;
5062 15 : move16();
5063 : }
5064 : ELSE
5065 : {
5066 0 : tmp_len = infoIGFStartLine;
5067 0 : move16();
5068 : }
5069 15 : IF( GT_16( tmp1, ONE_IN_Q14 ) ) /* 2 in Q13 = 1 in Q14 */
5070 : {
5071 0 : FOR( i = 0; i < tmp_len; i += 2 )
5072 : {
5073 0 : move16();
5074 0 : st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
5075 : }
5076 : }
5077 15 : ELSE IF( LT_16( tmp1, ONE_IN_Q12 ) ) /*0.5 in Q13 = 1 in Q12*/
5078 : {
5079 1127 : FOR( i = 0; i < tmp_len; i += 2 )
5080 : {
5081 1120 : move16();
5082 1120 : st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
5083 : }
5084 : }
5085 : }
5086 :
5087 8733 : noiseTiltFactor = MAX16B;
5088 8733 : move16();
5089 :
5090 8733 : tmp = 0;
5091 8733 : move16();
5092 8733 : test();
5093 8733 : if ( GE_32( total_brate, ACELP_13k20 ) && st->rf_flag == 0 )
5094 : {
5095 8496 : tmp = 1;
5096 8496 : move16();
5097 : }
5098 :
5099 8733 : tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor );
5100 :
5101 : Word32 CngLevelBackgroundTrace_bfi_fx;
5102 8733 : CngLevelBackgroundTrace_bfi_fx = L_deposit_l( hTcxDec->conCngLevelBackgroundTrace );
5103 : Word16 CngLevelBackgroundTrace_bfi_exp;
5104 8733 : CngLevelBackgroundTrace_bfi_exp = add( hTcxDec->conCngLevelBackgroundTrace_e, 16 );
5105 8733 : test();
5106 8733 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && MCT_flag == 0 )
5107 : {
5108 3108 : TonalMDCTConceal_InsertNoise_ivas_fx( st->hTonalMDCTConc, x, x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, concealment_noise_exp, CngLevelBackgroundTrace_bfi_fx, CngLevelBackgroundTrace_bfi_exp, infoIGFStartLine );
5109 : }
5110 : ELSE
5111 : {
5112 5625 : TonalMDCTConceal_InsertNoise_ivas_fx( st->hTonalMDCTConc, x, x_e, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, 0, CngLevelBackgroundTrace_bfi_fx, CngLevelBackgroundTrace_bfi_exp, infoIGFStartLine );
5113 : }
5114 : }
5115 : }
5116 : }
5117 :
5118 : /*------------------------- SPLIT 2 noise filling ------------------------*/
5119 850462 : IF( !bfi )
5120 : {
5121 841729 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
5122 : {
5123 496376417 : FOR( i = 0; i < L_spec; i++ )
5124 : {
5125 495753280 : x[i] = Mpy_32_16_1( x[i], gain_tcx );
5126 495753280 : move16();
5127 : }
5128 623137 : *x_e = add( *x_e, gain_tcx_e );
5129 623137 : move16();
5130 : }
5131 : }
5132 :
5133 850462 : IF( LT_16( L_spec, L_frame ) )
5134 : {
5135 2 : set32_fx( x + L_spec, 0, sub( L_frame, L_spec ) );
5136 : }
5137 850460 : ELSE IF( GT_16( L_spec, L_frameTCX ) )
5138 : {
5139 69420 : set32_fx( x + L_frameTCX, 0, sub( L_spec, L_frameTCX ) );
5140 : }
5141 850462 : test();
5142 850462 : test();
5143 850462 : test();
5144 850462 : test();
5145 850462 : test();
5146 850462 : test();
5147 850462 : test();
5148 850462 : test();
5149 850462 : test();
5150 850462 : test();
5151 850462 : test();
5152 850462 : test();
5153 850462 : test();
5154 850462 : IF( bfi && ( !st->enablePlcWaveadjust || EQ_16( *temp_concealment_method, TCX_TONAL ) ) && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( EQ_16( st->nbLostCmpt, 1 ) ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ) && ( NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) )
5155 : {
5156 5 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
5157 : /* also replace flat spectrum for the second TCX10 sub frame */
5158 5 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 1, IGF_GRID_LB_SHORT );
5159 5 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
5160 5 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 0, IGF_GRID_LB_SHORT );
5161 5 : Copy( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB );
5162 : }
5163 850457 : ELSE IF( bfi && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
5164 : {
5165 : /* copy second to first subframe */
5166 15 : IGFDecReplicateTCX10State_fx( st->hIGFDec );
5167 : }
5168 :
5169 850462 : IF( st->element_mode != EVS_MONO )
5170 : {
5171 850462 : IF( bfi )
5172 : {
5173 8733 : nf_seed = st->seed_tcx_plc;
5174 8733 : move16();
5175 : }
5176 841729 : ELSE IF( nf_seed == 0 )
5177 : {
5178 40388 : nf_seed = *st->hIGFDec->igfData.igfInfo.nfSeed;
5179 40388 : move16();
5180 : }
5181 : }
5182 :
5183 850462 : IF( st->igf )
5184 : {
5185 572614 : *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_add( L_mult0( nf_seed, 31821 ), 13849 ) );
5186 572614 : move16();
5187 : }
5188 :
5189 850462 : return;
5190 : }
5191 :
5192 : /*-------------------------------------------------------------------*
5193 : * decoder_tcx_noiseshaping_igf_fx()
5194 : *
5195 : * TCX: FDNS and IGF application
5196 : *-------------------------------------------------------------------*/
5197 :
5198 850462 : void decoder_tcx_noiseshaping_igf_fx(
5199 : Decoder_State *st, /* i/o: coder memory state */
5200 : const Word16 L_spec,
5201 : const Word16 L_frame,
5202 : const Word16 L_frameTCX,
5203 : const Word16 left_rect,
5204 : Word32 *x_fx,
5205 : Word16 *x_e,
5206 : Word16 *x_len,
5207 : const Word16 gainlpc2_fx[],
5208 : const Word16 gainlpc2_e[],
5209 : Word16 *temp_concealment_method,
5210 : const Word16 bfi /* i : Bad frame indicator */
5211 : )
5212 : {
5213 : TCX_DEC_HANDLE hTcxDec;
5214 : Word16 i;
5215 : Word32 tmp32;
5216 : Word8 tmp8;
5217 :
5218 : /*-----------------------------------------------------------*
5219 : * Noise shaping in frequency domain (1/Wz) *
5220 : *-----------------------------------------------------------*/
5221 850462 : hTcxDec = st->hTcxDec;
5222 :
5223 850462 : test();
5224 850462 : test();
5225 850462 : test();
5226 850462 : IF( st->igf && ( !bfi || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->prev_bfi ) ) )
5227 : {
5228 570109 : test();
5229 570109 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
5230 : {
5231 22442 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_SHORT );
5232 : }
5233 : ELSE
5234 : {
5235 547667 : IF( st->last_core == ACELP_CORE )
5236 : {
5237 7736 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_TRAN );
5238 : }
5239 : ELSE
5240 : {
5241 539931 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_NORM );
5242 : }
5243 : }
5244 : }
5245 : /* LPC gains already available */
5246 :
5247 850462 : test();
5248 850462 : test();
5249 850462 : test();
5250 850462 : test();
5251 850462 : test();
5252 850462 : IF( gainlpc2_fx && gainlpc2_e && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( !st->enablePlcWaveadjust || !bfi || ( EQ_16( *temp_concealment_method, TCX_TONAL ) ) ) )
5253 : {
5254 : Word16 spec_side_x_e, frame_side_x_e;
5255 :
5256 220416 : spec_side_x_e = *x_e;
5257 220416 : move16();
5258 :
5259 : /* NOTE: this function updates x till L_frame. From L_frame to L_spec, the exponent needs to be updated. */
5260 220416 : mdct_noiseShaping_ivas_fx( x_fx, x_e, L_frame, gainlpc2_fx, gainlpc2_e );
5261 :
5262 220416 : frame_side_x_e = *x_e;
5263 220416 : move16();
5264 :
5265 220416 : IF( bfi == 0 )
5266 : {
5267 85466960 : FOR( i = L_frame; i < L_spec; i++ )
5268 : {
5269 85248368 : x_fx[i] = Mpy_32_16_1( x_fx[i], gainlpc2_fx[FDNS_NPTS - 1] );
5270 85248368 : move32();
5271 : }
5272 218592 : spec_side_x_e = add( spec_side_x_e, gainlpc2_e[FDNS_NPTS - 1] );
5273 : }
5274 :
5275 220416 : IF( LT_16( spec_side_x_e, frame_side_x_e ) )
5276 : {
5277 : /* If the exponent on the spec side (i>L_frame) is lesser, then shift all the values in the
5278 : spec side by the difference to make both sides have the same exponent. */
5279 202303 : Word16 diff_e = sub( frame_side_x_e, spec_side_x_e );
5280 79696671 : FOR( i = L_frame; i < L_spec; i++ )
5281 : {
5282 79494368 : x_fx[i] = L_shr( x_fx[i], diff_e );
5283 79494368 : move32();
5284 : }
5285 : }
5286 18113 : ELSE IF( GT_16( spec_side_x_e, frame_side_x_e ) )
5287 : {
5288 : /* If the exponent on the spec side (i>L_frame) is greater, then shift all the values in the
5289 : frame side (i<L_frame) by the difference to make both sides have the same exponent. */
5290 0 : Word16 diff_e = sub( spec_side_x_e, frame_side_x_e );
5291 0 : FOR( i = 0; i < L_frame; i++ )
5292 : {
5293 0 : x_fx[i] = L_shr( x_fx[i], diff_e );
5294 0 : move32();
5295 : }
5296 : }
5297 220416 : *x_e = s_max( spec_side_x_e, frame_side_x_e );
5298 220416 : move16();
5299 :
5300 220416 : set32_fx( x_fx + L_spec, 0, sub( L_frameTCX, L_spec ) );
5301 : }
5302 :
5303 : /* PLC: [TCX: Tonal Concealment] */
5304 850462 : test();
5305 850462 : test();
5306 850462 : IF( bfi && st->tonal_mdct_plc_active && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
5307 : {
5308 192 : TonalMDCTConceal_Apply_ivas_fx( st->hTonalMDCTConc, x_fx, *x_e, st->hTcxCfg->psychParamsCurrent );
5309 :
5310 : /* If exponent has been updated after TonalMDCTConceal_Apply, then shift the spectrum to common exponent. */
5311 : }
5312 :
5313 850462 : test();
5314 850462 : IF( st->hTonalMDCTConc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
5315 : {
5316 220416 : tmp32 = L_deposit_h( 0 );
5317 220416 : if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
5318 : {
5319 106774 : tmp32 = st->old_fpitch;
5320 106774 : move32();
5321 : }
5322 :
5323 220416 : tmp8 = 0;
5324 220416 : move16();
5325 220416 : test();
5326 220416 : if ( bfi && st->tonal_mdct_plc_active )
5327 : {
5328 192 : tmp8 = 1;
5329 192 : move16();
5330 : }
5331 :
5332 220416 : TonalMDCTConceal_UpdateState( st->hTonalMDCTConc,
5333 : L_frameTCX,
5334 : tmp32,
5335 : bfi,
5336 : tmp8 );
5337 : }
5338 :
5339 850462 : *x_len = L_frameTCX;
5340 850462 : move16();
5341 :
5342 850462 : IF( st->enablePlcWaveadjust != 0 )
5343 : {
5344 0 : test();
5345 : /* spectrum concealment */
5346 0 : IF( bfi && EQ_16( *temp_concealment_method, TCX_NONTONAL ) )
5347 : {
5348 0 : concealment_decode_fix( st->core, x_fx, x_e, st->hPlcInfo );
5349 : }
5350 :
5351 : /* update spectrum buffer, tonality flag, etc. */
5352 0 : concealment_update_x( bfi, st->core, st->tonality_flag, x_fx, x_e, st->hPlcInfo );
5353 :
5354 0 : *x_len = s_max( *x_len, st->hPlcInfo->L_frameTCX );
5355 0 : move16();
5356 : }
5357 :
5358 : /*-----------------------------------------------------------*
5359 : * IGF *
5360 : *-----------------------------------------------------------*/
5361 :
5362 850462 : test();
5363 850462 : test();
5364 850462 : IF( st->igf && !( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
5365 : {
5366 550136 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
5367 : {
5368 : Word16 igfGridIdx;
5369 :
5370 206455 : test();
5371 206455 : IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && bfi ) )
5372 : {
5373 : /* packet loss after first TCX must be handled like transition frame */
5374 6802 : igfGridIdx = IGF_GRID_LB_TRAN;
5375 6802 : move16();
5376 : }
5377 : ELSE
5378 : {
5379 199653 : igfGridIdx = IGF_GRID_LB_NORM;
5380 199653 : move16();
5381 : }
5382 :
5383 206455 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
5384 :
5385 206455 : *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine );
5386 206455 : move16();
5387 : }
5388 : }
5389 850462 : test();
5390 850462 : test();
5391 850462 : IF( st->igf && ( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
5392 : {
5393 22478 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
5394 : {
5395 3802 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, IGF_GRID_LB_SHORT, bfi, st->element_mode );
5396 :
5397 3802 : *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[IGF_GRID_LB_SHORT].stopLine );
5398 3802 : move16();
5399 : }
5400 : }
5401 :
5402 850462 : return;
5403 : }
5404 :
5405 :
5406 : /*-------------------------------------------------------------------*
5407 : * decoder_tcx_tns()
5408 : *
5409 : * TCX: TNS application
5410 : *-------------------------------------------------------------------*/
5411 :
5412 1473018 : void decoder_tcx_tns_fx(
5413 : Decoder_State *st, /* i/o: coder memory state */
5414 : const Word16 L_frame_glob, /* i : frame length */
5415 : const Word16 L_spec,
5416 : const Word16 L_frame,
5417 : const Word16 L_frameTCX,
5418 : Word32 x_fx[N_MAX], // Qx
5419 : const Word16 fUseTns, /* i : flag that is set if TNS data is present */
5420 : STnsData *tnsData,
5421 : const Word16 bfi, /* i : Bad frame indicator */
5422 : const Word16 frame_cnt, /* i : frame counter in the super frame */
5423 : const Word16 whitenedDomain,
5424 : Word16 *length )
5425 : {
5426 : Word16 index, isTCX5, L, tmp;
5427 1473018 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
5428 :
5429 1473018 : index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
5430 1473018 : move16();
5431 :
5432 1473018 : isTCX5 = 0;
5433 1473018 : move16();
5434 1473018 : L = L_frameTCX;
5435 1473018 : move16();
5436 1473018 : tmp = L;
5437 1473018 : move16();
5438 :
5439 1473018 : test();
5440 1473018 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 )
5441 : {
5442 60600 : test();
5443 60600 : test();
5444 60600 : IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE )
5445 : {
5446 : /* fix sub-window overlap */
5447 30190 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
5448 30190 : move16();
5449 : }
5450 :
5451 60600 : test();
5452 60600 : test();
5453 60600 : test();
5454 60600 : test();
5455 60600 : IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) && whitenedDomain ) || GT_16( L_spec, L_frameTCX ) )
5456 : {
5457 20875 : L = L_spec;
5458 20875 : move16();
5459 20875 : tmp = L;
5460 20875 : move16();
5461 : }
5462 :
5463 60600 : test();
5464 60600 : test();
5465 60600 : test();
5466 60600 : test();
5467 60600 : test();
5468 60600 : test();
5469 60600 : test();
5470 60600 : IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ||
5471 : ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) ||
5472 : ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) &&
5473 : NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) )
5474 : {
5475 31383 : isTCX5 = 1;
5476 31383 : move16();
5477 :
5478 31383 : tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
5479 : }
5480 : }
5481 :
5482 : /*-----------------------------------------------------------*
5483 : * Temporal Noise Shaping Synthesis *
5484 : *-----------------------------------------------------------*/
5485 :
5486 :
5487 1473018 : test();
5488 1473018 : test();
5489 1473018 : test();
5490 1473018 : IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) )
5491 : {
5492 : /* Apply TNS to get the reconstructed signal */
5493 86580 : SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
5494 :
5495 86580 : test();
5496 86580 : test();
5497 86580 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
5498 : {
5499 12820 : tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx );
5500 : }
5501 :
5502 86580 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 );
5503 :
5504 86580 : test();
5505 86580 : test();
5506 86580 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
5507 : {
5508 12820 : test();
5509 12820 : test();
5510 12820 : IF( st->element_mode == EVS_MONO || ( LT_16( L_spec, L_frameTCX ) && !whitenedDomain ) ) /* todo: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */
5511 : {
5512 1190 : tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
5513 1190 : tmp = L_frameTCX;
5514 1190 : move16();
5515 : }
5516 : ELSE
5517 : {
5518 11630 : tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
5519 : }
5520 : }
5521 : }
5522 1473018 : test();
5523 1473018 : IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) )
5524 : {
5525 14638 : tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
5526 : }
5527 :
5528 : /* restore index */
5529 1473018 : test();
5530 1473018 : test();
5531 1473018 : test();
5532 1473018 : test();
5533 1473018 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && NE_16( st->tcxonly, 0 ) && NE_16( frame_cnt, 0 ) && EQ_16( bfi, 0 ) && NE_16( st->last_core, ACELP_CORE ) )
5534 : {
5535 : /* restore sub-window overlap */
5536 30190 : hTcxCfg->tcx_last_overlap_mode = index;
5537 30190 : move16();
5538 : }
5539 :
5540 1473018 : if ( length != NULL )
5541 : {
5542 1252602 : *length = tmp;
5543 1252602 : move16();
5544 : }
5545 :
5546 1473018 : return;
5547 : }
5548 :
5549 :
5550 846717 : void decoder_tcx_imdct_fx(
5551 : Decoder_State *st, /* i/o: coder memory state */
5552 : const Word16 L_frame_glob, /* i : frame length */
5553 : const Word16 L_frameTCX_glob,
5554 : const Word16 L_spec,
5555 : const Word16 tcx_offset,
5556 : const Word16 tcx_offsetFB,
5557 : const Word16 L_frame,
5558 : const Word16 L_frameTCX,
5559 : const Word16 left_rect,
5560 : Word32 x_fx[N_MAX], // Q(11)
5561 : Word16 q_x,
5562 : Word16 xn_buf_fx[], // Q(-2)
5563 : Word16 *q_win,
5564 : Word16 *q_winFB,
5565 : const UWord16 kernelType, /* i : TCX transform kernel type */
5566 : const Word16 fUseTns, /* i : flag that is set if TNS data is present */
5567 : Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */
5568 : Word16 synthFB_fx[], // Q(-2)
5569 : const Word16 bfi, /* i : Bad frame indicator */
5570 : const Word16 frame_cnt, /* i : frame counter in the super frame */
5571 : const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */
5572 : )
5573 : {
5574 : Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5;
5575 : Word16 overlapFB;
5576 : Word32 x_tmp_fx[L_FRAME_PLUS];
5577 846717 : Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 };
5578 : Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
5579 : Word16 acelp_zir_fx[L_FRAME_MAX / 2];
5580 : Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN];
5581 846717 : Word16 index, proc = 0;
5582 846717 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
5583 846717 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
5584 846717 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
5585 : Word16 predictionGain_fx;
5586 : Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf
5587 846717 : Word16 q_a_itf = 15;
5588 846717 : Word16 x_e = sub( 31, q_x );
5589 846717 : move16();
5590 846717 : Word16 q_acelp_zir_fx = 0;
5591 846717 : set16_fx( acelp_zir_fx, 0, L_FRAME_MAX / 2 );
5592 :
5593 : /*-----------------------------------------------------------------*
5594 : * Initializations
5595 : *-----------------------------------------------------------------*/
5596 :
5597 : /* Init lengths */
5598 846717 : overlap = hTcxCfg->tcx_mdct_window_length;
5599 846717 : move16();
5600 846717 : overlapFB = hTcxCfg->tcx_mdct_window_lengthFB;
5601 846717 : move16();
5602 :
5603 846717 : index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
5604 846717 : move16();
5605 846717 : test();
5606 846717 : test();
5607 846717 : test();
5608 846717 : test();
5609 846717 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) )
5610 : {
5611 : /* fix sub-window overlap */
5612 16073 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
5613 16073 : move16();
5614 : }
5615 :
5616 846717 : IF( st->igf != 0 )
5617 : {
5618 571234 : proc = st->hIGFDec->flatteningTrigger;
5619 571234 : move16();
5620 :
5621 571234 : test();
5622 571234 : IF( proc && fUseTns != 0 )
5623 : {
5624 57635 : proc = 0;
5625 57635 : move16();
5626 : }
5627 :
5628 571234 : IF( proc )
5629 : {
5630 :
5631 493655 : startLine = st->hIGFDec->infoIGFStartLine;
5632 493655 : move16();
5633 493655 : endLine = st->hIGFDec->infoIGFStopLine;
5634 493655 : move16();
5635 493655 : curr_order = 0;
5636 493655 : move16();
5637 493655 : predictionGain_fx = 0;
5638 493655 : move16();
5639 493655 : L = L_frameTCX;
5640 493655 : move16();
5641 493655 : isTCX5 = 0;
5642 493655 : move16();
5643 :
5644 : /* interleave again for ITF */
5645 493655 : test();
5646 493655 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
5647 : {
5648 9261 : test();
5649 9261 : test();
5650 9261 : test();
5651 9261 : IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) )
5652 : {
5653 1426 : L = L_spec;
5654 1426 : move16();
5655 : }
5656 :
5657 9261 : test();
5658 9261 : test();
5659 9261 : test();
5660 9261 : test();
5661 9261 : test();
5662 9261 : test();
5663 9261 : test();
5664 9261 : test();
5665 9261 : test();
5666 9261 : test();
5667 9261 : IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
5668 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) ||
5669 : ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) &&
5670 : ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) )
5671 : {
5672 2187 : isTCX5 = 1;
5673 2187 : move16();
5674 :
5675 2187 : tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
5676 : }
5677 : }
5678 :
5679 145563601 : FOR( j = startLine; j < endLine; j++ )
5680 : {
5681 145069946 : IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
5682 : {
5683 19626 : x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x
5684 19626 : move32();
5685 19626 : x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN];
5686 19626 : move32();
5687 : }
5688 : }
5689 :
5690 493655 : ITF_Detect_ivas_fx( x_fx + IGF_START_MN, startLine, endLine, 8 /*maxOrder*/, A_itf_fx, &q_a_itf, &predictionGain_fx, &curr_order, q_x );
5691 :
5692 493655 : ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order );
5693 :
5694 145563601 : FOR( j = startLine; j < endLine; j++ )
5695 : {
5696 145069946 : IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
5697 : {
5698 19626 : x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x
5699 19626 : move32();
5700 : }
5701 : }
5702 :
5703 : /* deinterleave */
5704 493655 : IF( NE_16( isTCX5, 0 ) )
5705 : {
5706 2187 : tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
5707 : }
5708 : }
5709 : }
5710 :
5711 : /*-----------------------------------------------------------*
5712 : * Prepare OLA buffer after waveadjustment. *
5713 : * Compute inverse MDCT of x[]. *
5714 : *-----------------------------------------------------------*/
5715 :
5716 :
5717 846717 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
5718 : {
5719 626301 : Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) );
5720 626301 : set32_fx( x_tmp_fx, 0, L_FRAME_PLUS );
5721 626301 : Copy32( x_fx, x_tmp_fx, copy_len ); // q_x
5722 626301 : Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
5723 : }
5724 220416 : ELSE IF( ( st->element_mode == EVS_MONO ) )
5725 : {
5726 0 : Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
5727 : }
5728 : ELSE
5729 : {
5730 220416 : Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) );
5731 220416 : Copy32( x_fx, x_tmp_fx, copy_len ); // q_x
5732 220416 : Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
5733 : }
5734 :
5735 846717 : IF( ( st->igf != 0 ) )
5736 : {
5737 571234 : set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine );
5738 : }
5739 :
5740 846717 : test();
5741 846717 : IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag )
5742 : {
5743 :
5744 1660304 : IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, &hTcxDec->Q_syn_Overl, hTcxDec->syn_Overl_TDAC, &hTcxDec->Q_syn_Overl_TDAC, xn_buf_fx, *q_win, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2,
5745 830152 : hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index,
5746 830152 : kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, &q_acelp_zir_fx, q_win );
5747 : }
5748 :
5749 : /* Generate additional comfort noise to mask potential coding artefacts */
5750 846717 : test();
5751 846717 : test();
5752 846717 : test();
5753 846717 : IF( ( st->flag_cna != 0 ) && NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && ( st->cna_dirac_flag == 0 ) )
5754 : {
5755 22605 : generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom );
5756 6637309 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
5757 : {
5758 6614704 : x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x
5759 : }
5760 : }
5761 :
5762 846717 : test();
5763 846717 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) )
5764 : {
5765 16565 : Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
5766 16565 : IMDCT_ivas_fx( xn_bufFB_fx, q_x, hTcxDec->syn_Overl, &hTcxDec->Q_syn_Overl, hTcxDec->syn_Overl_TDAC, &hTcxDec->Q_syn_Overl_TDAC, xn_buf_fx, *q_win, hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, index,
5767 16565 : kernelType, left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, frame_cnt, bfi, st->hHQ_core->old_out_LB_fx, &st->hHQ_core->Q_old_wtda_LB, 0, st, 0, acelp_zir_fx, &q_acelp_zir_fx, q_win );
5768 : }
5769 :
5770 : Word16 shift_q, q_x16;
5771 :
5772 846717 : shift_q = L_norm_arr( xn_bufFB_fx, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX );
5773 846717 : shift_q = sub( 16, shift_q );
5774 846717 : q_x16 = sub( q_x, shift_q );
5775 :
5776 1728149397 : FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
5777 : {
5778 1727302680 : assert( extract_h( L_shr( xn_bufFB_fx[ind], shift_q ) ) == 0 || extract_h( L_shr( xn_bufFB_fx[ind], shift_q ) ) == -1 );
5779 1727302680 : xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x16
5780 1727302680 : move16();
5781 : }
5782 :
5783 : Word16 ratio_e;
5784 846717 : Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9)
5785 846717 : ratio = shr( ratio, sub( 6, ratio_e ) );
5786 :
5787 846717 : IF( st->element_mode != EVS_MONO )
5788 : {
5789 1693434 : IMDCT_ivas_fx( x_tmp_fx, q_x, hTcxDec->syn_OverlFB, &hTcxDec->Q_syn_OverlFB, hTcxDec->syn_Overl_TDACFB, &hTcxDec->Q_syn_Overl_TDACFB, xn_bufFB_fx_16, q_x16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB,
5790 846717 : hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index,
5791 846717 : kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, &q_acelp_zir_fx, q_winFB );
5792 : }
5793 : ELSE
5794 : {
5795 0 : IMDCT_ivas_fx( x_fx, q_x, hTcxDec->syn_OverlFB, &hTcxDec->Q_syn_OverlFB, hTcxDec->syn_Overl_TDACFB, &hTcxDec->Q_syn_Overl_TDACFB, xn_bufFB_fx_16, q_x16, hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_half_lengthFB, hTcxCfg->tcx_mdct_window_min_lengthFB, index,
5796 0 : kernelType, left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, frame_cnt, bfi, st->hHQ_core->old_out_fx, &st->hHQ_core->Q_old_wtda, 1, st, ratio, acelp_zir_fx, &q_acelp_zir_fx, q_winFB );
5797 : }
5798 :
5799 846717 : shift_q = 16;
5800 846717 : move16();
5801 :
5802 1728149397 : FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
5803 : {
5804 1727302680 : xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // q_winFB
5805 : }
5806 :
5807 846717 : IF( ( bfi == 0 ) )
5808 : {
5809 837984 : Word16 res_m, res_e = 0;
5810 837984 : move16();
5811 837984 : st->second_last_tns_active = st->last_tns_active;
5812 837984 : move16();
5813 837984 : st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns;
5814 837984 : move16();
5815 837984 : hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
5816 837984 : move32();
5817 837984 : hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
5818 837984 : move32();
5819 837984 : res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e );
5820 837984 : st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) );
5821 :
5822 837984 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
5823 : {
5824 : // Using sat as a single instruction shifts and extracts
5825 619392 : st->old_fpitch = W_shl_sat_l( W_mult0_32_32( st->old_fpitch, L_frame_glob ), -8 ); // Divide by 256 ==> SHR by 8
5826 619392 : move32();
5827 : }
5828 :
5829 837984 : IF( GT_16( st->element_mode, EVS_MONO ) )
5830 : {
5831 837984 : res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e );
5832 837984 : st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
5833 837984 : move32();
5834 : }
5835 : ELSE
5836 : {
5837 0 : res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e );
5838 0 : st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
5839 0 : move32();
5840 : }
5841 : }
5842 :
5843 : /* Update old_syn_overl */
5844 846717 : IF( hTcxCfg->last_aldo == 0 )
5845 : {
5846 21801 : Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // q_win
5847 7752881 : FOR( Word16 ind = 0; ind < overlapFB; ind++ )
5848 : {
5849 7731080 : assert( extract_h( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ) == 0 || extract_h( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ) == -1 );
5850 7731080 : hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_winFB
5851 : }
5852 : }
5853 :
5854 : /* Output */
5855 846717 : Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // q_win
5856 695994877 : FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ )
5857 : {
5858 695148160 : assert( extract_h( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ) == 0 ||
5859 : extract_h( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ) == -1 );
5860 695148160 : synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_winFB
5861 : }
5862 :
5863 :
5864 846717 : return;
5865 : }
|