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