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