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