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