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 849869 : 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 849869 : Flag Overflow = 0;
1548 849869 : move32();
1549 : #endif
1550 :
1551 849869 : hTcxDec = st_fx->hTcxDec;
1552 :
1553 : /* TCX output */
1554 849869 : Copy( synth, xn_buf, st_fx->L_frame );
1555 :
1556 : /* first TCX frame after ACELP; overwrite ltp initialization done during acelp PLC */
1557 849869 : test();
1558 849869 : test();
1559 849869 : 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 849869 : test();
1565 849869 : test();
1566 849869 : test();
1567 849869 : 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 449557 : st_fx->hTcxLtpDec->tcxltp = 0;
1571 449557 : move16();
1572 449557 : st_fx->hTcxLtpDec->tcxltp_gain = 0;
1573 449557 : move16();
1574 : }
1575 849869 : test();
1576 849869 : IF( bfi != 0 && st_fx->use_partial_copy == 0 )
1577 : {
1578 9423 : test();
1579 9423 : test();
1580 : /* run lpc gain compensation not for waveform adjustment */
1581 9423 : IF( 0 == st_fx->enablePlcWaveadjust || ( st_fx->hPlcInfo != NULL && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_TONAL ) ) )
1582 : {
1583 : UWord32 dmy;
1584 9423 : tmp32_1 /*gainHelperFB*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1585 9423 : tmp32_2 /*stepCompensateFB*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1586 :
1587 9423 : Mpy_32_32_ss( tmp32_2 /*Q28*/,
1588 9423 : L_shl( L_mult0( st_fx->L_frame,
1589 9423 : getInvFrameLen( hTcxDec->L_frameTCX ) /*Q21*/ ) /*Q21*/,
1590 : 8 ) /*Q29*/,
1591 : &tmp32_2,
1592 : &dmy ); /*Q26*/
1593 :
1594 9423 : tmp32_2 = L_shl( tmp32_2, 3 - 1 ); /*Q28*/
1595 :
1596 6616143 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1597 : {
1598 6606720 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1599 6606720 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp32, synthFB[i] ), 16 ) ); // Q_syn
1600 6606720 : move16();
1601 6606720 : tmp32_1 = L_sub( tmp32_1, tmp32_2 );
1602 : }
1603 : }
1604 9423 : tmp32_1 /*gainHelper*/ = L_shl_r( L_deposit_h( hTcxDec->gainHelper ), sub( hTcxDec->gainHelper_e, 31 - 28 ) ); /*Q28*/
1605 9423 : tmp32_2 /*stepCompensate*/ = L_shl_r( L_deposit_h( hTcxDec->stepCompensate ), sub( hTcxDec->stepCompensate_e, 31 - 28 ) ); /*Q28*/
1606 4478287 : FOR( i = 0; i < st_fx->L_frame; i++ )
1607 : {
1608 4468864 : tmp32 = L_shl( tmp32_1 /*Q28*/, -( 28 - 15 ) ); /*16Q15*/
1609 4468864 : xn_buf[i] = extract_h( L_shl_sat( Mpy_32_16_1( tmp32, xn_buf[i] ), 16 ) ); // Q_syn
1610 4468864 : move16();
1611 4468864 : 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 849869 : s = sub( getScaleFactor16( synthFB, hTcxDec->L_frameTCX ), 4 );
1620 : {
1621 849869 : Word64 tmp64 = 0;
1622 849869 : move64();
1623 709271629 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1624 : {
1625 708421760 : tmp1 = shl( synthFB[i], s );
1626 708421760 : tmp64 = W_mac0_16_16( tmp64, tmp1, tmp1 );
1627 : }
1628 849869 : tmp32 = W_sat_l( tmp64 );
1629 : }
1630 849869 : tmp32 = Mpy_32_16_1( tmp32, getInvFrameLen( hTcxDec->L_frameTCX ) );
1631 849869 : tmp2 = norm_l( tmp32 );
1632 849869 : 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 849869 : s = sub( 25, add( shl( add( Q_syn, s ), 1 ), tmp2 ) );
1635 849869 : tmp1 = Sqrt16( tmp1, &s );
1636 849869 : move16();
1637 849869 : level_syn = tmp1; /*Q0*/
1638 :
1639 : /* PLC: [TCX: Fade-out]
1640 : * PLC: estimate and update CNG energy */
1641 :
1642 849869 : level_syn_e = s; // add(s, 15);
1643 849869 : move16();
1644 849869 : test();
1645 849869 : test();
1646 849869 : test();
1647 849869 : test();
1648 849869 : 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 849869 : IF( bfi != 0 )
1676 : {
1677 : Word32 conceal_eof_gainFB;
1678 : Word16 conceal_eof_gainFB_e;
1679 9423 : move16();
1680 9423 : move16();
1681 9423 : gainCNG = 1;
1682 9423 : gainCNG_e = 14 + 15 + 6; /*gainCNG is 2`097`152 - should be enough in case tracinglevel =~0 */
1683 9423 : IF( st_fx->tcxonly != 0 )
1684 : {
1685 : /*gainCNG = st_fx->conCngLevelBackgroundTrace/(tracingLevel+0.01f);*/
1686 8185 : IF( level_syn )
1687 : {
1688 6847 : 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 1338 : level_syn = 328; /* (1 / 0.01) in Q15 */
1693 1338 : level_syn_e = 0;
1694 1338 : move16();
1695 1338 : 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 1238 : IF( level_syn )
1728 : {
1729 1237 : 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 1238 : IF( level_syn != 0 )
1740 : {
1741 1238 : BASOP_Util_Divide_MantExp(
1742 1238 : st_fx->cngTDLevel,
1743 1238 : st_fx->cngTDLevel_e,
1744 : level_syn,
1745 : level_syn_e,
1746 : &gainCNG,
1747 : &gainCNG_e );
1748 : }
1749 : }
1750 :
1751 9423 : IF( ( EQ_16( st_fx->nbLostCmpt, 1 ) ) )
1752 : {
1753 5075 : hTcxDec->conceal_eof_gain32 = ONE_IN_Q30 /*1.0f Q30*/;
1754 5075 : move32();
1755 5075 : hTcxDec->conceal_eof_gain_e = 1;
1756 5075 : 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 18846 : Word32 L_tmp = BASOP_Util_Add_Mant32Exp(
1761 : Mpy_32_16_1( hTcxDec->conceal_eof_gain32,
1762 9423 : hTcxDec->damping /*Q14*/ ),
1763 9423 : add( 1, hTcxDec->conceal_eof_gain_e ) /*->Q15*/,
1764 9423 : L_mult( gainCNG /*Q15*/, sub( 0x4000, hTcxDec->damping /*Q14*/ ) ) /*Q14*/,
1765 9423 : add( gainCNG_e, 15 - 14 ) /*->Q15*/,
1766 : &tmp2 );
1767 :
1768 9423 : L_tmp = BASOP_Util_Add_Mant32Exp( hTcxDec->conceal_eof_gain32, hTcxDec->conceal_eof_gain_e, L_negate( L_tmp ), tmp2, &tmp2 );
1769 9423 : step = Mpy_32_16_1( L_tmp, getInvFrameLen( st_fx->L_frame ) );
1770 9423 : step_e = sub( tmp2, 6 );
1771 : {
1772 : Word32 stepFB;
1773 : Word16 stepFB_e;
1774 : UWord32 dmy;
1775 : Word16 tmp_shift;
1776 9423 : conceal_eof_gainFB = hTcxDec->conceal_eof_gain32;
1777 9423 : conceal_eof_gainFB_e = hTcxDec->conceal_eof_gain_e;
1778 9423 : move32();
1779 9423 : move16();
1780 9423 : Mpy_32_32_ss( step, L_shl( L_mult0( st_fx->L_frame, getInvFrameLen( hTcxDec->L_frameTCX ) ), 8 ), &stepFB, &dmy );
1781 9423 : stepFB_e = add( step_e, 2 );
1782 :
1783 6616143 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
1784 : {
1785 6606720 : tmp_shift = conceal_eof_gainFB_e;
1786 6606720 : synthFB[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( conceal_eof_gainFB, synthFB[i] ), tmp_shift ) ); // Q_syn
1787 6606720 : move16();
1788 6606720 : 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 4478287 : FOR( i = 0; i < st_fx->L_frame; i++ )
1792 : {
1793 4468864 : 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 4468864 : move16();
1795 4468864 : 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 4468864 : move32();
1797 : }
1798 :
1799 : /* run lpc gain compensation not for waveform adjustment */
1800 9423 : 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 849869 : 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 849869 : st_fx->old_pitch_buf_fx[0] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr];
1833 849869 : move32();
1834 849869 : st_fx->old_pitch_buf_fx[1] = st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 1];
1835 849869 : move32();
1836 849869 : Copy32( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], &st_fx->old_pitch_buf_fx[2], st_fx->nb_subfr );
1837 849869 : set32_fx( &st_fx->old_pitch_buf_fx[st_fx->nb_subfr + 2], st_fx->old_fpitch, st_fx->nb_subfr );
1838 849869 : st_fx->bfi_pitch_fx = shl_sat( round_fx( st_fx->old_fpitch ), 6 );
1839 849869 : st_fx->bfi_pitch_frame = st_fx->L_frame;
1840 849869 : move16();
1841 :
1842 849869 : st_fx->mem_pitch_gain[st_fx->nb_subfr * 2 + 1] = st_fx->mem_pitch_gain[st_fx->nb_subfr + 1]; // Q14
1843 849869 : move16();
1844 849869 : st_fx->mem_pitch_gain[st_fx->nb_subfr * 2] = st_fx->mem_pitch_gain[st_fx->nb_subfr]; // Q14
1845 849869 : move16();
1846 :
1847 4789021 : FOR( i = 0; i < st_fx->nb_subfr; i++ )
1848 : {
1849 3939152 : 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 3939152 : move16();
1851 3939152 : st_fx->mem_pitch_gain[st_fx->nb_subfr - 1 - i] = shr( hTcxDec->tcxltp_last_gain_unmodified, 1 ); /* Q14 */
1852 3939152 : move16();
1853 : }
1854 849869 : }
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 1585142 : void IMDCT_ivas_fx(
2576 : Word32 *x_fx, // Q(q_x)
2577 : Word16 q_x,
2578 : Word16 *old_syn_overl_fx, // Q(-2)
2579 : Word16 *syn_Overl_TDAC_fx, // Q(-2)
2580 : Word16 *xn_buf_fx, // Q(-2)
2581 : const Word16 *tcx_aldo_window_1_fx, // Q(15)
2582 : const PWord16 *tcx_aldo_window_1_trunc_fx, // Q(15)
2583 : const PWord16 *tcx_aldo_window_2_fx, // Q(15)
2584 : const PWord16 *tcx_mdct_window_half_fx, // Q(15)
2585 : const PWord16 *tcx_mdct_window_minimum_fx, // Q(15)
2586 : const PWord16 *tcx_mdct_window_trans_fx, // Q(15)
2587 : const Word16 tcx_mdct_window_half_length, // Q(15)
2588 : const Word16 tcx_mdct_window_min_length, // Q(15)
2589 : Word16 index,
2590 : const UWord16 kernel_type, /* i : TCX transform kernel type */
2591 : const Word16 left_rect,
2592 : const Word16 tcx_offset,
2593 : const Word16 overlap,
2594 : const Word16 L_frame,
2595 : const Word16 L_frameTCX,
2596 : const Word16 L_spec_TCX5,
2597 : const Word16 L_frame_glob,
2598 : const Word16 frame_cnt,
2599 : const Word16 bfi,
2600 : Word16 *old_out_fx, // Q(-2)
2601 : const Word16 FB_flag,
2602 : Decoder_State *st,
2603 : const Word16 fullbandScale,
2604 : Word16 *acelp_zir_fx,
2605 : Word16 q_win ) // Q(-2)
2606 : {
2607 : Word16 i, nz, aldo, w, L_win, L_ola;
2608 : Word16 win_fx[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2609 1585142 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
2610 1585142 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
2611 : Word16 x_e_hdrm;
2612 : Word32 c;
2613 : Word16 exp;
2614 1585142 : x_e_hdrm = add( q_win, sub( Q16, q_x ) );
2615 :
2616 1585142 : aldo = 0;
2617 1585142 : move16();
2618 :
2619 1585142 : c = L_mult0( NS2SA_FX2( st->output_Fs, N_ZERO_MDCT_NS ), L_frame );
2620 1585142 : exp = 0;
2621 1585142 : move16();
2622 1585142 : nz = BASOP_Util_Divide3216_Scale( c, L_frameTCX, &exp );
2623 1585142 : exp = add( exp, ( 31 - 15 ) );
2624 1585142 : nz = shr( nz, sub( 15, exp ) ); // Q0
2625 :
2626 1585142 : test();
2627 1585142 : test();
2628 1585142 : test();
2629 1585142 : test();
2630 1585142 : test();
2631 1585142 : test();
2632 1585142 : 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 ) )
2633 : {
2634 : Word32 fac;
2635 : // 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 );
2636 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
2637 : #ifdef OPT_SBA_DEC_V2_BE
2638 30 : Word16 eff_e = add( hTcxDec->conceal_eof_gain_e, st->last_concealed_gain_syn_deemph_e );
2639 : #endif /* OPT_SBA_DEC_V2_BE */
2640 6442 : FOR( Word16 ind = 0; ind < overlap; ind++ )
2641 : {
2642 : #ifdef OPT_SBA_DEC_V2_BE
2643 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)
2644 : #else /* OPT_SBA_DEC_V2_BE */
2645 : 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)
2646 : #endif /* OPT_SBA_DEC_V2_BE */
2647 6412 : move16();
2648 : }
2649 : }
2650 :
2651 1585142 : test();
2652 1585142 : IF( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && st->tcxonly )
2653 : {
2654 : /* Mode decision in PLC
2655 :
2656 : last OL curr OL left TCX-10 right TCX-10
2657 : -------------------------------------------------------------
2658 : 0 0 2x TCX-5* 1x TCX-10
2659 : 0 2 1x TCX-10 1x TCX-10
2660 : 0 3 1x TCX-10 1x TCX-10
2661 : 2 0 2x TCX-5 1x TCX-10
2662 : 2 2 2x TCX-5 2x TCX-5
2663 : 2 3 2x TCX-5 2x TCX-5
2664 : 3 0 2x TCX-5 1x TCX-10
2665 : 3 2 2x TCX-5 2x TCX-5
2666 : 3 3 2x TCX-5 2x TCX-5
2667 : */
2668 58344 : test();
2669 58344 : test();
2670 58344 : test();
2671 58344 : test();
2672 58344 : test();
2673 58344 : test();
2674 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 ) ) )
2675 17192 : {
2676 : /* minimum or half overlap, two transforms, grouping into one window */
2677 17192 : L_win = shr( L_frame, 1 );
2678 : // L_ola = EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ? tcx_mdct_window_min_length : tcx_mdct_window_half_length;
2679 17192 : IF( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
2680 : {
2681 7530 : L_ola = tcx_mdct_window_min_length;
2682 : }
2683 : ELSE
2684 : {
2685 9662 : L_ola = tcx_mdct_window_half_length;
2686 : }
2687 17192 : move16();
2688 :
2689 17192 : set16_fx( win_fx, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) >> 1 );
2690 17192 : Word16 tcx_offset_tmp = add( tcx_offset, shr( L_ola, 1 ) );
2691 17192 : set16_fx( xn_buf_fx, 0, tcx_offset_tmp ); /* zero left end of buffer */
2692 :
2693 17192 : Word16 L_spec_TCX5_tmp = 0;
2694 17192 : move16();
2695 51576 : FOR( w = 0; w < 2; w++ )
2696 : {
2697 34384 : test();
2698 34384 : test();
2699 34384 : L_spec_TCX5_tmp = imult1616( w, L_spec_TCX5 );
2700 34384 : IF( EQ_16( kernel_type, MDST_IV ) || s_and( kernel_type, w ) )
2701 : {
2702 8 : TCX_MDST_Inverse_fx( x_fx + L_spec_TCX5_tmp, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola );
2703 : }
2704 34376 : ELSE IF( ( kernel_type != 0 ) && ( w == 0 ) ) /* type 1 or 2 */
2705 : {
2706 34 : 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 );
2707 : }
2708 : ELSE
2709 : {
2710 34342 : 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 );
2711 : }
2712 :
2713 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 );
2714 :
2715 34384 : IF( w > 0 )
2716 : {
2717 : Word16 tmp;
2718 17192 : tmp = add( sub( tcx_offset, shr( L_ola, 1 ) ), imult1616( w, L_win ) );
2719 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 );
2720 : }
2721 :
2722 : /* add part of current sub-window overlapping with previous window */
2723 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 );
2724 :
2725 : /* copy new sub-window region not overlapping with previous window */
2726 34384 : Copy( win_fx + L_ola, xn_buf_fx + add( tcx_offset, add( shr( L_ola, 1 ), imult1616( w, L_win ) ) ), L_win );
2727 : }
2728 :
2729 : /* To assure that no garbage values are passed to overlap */
2730 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 ) ) ) );
2731 17192 : test();
2732 17192 : test();
2733 17192 : test();
2734 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 ) )
2735 : {
2736 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 );
2737 2 : v_add_16( xn_buf_fx, old_syn_overl_fx, xn_buf_fx, overlap );
2738 : }
2739 : }
2740 41152 : ELSE IF( ( bfi == 0 ) && ( frame_cnt == 0 ) && EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
2741 : {
2742 : /* special overlap attempt, two transforms, grouping into one window */
2743 13148 : L_win = shr( L_frame, 1 );
2744 13148 : L_ola = tcx_mdct_window_min_length;
2745 13148 : move16();
2746 :
2747 13148 : set16_fx( win_fx, 0, shr( add( L_FRAME_PLUS, L_MDCT_OVLP_MAX ), 1 ) );
2748 :
2749 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
2750 13148 : IF( EQ_16( kernel_type, MDST_IV ) )
2751 : {
2752 0 : TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, win_fx + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola );
2753 : }
2754 13148 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
2755 : {
2756 4 : 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 );
2757 : }
2758 : ELSE
2759 : {
2760 13144 : 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 );
2761 : }
2762 :
2763 13148 : set16_fx( xn_buf_fx, 0, shr( overlap, 1 ) );
2764 :
2765 : /* copy new sub-window region not overlapping with previous window */
2766 13148 : Copy( win_fx + L_win, xn_buf_fx + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
2767 :
2768 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
2769 13148 : IF( s_and( kernel_type, 1 ) )
2770 : {
2771 4 : TCX_MDST_Inverse_fx( x_fx + L_spec_TCX5, x_e_hdrm, win_fx, L_ola, sub( L_win, L_ola ), L_ola );
2772 : }
2773 : ELSE
2774 : {
2775 13144 : 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 );
2776 : }
2777 :
2778 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,
2779 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 );
2780 :
2781 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 );
2782 :
2783 : /* add part of current sub-window overlapping with previous window */
2784 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 );
2785 :
2786 : /* copy new sub-window region not overlapping with previous window */
2787 13148 : Copy( win_fx + L_ola, xn_buf_fx + add( add( shr( overlap, 1 ), L_win ), shr( L_ola, 1 ) ), L_win );
2788 :
2789 : /* extra folding-out on left side of win, for perfect reconstruction */
2790 13148 : IF( GE_16( kernel_type, MDCT_II ) )
2791 : {
2792 0 : FOR( w = overlap / 2; w < overlap; w++ )
2793 : {
2794 0 : xn_buf_fx[overlap - 1 - w] = xn_buf_fx[w];
2795 0 : move16();
2796 : }
2797 : }
2798 : ELSE
2799 : {
2800 2049672 : FOR( w = overlap / 2; w < overlap; w++ )
2801 : {
2802 2036524 : xn_buf_fx[overlap - 1 - w] = negate( xn_buf_fx[w] );
2803 2036524 : move16();
2804 : }
2805 : }
2806 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 );
2807 : }
2808 : ELSE
2809 : {
2810 : /* default, i.e. maximum overlap, single transform, no grouping */
2811 28004 : IF( EQ_16( kernel_type, MDST_IV ) )
2812 : {
2813 8 : TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap );
2814 : }
2815 27996 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
2816 : {
2817 24 : TCX_MDXT_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, kernel_type );
2818 : }
2819 : ELSE
2820 : {
2821 27972 : TCX_MDCT_Inverse( x_fx, x_e_hdrm, xn_buf_fx, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
2822 : }
2823 :
2824 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 );
2825 :
2826 : } /* tcx_last_overlap_mode != FULL_OVERLAP */
2827 : }
2828 : ELSE
2829 : {
2830 : /* frame is TCX-20 or not TCX-only */
2831 1526798 : assert( frame_cnt == 0 );
2832 1526798 : IF( NE_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
2833 : {
2834 :
2835 : Word16 q_tmp_fx_32, q_xn_buf_fx_32;
2836 1510152 : q_tmp_fx_32 = 15;
2837 1510152 : q_xn_buf_fx_32 = q_x;
2838 1510152 : move16();
2839 1510152 : move16();
2840 : Word32 xn_buf_fx_32[2000], tmp_fx_32[1200], old_out_fx_32[1200];
2841 1510152 : set32_fx( xn_buf_fx_32, 0, 2000 );
2842 1510152 : IF( NE_16( kernel_type, MDCT_IV ) ) /* inverse transform */
2843 : {
2844 1578 : Word16 tmp_a = add( shr( overlap, 1 ), nz );
2845 1578 : IF( EQ_16( kernel_type, MDST_IV ) )
2846 : {
2847 600 : edst_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, &q_xn_buf_fx_32 );
2848 : }
2849 : ELSE /* type 1 or 2 */
2850 : {
2851 978 : edxt_fx( x_fx, xn_buf_fx_32 + tmp_a, L_frame, kernel_type, TRUE );
2852 : }
2853 :
2854 : Word16 res_m, res_e;
2855 1578 : res_e = 0;
2856 1578 : move16();
2857 1578 : res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
2858 1578 : res_m = Sqrt16( res_m, &res_e );
2859 :
2860 782442 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2861 : {
2862 780864 : tmp_fx_32[ind] = L_shl( Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m ), res_e );
2863 780864 : move32();
2864 : }
2865 1578 : q_tmp_fx_32 = q_xn_buf_fx_32;
2866 1578 : move16();
2867 :
2868 1578 : Word16 diff = sub( q_tmp_fx_32, q_win );
2869 782442 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2870 : {
2871 780864 : old_out_fx_32[ind] = L_shl( old_out_fx[ind], diff );
2872 780864 : move32();
2873 : }
2874 :
2875 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 );
2876 :
2877 782442 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2878 : {
2879 780864 : old_out_fx[ind] = extract_l( L_shr( old_out_fx_32[ind], diff ) );
2880 780864 : xn_buf_fx[ind] = extract_l( L_shr( xn_buf_fx_32[ind], diff ) );
2881 780864 : move16();
2882 780864 : move16();
2883 : }
2884 : }
2885 : ELSE
2886 : {
2887 1508574 : Word16 q_old_out = q_win;
2888 1508574 : move16();
2889 1508574 : edct_ivas_fx( x_fx, xn_buf_fx_32 + add( shr( overlap, 1 ), nz ), L_frame, &q_xn_buf_fx_32 );
2890 : Word16 res_m, res_e;
2891 1508574 : res_e = 0;
2892 1508574 : move16();
2893 1508574 : res_m = BASOP_Util_Divide1616_Scale( L_frame, NORM_MDCT_FACTOR, &res_e );
2894 1508574 : res_m = Sqrt16( res_m, &res_e );
2895 :
2896 1031244254 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2897 : {
2898 1029735680 : tmp_fx_32[ind] = Mpy_32_16_1( xn_buf_fx_32[( overlap / 2 ) + nz + ind], res_m );
2899 1029735680 : move32();
2900 : }
2901 1508574 : q_tmp_fx_32 = sub( q_xn_buf_fx_32, res_e );
2902 : // v_multc_fixed( xn_buf_fx_32 + overlap / 2 + nz, (float) sqrt( (float) L_frame / NORM_MDCT_FACTOR ), tmp_fx_32, L_frame );
2903 :
2904 1508574 : Word16 q_diff = sub( q_xn_buf_fx_32, q_win );
2905 1031244254 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2906 : {
2907 1029735680 : xn_buf_fx[( ind + ( overlap / 2 ) ) + nz] = extract_l( L_shr( xn_buf_fx_32[( ind + ( overlap / 2 ) ) + nz], q_diff ) );
2908 1029735680 : move16();
2909 : }
2910 :
2911 1508574 : 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 );
2912 :
2913 1508574 : q_diff = sub( q_old_out, q_win );
2914 :
2915 1508574 : Word16 diff = sub( q_tmp_fx_32, q_win );
2916 1031244254 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
2917 : {
2918 1029735680 : old_out_fx[ind] = shr_sat( old_out_fx[ind], q_diff );
2919 1029735680 : move16();
2920 1029735680 : xn_buf_fx[ind] = shr_sat( xn_buf_fx[ind], diff );
2921 1029735680 : move16();
2922 : }
2923 : }
2924 1510152 : aldo = 1;
2925 1510152 : move16();
2926 : }
2927 : ELSE
2928 : {
2929 : // Word16 acelp_mem_len = tcx_offset < 0 ? -tcx_offset : 0;
2930 : Word16 acelp_mem_len;
2931 :
2932 16646 : IF( tcx_offset < 0 )
2933 : {
2934 16646 : acelp_mem_len = negate( tcx_offset );
2935 : }
2936 : ELSE
2937 : {
2938 0 : acelp_mem_len = 0;
2939 0 : move16();
2940 : }
2941 :
2942 16646 : IF( EQ_16( kernel_type, MDST_IV ) )
2943 : {
2944 0 : TCX_MDST_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap );
2945 : }
2946 16646 : ELSE IF( NE_16( kernel_type, MDCT_IV ) ) /* type 1 or 2 */
2947 : {
2948 0 : TCX_MDXT_Inverse_fx( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, kernel_type );
2949 : }
2950 : ELSE
2951 : {
2952 16646 : TCX_MDCT_Inverse( x_fx, x_e_hdrm, xn_buf_fx, overlap, L_frame - overlap, overlap, st->element_mode );
2953 : }
2954 :
2955 : /*-----------------------------------------------------------*
2956 : * Windowing, overlap and add *
2957 : *-----------------------------------------------------------*/
2958 16646 : test();
2959 16646 : test();
2960 16646 : test();
2961 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 ) )
2962 : {
2963 : /* get LPC from that signal part to use for acelp zir smoothing */
2964 1263 : const Word16 analysis_len = shr( L_frame_glob, 2 );
2965 : Word16 buf_fx[L_FRAME_MAX / 4];
2966 : Word16 window_buf_fx[L_FRAME_MAX / 4];
2967 : Word32 r_fx[M + 1];
2968 : Word16 q_r, q_buf;
2969 :
2970 : /* get the first 5 ms of non-aliased TCX syntesis */
2971 1263 : Copy( xn_buf_fx + add( shr( overlap, 1 ), shl( acelp_mem_len, 1 ) ), &buf_fx[0], analysis_len );
2972 :
2973 1263 : q_buf = q_win;
2974 1263 : move16();
2975 :
2976 1263 : ham_cos_window_ivas( &window_buf_fx[0], shr( analysis_len, 1 ), shr( analysis_len, 1 ) );
2977 1263 : autocorr_fx_32( &buf_fx[0], M, &r_fx[0], &q_r, analysis_len, &window_buf_fx[0], 0, 0 );
2978 1263 : lag_wind_32( r_fx, M, L_frame_glob * FRAMES_PER_SEC, LAGW_STRONG );
2979 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 ) );
2980 22734 : FOR( Word16 ind = 0; ind <= M; ind++ )
2981 : {
2982 21471 : st->old_Aq_12_8_fx[ind] = (Word16) L_shr( st->old_Aq_12_8_fx_32[ind], 16 ); // Q28 -> Q12
2983 21471 : move16();
2984 : }
2985 : }
2986 :
2987 : /* Window current frame */
2988 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 );
2989 : }
2990 : } /* TCX-20 and TCX-only */
2991 1585142 : test();
2992 1585142 : IF( ( frame_cnt != 0 ) || GT_16( st->last_core_bfi, ACELP_CORE ) )
2993 : {
2994 1555720 : test();
2995 1555720 : test();
2996 1555720 : IF( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( st->tcxonly != 0 ) ) ||
2997 : EQ_16( hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
2998 : {
2999 52442 : test();
3000 52442 : test();
3001 52442 : test();
3002 52442 : test();
3003 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 ) )
3004 : {
3005 13148 : index = MIN_OVERLAP; /* use minimum overlap between the two TCX-10 windows */
3006 13148 : move16();
3007 : }
3008 :
3009 52442 : IF( hTcxCfg->last_aldo != 0 )
3010 : {
3011 5646948 : FOR( i = 0; i < sub( overlap, tcx_mdct_window_min_length ); i++ )
3012 : {
3013 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)
3014 5624952 : move16();
3015 : }
3016 :
3017 : /* fade truncated ALDO window */
3018 21996 : test();
3019 21996 : test();
3020 21996 : test();
3021 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 ) )
3022 : {
3023 : // tested
3024 596792 : FOR( ; i < overlap; i++ ) /* perfectly reconstructing ALDO shortening */
3025 : {
3026 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(-2)
3027 583040 : move16();
3028 : }
3029 305272 : FOR( i = 0; i < ( tcx_mdct_window_min_length / 2 ); i++ )
3030 : {
3031 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(-2)
3032 291520 : move16();
3033 : }
3034 305272 : FOR( ; i < tcx_mdct_window_min_length; i++ )
3035 : {
3036 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(-2)
3037 291520 : move16();
3038 : }
3039 : }
3040 : ELSE
3041 : {
3042 185470 : FOR( ; i < ( overlap - ( tcx_mdct_window_min_length / 2 ) ); i++ )
3043 : {
3044 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)
3045 177226 : move16();
3046 : }
3047 185470 : FOR( ; i < overlap; i++ )
3048 : {
3049 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)
3050 177226 : move16();
3051 : }
3052 : }
3053 : }
3054 : ELSE
3055 : {
3056 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 );
3057 :
3058 30446 : IF( bfi != 0 )
3059 : {
3060 7264 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
3061 : {
3062 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)
3063 7110 : move16();
3064 : }
3065 7264 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3066 : {
3067 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)
3068 7110 : move16();
3069 : }
3070 : }
3071 30292 : ELSE IF( left_rect == 0 )
3072 : {
3073 9155604 : FOR( i = 0; i < overlap; i++ )
3074 : {
3075 9125312 : xn_buf_fx[i] = add_sat( xn_buf_fx[i], old_syn_overl_fx[i] ); // Q(-2)
3076 9125312 : move16();
3077 : }
3078 : }
3079 : ELSE
3080 : {
3081 0 : FOR( i = 0; i < overlap; i++ )
3082 : {
3083 0 : xn_buf_fx[( i + ( overlap / 2 ) )] = add_sat( xn_buf_fx[( i + ( overlap / 2 ) )], old_syn_overl_fx[i] ); // Q(-2)
3084 0 : move16();
3085 : }
3086 : }
3087 : }
3088 : }
3089 : }
3090 1585142 : test();
3091 1585142 : test();
3092 1585142 : test();
3093 1585142 : IF( ( aldo == 0 ) && ( ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) && ( frame_cnt > 0 ) ) || NE_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
3094 : {
3095 : /* Compute windowed synthesis in case of switching to ALDO windows in next frame */
3096 45818 : Copy( xn_buf_fx + sub( L_frame, nz ), old_out_fx, add( nz, overlap ) );
3097 45818 : set16_fx( old_out_fx + add( nz, overlap ), 0, nz );
3098 :
3099 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 );
3100 :
3101 : /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
3102 45818 : IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
3103 : {
3104 35220 : IF( s_and( kernel_type, 1 ) )
3105 : {
3106 1522 : FOR( i = 0; i < nz; i++ )
3107 : {
3108 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)
3109 1512 : move16();
3110 : }
3111 : }
3112 : ELSE
3113 : {
3114 6448610 : FOR( i = 0; i < nz; i++ )
3115 : {
3116 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)
3117 6413400 : move16();
3118 : }
3119 : }
3120 35220 : aldo = 1;
3121 35220 : move16();
3122 : }
3123 : }
3124 :
3125 1585142 : if ( FB_flag != 0 )
3126 : {
3127 792571 : hTcxCfg->last_aldo = aldo;
3128 792571 : move16();
3129 : }
3130 :
3131 : /* Smoothing between the ACELP PLC and TCX Transition frame. Using the shape of the half overlap window for the crossfading. */
3132 1585142 : test();
3133 1585142 : test();
3134 1585142 : test();
3135 1585142 : IF( ( left_rect != 0 ) && ( frame_cnt == 0 ) && st->last_core_bfi == ACELP_CORE && ( st->prev_bfi != 0 ) )
3136 : {
3137 194 : IF( FB_flag != 0 )
3138 : {
3139 6817 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
3140 : {
3141 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)
3142 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)
3143 6720 : move16();
3144 6720 : move16();
3145 : }
3146 6817 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3147 : {
3148 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)
3149 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)
3150 6720 : move16();
3151 6720 : move16();
3152 : }
3153 : }
3154 : ELSE
3155 : {
3156 3757 : FOR( i = 0; i < ( tcx_mdct_window_half_length / 2 ); i++ )
3157 : {
3158 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 );
3159 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)
3160 3660 : move16();
3161 3660 : move16();
3162 : }
3163 3757 : FOR( ; i < tcx_mdct_window_half_length; i++ )
3164 : {
3165 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 );
3166 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)
3167 3660 : move16();
3168 3660 : move16();
3169 : }
3170 : }
3171 : }
3172 :
3173 1585142 : return;
3174 : }
3175 :
3176 2333163 : void init_tcx_info_fx(
3177 : Decoder_State *st, /* i/o: coder memory state */
3178 : const Word16 L_frame_glob, /* i : global frame length */
3179 : const Word16 L_frameTCX_glob, /* i : FB global frame length */
3180 : const Word16 frame_cnt, /* i : frame counter in the super_frame */
3181 : const Word16 bfi, /* i : bad frame indicator */
3182 : Word16 *tcx_offset, /* o : folding point offset relative to the end of the previous frame */
3183 : Word16 *tcx_offsetFB, /* o : FB folding point offset relative to the end of the previous frame*/
3184 : Word16 *L_frame, /* o : frame length */
3185 : Word16 *L_frameTCX, /* o : TCX frame length */
3186 : Word16 *left_rect, /* o : left part is rectangular */
3187 : Word16 *L_spec /* o : spectrum length */
3188 : )
3189 : {
3190 2333163 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
3191 2333163 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
3192 :
3193 : /* Init lengths */
3194 2333163 : *tcx_offset = hTcxCfg->tcx_offset;
3195 2333163 : *tcx_offsetFB = hTcxCfg->tcx_offsetFB;
3196 2333163 : move16();
3197 2333163 : move16();
3198 :
3199 2333163 : IF( bfi )
3200 : {
3201 : /* PLC: [TCX: Memory update]
3202 : * PLC: Init buffers */
3203 :
3204 26840 : assert( st->L_frame_past > 0 );
3205 26840 : *L_frame = st->L_frame_past;
3206 26840 : move16();
3207 26840 : *L_frameTCX = st->L_frameTCX_past;
3208 26840 : move16();
3209 :
3210 26840 : *left_rect = hTcxDec->prev_widow_left_rect;
3211 26840 : move16();
3212 :
3213 26840 : IF( *left_rect )
3214 : {
3215 430 : *tcx_offset = hTcxCfg->lfacNext;
3216 430 : move16();
3217 430 : *tcx_offsetFB = hTcxCfg->lfacNextFB;
3218 430 : move16();
3219 430 : *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
3220 : }
3221 : }
3222 : ELSE
3223 : {
3224 2306323 : test();
3225 2306323 : IF( frame_cnt == 0 && st->last_core == ACELP_CORE )
3226 : {
3227 12095 : if ( !st->prev_bfi )
3228 : {
3229 11870 : hTcxCfg->last_aldo = 0;
3230 11870 : move16();
3231 : }
3232 :
3233 : /* if past frame is ACELP */
3234 12095 : *L_frame = add( L_frame_glob, *tcx_offset );
3235 12095 : *L_frameTCX = add( L_frameTCX_glob, *tcx_offsetFB );
3236 12095 : move16();
3237 12095 : move16();
3238 12095 : IF( EQ_16( st->last_core, st->last_core_from_bs ) )
3239 : {
3240 : /* case: last frame was lost and concealed as CNG */
3241 : /* using the longer transition spec length causes reading of uninitialized data */
3242 11985 : *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
3243 11985 : move16();
3244 : }
3245 :
3246 12095 : assert( hTcxCfg->lfacNext <= 0 );
3247 12095 : *L_frame = sub( *L_frame, hTcxCfg->lfacNext );
3248 12095 : *L_frameTCX = sub( *L_frameTCX, hTcxCfg->lfacNextFB );
3249 12095 : *tcx_offset = hTcxCfg->lfacNext;
3250 12095 : move16();
3251 12095 : move16();
3252 12095 : move16();
3253 12095 : *tcx_offsetFB = hTcxCfg->lfacNextFB;
3254 12095 : move16();
3255 :
3256 12095 : *left_rect = 1;
3257 12095 : move16();
3258 12095 : hTcxDec->prev_widow_left_rect = 1;
3259 12095 : move16();
3260 : }
3261 : ELSE
3262 : {
3263 2294228 : *L_frame = L_frame_glob;
3264 2294228 : move16();
3265 2294228 : *L_frameTCX = L_frameTCX_glob;
3266 2294228 : move16();
3267 2294228 : *left_rect = 0;
3268 2294228 : move16();
3269 2294228 : hTcxDec->prev_widow_left_rect = 0;
3270 2294228 : move16();
3271 : }
3272 :
3273 2306323 : st->L_frame_past = *L_frame;
3274 2306323 : move16();
3275 2306323 : st->L_frameTCX_past = *L_frameTCX;
3276 2306323 : move16();
3277 : }
3278 :
3279 2333163 : IF( st->igf )
3280 : {
3281 1527844 : test();
3282 1527844 : IF( EQ_16( *L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
3283 : {
3284 67251 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_SHORT );
3285 : }
3286 : ELSE
3287 : {
3288 1460593 : test();
3289 1460593 : test();
3290 1460593 : IF( st->last_core == ACELP_CORE || ( *left_rect && st->bfi ) )
3291 : {
3292 10648 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_TRAN );
3293 : }
3294 : ELSE
3295 : {
3296 1449945 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, IGF_GRID_LB_NORM );
3297 : }
3298 : }
3299 : }
3300 2333163 : }
3301 :
3302 :
3303 : /*-------------------------------------------------------------------*
3304 : * decoder_tcx_IGF_mono_fx()
3305 : *
3306 : * TCX: apply mono IGF
3307 : *-------------------------------------------------------------------*/
3308 :
3309 170463 : void decoder_tcx_IGF_mono_fx(
3310 : Decoder_State *st, /* i/o: coder memory state */
3311 : Word32 x_fx[], /* o : de-quatized coefficients */
3312 : Word16 *x_e, /* o : de-quatized coefficients exponent */
3313 : Word16 *x_len, /* o : de-quatized coefficients length */
3314 : const Word16 L_frame, /* i : frame length */
3315 : const Word16 left_rect, /* i : left part is rectangular */
3316 : const Word16 bfi, /* i : bad frame indicator */
3317 : const Word16 frame_cnt /* i : frame counter in the super_frame */
3318 : )
3319 : {
3320 : Word16 igfGridIdx;
3321 :
3322 170463 : test();
3323 170463 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly ) )
3324 : {
3325 8518 : igfGridIdx = IGF_GRID_LB_SHORT;
3326 8518 : move16();
3327 : }
3328 : ELSE
3329 : {
3330 161945 : test();
3331 161945 : IF( ( EQ_16( st->last_core, ACELP_CORE ) || left_rect ) )
3332 : {
3333 1003 : igfGridIdx = IGF_GRID_LB_TRAN;
3334 1003 : move16();
3335 : }
3336 : ELSE
3337 : {
3338 160942 : igfGridIdx = IGF_GRID_LB_NORM;
3339 160942 : move16();
3340 : }
3341 : }
3342 :
3343 170463 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, frame_cnt, igfGridIdx );
3344 :
3345 170463 : IF( st->igf )
3346 : {
3347 170463 : igfGridIdx = IGF_GRID_LB_SHORT;
3348 170463 : move16();
3349 : /*st->hIGFDec.igfData.igfInfo.nfSeed = (int16_t)(*nf_seed * 31821L + 13849L);*/
3350 :
3351 170463 : test();
3352 170463 : IF( NE_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
3353 : {
3354 161945 : test();
3355 161945 : test();
3356 161945 : IF( EQ_16( st->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
3357 : {
3358 1003 : igfGridIdx = IGF_GRID_LB_TRAN;
3359 1003 : move16();
3360 : }
3361 : ELSE
3362 : {
3363 160942 : igfGridIdx = IGF_GRID_LB_NORM;
3364 160942 : move16();
3365 : }
3366 : }
3367 :
3368 170463 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
3369 :
3370 170463 : *x_len = st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
3371 170463 : move16();
3372 : }
3373 :
3374 170463 : return;
3375 : }
3376 :
3377 :
3378 81130 : void decoder_tcx_IGF_stereo_fx(
3379 : Decoder_State **sts, /* i/o: coder memory states */
3380 : STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo structure */
3381 : Word16 ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */
3382 : Word32 *x_fx[CPE_CHANNELS][NB_DIV], /* i/o: de-quatized coefficients */
3383 : Word16 x_e[CPE_CHANNELS][NB_DIV], /* i/o: de-quatized coefficients exponents */
3384 : Word16 x_len[CPE_CHANNELS][NB_DIV], /* o : length of de-quantized coefficients */
3385 : const Word16 L_frame, /* i : frame length */
3386 : const Word16 left_rect, /* i : left part is rectangular */
3387 : const Word16 k, /* i : Subframe index */
3388 : const Word16 bfi, /* i : bad frame indicator */
3389 : const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */
3390 : )
3391 : {
3392 : Word16 coreMsMask[N_MAX];
3393 : STEREO_MDCT_BAND_PARAMETERS *sfbConf;
3394 : Word16 core, sfb, igfGridIdx, restrict_hopsize;
3395 :
3396 81130 : core = sts[0]->core;
3397 81130 : move16();
3398 :
3399 : /* assumptions: stereo filling was already done on the flattened spectra
3400 : * IGF region is always coded M/S, never L/R (to be done in the encoder)
3401 : * for residual bands with stereo filling infoTcxNoise is set to zero
3402 : * both channels have the same IGF configuration
3403 : */
3404 :
3405 :
3406 : /* initialization */
3407 81130 : IF( EQ_16( core, TCX_20_CORE ) )
3408 : {
3409 77127 : sfbConf = &hStereoMdct->stbParamsTCX20;
3410 : }
3411 : ELSE
3412 : {
3413 4003 : sfbConf = &hStereoMdct->stbParamsTCX10;
3414 : }
3415 :
3416 81130 : if ( EQ_16( sts[0]->last_core, ACELP_CORE ) )
3417 : {
3418 8 : sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
3419 : }
3420 :
3421 : /* create line wise ms mask for the core bands */
3422 81130 : set16_fx( coreMsMask, 0, N_MAX );
3423 :
3424 3444502 : FOR( sfb = 0; sfb < sfbConf->sfbCnt; sfb++ )
3425 : {
3426 3363372 : set16_fx( &coreMsMask[sfbConf->sfbOffset[sfb]], ms_mask[k][sfb], sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ) );
3427 : }
3428 :
3429 81130 : test();
3430 81130 : IF( EQ_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
3431 : {
3432 4003 : igfGridIdx = IGF_GRID_LB_SHORT;
3433 4003 : move16();
3434 : }
3435 : ELSE
3436 : {
3437 77127 : test();
3438 77127 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || left_rect )
3439 : {
3440 8 : igfGridIdx = IGF_GRID_LB_TRAN;
3441 8 : move16();
3442 : }
3443 : ELSE
3444 : {
3445 77119 : igfGridIdx = IGF_GRID_LB_NORM;
3446 77119 : move16();
3447 : }
3448 : }
3449 81130 : IGFDecUpdateInfo_ivas_fx( sts[0]->hIGFDec, k, igfGridIdx );
3450 :
3451 81130 : test();
3452 81130 : IF( EQ_16( L_frame, shr( sts[1]->L_frame, 1 ) ) && ( sts[1]->tcxonly ) )
3453 : {
3454 4003 : igfGridIdx = IGF_GRID_LB_SHORT;
3455 4003 : move16();
3456 : }
3457 : ELSE
3458 : {
3459 77127 : test();
3460 77127 : IF( EQ_16( sts[1]->last_core, ACELP_CORE ) || left_rect )
3461 : {
3462 8 : igfGridIdx = IGF_GRID_LB_TRAN;
3463 8 : move16();
3464 : }
3465 : ELSE
3466 : {
3467 77119 : igfGridIdx = IGF_GRID_LB_NORM;
3468 77119 : move16();
3469 : }
3470 : }
3471 81130 : IGFDecUpdateInfo_ivas_fx( sts[1]->hIGFDec, k, igfGridIdx );
3472 :
3473 :
3474 81130 : IF( sts[0]->igf )
3475 : {
3476 81130 : igfGridIdx = IGF_GRID_LB_SHORT;
3477 81130 : move16();
3478 81130 : test();
3479 81130 : IF( NE_16( L_frame, shr( sts[0]->L_frame, 1 ) ) && ( sts[0]->tcxonly ) )
3480 : {
3481 77127 : test();
3482 77127 : IF( EQ_16( sts[0]->last_core, ACELP_CORE ) || ( left_rect && bfi ) )
3483 : {
3484 8 : igfGridIdx = IGF_GRID_LB_TRAN;
3485 8 : move16();
3486 : }
3487 : ELSE
3488 : {
3489 77119 : igfGridIdx = IGF_GRID_LB_NORM;
3490 77119 : move16();
3491 : }
3492 : }
3493 :
3494 81130 : restrict_hopsize = 0;
3495 81130 : move16();
3496 81130 : if ( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
3497 : {
3498 13224 : restrict_hopsize = 1;
3499 13224 : move16();
3500 : }
3501 :
3502 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 );
3503 :
3504 81130 : x_len[0][k] = sts[0]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
3505 81130 : move16();
3506 81130 : x_len[1][k] = sts[1]->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine;
3507 81130 : move16();
3508 : }
3509 :
3510 81130 : return;
3511 : }
3512 :
3513 :
3514 216113 : void decoder_tcx_ivas_fx(
3515 : Decoder_State *st,
3516 : Word16 prm[],
3517 : Word16 A_fx[], // Q: 14 - norm_s(A_fx[0])
3518 : Word16 Aind[], // Q: 14 - norm_s(Aind[0])
3519 : Word16 synth_fx[], // Q_syn
3520 : Word16 synthFB_fx[], // Q_syn
3521 : const Word16 bfi,
3522 : const Word16 frame_cnt,
3523 : const Word16 sba_dirac_stereo_flag )
3524 : {
3525 : Word32 x_fx[N_MAX];
3526 : Word16 x_e;
3527 : Word16 gainlpc2_fx[FDNS_NPTS];
3528 : Word16 gainlpc2_e[FDNS_NPTS];
3529 : Word16 gain_tcx_e, gain_tcx_fx;
3530 : Word16 fUseTns, L_frame_glob, L_frameTCX_glob;
3531 : STnsData tnsData;
3532 : Word16 tcx_offset, tcx_offsetFB, L_frame, L_frameTCX;
3533 : Word16 left_rect, L_spec, tmp_concealment_method, nf_seed;
3534 : const Word16 *prm_sqQ;
3535 : Word16 xn_buf_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* Q14 */
3536 : Word16 shift;
3537 : Word16 x_len;
3538 : Word16 q_x;
3539 216113 : q_x = Q11;
3540 216113 : move16();
3541 216113 : x_e = 30;
3542 216113 : move16();
3543 216113 : gain_tcx_e = 0;
3544 216113 : gain_tcx_fx = 0;
3545 216113 : move16();
3546 216113 : move16();
3547 216113 : set32_fx( x_fx, 0, N_MAX );
3548 216113 : set16_fx( gainlpc2_fx, 0, FDNS_NPTS );
3549 216113 : set16_fx( gainlpc2_e, 0, FDNS_NPTS );
3550 :
3551 216113 : L_spec = st->hTcxCfg->tcx_coded_lines;
3552 216113 : move16();
3553 216113 : L_frame_glob = st->L_frame;
3554 216113 : move16();
3555 216113 : L_frameTCX_glob = st->hTcxDec->L_frameTCX;
3556 216113 : move16();
3557 216113 : IF( EQ_16( st->core, TCX_10_CORE ) )
3558 : {
3559 3900 : L_spec = shr( L_spec, 1 );
3560 3900 : L_frame_glob = shr( L_frame_glob, 1 );
3561 3900 : L_frameTCX_glob = shr( L_frameTCX_glob, 1 );
3562 : }
3563 :
3564 216113 : tmp_concealment_method = 0;
3565 216113 : move16();
3566 216113 : nf_seed = 0;
3567 216113 : move16();
3568 216113 : fUseTns = 0; /* flag that is set if TNS data is present */
3569 216113 : move16();
3570 :
3571 216113 : set16_fx( xn_buf_fx, 0, L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX );
3572 :
3573 216113 : 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 );
3574 :
3575 216113 : 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 );
3576 :
3577 216113 : shift = Find_Max_Norm32( x_fx, N_MAX );
3578 216113 : Scale_sig32( x_fx, N_MAX, shift );
3579 216113 : x_e = sub( x_e, shift );
3580 :
3581 216113 : 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 );
3582 :
3583 216113 : 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 );
3584 :
3585 216113 : shift = sub( Find_Max_Norm32( x_fx, N_MAX ), 6 ); // 6 -> guardbits//
3586 216113 : Scale_sig32( x_fx, N_MAX, shift );
3587 216113 : x_e = sub( x_e, shift );
3588 :
3589 216113 : decoder_tcx_tns_fx( st, L_frame_glob, L_spec, L_frame, L_frameTCX, x_fx, fUseTns, &tnsData, bfi, frame_cnt, 0, NULL );
3590 :
3591 216113 : Scale_sig32( x_fx, N_MAX, sub( x_e, 20 ) ); // Scaling x_fx to Q11
3592 216113 : 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
3593 216113 : x_e = sub( 31, 11 );
3594 :
3595 216113 : IF( st->igf != 0 )
3596 : {
3597 206390 : Scale_sig32( st->hIGFDec->virtualSpec, ( N_MAX_TCX - IGF_START_MN ), ( sub( st->hIGFDec->virtualSpec_e, x_e ) ) );
3598 206390 : st->hIGFDec->virtualSpec_e = x_e;
3599 206390 : move16();
3600 : }
3601 :
3602 : /* Scaling down buffers for decoder_tcx_imdct_fx*/
3603 216113 : 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
3604 216113 : st->hTcxDec->Q_syn_Overl_TDACFB = st->Q_syn;
3605 216113 : move16();
3606 216113 : Scale_sig( st->hTcxDec->syn_Overl_TDAC, L_FRAME32k / 2, sub( st->Q_syn, st->hTcxDec->Q_syn_Overl_TDAC ) ); // Scaling to Q_syn
3607 216113 : st->hTcxDec->Q_syn_Overl_TDAC = st->Q_syn;
3608 216113 : move16();
3609 216113 : Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, negate( st->hHQ_core->Q_old_wtda ) ); // Scaling to Q_syn
3610 216113 : Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, negate( st->hHQ_core->Q_old_wtda_LB ) ); // Scaling to Q_syn
3611 216113 : st->hHQ_core->Q_old_wtda = 0;
3612 216113 : move16();
3613 216113 : st->hHQ_core->Q_old_wtda_LB = 0;
3614 216113 : move16();
3615 :
3616 216113 : Scale_sig( st->hTcxDec->old_syn_Overl, 320, st->Q_syn - st->hTcxDec->Q_old_syn_Overl ); // Scaling to Q_syn
3617 216113 : st->hTcxDec->Q_old_syn_Overl = st->Q_syn;
3618 216113 : 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 ) ) ) ) ) ) );
3619 :
3620 216113 : Scale_sig( synth_fx, L_frame_glob, st->Q_syn ); // Scaling to Q_syn
3621 216113 : Scale_sig( synthFB_fx, L_frameTCX_glob, st->Q_syn ); // Scaling to Q_syn
3622 :
3623 216113 : 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,
3624 : fUseTns, &synth_fx[0], &synthFB_fx[0], bfi, frame_cnt, sba_dirac_stereo_flag );
3625 :
3626 : /* Scaling up again */
3627 216113 : Scale_sig( synth_fx, L_frame_glob, negate( st->Q_syn ) );
3628 216113 : Scale_sig( synthFB_fx, L_frameTCX_glob, negate( st->Q_syn ) );
3629 : // Scale_sig( st->hTcxDec->syn_Overl, L_FRAME32k / 2, 1 );
3630 216113 : st->hHQ_core->Q_old_wtda = st->Q_syn;
3631 : // Scale_sig( st->hHQ_core->old_out_LB_fx, L_FRAME32k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) );
3632 216113 : st->hHQ_core->Q_old_wtda_LB = st->Q_syn;
3633 : // Scale_sig( st->hHQ_core->old_out_fx, L_FRAME48k, ( sub( st->hHQ_core->Q_old_wtda, st->Q_syn ) ) );
3634 216113 : Scale_sig( st->hTcxDec->old_syn_Overl, 320, ( -2 - st->hTcxDec->Q_old_syn_Overl ) ); // Scaling to Q-2
3635 216113 : st->hTcxDec->Q_old_syn_Overl = -2;
3636 216113 : }
3637 :
3638 : /*-------------------------------------------------------------------*
3639 : * decoder_tcx_invQ_fx
3640 : *
3641 : * TCX: inverse quantization
3642 : *-------------------------------------------------------------------*/
3643 796316 : void decoder_tcx_invQ_fx(
3644 : Decoder_State *st, /* i/o: coder memory state */
3645 : int16_t prm[], /* i : parameters */
3646 : Word16 A[], /* i : coefficients NxAz[M+1] */
3647 : Word16 Aind[], /* i : frame-independent coefficients Az[M+1] */
3648 : const Word16 L_spec,
3649 : const Word16 L_frame,
3650 : const Word16 L_frameTCX,
3651 : Word32 x[],
3652 : Word16 *x_e,
3653 : Word16 gainlpc2[],
3654 : Word16 gainlpc2_e[],
3655 : Word16 xn_buf[], /* Q14 */
3656 : Word16 *fUseTns, /* o : flag that is set if TNS data is present */
3657 : STnsData *tnsData,
3658 : Word16 *gain_tcx,
3659 : Word16 *gain_tcx_e,
3660 : const Word16 **prm_sqQ1,
3661 : Word16 *nf_seed,
3662 : const Word16 bfi, /* i : Bad frame indicator */
3663 : const Word16 frame_cnt /* i : frame counter in the super frame */
3664 : )
3665 : {
3666 : Word16 i, index;
3667 : Word16 start_zeroing;
3668 : Word16 Ap[M + 2];
3669 :
3670 : Word16 noiseFillingSize;
3671 : Word16 tnsSize; /* number of tns parameters put into prm */
3672 :
3673 : Word16 gamma1; /* Q15 */
3674 : Word16 gamma; /* Q15 */
3675 : Word16 mem[M];
3676 : Word16 gainCompensate, gainCompensate_e;
3677 : Word16 h1[L_SUBFR + 1];
3678 : Word16 tmp1, tmp2;
3679 : Word32 tmp32;
3680 : Word16 s;
3681 :
3682 : Word16 arith_bits, signaling_bits;
3683 : Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_sqQ, *prm_target;
3684 796316 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
3685 796316 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
3686 796316 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
3687 :
3688 796316 : gainCompensate = 0;
3689 796316 : gainCompensate_e = 0;
3690 796316 : move16();
3691 796316 : move16();
3692 :
3693 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
3694 796316 : Flag Overflow = 0;
3695 796316 : move32();
3696 : #endif
3697 :
3698 796316 : tnsSize = 0;
3699 796316 : move16();
3700 796316 : prm_target = NULL; /* just to suppress MSVC warnigs */
3701 :
3702 : /*-----------------------------------------------------------------*
3703 : * Initializations
3704 : *-----------------------------------------------------------------*/
3705 :
3706 : /* Init lengths */
3707 796316 : gamma1 = st->gamma;
3708 796316 : move16();
3709 :
3710 796316 : if ( hTcxDec->enableTcxLpc != 0 )
3711 : {
3712 14118 : gamma1 = MAX16B;
3713 14118 : move16();
3714 : }
3715 :
3716 796316 : noiseFillingSize = L_spec;
3717 796316 : move16();
3718 796316 : if ( st->igf != 0 )
3719 : {
3720 539113 : noiseFillingSize = st->hIGFDec->infoIGFStartLine;
3721 539113 : move16();
3722 : }
3723 :
3724 796316 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
3725 796316 : prm_tns = prm_ltp + LTPSIZE;
3726 :
3727 796316 : gainCompensate = ONE_IN_Q14;
3728 796316 : move16();
3729 796316 : gainCompensate_e = 1;
3730 796316 : move16();
3731 :
3732 : /*-----------------------------------------------------------*
3733 : * Read TCX parameters *
3734 : *-----------------------------------------------------------*/
3735 :
3736 796316 : index = 0;
3737 796316 : move16();
3738 :
3739 796316 : IF( !bfi )
3740 : {
3741 787829 : index = prm[0];
3742 787829 : move16();
3743 :
3744 : /* read noise level (fac_ns) */
3745 787829 : st->hTcxDec->noise_filling_index[frame_cnt] = prm[1];
3746 787829 : move16();
3747 : }
3748 :
3749 : /* read TNS data */
3750 796316 : test();
3751 796316 : IF( !bfi && hTcxCfg->fIsTNSAllowed )
3752 : {
3753 721991 : *fUseTns = DecodeTnsData_ivas_fx( hTcxCfg->pCurrentTnsConfig, prm_tns, &tnsSize, tnsData );
3754 721991 : move16();
3755 : }
3756 : ELSE
3757 : {
3758 74325 : *fUseTns = 0;
3759 74325 : move16();
3760 : }
3761 :
3762 796316 : prm_hm = prm_tns + tnsSize;
3763 796316 : prm_sqQ = prm_hm + NPRM_CTX_HM;
3764 796316 : *prm_sqQ1 = prm_sqQ;
3765 :
3766 : /*-----------------------------------------------------------*
3767 : * Spectrum data *
3768 : *-----------------------------------------------------------*/
3769 :
3770 796316 : IF( !bfi )
3771 : {
3772 : /*-----------------------------------------------------------*
3773 : * Context HM *
3774 : *-----------------------------------------------------------*/
3775 787829 : test();
3776 787829 : test();
3777 787829 : IF( hTcxCfg->ctx_hm && ( ( st->last_core_from_bs != ACELP_CORE ) || ( frame_cnt > 0 ) ) )
3778 : {
3779 166700 : st->last_ctx_hm_enabled = prm_hm[0];
3780 166700 : move16();
3781 :
3782 141828460 : FOR( i = 0; i < L_spec; i++ )
3783 : {
3784 : /* no context harmonic model, copy MDCT coefficients to x */
3785 141661760 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
3786 141661760 : move32();
3787 : }
3788 166700 : *x_e = SPEC_EXP_DEC;
3789 166700 : move16();
3790 : }
3791 : ELSE /* hTcxCfg->ctx_hm == 0 */
3792 : {
3793 621129 : IF( hTcxDec->tcx_lpc_shaped_ari ) /* low rates: envelope based arithmetic coder */
3794 : {
3795 13989 : prm_target = prm_sqQ;
3796 13989 : move16();
3797 13989 : prm_sqQ = prm_target + 1;
3798 13989 : move16();
3799 :
3800 13989 : IF( GT_32( st->bwidth, WB ) )
3801 : {
3802 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 );
3803 : }
3804 : ELSE
3805 : {
3806 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 );
3807 : }
3808 :
3809 13989 : hTcxDec->resQBits[frame_cnt] = sub( *prm_target, arith_bits );
3810 13989 : move16();
3811 :
3812 : /* Noise filling seed */
3813 2934661 : FOR( i = 0; i < noiseFillingSize; ++i )
3814 : {
3815 2920672 : tmp32 = L_shr( x[i], sub( 31, *x_e ) );
3816 2920672 : *nf_seed = add_o( *nf_seed, extract_l( L_shl( i_mult( (Word16) L_abs( tmp32 ), i ), 1 ) ), &Overflow ); // abs( tmp32 ) * i * 2
3817 2920672 : move16();
3818 : }
3819 : }
3820 : ELSE /* TCX-only: context based arithmetic coder */
3821 : {
3822 485805460 : FOR( i = 0; i < L_spec; i++ )
3823 : {
3824 485198320 : x[i] = L_mult( prm_sqQ[i], shl( 1, sub( 30, SPEC_EXP_DEC ) ) );
3825 485198320 : move32();
3826 : }
3827 :
3828 607140 : set32_fx( x + L_spec, 0, sub( L_frameTCX, L_spec ) );
3829 :
3830 607140 : *x_e = SPEC_EXP_DEC;
3831 607140 : move16();
3832 : }
3833 :
3834 : } /* else of if hTcxCfg->ctx_hm */
3835 :
3836 : // start_zeroing = ( st->last_core != st->last_core_from_bs ) ? min( L_spec, L_frame ) : L_spec;
3837 787829 : IF( NE_16( st->last_core, st->last_core_from_bs ) )
3838 : {
3839 75 : start_zeroing = s_min( L_spec, L_frame );
3840 : }
3841 : ELSE
3842 : {
3843 787754 : start_zeroing = L_spec;
3844 787754 : move16();
3845 : }
3846 787829 : test();
3847 787829 : test();
3848 787829 : IF( frame_cnt == 0 && EQ_16( st->last_core, ACELP_CORE ) && NE_16( st->last_core_from_bs, ACELP_CORE ) )
3849 : {
3850 : Word16 L_spec_con;
3851 26 : L_spec_con = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
3852 :
3853 12346 : FOR( i = start_zeroing; i < L_spec_con; i++ )
3854 : {
3855 12320 : x[i] = 0;
3856 12320 : move32();
3857 : }
3858 :
3859 26 : start_zeroing = L_spec_con;
3860 26 : move16();
3861 : }
3862 :
3863 36612677 : FOR( i = start_zeroing; i < s_max( L_frame, L_frameTCX ); i++ )
3864 : {
3865 35824848 : x[i] = 0;
3866 35824848 : move32();
3867 : }
3868 :
3869 : /*-----------------------------------------------------------*
3870 : * adaptive low frequency deemphasis. *
3871 : *-----------------------------------------------------------*/
3872 :
3873 787829 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
3874 : {
3875 214310 : weight_a_fx( A, Ap, gamma1, M );
3876 214310 : lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
3877 : }
3878 :
3879 : /* initialize LF deemphasis factors in xn_buf */
3880 787829 : test();
3881 787829 : test();
3882 787829 : IF( !st->tcxonly || ( hTcxCfg->resq && hTcxDec->tcx_lpc_shaped_ari ) )
3883 : {
3884 111198 : Word16 len = s_max( L_spec, L_frameTCX );
3885 99745278 : FOR( i = 0; i < len; i++ )
3886 : {
3887 99634080 : xn_buf[i] = ONE_IN_Q14;
3888 99634080 : move16();
3889 : }
3890 : }
3891 787829 : IF( !st->tcxonly )
3892 : {
3893 111198 : AdaptLowFreqDeemph( x, *x_e, hTcxDec->tcx_lpc_shaped_ari, gainlpc2, gainlpc2_e, L_frame, xn_buf /* LF deemphasis factors */ );
3894 : }
3895 : }
3896 :
3897 796316 : hTcxDec->damping = 0;
3898 796316 : move16();
3899 :
3900 796316 : IF( bfi == 0 )
3901 : {
3902 : /*-----------------------------------------------------------*
3903 : * Compute global gain *
3904 : *-----------------------------------------------------------*/
3905 :
3906 787829 : tmp32 = L_shl( L_mult0( index, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
3907 787829 : *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
3908 787829 : *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, (Word32) 0xFE000000 ) ) );
3909 787829 : move16();
3910 787829 : move16();
3911 :
3912 787829 : tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
3913 787829 : s = 15 - 5 - 7;
3914 787829 : move16();
3915 787829 : IF( GE_16( L_spec, 1024 ) ) /*reduce precision for avoiding overflow*/
3916 : {
3917 3623 : tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
3918 3623 : s = 15 - 4 - 7;
3919 3623 : move16();
3920 : }
3921 787829 : tmp1 = ISqrt16( tmp1, &s );
3922 :
3923 787829 : *gain_tcx = mult( *gain_tcx, tmp1 );
3924 787829 : *gain_tcx_e = add( *gain_tcx_e, s );
3925 787829 : move16();
3926 787829 : move16();
3927 :
3928 787829 : hTcxDec->old_gaintcx_bfi = *gain_tcx;
3929 787829 : move16();
3930 787829 : hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
3931 787829 : move16();
3932 :
3933 787829 : hTcxDec->cummulative_damping_tcx = MAX16B; // 1 in Q15
3934 787829 : move16();
3935 : }
3936 : ELSE /* bfi = 1 */
3937 : {
3938 : /* PLC: [TCX: Fade-out]
3939 : * derivation of damping factor */
3940 8487 : IF( st->use_partial_copy )
3941 : {
3942 0 : IF( EQ_16( st->rf_frame_type, RF_TCXFD ) )
3943 : {
3944 0 : tmp32 = L_shl( L_mult0( hTcxDec->old_gaintcx_bfi, 0x797D ), 7 ); /* 6Q25; 0x797D -> log2(10)/28 (Q18) */
3945 0 : *gain_tcx_e = add( extract_l( L_shr( tmp32, 25 ) ), 1 ); /* get exponent */
3946 0 : *gain_tcx = round_fx( BASOP_Util_InvLog2( L_or( tmp32, 0xFE000000 ) ) );
3947 0 : move16();
3948 0 : move16();
3949 :
3950 0 : tmp1 = mult_r( shl( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
3951 0 : s = 15 - 5 - 7;
3952 0 : move16();
3953 0 : tmp1 = ISqrt16( tmp1, &s );
3954 :
3955 0 : *gain_tcx = mult( *gain_tcx, tmp1 );
3956 0 : *gain_tcx_e = add( *gain_tcx_e, s );
3957 0 : move16();
3958 0 : move16();
3959 :
3960 0 : hTcxDec->old_gaintcx_bfi = *gain_tcx;
3961 0 : move16();
3962 0 : hTcxDec->old_gaintcx_bfi_e = *gain_tcx_e;
3963 0 : move16();
3964 : }
3965 : ELSE
3966 : {
3967 0 : *gain_tcx = hTcxDec->old_gaintcx_bfi;
3968 0 : move16();
3969 0 : *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
3970 0 : move16();
3971 : }
3972 :
3973 0 : hTcxDec->damping = ONE_IN_Q14; // Q14
3974 0 : move16();
3975 : }
3976 : ELSE
3977 : {
3978 8487 : *gain_tcx = hTcxDec->old_gaintcx_bfi;
3979 8487 : move16();
3980 8487 : *gain_tcx_e = hTcxDec->old_gaintcx_bfi_e;
3981 8487 : move16();
3982 :
3983 16974 : hTcxDec->damping = Damping_fact_fx( st->coder_type, st->nbLostCmpt, st->last_good,
3984 8487 : st->stab_fac_fx,
3985 : &st->Mode2_lp_gainp,
3986 8487 : st->last_core );
3987 8487 : move16();
3988 : }
3989 :
3990 8487 : hTcxDec->cummulative_damping_tcx = shl( mult( hTcxDec->cummulative_damping_tcx, hTcxDec->damping ), 1 ); /*shl(Q15*Q14,1)=shl(Q14,1) = Q15*/
3991 8487 : move16();
3992 : }
3993 :
3994 796316 : IF( bfi )
3995 : {
3996 8487 : IF( hTcxDec->envWeighted )
3997 : {
3998 0 : gamma = st->gamma;
3999 0 : move16();
4000 : }
4001 : ELSE
4002 : {
4003 8487 : gamma = gamma1;
4004 8487 : move16();
4005 : }
4006 :
4007 : /* PLC: [TCX: Fade-out]
4008 : * PLC: invert LPC weighting in case of PLC */
4009 :
4010 8487 : IF( hTcxDec->enableTcxLpc )
4011 : {
4012 129 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( st->gamma, MAX16B ) ), MAX16B );
4013 : }
4014 : ELSE
4015 : {
4016 8358 : gamma = add( mult_r( hTcxDec->cummulative_damping_tcx, sub( gamma1, MAX16B ) ), MAX16B );
4017 : }
4018 :
4019 8487 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4020 : {
4021 1803 : weight_a_fx( A, Ap, gamma, M );
4022 1803 : lpc2mdct_2( Ap, M, NULL, NULL, gainlpc2, gainlpc2_e, FDNS_NPTS );
4023 : }
4024 : }
4025 :
4026 796316 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4027 : {
4028 216113 : set16_fx( h1, 0, L_SUBFR + 1 );
4029 216113 : set16_fx( mem, 0, M );
4030 216113 : h1[0] = ONE_IN_Q10;
4031 216113 : move16();
4032 216113 : E_UTIL_synthesis( 0, Ap, h1, h1, L_SUBFR, mem, 0, M ); /* impulse response of LPC */
4033 :
4034 216113 : tmp2 = 0;
4035 216113 : move16();
4036 216113 : deemph_fx( h1, st->preemph_fac, L_SUBFR, &tmp2 ); /* tmp2 in Q10 */
4037 : }
4038 :
4039 : /* impulse response level = gain introduced by synthesis+deemphasis */
4040 796316 : test();
4041 796316 : IF( !bfi )
4042 : {
4043 787829 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4044 : {
4045 573519 : st->last_gain_syn_deemph = 0;
4046 573519 : move16();
4047 573519 : st->last_gain_syn_deemph_e = 0;
4048 573519 : move16();
4049 : }
4050 : ELSE
4051 : {
4052 214310 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &st->last_gain_syn_deemph_e ) /*Q15, st->last_gain_syn_deemph_e*/;
4053 214310 : st->last_gain_syn_deemph_e = add( st->last_gain_syn_deemph_e, 10 /*scaling of h1[0] and E_UTIL_synthesis * 2*/ );
4054 214310 : move16();
4055 214310 : tmp32 = Sqrt32( tmp32, &st->last_gain_syn_deemph_e );
4056 214310 : st->last_gain_syn_deemph = round_fx_o( tmp32, &Overflow ); // Q15
4057 214310 : move16();
4058 : }
4059 :
4060 : /*for avoiding compiler warnings*/
4061 787829 : hTcxDec->gainHelper = ONE_IN_Q14;
4062 787829 : move16();
4063 787829 : hTcxDec->gainHelper_e = 1;
4064 787829 : move16();
4065 787829 : hTcxDec->stepCompensate = 0;
4066 787829 : move16();
4067 787829 : hTcxDec->stepCompensate_e = 0;
4068 787829 : move16();
4069 : }
4070 : /* not instrumenting the additional test() here seems to be common practice */
4071 8487 : ELSE IF( EQ_16( TCX_20_CORE, st->core ) || EQ_16( frame_cnt, 1 ) )
4072 : {
4073 8433 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4074 : {
4075 6638 : gainCompensate = ONE_IN_Q14;
4076 6638 : move16();
4077 6638 : gainCompensate_e = 1;
4078 6638 : move16();
4079 : }
4080 : ELSE
4081 : {
4082 1795 : tmp32 = Dot_productSq16HQ( 0, h1, L_SUBFR, &gainCompensate_e ) /*Q15, gainCompensate_e*/;
4083 1795 : gainCompensate_e = add( gainCompensate_e, 10 /*scaling of h1[0] and E_UTIL:synthesis*/ );
4084 1795 : gainCompensate = round_fx_sat( Sqrt32( tmp32, &gainCompensate_e ) ) /*Q15, gainCompensate_e*/;
4085 1795 : BASOP_Util_Divide_MantExp( st->last_gain_syn_deemph,
4086 1795 : st->last_gain_syn_deemph_e,
4087 : gainCompensate,
4088 : gainCompensate_e,
4089 : &gainCompensate,
4090 : &gainCompensate_e );
4091 : }
4092 :
4093 8433 : tmp1 = T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )]; /* indexing for lookup table */
4094 :
4095 8433 : IF( EQ_16( st->nbLostCmpt, 1 ) )
4096 : {
4097 4578 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
4098 : tmp1,
4099 : -7,
4100 4578 : negate( mult( gainCompensate, tmp1 ) ),
4101 4578 : add( -7, gainCompensate_e ),
4102 : &hTcxDec->stepCompensate );
4103 4578 : hTcxDec->gainHelper = ONE_IN_Q14;
4104 4578 : move16();
4105 4578 : hTcxDec->gainHelper_e = 1;
4106 4578 : move16();
4107 : }
4108 : ELSE
4109 : {
4110 3855 : hTcxDec->stepCompensate_e = BASOP_Util_Add_MantExp(
4111 3855 : mult( tmp1, st->last_concealed_gain_syn_deemph ),
4112 3855 : add( -7, st->last_concealed_gain_syn_deemph_e ),
4113 3855 : negate( mult( tmp1, gainCompensate ) ),
4114 3855 : add( -7, gainCompensate_e ),
4115 : &hTcxDec->stepCompensate );
4116 :
4117 3855 : hTcxDec->gainHelper = st->last_concealed_gain_syn_deemph;
4118 3855 : move16();
4119 3855 : hTcxDec->gainHelper_e = st->last_concealed_gain_syn_deemph_e;
4120 3855 : move16();
4121 : }
4122 :
4123 8433 : st->last_concealed_gain_syn_deemph = gainCompensate;
4124 8433 : move16();
4125 8433 : st->last_concealed_gain_syn_deemph_e = gainCompensate_e;
4126 8433 : move16();
4127 : }
4128 :
4129 : /*-----------------------------------------------------------*
4130 : * Residual inv. Q. *
4131 : *-----------------------------------------------------------*/
4132 796316 : test();
4133 796316 : IF( !bfi && hTcxCfg->resq )
4134 : {
4135 358407 : IF( hTcxDec->tcx_lpc_shaped_ari )
4136 : {
4137 : /* envelope based arithmetic coder */
4138 : const Word16 *prm_resq;
4139 13989 : prm_resq = prm_sqQ + sub( *prm_target /* = targetBits */, hTcxDec->resQBits[frame_cnt] );
4140 :
4141 13989 : i = tcx_ari_res_invQ_spec( x, *x_e, L_spec,
4142 : prm_resq,
4143 13989 : hTcxDec->resQBits[frame_cnt],
4144 : 0,
4145 13989 : hTcxCfg->sq_rounding,
4146 : xn_buf /* LF deemphasis factors */ );
4147 : }
4148 : ELSE
4149 : {
4150 : /* context based arithmetic coder */
4151 344418 : i = tcx_res_invQ_gain( gain_tcx, gain_tcx_e, &prm_sqQ[L_spec], hTcxDec->resQBits[frame_cnt] );
4152 :
4153 344418 : Word16 *tmpP16 = xn_buf;
4154 344418 : if ( st->tcxonly != 0 )
4155 247209 : tmpP16 = NULL;
4156 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 */ );
4157 : }
4158 : }
4159 :
4160 796316 : test();
4161 796316 : test();
4162 796316 : IF( !bfi && st->tcxonly && st->element_mode != IVAS_CPE_MDCT )
4163 : {
4164 103112 : test();
4165 103112 : test();
4166 103112 : IF( hTcxLtpDec->tcxltp && ( hTcxLtpDec->tcxltp_gain > 0 ) && !( *fUseTns ) )
4167 : {
4168 3660 : PsychAdaptLowFreqDeemph( x, gainlpc2, gainlpc2_e, NULL );
4169 : }
4170 : }
4171 796316 : test();
4172 796316 : IF( !bfi && !st->tcxonly )
4173 : {
4174 : /* Replication of ACELP formant enhancement for low rates */
4175 111198 : IF( LT_32( st->total_brate, ACELP_13k20 ) )
4176 : {
4177 26386 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4178 : {
4179 0 : assert( !"Not adapted to warped scale" );
4180 : }
4181 :
4182 : Word16 xn_buf_e;
4183 26386 : tcxFormantEnhancement_with_shift( xn_buf, &xn_buf_e, gainlpc2, gainlpc2_e, x, x_e, L_frame, L_frameTCX );
4184 1715090 : FOR( i = 0; i < FDNS_NPTS; i++ )
4185 : {
4186 1688704 : xn_buf[i] = shl( xn_buf[i], xn_buf_e - 1 );
4187 1688704 : move16();
4188 : }
4189 : }
4190 : }
4191 :
4192 : /*-----------------------------------------------------------*
4193 : * Add gain to the lpc gains *
4194 : *-----------------------------------------------------------*/
4195 :
4196 796316 : IF( st->VAD == 0 )
4197 : {
4198 535046 : *gain_tcx = mult_r( *gain_tcx, hTcxCfg->na_scale );
4199 535046 : move16();
4200 : }
4201 :
4202 796316 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4203 : {
4204 216113 : i = norm_s( *gain_tcx );
4205 216113 : *gain_tcx = shl( *gain_tcx, i );
4206 216113 : *gain_tcx_e = sub( *gain_tcx_e, i );
4207 216113 : move16();
4208 216113 : move16();
4209 14047345 : FOR( i = 0; i < FDNS_NPTS; i++ )
4210 : {
4211 13831232 : gainlpc2[i] = mult( gainlpc2[i], *gain_tcx );
4212 13831232 : move16();
4213 13831232 : gainlpc2_e[i] = add( gainlpc2_e[i], *gain_tcx_e );
4214 13831232 : move16();
4215 : }
4216 : }
4217 :
4218 796316 : return;
4219 : }
4220 :
4221 : /*-------------------------------------------------------------------*
4222 : * decoder_tcx_noisefilling()
4223 : *
4224 : * TCX: core noise filling, IGF updates
4225 : *-------------------------------------------------------------------*/
4226 :
4227 796316 : void decoder_tcx_noisefilling_fx(
4228 : Decoder_State *st, /* i/o: coder memory state */
4229 : const Word32 concealment_noise[L_FRAME48k],
4230 : const Word16 concealment_noise_exp,
4231 : const Word16 A[], /* i : coefficients NxAz[M+1] */
4232 : const Word16 L_frameTCX_glob,
4233 : const Word16 L_spec,
4234 : const Word16 L_frame,
4235 : const Word16 L_frameTCX,
4236 : Word32 x[],
4237 : Word16 *x_e,
4238 : Word16 *gainlpc2,
4239 : Word16 *gainlpc2_e,
4240 : Word16 *temp_concealment_method,
4241 : const Word16 gain_tcx,
4242 : const Word16 gain_tcx_e,
4243 : const Word16 *prm_sqQ,
4244 : Word16 nf_seed,
4245 : const Word16 bfi, /* i : Bad frame indicator */
4246 : const Word16 MCT_flag,
4247 : const Word16 frame_cnt /* i : frame counter in the super frame*/
4248 : )
4249 : {
4250 : Word16 i;
4251 : Word16 firstLine;
4252 : Word16 fac_ns;
4253 : Word16 noiseFillingSize;
4254 796316 : Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
4255 796316 : move16();
4256 : Word16 tmp, tmp1, tmp2;
4257 : Word16 sum_word16;
4258 : Word16 infoIGFStartLine;
4259 : Word16 f, noiseTiltFactor;
4260 : Word32 smooth_gain;
4261 796316 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
4262 796316 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
4263 796316 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
4264 : Word32 total_brate;
4265 : Word32 tmp32;
4266 : Word16 *pInfoTCXNoise;
4267 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
4268 796316 : Flag Overflow = 0;
4269 796316 : move32();
4270 796316 : Flag Carry = 0;
4271 796316 : move32();
4272 : #endif
4273 796316 : total_brate = ( (Word16) EQ_16( st->element_mode, IVAS_CPE_MDCT ) ? st->element_brate : st->total_brate );
4274 796316 : move32();
4275 : /*-----------------------------------------------------------------*
4276 : * Initializations
4277 : *-----------------------------------------------------------------*/
4278 :
4279 : /* Init lengths */
4280 796316 : infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX );
4281 :
4282 796316 : noiseFillingSize = L_spec;
4283 796316 : move16();
4284 796316 : if ( st->igf != 0 )
4285 : {
4286 539113 : noiseFillingSize = st->hIGFDec->infoIGFStartLine;
4287 539113 : move16();
4288 : }
4289 :
4290 796316 : IF( bfi == 0 )
4291 : {
4292 787829 : fac_ns = extract_l( L_shr( L_mult0( hTcxDec->noise_filling_index[frame_cnt], 0x6000 /* 0.75f in Q15 */ ), NBITS_NOISE_FILL_LEVEL ) );
4293 : }
4294 : ELSE
4295 : {
4296 8487 : fac_ns = 0;
4297 8487 : move16();
4298 : }
4299 :
4300 : /*-----------------------------------------------------------*
4301 : * Noise filling. *
4302 : *-----------------------------------------------------------*/
4303 :
4304 796316 : test();
4305 796316 : IF( bfi == 0 && ( fac_ns > 0 ) )
4306 : {
4307 750780 : firstLine = tcxGetNoiseFillingTilt( A, M, L_frame, ( GE_32( total_brate, ACELP_13k20 ) && !st->rf_flag ), &noiseTiltFactor );
4308 :
4309 750780 : IF( st->tcxonly != 0 )
4310 : {
4311 639930 : tmp1 = 0;
4312 639930 : move16();
4313 639930 : test();
4314 639930 : test();
4315 639930 : if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( st->last_ctx_hm_enabled != 0 ) )
4316 : {
4317 4386 : tmp1 = 10240 /*0.3125f Q15*/;
4318 4386 : move16();
4319 : }
4320 639930 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4321 : {
4322 550116 : IF( frame_cnt == 0 )
4323 : {
4324 537986 : Copy( hTcxDec->ltpGainMemory_fx, &hTcxDec->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
4325 537986 : hTcxDec->ltpGainMemory_fx[0] = hTcxLtpDec->tcxltp_gain; /* Q15 */
4326 537986 : move16();
4327 : }
4328 550116 : smooth_gain = Dot_product( hTcxDec->ltpGainMemory_fx, nf_tw_smoothing_coeffs_fx, N_LTP_GAIN_MEMS ); /* Q31 */
4329 550116 : noiseTransWidth = HOLE_SIZE_FROM_LTP32( L_max( smooth_gain, L_deposit_h( tmp1 ) ) ); /* using 32-bit for increased precision. */
4330 : }
4331 : ELSE
4332 : {
4333 89814 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxLtpDec->tcxltp_gain, tmp1 ) );
4334 : }
4335 :
4336 639930 : if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
4337 : {
4338 25244 : noiseTransWidth = 3; /* minimum transition fading for noise filling in TCX-10 */
4339 25244 : move16();
4340 : }
4341 : }
4342 :
4343 750780 : IF( hTcxDec->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
4344 : {
4345 : /* noise filling seed */
4346 736956 : tmp32 = L_deposit_l( 0 );
4347 601974316 : FOR( i = 0; i < L_spec; i++ )
4348 : {
4349 601237360 : tmp32 = L_macNs_co( tmp32, abs_s( prm_sqQ[i] ), i, &Carry, &Overflow );
4350 : }
4351 736956 : nf_seed = extract_l( tmp32 );
4352 : }
4353 750780 : pInfoTCXNoise = NULL;
4354 750780 : if ( st->igf )
4355 : {
4356 519419 : pInfoTCXNoise = st->hIGFDec->infoTCXNoise_ptr;
4357 : }
4358 750780 : tcx_noise_filling_with_shift( x, x_e, nf_seed, firstLine, noiseFillingSize, noiseTransWidth, L_frame, noiseTiltFactor, fac_ns, pInfoTCXNoise, st->element_mode );
4359 750780 : st->seed_tcx_plc = nf_seed;
4360 750780 : move16();
4361 : }
4362 :
4363 796316 : IF( st->enablePlcWaveadjust )
4364 : {
4365 0 : IF( bfi )
4366 : {
4367 0 : IF( EQ_16( st->nbLostCmpt, 1 ) )
4368 : {
4369 0 : st->hPlcInfo->concealment_method = TCX_NONTONAL;
4370 0 : move16();
4371 :
4372 : /* tonal/non-tonal decision */
4373 0 : test();
4374 0 : test();
4375 0 : IF( EQ_16( st->hPlcInfo->Transient[0], 1 ) && EQ_16( st->hPlcInfo->Transient[1], 1 ) && EQ_16( st->hPlcInfo->Transient[2], 1 ) )
4376 : {
4377 0 : sum_word16 = 0;
4378 0 : move16();
4379 :
4380 0 : FOR( i = 9; i >= 0; i-- )
4381 : {
4382 0 : sum_word16 = add( sum_word16, st->hPlcInfo->TCX_Tonality[i] );
4383 : }
4384 :
4385 0 : if ( GE_16( sum_word16, 6 ) )
4386 : {
4387 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4388 0 : move16();
4389 : }
4390 : }
4391 :
4392 0 : if ( st->tonal_mdct_plc_active )
4393 : {
4394 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4395 0 : move16();
4396 : }
4397 : }
4398 :
4399 0 : if ( GT_16( L_frameTCX, hTcxDec->L_frameTCX ) )
4400 : {
4401 0 : st->hPlcInfo->concealment_method = TCX_TONAL;
4402 0 : move16();
4403 : }
4404 :
4405 0 : *temp_concealment_method = st->hPlcInfo->concealment_method;
4406 0 : move16();
4407 :
4408 0 : if ( EQ_16( st->core, TCX_10_CORE ) )
4409 : {
4410 0 : *temp_concealment_method = TCX_TONAL;
4411 0 : move16();
4412 : }
4413 : }
4414 :
4415 : /* get the starting location of the subframe in the frame */
4416 0 : IF( EQ_16( st->core, TCX_10_CORE ) )
4417 : {
4418 0 : st->hPlcInfo->subframe_fx = extract_l( L_mult0( frame_cnt, L_frameTCX_glob ) );
4419 0 : move16();
4420 : }
4421 : }
4422 :
4423 : /* PLC: [TCX: Tonal Concealment] */
4424 : /* PLC: [TCX: Fade-out]
4425 : * PLC: Fade out to white noise */
4426 796316 : IF( st->hTonalMDCTConc != NULL )
4427 : {
4428 796316 : test();
4429 796316 : IF( bfi == 0 && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4430 : {
4431 214310 : TonalMDCTConceal_SaveFreqSignal_ivas_fx( st->hTonalMDCTConc, x, *x_e, L_frameTCX, L_frame, gainlpc2, gainlpc2_e, gain_tcx_e, infoIGFStartLine );
4432 : }
4433 582006 : ELSE IF( bfi )
4434 : {
4435 8487 : test();
4436 8487 : IF( !st->enablePlcWaveadjust || EQ_16( *temp_concealment_method, TCX_TONAL ) )
4437 : {
4438 : /* set f to 1 to not fade out */
4439 : /* set f to 0 to immediately switch to white noise */
4440 8487 : test();
4441 8487 : test();
4442 8487 : IF( st->tcxonly && ( NE_16( st->element_mode, IVAS_CPE_MDCT ) || MCT_flag ) )
4443 : {
4444 4156 : f = MAX16B;
4445 4156 : move16();
4446 : }
4447 : ELSE
4448 : {
4449 4331 : f = hTcxDec->cummulative_damping_tcx;
4450 4331 : move16();
4451 : }
4452 :
4453 8487 : test();
4454 8487 : test();
4455 8487 : test();
4456 8487 : test();
4457 8487 : test();
4458 8487 : test();
4459 8487 : 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 ) ) )
4460 : {
4461 : Word16 exp1, exp2;
4462 15 : exp1 = 0;
4463 15 : exp2 = 0;
4464 : Word64 E_2ndlast, E_last;
4465 15 : E_2ndlast = E_last = EPSILON_FX;
4466 15 : move16();
4467 15 : move16();
4468 15 : move64();
4469 15 : move64();
4470 :
4471 : Word16 tmp_len;
4472 15 : IF( st->element_mode > EVS_MONO )
4473 : {
4474 15 : tmp_len = L_frameTCX;
4475 15 : move16();
4476 : }
4477 : ELSE
4478 : {
4479 0 : tmp_len = infoIGFStartLine;
4480 0 : move16();
4481 : }
4482 :
4483 2015 : FOR( i = 0; i < tmp_len; i = i + 2 )
4484 : {
4485 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) */
4486 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) */
4487 : }
4488 :
4489 15 : exp2 = W_norm( E_2ndlast );
4490 15 : E_2ndlast = W_shl( E_2ndlast, exp2 );
4491 15 : exp2 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp2 ) );
4492 :
4493 15 : exp1 = W_norm( E_last );
4494 15 : E_last = W_shl( E_last, exp1 );
4495 15 : exp1 = sub( 63, add( sub( 31, shl( st->hTonalMDCTConc->lastBlockData.spectralData_exp, 1 ) ), exp1 ) );
4496 :
4497 15 : tmp1 = BASOP_Util_Divide3232_Scale( W_extract_h( E_2ndlast ), W_extract_h( E_last ), &tmp2 );
4498 15 : tmp2 = add( tmp2, sub( exp2, exp1 ) );
4499 :
4500 15 : tmp1 = shl_sat( tmp1, sub( tmp2, 2 ) );
4501 :
4502 : /* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
4503 15 : IF( st->element_mode > EVS_MONO )
4504 : {
4505 15 : tmp_len = L_frameTCX;
4506 15 : move16();
4507 : }
4508 : ELSE
4509 : {
4510 0 : tmp_len = infoIGFStartLine;
4511 0 : move16();
4512 : }
4513 15 : IF( GT_16( tmp1, ONE_IN_Q14 ) ) /* 2 in Q13 = 1 in Q14 */
4514 : {
4515 0 : FOR( i = 0; i < tmp_len; i += 2 )
4516 : {
4517 0 : move16();
4518 0 : st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
4519 : }
4520 : }
4521 15 : ELSE IF( LT_16( tmp1, ONE_IN_Q12 ) ) /*0.5 in Q13 = 1 in Q12*/
4522 : {
4523 1127 : FOR( i = 0; i < tmp_len; i += 2 )
4524 : {
4525 1120 : move16();
4526 1120 : st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
4527 : }
4528 : }
4529 : }
4530 :
4531 8487 : noiseTiltFactor = MAX16B;
4532 8487 : move16();
4533 :
4534 8487 : tmp = 0;
4535 8487 : move16();
4536 8487 : test();
4537 8487 : if ( GE_32( total_brate, ACELP_13k20 ) && st->rf_flag == 0 )
4538 : {
4539 8266 : tmp = 1;
4540 8266 : move16();
4541 : }
4542 :
4543 8487 : tcxGetNoiseFillingTilt( A, M, L_frame, tmp, &noiseTiltFactor );
4544 :
4545 : Word32 CngLevelBackgroundTrace_bfi_fx;
4546 8487 : CngLevelBackgroundTrace_bfi_fx = L_deposit_l( hTcxDec->conCngLevelBackgroundTrace );
4547 : Word16 CngLevelBackgroundTrace_bfi_exp;
4548 8487 : CngLevelBackgroundTrace_bfi_exp = add( hTcxDec->conCngLevelBackgroundTrace_e, 16 );
4549 8487 : test();
4550 8487 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && MCT_flag == 0 )
4551 : {
4552 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 );
4553 : }
4554 : ELSE
4555 : {
4556 5394 : 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 );
4557 : }
4558 : }
4559 : }
4560 : }
4561 :
4562 : /*------------------------- SPLIT 2 noise filling ------------------------*/
4563 796316 : IF( !bfi )
4564 : {
4565 787829 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4566 : {
4567 455819999 : FOR( i = 0; i < L_spec; i++ )
4568 : {
4569 455246480 : x[i] = Mpy_32_16_1( x[i], gain_tcx );
4570 455246480 : move16();
4571 : }
4572 573519 : *x_e = add( *x_e, gain_tcx_e );
4573 573519 : move16();
4574 : }
4575 : }
4576 :
4577 796316 : IF( LT_16( L_spec, L_frame ) )
4578 : {
4579 2 : set32_fx( x + L_spec, 0, sub( L_frame, L_spec ) );
4580 : }
4581 796314 : ELSE IF( GT_16( L_spec, L_frameTCX ) )
4582 : {
4583 63241 : set32_fx( x + L_frameTCX, 0, sub( L_spec, L_frameTCX ) );
4584 : }
4585 796316 : test();
4586 796316 : test();
4587 796316 : test();
4588 796316 : test();
4589 796316 : test();
4590 796316 : test();
4591 796316 : test();
4592 796316 : test();
4593 796316 : test();
4594 796316 : test();
4595 796316 : test();
4596 796316 : test();
4597 796316 : test();
4598 796316 : 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 ) ) )
4599 : {
4600 5 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
4601 : /* also replace flat spectrum for the second TCX10 sub frame */
4602 5 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 1, IGF_GRID_LB_SHORT );
4603 5 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x, *x_e, IGF_GRID_LB_SHORT );
4604 5 : IGFDecUpdateInfo_ivas_fx( st->hIGFDec, 0, IGF_GRID_LB_SHORT );
4605 5 : Copy( st->hIGFDec->igfData.igf_curr_subframe[0][0], st->hIGFDec->igfData.igf_curr_subframe[1][0], IGF_MAX_SFB );
4606 : }
4607 796311 : ELSE IF( bfi && st->igf && ( frame_cnt == 0 ) && ( EQ_16( L_frameTCX, shr( hTcxDec->L_frameTCX, 1 ) ) ) )
4608 : {
4609 : /* copy second to first subframe */
4610 13 : IGFDecReplicateTCX10State_fx( st->hIGFDec );
4611 : }
4612 :
4613 796316 : IF( st->element_mode != EVS_MONO )
4614 : {
4615 796316 : IF( bfi )
4616 : {
4617 8487 : nf_seed = st->seed_tcx_plc;
4618 8487 : move16();
4619 : }
4620 787829 : ELSE IF( nf_seed == 0 )
4621 : {
4622 38638 : nf_seed = *st->hIGFDec->igfData.igfInfo.nfSeed;
4623 38638 : move16();
4624 : }
4625 : }
4626 :
4627 796316 : IF( st->igf )
4628 : {
4629 539113 : *st->hIGFDec->igfData.igfInfo.nfSeed = extract_l( L_add( L_mult0( nf_seed, 31821 ), 13849 ) );
4630 539113 : move16();
4631 : }
4632 :
4633 796316 : return;
4634 : }
4635 :
4636 : /*-------------------------------------------------------------------*
4637 : * decoder_tcx_noiseshaping_igf_fx()
4638 : *
4639 : * TCX: FDNS and IGF application
4640 : *-------------------------------------------------------------------*/
4641 :
4642 796316 : void decoder_tcx_noiseshaping_igf_fx(
4643 : Decoder_State *st, /* i/o: coder memory state */
4644 : const Word16 L_spec,
4645 : const Word16 L_frame,
4646 : const Word16 L_frameTCX,
4647 : const Word16 left_rect,
4648 : Word32 *x_fx,
4649 : Word16 *x_e,
4650 : Word16 *x_len,
4651 : const Word16 gainlpc2_fx[],
4652 : const Word16 gainlpc2_e[],
4653 : Word16 *temp_concealment_method,
4654 : const Word16 bfi /* i : Bad frame indicator */
4655 : )
4656 : {
4657 : TCX_DEC_HANDLE hTcxDec;
4658 : Word16 i;
4659 : Word32 tmp32;
4660 : Word8 tmp8;
4661 :
4662 : /*-----------------------------------------------------------*
4663 : * Noise shaping in frequency domain (1/Wz) *
4664 : *-----------------------------------------------------------*/
4665 796316 : hTcxDec = st->hTcxDec;
4666 :
4667 796316 : test();
4668 796316 : test();
4669 796316 : test();
4670 796316 : IF( st->igf && ( !bfi || ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->prev_bfi ) ) )
4671 : {
4672 536646 : test();
4673 536646 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) )
4674 : {
4675 20274 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_SHORT );
4676 : }
4677 : ELSE
4678 : {
4679 516372 : IF( st->last_core == ACELP_CORE )
4680 : {
4681 7447 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_TRAN );
4682 : }
4683 : ELSE
4684 : {
4685 508925 : IGFDecCopyLPCFlatSpectrum_fx( st->hIGFDec, x_fx, *x_e, IGF_GRID_LB_NORM );
4686 : }
4687 : }
4688 : }
4689 : /* LPC gains already available */
4690 :
4691 796316 : test();
4692 796316 : test();
4693 796316 : test();
4694 796316 : test();
4695 796316 : test();
4696 796316 : IF( gainlpc2_fx && gainlpc2_e && NE_16( st->element_mode, IVAS_CPE_MDCT ) && ( !st->enablePlcWaveadjust || !bfi || ( EQ_16( *temp_concealment_method, TCX_TONAL ) ) ) )
4697 : {
4698 : Word16 spec_side_x_e, frame_side_x_e;
4699 :
4700 216113 : spec_side_x_e = *x_e;
4701 216113 : move16();
4702 :
4703 : /* NOTE: this function updates x till L_frame. From L_frame to L_spec, the exponent needs to be updated. */
4704 216113 : mdct_noiseShaping_ivas_fx( x_fx, x_e, L_frame, gainlpc2_fx, gainlpc2_e );
4705 :
4706 216113 : frame_side_x_e = *x_e;
4707 216113 : move16();
4708 :
4709 216113 : IF( bfi == 0 )
4710 : {
4711 83670870 : FOR( i = L_frame; i < L_spec; i++ )
4712 : {
4713 83456560 : x_fx[i] = Mpy_32_16_1( x_fx[i], gainlpc2_fx[FDNS_NPTS - 1] );
4714 83456560 : move32();
4715 : }
4716 214310 : spec_side_x_e = add( spec_side_x_e, gainlpc2_e[FDNS_NPTS - 1] );
4717 : }
4718 :
4719 216113 : IF( LT_16( spec_side_x_e, frame_side_x_e ) )
4720 : {
4721 : /* If the exponent on the spec side (i>L_frame) is lesser, then shift all the values in the
4722 : spec side by the difference to make both sides have the same exponent. */
4723 : #ifdef OPT_SBA_DEC_V2_BE
4724 196190 : Word16 diff_e = sub( frame_side_x_e, spec_side_x_e );
4725 : #endif /* OPT_SBA_DEC_V2_BE */
4726 77299470 : FOR( i = L_frame; i < L_spec; i++ )
4727 : {
4728 : #ifdef OPT_SBA_DEC_V2_BE
4729 77103280 : x_fx[i] = L_shr( x_fx[i], diff_e );
4730 : #else /* OPT_SBA_DEC_V2_BE */
4731 : x_fx[i] = L_shr( x_fx[i], sub( frame_side_x_e, spec_side_x_e ) );
4732 : #endif /* OPT_SBA_DEC_V2_BE */
4733 77103280 : move32();
4734 : }
4735 : }
4736 19923 : ELSE IF( GT_16( spec_side_x_e, frame_side_x_e ) )
4737 : {
4738 : /* If the exponent on the spec side (i>L_frame) is greater, then shift all the values in the
4739 : frame side (i<L_frame) by the difference to make both sides have the same exponent. */
4740 : #ifdef OPT_SBA_DEC_V2_BE
4741 0 : Word16 diff_e = sub( spec_side_x_e, frame_side_x_e );
4742 : #endif /* OPT_SBA_DEC_V2_BE */
4743 0 : FOR( i = 0; i < L_frame; i++ )
4744 : {
4745 : #ifdef OPT_SBA_DEC_V2_BE
4746 0 : x_fx[i] = L_shr( x_fx[i], diff_e );
4747 : #else /* OPT_SBA_DEC_V2_BE */
4748 : x_fx[i] = L_shr( x_fx[i], sub( spec_side_x_e, frame_side_x_e ) );
4749 : #endif /* OPT_SBA_DEC_V2_BE */
4750 0 : move32();
4751 : }
4752 : }
4753 216113 : *x_e = s_max( spec_side_x_e, frame_side_x_e );
4754 216113 : move16();
4755 :
4756 216113 : set32_fx( x_fx + L_spec, 0, sub( L_frameTCX, L_spec ) );
4757 : }
4758 :
4759 : /* PLC: [TCX: Tonal Concealment] */
4760 796316 : test();
4761 796316 : test();
4762 796316 : IF( bfi && st->tonal_mdct_plc_active && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4763 : {
4764 : Word16 tmp_x_fx_exp[L_FRAME48k], temp;
4765 182 : temp = -MAX_16;
4766 182 : move16();
4767 :
4768 182 : set16_fx( tmp_x_fx_exp, *x_e, L_frameTCX );
4769 182 : TonalMDCTConceal_Apply_ivas_fx( st->hTonalMDCTConc, x_fx, tmp_x_fx_exp, st->hTcxCfg->psychParamsCurrent );
4770 :
4771 : /* If exponent has been updated after TonalMDCTConceal_Apply, then shift the spectrum to common exponent. */
4772 153462 : FOR( i = 0; i < L_frameTCX; i++ )
4773 : {
4774 153280 : temp = s_max( temp, tmp_x_fx_exp[i] );
4775 : }
4776 :
4777 : {
4778 182 : *x_e = temp;
4779 182 : move16();
4780 153462 : FOR( i = 0; i < L_frameTCX; i++ )
4781 : {
4782 153280 : x_fx[i] = L_shr( x_fx[i], sub( temp, tmp_x_fx_exp[i] ) );
4783 153280 : move32();
4784 : }
4785 : }
4786 : }
4787 :
4788 796316 : test();
4789 796316 : IF( st->hTonalMDCTConc != NULL && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4790 : {
4791 216113 : tmp32 = L_deposit_h( 0 );
4792 216113 : if ( hTcxDec->tcxltp_last_gain_unmodified > 0 )
4793 : {
4794 105526 : tmp32 = st->old_fpitch;
4795 105526 : move32();
4796 : }
4797 :
4798 216113 : tmp8 = 0;
4799 216113 : move16();
4800 216113 : test();
4801 216113 : if ( bfi && st->tonal_mdct_plc_active )
4802 : {
4803 182 : tmp8 = 1;
4804 182 : move16();
4805 : }
4806 :
4807 216113 : TonalMDCTConceal_UpdateState( st->hTonalMDCTConc,
4808 : L_frameTCX,
4809 : tmp32,
4810 : bfi,
4811 : tmp8 );
4812 : }
4813 :
4814 796316 : *x_len = L_frameTCX;
4815 796316 : move16();
4816 :
4817 796316 : IF( st->enablePlcWaveadjust != 0 )
4818 : {
4819 0 : test();
4820 : /* spectrum concealment */
4821 0 : IF( bfi && EQ_16( *temp_concealment_method, TCX_NONTONAL ) )
4822 : {
4823 0 : concealment_decode_fix( st->core, x_fx, x_e, st->hPlcInfo );
4824 : }
4825 :
4826 : /* update spectrum buffer, tonality flag, etc. */
4827 0 : concealment_update_x( bfi, st->core, st->tonality_flag, x_fx, x_e, st->hPlcInfo );
4828 :
4829 0 : *x_len = s_max( *x_len, st->hPlcInfo->L_frameTCX );
4830 0 : move16();
4831 : }
4832 :
4833 : /*-----------------------------------------------------------*
4834 : * IGF *
4835 : *-----------------------------------------------------------*/
4836 :
4837 796316 : test();
4838 796316 : test();
4839 796316 : IF( st->igf && !( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
4840 : {
4841 518807 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4842 : {
4843 : Word16 igfGridIdx;
4844 :
4845 202608 : test();
4846 202608 : IF( ( EQ_16( st->last_core, ACELP_CORE ) ) || ( left_rect && bfi ) )
4847 : {
4848 : /* packet loss after first TCX must be handled like transition frame */
4849 6566 : igfGridIdx = IGF_GRID_LB_TRAN;
4850 6566 : move16();
4851 : }
4852 : ELSE
4853 : {
4854 196042 : igfGridIdx = IGF_GRID_LB_NORM;
4855 196042 : move16();
4856 : }
4857 :
4858 202608 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, igfGridIdx, bfi, st->element_mode );
4859 :
4860 202608 : *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[igfGridIdx].stopLine );
4861 202608 : move16();
4862 : }
4863 : }
4864 796316 : test();
4865 796316 : test();
4866 796316 : IF( st->igf && ( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly ) ) )
4867 : {
4868 20306 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
4869 : {
4870 3782 : IGFDecApplyMono_ivas( st->hIGFDec, x_fx, x_e, IGF_GRID_LB_SHORT, bfi, st->element_mode );
4871 :
4872 3782 : *x_len = s_max( *x_len, st->hIGFDec->igfData.igfInfo.grid[IGF_GRID_LB_SHORT].stopLine );
4873 3782 : move16();
4874 : }
4875 : }
4876 :
4877 796316 : return;
4878 : }
4879 :
4880 :
4881 : /*-------------------------------------------------------------------*
4882 : * decoder_tcx_tns()
4883 : *
4884 : * TCX: TNS application
4885 : *-------------------------------------------------------------------*/
4886 :
4887 1369029 : void decoder_tcx_tns_fx(
4888 : Decoder_State *st, /* i/o: coder memory state */
4889 : const Word16 L_frame_glob, /* i : frame length */
4890 : const Word16 L_spec,
4891 : const Word16 L_frame,
4892 : const Word16 L_frameTCX,
4893 : Word32 x_fx[N_MAX], // Qx
4894 : const Word16 fUseTns, /* i : flag that is set if TNS data is present */
4895 : STnsData *tnsData,
4896 : const Word16 bfi, /* i : Bad frame indicator */
4897 : const Word16 frame_cnt, /* i : frame counter in the super frame */
4898 : const Word16 whitenedDomain,
4899 : Word16 *length )
4900 : {
4901 : Word16 index, isTCX5, L, tmp;
4902 1369029 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
4903 :
4904 1369029 : index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
4905 1369029 : move16();
4906 :
4907 1369029 : isTCX5 = 0;
4908 1369029 : move16();
4909 1369029 : L = L_frameTCX;
4910 1369029 : move16();
4911 1369029 : tmp = L;
4912 1369029 : move16();
4913 :
4914 1369029 : test();
4915 1369029 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 )
4916 : {
4917 54444 : test();
4918 54444 : test();
4919 54444 : IF( frame_cnt != 0 && bfi == 0 && st->last_core != ACELP_CORE )
4920 : {
4921 : /* fix sub-window overlap */
4922 27122 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
4923 27122 : move16();
4924 : }
4925 :
4926 54444 : test();
4927 54444 : test();
4928 54444 : test();
4929 54444 : IF( ( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && NE_16( fUseTns, 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) )
4930 : {
4931 31831 : L = L_spec;
4932 31831 : move16();
4933 31831 : tmp = L;
4934 31831 : move16();
4935 : }
4936 :
4937 54444 : test();
4938 54444 : test();
4939 54444 : test();
4940 54444 : test();
4941 54444 : test();
4942 54444 : test();
4943 54444 : test();
4944 54444 : IF( ( EQ_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) ||
4945 : ( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) && EQ_16( frame_cnt, 0 ) && EQ_16( index, 0 ) ) ) ) ||
4946 : ( NE_16( bfi, 0 ) && ( NE_16( hTcxCfg->tcx_last_overlap_mode, FULL_OVERLAP ) &&
4947 : NE_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) ) ) )
4948 : {
4949 28247 : isTCX5 = 1;
4950 28247 : move16();
4951 :
4952 28247 : tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
4953 : }
4954 : }
4955 :
4956 : /*-----------------------------------------------------------*
4957 : * Temporal Noise Shaping Synthesis *
4958 : *-----------------------------------------------------------*/
4959 :
4960 :
4961 1369029 : test();
4962 1369029 : test();
4963 1369029 : test();
4964 1369029 : IF( NE_16( hTcxCfg->fIsTNSAllowed, 0 ) && fUseTns != 0 && NE_16( bfi, 1 ) && EQ_16( tnsData->tnsOnWhitenedSpectra, whitenedDomain ) )
4965 : {
4966 : /* Apply TNS to get the reconstructed signal */
4967 80721 : SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
4968 :
4969 80721 : test();
4970 80721 : test();
4971 80721 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
4972 : {
4973 11540 : tcx5TnsGrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx );
4974 : }
4975 :
4976 80721 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x_fx, 0 );
4977 :
4978 80721 : test();
4979 80721 : test();
4980 80721 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly != 0 && isTCX5 != 0 )
4981 : {
4982 11540 : test();
4983 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) */
4984 : {
4985 937 : tcx5TnsUngrouping_fx( shr( L_frameTCX, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
4986 937 : tmp = L_frameTCX;
4987 937 : move16();
4988 : }
4989 : ELSE
4990 : {
4991 10603 : tcx5TnsUngrouping_fx( shr( L, 1 ), shr( hTcxCfg->tnsConfig[0][0].iFilterBorders[0], 1 ), x_fx, DEC );
4992 : }
4993 : }
4994 : }
4995 1369029 : test();
4996 1369029 : IF( NE_16( whitenedDomain, 0 ) && NE_16( isTCX5, 0 ) )
4997 : {
4998 13077 : tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
4999 : }
5000 :
5001 : /* restore index */
5002 1369029 : test();
5003 1369029 : test();
5004 1369029 : test();
5005 1369029 : test();
5006 1369029 : 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 ) )
5007 : {
5008 : /* restore sub-window overlap */
5009 27122 : hTcxCfg->tcx_last_overlap_mode = index;
5010 27122 : move16();
5011 : }
5012 :
5013 1369029 : if ( length != NULL )
5014 : {
5015 1152916 : *length = tmp;
5016 1152916 : move16();
5017 : }
5018 :
5019 1369029 : return;
5020 : }
5021 :
5022 :
5023 792571 : void decoder_tcx_imdct_fx(
5024 : Decoder_State *st, /* i/o: coder memory state */
5025 : const Word16 L_frame_glob, /* i : frame length */
5026 : const Word16 L_frameTCX_glob,
5027 : const Word16 L_spec,
5028 : const Word16 tcx_offset,
5029 : const Word16 tcx_offsetFB,
5030 : const Word16 L_frame,
5031 : const Word16 L_frameTCX,
5032 : const Word16 left_rect,
5033 : Word32 x_fx[N_MAX], // Q(11)
5034 : Word16 q_x,
5035 : Word16 xn_buf_fx[], // Q(-2)
5036 : Word16 q_win,
5037 : const UWord16 kernelType, /* i : TCX transform kernel type */
5038 : const Word16 fUseTns, /* i : flag that is set if TNS data is present */
5039 : Word16 synth_fx[], // Q(-2) /* i/o: synth[-M..L_frame] */
5040 : Word16 synthFB_fx[], // Q(-2)
5041 : const Word16 bfi, /* i : Bad frame indicator */
5042 : const Word16 frame_cnt, /* i : frame counter in the super frame */
5043 : const Word16 sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */
5044 : )
5045 : {
5046 : Word16 j, L, overlap, curr_order, startLine, endLine, isTCX5;
5047 : Word16 overlapFB;
5048 : Word32 x_tmp_fx[L_FRAME_PLUS];
5049 792571 : Word32 xn_bufFB_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX] = { 0 };
5050 : Word16 xn_bufFB_fx_16[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
5051 : Word16 acelp_zir_fx[L_FRAME_MAX / 2];
5052 : Word32 x_itf_fx[N_MAX_TCX - IGF_START_MN];
5053 792571 : Word16 index, proc = 0;
5054 792571 : TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec;
5055 792571 : TCX_DEC_HANDLE hTcxDec = st->hTcxDec;
5056 792571 : TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg;
5057 : Word16 predictionGain_fx;
5058 : Word16 A_itf_fx[ITF_MAX_FILTER_ORDER + 1]; // q_a_itf
5059 792571 : Word16 q_a_itf = 15;
5060 792571 : Word16 x_e = sub( 31, q_x );
5061 792571 : move16();
5062 792571 : Word16 shift_q = sub( q_x, q_win );
5063 :
5064 : /*-----------------------------------------------------------------*
5065 : * Initializations
5066 : *-----------------------------------------------------------------*/
5067 :
5068 : /* Init lengths */
5069 792571 : overlap = hTcxCfg->tcx_mdct_window_length;
5070 792571 : move16();
5071 792571 : overlapFB = hTcxCfg->tcx_mdct_window_lengthFB;
5072 792571 : move16();
5073 :
5074 792571 : index = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
5075 792571 : move16();
5076 792571 : test();
5077 792571 : test();
5078 792571 : test();
5079 792571 : test();
5080 792571 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && ( st->tcxonly != 0 ) && ( frame_cnt != 0 ) && ( bfi == 0 ) && ( st->last_core != ACELP_CORE ) )
5081 : {
5082 : /* fix sub-window overlap */
5083 14532 : hTcxCfg->tcx_last_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
5084 14532 : move16();
5085 : }
5086 :
5087 792571 : IF( st->igf != 0 )
5088 : {
5089 537733 : proc = st->hIGFDec->flatteningTrigger;
5090 537733 : move16();
5091 :
5092 537733 : test();
5093 537733 : IF( proc && fUseTns != 0 )
5094 : {
5095 54007 : proc = 0;
5096 54007 : move16();
5097 : }
5098 :
5099 537733 : IF( proc )
5100 : {
5101 :
5102 464813 : startLine = st->hIGFDec->infoIGFStartLine;
5103 464813 : move16();
5104 464813 : endLine = st->hIGFDec->infoIGFStopLine;
5105 464813 : move16();
5106 464813 : curr_order = 0;
5107 464813 : move16();
5108 464813 : predictionGain_fx = 0;
5109 464813 : move16();
5110 464813 : L = L_frameTCX;
5111 464813 : move16();
5112 464813 : isTCX5 = 0;
5113 464813 : move16();
5114 :
5115 : /* interleave again for ITF */
5116 464813 : test();
5117 464813 : IF( EQ_16( L_frame, shr( st->L_frame, 1 ) ) && st->tcxonly )
5118 : {
5119 8376 : test();
5120 8376 : test();
5121 8376 : test();
5122 8376 : IF( ( hTcxCfg->fIsTNSAllowed && ( fUseTns != 0 ) && NE_16( bfi, 1 ) ) || GT_16( L_spec, L_frameTCX ) )
5123 : {
5124 1150 : L = L_spec;
5125 1150 : move16();
5126 : }
5127 :
5128 8376 : test();
5129 8376 : test();
5130 8376 : test();
5131 8376 : test();
5132 8376 : test();
5133 8376 : test();
5134 8376 : test();
5135 8376 : test();
5136 8376 : test();
5137 8376 : test();
5138 8376 : IF( ( ( bfi == 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
5139 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( index == 0 ) ) ) ) ||
5140 : ( ( bfi != 0 ) && ( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) &&
5141 : ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) ) ) )
5142 : {
5143 2018 : isTCX5 = 1;
5144 2018 : move16();
5145 :
5146 2018 : tcx5SpectrumInterleaving_fx( shr( L, 1 ), x_fx );
5147 : }
5148 : }
5149 :
5150 137203633 : FOR( j = startLine; j < endLine; j++ )
5151 : {
5152 136738820 : IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
5153 : {
5154 19453 : x_itf_fx[j - IGF_START_MN] = x_fx[j]; // q_x
5155 19453 : move32();
5156 19453 : x_fx[j] = st->hIGFDec->virtualSpec_fx[j - IGF_START_MN];
5157 19453 : move32();
5158 : }
5159 : }
5160 :
5161 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 );
5162 :
5163 464813 : ITF_Apply_fx( x_fx, startLine, endLine, A_itf_fx, q_a_itf, curr_order );
5164 :
5165 137203633 : FOR( j = startLine; j < endLine; j++ )
5166 : {
5167 136738820 : IF( EQ_16( st->hIGFDec->flag_sparse[j - IGF_START_MN], 2 ) )
5168 : {
5169 19453 : x_fx[j] = x_itf_fx[j - IGF_START_MN]; // q_x
5170 19453 : move32();
5171 : }
5172 : }
5173 :
5174 : /* deinterleave */
5175 464813 : IF( NE_16( isTCX5, 0 ) )
5176 : {
5177 2018 : tcx5SpectrumDeinterleaving_fx( shr( L, 1 ), x_fx );
5178 : }
5179 : }
5180 : }
5181 :
5182 : /*-----------------------------------------------------------*
5183 : * Prepare OLA buffer after waveadjustment. *
5184 : * Compute inverse MDCT of x[]. *
5185 : *-----------------------------------------------------------*/
5186 :
5187 :
5188 792571 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
5189 : {
5190 576458 : Word16 copy_len = s_min( L_FRAME48k, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) );
5191 576458 : set32_fx( x_tmp_fx, 0, L_FRAME_PLUS );
5192 576458 : Copy32( x_fx, x_tmp_fx, copy_len ); // q_x
5193 576458 : Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
5194 : }
5195 216113 : ELSE IF( ( st->element_mode == EVS_MONO ) )
5196 : {
5197 0 : Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
5198 : }
5199 : ELSE
5200 : {
5201 216113 : Word16 copy_len = s_max( L_spec, s_max( L_frame, L_frameTCX ) );
5202 216113 : Copy32( x_fx, x_tmp_fx, copy_len ); // q_x
5203 216113 : Copy32( x_fx, xn_bufFB_fx, copy_len ); // q_x
5204 : }
5205 :
5206 792571 : IF( ( st->igf != 0 ) )
5207 : {
5208 537733 : set32_fx( xn_bufFB_fx + st->hIGFDec->infoIGFStartLine, 0, L_frameTCX - st->hIGFDec->infoIGFStartLine );
5209 : }
5210 :
5211 792571 : test();
5212 792571 : IF( NE_16( st->element_mode, IVAS_CPE_DFT ) && !sba_dirac_stereo_flag )
5213 : {
5214 :
5215 1552472 : 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,
5216 776236 : 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,
5217 776236 : 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 );
5218 : }
5219 :
5220 : /* Generate additional comfort noise to mask potential coding artefacts */
5221 792571 : test();
5222 792571 : test();
5223 792571 : test();
5224 792571 : 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 ) )
5225 : {
5226 22705 : generate_masking_noise_mdct_ivas_fx( x_fx, &x_e, st->hFdCngDec->hFdCngCom );
5227 6663841 : FOR( Word16 ind = 0; ind < L_frame; ind++ )
5228 : {
5229 6641136 : x_fx[ind] = L_shr( x_fx[ind], sub( 31, add( x_e, q_x ) ) ); // q_x
5230 : }
5231 : }
5232 :
5233 792571 : test();
5234 792571 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || ( sba_dirac_stereo_flag != 0 ) )
5235 : {
5236 16335 : Copy32( x_fx, xn_bufFB_fx, s_max( L_spec, s_max( L_frame, L_frameTCX ) ) ); // q_x
5237 :
5238 16335 : 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,
5239 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, 0, st, 0, acelp_zir_fx, q_win );
5240 : }
5241 :
5242 1617637411 : FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
5243 : {
5244 1616844840 : xn_bufFB_fx_16[ind] = extract_l( L_shr( xn_bufFB_fx[ind], shift_q ) ); // q_x
5245 1616844840 : move16();
5246 : }
5247 :
5248 : Word16 ratio_e;
5249 792571 : Word16 ratio = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &ratio_e ); // Q = 15-ratio_e. * FSCALE_DENOM is (1 << 9)
5250 792571 : ratio = shr( ratio, sub( 6, ratio_e ) );
5251 :
5252 792571 : IF( st->element_mode != EVS_MONO )
5253 : {
5254 1585142 : 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,
5255 792571 : 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,
5256 792571 : 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 );
5257 : }
5258 : ELSE
5259 : {
5260 :
5261 0 : 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,
5262 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, 1, st, ratio, acelp_zir_fx, q_win );
5263 : }
5264 1617637411 : FOR( Word16 ind = 0; ind < L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX; ind++ )
5265 : {
5266 1616844840 : xn_bufFB_fx[ind] = L_shl( L_deposit_l( xn_bufFB_fx_16[ind] ), shift_q ); // Q_x
5267 : }
5268 :
5269 792571 : IF( ( bfi == 0 ) )
5270 : {
5271 784084 : Word16 res_m, res_e = 0;
5272 784084 : move16();
5273 784084 : st->second_last_tns_active = st->last_tns_active;
5274 784084 : move16();
5275 784084 : st->last_tns_active = hTcxCfg->fIsTNSAllowed & fUseTns;
5276 784084 : move16();
5277 784084 : hTcxDec->tcxltp_third_last_pitch = hTcxDec->tcxltp_second_last_pitch;
5278 784084 : move32();
5279 784084 : hTcxDec->tcxltp_second_last_pitch = st->old_fpitch;
5280 784084 : move32();
5281 784084 : res_m = BASOP_Util_Divide1616_Scale( hTcxLtpDec->tcxltp_pitch_fr, st->pit_res_max, &res_e );
5282 784084 : st->old_fpitch = L_add( L_shl( hTcxLtpDec->tcxltp_pitch_int, 16 ), L_shl( res_m, add( res_e, 1 ) ) );
5283 :
5284 784084 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
5285 : {
5286 : // Using sat as a single instruction shifts and extracts
5287 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
5288 569774 : move32();
5289 : }
5290 :
5291 784084 : IF( GT_16( st->element_mode, EVS_MONO ) )
5292 : {
5293 784084 : res_m = BASOP_Util_Divide1616_Scale( L_frameTCX_glob, L_frame_glob, &res_e );
5294 784084 : st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
5295 784084 : move32();
5296 : }
5297 : ELSE
5298 : {
5299 0 : res_m = BASOP_Util_Divide1616_Scale( L_frameTCX, L_frame, &res_e );
5300 0 : st->old_fpitchFB = L_shl( Mpy_32_16_1( st->old_fpitch, res_m ), res_e );
5301 0 : move32();
5302 : }
5303 : }
5304 :
5305 : /* Update old_syn_overl */
5306 792571 : IF( hTcxCfg->last_aldo == 0 )
5307 : {
5308 19885 : Copy( xn_buf_fx + L_frame, hTcxDec->syn_Overl, overlap ); // Q(-2)
5309 7069865 : FOR( Word16 ind = 0; ind < overlapFB; ind++ )
5310 : {
5311 7049980 : hTcxDec->syn_OverlFB[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + L_frameTCX )], shift_q ) ); // q_x
5312 : }
5313 : }
5314 :
5315 : /* Output */
5316 792571 : Copy( xn_buf_fx + sub( shr( overlap, 1 ), tcx_offset ), synth_fx, L_frame_glob ); // Q(-2)
5317 649002171 : FOR( Word16 ind = 0; ind < L_frameTCX_glob; ind++ )
5318 : {
5319 648209600 : synthFB_fx[ind] = extract_l( L_shr( xn_bufFB_fx[( ind + ( ( overlapFB >> 1 ) - tcx_offsetFB ) )], shift_q ) ); // q_x
5320 : }
5321 :
5322 :
5323 792571 : return;
5324 : }
|