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