Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdlib.h>
7 : #include <stdio.h>
8 : #include <assert.h>
9 : #include "rom_com.h"
10 : #include "stat_com.h"
11 : // #include "prot_fx.h"
12 : #include "prot_fx.h"
13 : #include "basop_util.h"
14 : #include "stl.h"
15 : // #include "basop_mpy.h"
16 : #include "prot_fx_enc.h"
17 : #include <math.h>
18 : #include "ivas_prot_fx.h"
19 : #include "ivas_rom_com_fx.h"
20 : #ifdef DEBUGGING
21 : #include "debug.h"
22 : #endif
23 :
24 : #define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 )
25 : #define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 )
26 : #define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 )
27 :
28 : /* Up to the Autocorrelation it is the same code as in GetMDCT, with the difference in the parameters in the call to tcx_windowing_analysis */
29 108948 : void HBAutocorrelation_fx(
30 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
31 : Word16 left_overlap_mode, /* input: overlap mode of left window half */
32 : Word16 right_overlap_mode, /* input: overlap mode of right window half */
33 : Word16 speech[], /* input: speech[-LFAC..L_frame+LFAC] Qx*/
34 : Word16 L_frame, /* input: frame length */
35 : Word32 *r, /* output: autocorrelations vector */
36 : Word16 m /* input : order of LP filter */
37 : )
38 : {
39 : Word16 i, j, left_overlap, right_overlap;
40 : Word16 len, norm, shift, fact;
41 : Word32 L_tmp, L_sum;
42 : Word16 y[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
43 :
44 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
45 108948 : Flag Overflow = 0;
46 108948 : move32();
47 : #endif
48 :
49 : /*-----------------------------------------------------------*
50 : * Windowing *
51 : *-----------------------------------------------------------*/
52 :
53 108948 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offset, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, speech, &L_frame, y, 1, 0 );
54 :
55 : /*-----------------------------------------------------------*
56 : * Autocorrelation *
57 : *-----------------------------------------------------------*/
58 :
59 108948 : len = add( L_frame, shr( add( left_overlap, right_overlap ), 1 ) );
60 :
61 : /* calculate shift */
62 108948 : shift = 0;
63 108948 : move16();
64 108948 : L_sum = L_deposit_l( 0 );
65 108948 : Overflow = 0;
66 108948 : move32();
67 96671397 : FOR( i = 0; i < len; i += 1 )
68 : {
69 : /* Test Addition */
70 96562451 : L_mac0_o( L_sum, y[i], y[i], &Overflow );
71 96562451 : IF( Overflow )
72 : {
73 2 : Overflow = 0;
74 2 : move32();
75 2 : shift = 1;
76 2 : move16();
77 2 : L_tmp = L_msu0( 0, y[i], y[i] );
78 2 : L_tmp = L_shr( L_tmp, 1 );
79 2 : L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 );
80 2 : L_sum = L_sub_o( L_sum, L_tmp, &Overflow );
81 375 : FOR( j = i + 1; j < len; j++ )
82 : {
83 373 : L_tmp = L_msu0( 0, y[j], y[j] );
84 373 : L_tmp = L_shr( L_tmp, shift );
85 :
86 : /* Test Addition */
87 373 : L_sub_o( L_sum, L_tmp, &Overflow );
88 373 : IF( Overflow )
89 : {
90 0 : Overflow = 0;
91 0 : move32();
92 0 : shift = add( shift, 1 );
93 0 : L_tmp = L_shr( L_tmp, 1 );
94 0 : L_sum = L_add( L_shr( L_sub_o( L_sum, 1, &Overflow ), 1 ), 1 );
95 : }
96 373 : L_sum = L_sub_o( L_sum, L_tmp, &Overflow );
97 : }
98 2 : BREAK;
99 : }
100 : /* Perform Addition */
101 96562449 : L_sum = L_mac0_o( L_sum, y[i], y[i], &Overflow );
102 : }
103 :
104 : /* scale signal to avoid overflow in autocorrelation */
105 108948 : IF( shift > 0 )
106 : {
107 2 : fact = lshr( -32768, shift );
108 1474 : FOR( i = 0; i < len; i++ )
109 : {
110 1472 : y[i] = mult_r( y[i], fact );
111 1472 : move16();
112 : }
113 : }
114 :
115 : /* Compute and normalize r[0] */
116 108948 : L_sum = L_mac0( 1, y[0], y[0] );
117 96562824 : FOR( i = 1; i < len; i++ )
118 : {
119 96453876 : L_sum = L_mac0( L_sum, y[i], y[i] );
120 : }
121 :
122 108948 : norm = norm_l( L_sum );
123 108948 : L_sum = L_shl( L_sum, norm );
124 108948 : r[0] = L_sum;
125 108948 : move32();
126 :
127 : /* Compute r[1] to r[m] */
128 1852116 : FOR( i = 1; i <= m; i++ )
129 : {
130 1743168 : L_sum = L_mult0( y[0], y[i] );
131 1530188256 : FOR( j = 1; j < len - i; j++ )
132 : {
133 1528445088 : L_sum = L_mac0( L_sum, y[j], y[j + i] );
134 : }
135 :
136 1743168 : L_sum = L_shl( L_sum, norm );
137 1743168 : r[i] = L_sum;
138 1743168 : move32();
139 : }
140 108948 : }
141 :
142 372 : void TNSAnalysis_fx(
143 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
144 : Word16 L_frame, /* input: frame length */
145 : Word16 L_spec,
146 : Word16 tcxMode, /* input: TCX mode for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */
147 : Word8 isAfterACELP, /* input: Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */
148 : Word32 spectrum[], /* input: MDCT spectrum Qx*/
149 : STnsData *pTnsData, /* output: Tns data */
150 : Word8 *pfUseTns, /* output: Flag indicating if TNS is used */
151 : Word16 *predictionGain /*Q7*/
152 : )
153 : {
154 : Word32 buff[8];
155 372 : Word16 tmp = 0; /* initialization only to avoid compiler warning, not counted */
156 372 : Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
157 372 : move16();
158 372 : move16();
159 :
160 : /* Init TNS */
161 372 : *pfUseTns = 0;
162 372 : move16();
163 :
164 372 : IF( hTcxCfg->fIsTNSAllowed != 0 )
165 : {
166 372 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( tcxMode - TCX_20 ) == 0][isAfterACELP];
167 372 : L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
168 372 : move16();
169 :
170 : /*-----------------------------------------------------------*
171 : * Temporal Noise Shaping analysis *
172 : *-----------------------------------------------------------*/
173 :
174 372 : IF( EQ_16( tcxMode, TCX_5 ) )
175 : {
176 0 : tmp = shr( L_frame, 2 );
177 :
178 : /* rearrange LF sub-window lines prior to TNS analysis & filtering */
179 0 : tmp2 = shr( L_spec, 1 );
180 :
181 0 : IF( LT_16( tmp2, tmp ) )
182 : {
183 0 : Copy32( spectrum + 8, spectrum + 16, sub( tmp2, 8 ) );
184 0 : Copy32( spectrum + tmp, spectrum + 8, 8 );
185 0 : Copy32( spectrum + tmp + 8, spectrum + tmp2 + 8, sub( tmp2, 8 ) );
186 : }
187 : ELSE
188 : {
189 0 : Copy32( spectrum + tmp, buff, 8 );
190 0 : Copy32( spectrum + 8, spectrum + 16, sub( tmp, 8 ) );
191 0 : Copy32( buff, spectrum + 8, 8 );
192 : }
193 : }
194 :
195 372 : move16();
196 372 : *pfUseTns = (Word8) DetectTnsFilt_fx( hTcxCfg->pCurrentTnsConfig, spectrum, pTnsData, predictionGain );
197 :
198 : /* If TNS should be used then get the residual after applying it inplace in spectrum */
199 372 : IF( *pfUseTns != 0 )
200 : {
201 4 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
202 : }
203 :
204 372 : IF( EQ_16( tcxMode, TCX_5 ) )
205 : {
206 : /* undo rearrangement of LF sub-window lines prior to TNS analysis */
207 0 : IF( LT_16( tmp2, tmp ) )
208 : {
209 0 : Copy32( spectrum + tmp2 + 8, spectrum + tmp + 8, sub( tmp2, 8 ) );
210 0 : Copy32( spectrum + 8, spectrum + tmp, 8 );
211 0 : Copy32( spectrum + 16, spectrum + 8, sub( tmp2, 8 ) );
212 0 : set32_fx( spectrum + tmp2, 0, sub( tmp, tmp2 ) );
213 0 : set32_fx( spectrum + tmp + tmp2, 0, sub( tmp, tmp2 ) );
214 : }
215 : ELSE
216 : {
217 0 : Copy32( spectrum + 8, buff, 8 );
218 0 : Copy32( spectrum + 16, spectrum + 8, sub( tmp, 8 ) );
219 0 : Copy32( buff, spectrum + tmp, 8 );
220 : }
221 : }
222 : }
223 372 : }
224 :
225 238490 : void TNSAnalysis_ivas_fx(
226 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
227 : Word16 L_frame, /* i : frame length */
228 : Word16 L_spec, /* i : length of the spectrum */
229 : Word16 transform_type, /* i : transform type for the frame/subframe - TCX20 | TCX10 | TCX 5 (meaning 2 x TCX 5) */
230 : Word8 isAfterACELP, /* i : Flag indicating if the last frame was ACELP. For the second TCX subframe it should be 0 */
231 : Word32 spectrum[], /* i : MDCT spectrum Q=Qx*/
232 : TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */
233 : Word16 ltp_gain, /* i : ltp gain Q=15*/
234 : STnsData *pTnsData, /* o : Tns data */
235 : Word8 *pfUseTns, /* o : Flag indicating if TNS is used */
236 : Word16 *predictionGain /* o : TNS prediction gain Q=7 */
237 : )
238 : {
239 : Word32 buff[8];
240 238490 : Word16 tmp = 0; /* initialization only to avoid compiler warning, not counted */
241 238490 : Word16 tmp2 = 0; /* initialization only to avoid compiler warning, not counted */
242 238490 : move16();
243 238490 : move16();
244 :
245 : /* Init TNS */
246 238490 : *pfUseTns = 0;
247 238490 : move16();
248 :
249 238490 : IF( hTcxCfg->fIsTNSAllowed != 0 )
250 : {
251 161621 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[( transform_type - TCX_20 ) == 0][isAfterACELP];
252 161621 : L_spec = hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
253 161621 : move16();
254 :
255 : /*-----------------------------------------------------------*
256 : * Temporal Noise Shaping analysis *
257 : *-----------------------------------------------------------*/
258 :
259 161621 : IF( EQ_16( transform_type, TCX_5 ) )
260 : {
261 2197 : tmp = shr( L_frame, 2 );
262 :
263 : /* rearrange LF sub-window lines prior to TNS analysis & filtering */
264 2197 : tmp2 = shr( L_spec, 1 );
265 :
266 2197 : IF( LT_16( tmp2, tmp ) )
267 : {
268 2129 : Copy32( spectrum + 8, spectrum + 16, sub( tmp2, 8 ) );
269 2129 : Copy32( spectrum + tmp, spectrum + 8, 8 );
270 2129 : Copy32( spectrum + tmp + 8, spectrum + tmp2 + 8, sub( tmp2, 8 ) );
271 : }
272 : ELSE
273 : {
274 68 : Copy32( spectrum + tmp, buff, 8 );
275 68 : Copy32( spectrum + 8, spectrum + 16, sub( tmp, 8 ) );
276 68 : Copy32( buff, spectrum + 8, 8 );
277 : }
278 : }
279 :
280 161621 : move16();
281 161621 : *pfUseTns = (Word8) DetectTnsFilt_ivas_fx( hTcxCfg->pCurrentTnsConfig, spectrum, pTnsData, hTranDet, (Word8) NE_16( transform_type, TCX_20 ), ltp_gain, predictionGain );
282 :
283 : /* If TNS should be used then get the residual after applying it inplace in spectrum */
284 161621 : IF( *pfUseTns != 0 )
285 : {
286 17629 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 1 );
287 : }
288 :
289 161621 : IF( EQ_16( transform_type, TCX_5 ) )
290 : {
291 : /* undo rearrangement of LF sub-window lines prior to TNS analysis */
292 2197 : IF( LT_16( tmp2, tmp ) )
293 : {
294 2129 : Copy32( spectrum + tmp2 + 8, spectrum + tmp + 8, sub( tmp2, 8 ) );
295 2129 : Copy32( spectrum + 8, spectrum + tmp, 8 );
296 2129 : Copy32( spectrum + 16, spectrum + 8, sub( tmp2, 8 ) );
297 2129 : set32_fx( spectrum + tmp2, 0, sub( tmp, tmp2 ) );
298 2129 : set32_fx( spectrum + tmp + tmp2, 0, sub( tmp, tmp2 ) );
299 : }
300 : ELSE
301 : {
302 68 : Copy32( spectrum + 8, buff, 8 );
303 68 : Copy32( spectrum + 16, spectrum + 8, sub( tmp, 8 ) );
304 68 : Copy32( buff, spectrum + tmp, 8 );
305 : }
306 : }
307 : }
308 238490 : }
309 :
310 634 : void ShapeSpectrum_fx(
311 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
312 : Word16 A[], /* input: quantized coefficients NxAz_q[M+1] Q = 14 - norm(A[0])*/
313 : Word16 gainlpc[], /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/
314 : Word16 gainlpc_e[], /* output: MDCT gains exponents */
315 : Word16 L_frame_glob, /* input: frame length */
316 : Word16 L_spec,
317 : Word32 spectrum[], /* i/o: MDCT spectrum */
318 : Word8 pfUseTns, /* output: Flag indicating if TNS is used */
319 : Encoder_State *st )
320 : {
321 : Word16 L_frame;
322 : Word16 Ap[M + 2];
323 : Word16 gamma1;
324 : Word16 gainlpc_noinv[FDNS_NPTS];
325 : Word16 gainlpc_noinv_e[FDNS_NPTS];
326 : Word16 i;
327 634 : Word32 max_low_pre = 0, max_high_pre = 0;
328 634 : move32();
329 634 : move32();
330 634 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
331 :
332 : /*-----------------------------------------------------------*
333 : * Init *
334 : *-----------------------------------------------------------*/
335 :
336 : /* Init lengths */
337 634 : L_frame = L_frame_glob;
338 634 : move16();
339 634 : gamma1 = st->gamma;
340 634 : move16();
341 634 : if ( st->enableTcxLpc != 0 )
342 : {
343 0 : gamma1 = 0x7FFF;
344 0 : move16();
345 : }
346 :
347 : /* if past frame is ACELP */
348 :
349 634 : IF( st->last_core == ACELP_CORE )
350 : {
351 38 : L_frame = add( L_frame, hTcxCfg->tcx_offset );
352 38 : L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
353 38 : if ( hTcxCfg->lfacNext < 0 )
354 : {
355 38 : L_frame = sub( L_frame, hTcxCfg->lfacNext );
356 38 : move16();
357 : }
358 : }
359 :
360 634 : test();
361 634 : tcxGetNoiseFillingTilt( A,
362 : M,
363 : L_frame,
364 634 : ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 ),
365 : &hTcxEnc->noiseTiltFactor );
366 :
367 : /* Calculate Spectrum Flatness Measure for the TCX Concealment */
368 634 : IF( st->enablePlcWaveadjust )
369 : {
370 0 : hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
371 0 : move32();
372 : }
373 :
374 634 : test();
375 634 : test();
376 634 : test();
377 634 : IF( ( EQ_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, SWB ) ) ||
378 : ( EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) )
379 : {
380 262 : max_low_pre = 0;
381 262 : move32();
382 68294 : FOR( i = 0; i < L_frame; i++ )
383 : {
384 68032 : Word32 tmp = L_abs( spectrum[i] );
385 68032 : if ( GT_32( tmp, max_low_pre ) )
386 : {
387 1624 : max_low_pre = tmp;
388 1624 : move32();
389 : }
390 : }
391 :
392 262 : max_high_pre = 0;
393 262 : move32();
394 102310 : FOR( i = 0; i < L_spec - L_frame; i++ )
395 : {
396 102048 : Word32 tmp = L_abs( spectrum[L_frame + i] );
397 102048 : if ( GT_32( tmp, max_high_pre ) )
398 : {
399 2 : max_high_pre = tmp;
400 2 : move32();
401 : }
402 : }
403 : }
404 :
405 : /*-----------------------------------------------------------*
406 : * Pre-shaping in frequency domain using weighted LPC (Wz) *
407 : *-----------------------------------------------------------*/
408 :
409 634 : weight_a_fx( A, Ap, gamma1, M );
410 :
411 634 : lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
412 :
413 634 : mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
414 223562 : FOR( i = L_frame; i < L_spec; i++ )
415 : {
416 222928 : spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
417 222928 : move32();
418 : }
419 :
420 : /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
421 634 : test();
422 634 : test();
423 634 : test();
424 634 : IF( ( EQ_32( st->total_brate, ACELP_9k60 ) && EQ_16( st->bwidth, SWB ) ) ||
425 : ( EQ_32( st->total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) ) )
426 : {
427 : Word16 sf_width;
428 : Word16 dist_low, dist_high;
429 : Word16 max_fac_s, max_fac_m;
430 : Word32 max_low, max_low1, max_low2, max_high;
431 : Word16 headroom, shift, tmp16;
432 :
433 :
434 262 : max_fac_m = 24576;
435 262 : move16();
436 : /* max_fac = 3 */
437 262 : max_fac_s = 2;
438 262 : move16();
439 262 : if ( hTcxEnc->tcx_lpc_shaped_ari )
440 : {
441 : /* max_fac = 1.5 */
442 0 : max_fac_s = 1;
443 0 : move16();
444 : }
445 :
446 262 : sf_width = shr( L_frame, 1 );
447 :
448 262 : max_low2 = 0;
449 262 : move32();
450 262 : dist_low = 0;
451 262 : move16();
452 34278 : FOR( i = 0; i < sf_width; i++ )
453 : {
454 34016 : Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
455 34016 : IF( GT_32( tmp, max_low2 ) )
456 : {
457 1490 : max_low2 = tmp;
458 1490 : move32();
459 1490 : dist_low = i;
460 1490 : move16();
461 : }
462 : }
463 :
464 262 : max_low1 = 0;
465 262 : move32();
466 34278 : FOR( i = 0; i < ( L_frame - sf_width ); i++ )
467 : {
468 34016 : Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
469 34016 : if ( GT_32( tmp, max_low1 ) )
470 : {
471 2350 : max_low1 = tmp;
472 2350 : move32();
473 : }
474 34016 : if ( GT_32( tmp, max_low2 ) )
475 : {
476 3886 : dist_low = add( sf_width, i );
477 : }
478 : }
479 :
480 262 : max_low = L_max( max_low1, max_low2 );
481 :
482 262 : max_high = 0;
483 262 : move32();
484 262 : dist_high = 0;
485 262 : move16();
486 102310 : FOR( i = 0; i < ( L_spec - L_frame ); i++ )
487 : {
488 102048 : Word32 tmp = L_abs( spectrum[L_frame + i] );
489 102048 : IF( GT_32( tmp, max_high ) )
490 : {
491 2 : max_high = tmp;
492 2 : move32();
493 2 : dist_high = i;
494 2 : move16();
495 : }
496 : }
497 :
498 : /* at least 9 bits headroom are needed for below multiplicitions */
499 262 : shift = 0;
500 262 : move16();
501 262 : headroom = 31;
502 262 : move16();
503 :
504 262 : tmp16 = norm_l( max_low );
505 262 : if ( max_low != 0 )
506 262 : headroom = s_min( headroom, tmp16 );
507 :
508 262 : tmp16 = norm_l( max_low2 );
509 262 : if ( max_low2 != 0 )
510 262 : headroom = s_min( headroom, tmp16 );
511 :
512 262 : tmp16 = norm_l( max_high );
513 262 : if ( max_high != 0 )
514 1 : headroom = s_min( headroom, tmp16 );
515 :
516 262 : if ( LT_16( headroom, 9 ) )
517 : {
518 0 : shift = sub( 9, headroom );
519 : }
520 262 : max_low = L_shr( max_low, shift );
521 262 : max_low2 = L_shr( max_low2, shift );
522 262 : max_high = L_shr( max_high, shift );
523 :
524 262 : test();
525 262 : test();
526 262 : IF( GT_32( imult3216( max_high, dist_high ), imult3216( L_shr( max_low, 2 ), dist_low ) ) && ( GT_32( max_low_pre, L_shr( max_high_pre, 4 ) ) ) && ( GT_32( max_high, L_shl( Mpy_32_16_r( max_low2, max_fac_m ), max_fac_s ) ) ) )
527 : {
528 : Word16 fac;
529 1 : fac = divide3232( max_low2, max_high );
530 1 : fac = shl( mult_r( fac, max_fac_m ), max_fac_s );
531 :
532 385 : FOR( i = 0; i < sub( L_spec, L_frame ); i++ )
533 : {
534 384 : spectrum[L_frame + i] = Mpy_32_16_1( spectrum[L_frame + i], fac );
535 384 : move32();
536 : }
537 : }
538 : }
539 :
540 :
541 634 : test();
542 634 : test();
543 634 : test();
544 634 : IF( st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
545 : {
546 0 : PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
547 : }
548 634 : }
549 1476874 : void ShapeSpectrum_ivas_fx(
550 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
551 : Word16 A[], /* input: quantized coefficients NxAz_q[M+1], Q = 14 - norm(A[0]) */
552 : Word16 gainlpc[], /* output: MDCT gains for the previous frame Q(15-gainlpc_e)*/
553 : Word16 gainlpc_e[], /* output: MDCT gains exponents */
554 : Word16 L_frame_glob, /* input: frame length */
555 : Word16 L_spec,
556 : Word32 spectrum[], /* i/o: MDCT spectrum Q(31-spectrum_e) */
557 : Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */
558 : Word8 pfUseTns, /* output: Flag indicating if TNS is used */
559 : Encoder_State *st,
560 : Word32 *scf /* Q16 */
561 : )
562 : {
563 : Word16 L_frame;
564 : Word16 Ap[M + 2];
565 : Word16 gamma1;
566 : Word16 gainlpc_noinv[FDNS_NPTS];
567 : Word16 gainlpc_noinv_e[FDNS_NPTS];
568 : Word32 sns_int_scf[FDNS_NPTS];
569 : Word16 i;
570 : Word16 q_spectrum;
571 1476874 : Word32 max_low_pre = 0, max_high_pre = 0;
572 1476874 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
573 1476874 : move32();
574 1476874 : move32();
575 1476874 : Word32 total_brate = st->total_brate;
576 1476874 : move32();
577 1476874 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
578 : {
579 1238384 : total_brate = st->element_brate;
580 1238384 : move32();
581 : }
582 :
583 : /*-----------------------------------------------------------*
584 : * Init *
585 : *-----------------------------------------------------------*/
586 :
587 : /* Init lengths */
588 1476874 : L_frame = L_frame_glob;
589 1476874 : move16();
590 1476874 : gamma1 = st->gamma;
591 1476874 : move16();
592 1476874 : if ( st->enableTcxLpc != 0 )
593 : {
594 17425 : gamma1 = 0x7FFF;
595 17425 : move16();
596 : }
597 :
598 : /* if past frame is ACELP */
599 1476874 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) /* in MDCT, this is already done outside the function */
600 : {
601 238490 : IF( st->last_core == ACELP_CORE )
602 : {
603 7931 : L_frame = add( L_frame, hTcxCfg->tcx_offset );
604 7931 : L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
605 7931 : if ( hTcxCfg->lfacNext < 0 )
606 : {
607 7931 : L_frame = sub( L_frame, hTcxCfg->lfacNext );
608 7931 : move16();
609 : }
610 : }
611 : }
612 :
613 1476874 : test();
614 1476874 : tcxGetNoiseFillingTilt( A,
615 : M,
616 : L_frame,
617 1476874 : ( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 ),
618 : &hTcxEnc->noiseTiltFactor );
619 :
620 : /* Calculate Spectrum Flatness Measure for the TCX Concealment */
621 1476874 : IF( st->enablePlcWaveadjust )
622 : {
623 0 : hTcxCfg->SFM2 = SFM_Cal_fx( spectrum, s_min( 200, L_frame ) );
624 0 : move32();
625 : }
626 :
627 1476874 : test();
628 1476874 : IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) )
629 : {
630 31063 : max_low_pre = 0;
631 31063 : move32();
632 8124375 : FOR( i = 0; i < L_frame; i++ )
633 : {
634 8093312 : Word32 tmp = L_abs( spectrum[i] );
635 8093312 : if ( GT_32( tmp, max_low_pre ) )
636 : {
637 137344 : max_low_pre = tmp;
638 137344 : move32();
639 : }
640 : }
641 :
642 31063 : max_high_pre = 0;
643 31063 : move32();
644 12171031 : FOR( i = 0; i < L_spec - L_frame; i++ )
645 : {
646 12139968 : Word32 tmp = L_abs( spectrum[L_frame + i] );
647 12139968 : if ( GT_32( tmp, max_high_pre ) )
648 : {
649 2470 : max_high_pre = tmp;
650 2470 : move32();
651 : }
652 : }
653 : }
654 :
655 1476874 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
656 : {
657 : Word64 W_tmp;
658 : Word16 len;
659 1238384 : q_spectrum = sub( 31, *spectrum_e );
660 1238384 : sns_interpolate_scalefactors_fx( &sns_int_scf[0], scf, ENC );
661 1238384 : sns_shape_spectrum_fx( spectrum, &q_spectrum, st->hTcxCfg->psychParamsCurrent, &sns_int_scf[0], Q16, L_frame, &len ); // The output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1
662 :
663 1238384 : test();
664 1238384 : test();
665 1238384 : IF( NE_16( len, L_spec ) && LT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
666 : {
667 113 : scale_sig32( spectrum + len, sub( L_spec, len ), sub( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) ); // Q31
668 : }
669 1238271 : ELSE IF( NE_16( len, L_spec ) && GT_16( add( q_spectrum, 1 ), sub( 31, *spectrum_e ) ) )
670 : {
671 989834 : scale_sig32( spectrum, len, sub( sub( 31, *spectrum_e ), add( q_spectrum, 1 ) ) ); // Q(30-specturm_e)
672 989834 : q_spectrum = sub( 31 - 1, *spectrum_e );
673 : }
674 :
675 312243424 : FOR( i = L_frame; i < L_spec; i++ )
676 : {
677 311005040 : W_tmp = W_mult0_32_32( spectrum[i], sns_int_scf[hTcxCfg->psychParamsCurrent->nBands - 1] );
678 311005040 : spectrum[i] = W_extract_h( W_shl( W_tmp, Q16 ) );
679 311005040 : move32();
680 : }
681 1238384 : *spectrum_e = sub( 31 - 1, q_spectrum ); // As the output spectrum from sns_shape_spectrum_fx has Q = q_spectrum + 1
682 1238384 : move16();
683 : }
684 : ELSE
685 : {
686 : /*-----------------------------------------------------------*
687 : * Pre-shaping in frequency domain using weighted LPC (Wz) *
688 : *-----------------------------------------------------------*/
689 :
690 238490 : weight_a_fx( A, Ap, gamma1, M );
691 :
692 238490 : lpc2mdct( Ap, M, gainlpc_noinv, gainlpc_noinv_e, gainlpc, gainlpc_e, FDNS_NPTS, 0 );
693 :
694 238490 : mdct_shaping( spectrum, L_frame, gainlpc_noinv, gainlpc_noinv_e );
695 93099690 : FOR( i = L_frame; i < L_spec; i++ )
696 : {
697 92861200 : spectrum[i] = L_shl( Mpy_32_16_1( spectrum[i], gainlpc_noinv[FDNS_NPTS - 1] ), gainlpc_noinv_e[FDNS_NPTS - 1] );
698 92861200 : move32();
699 : }
700 : }
701 :
702 : /* reduce the peaks in the IGF region, to make life of the core-coder easier... */
703 1476874 : test();
704 1476874 : IF( LE_32( total_brate, ACELP_13k20 ) && EQ_16( st->bwidth, SWB ) )
705 : {
706 : Word16 sf_width;
707 : Word16 dist_low, dist_high;
708 : Word16 max_fac_s, max_fac_m;
709 : Word32 max_low, max_low1, max_low2, max_high;
710 : Word16 headroom, shift, tmp16;
711 :
712 :
713 31063 : max_fac_m = 24576;
714 31063 : move16();
715 : /* max_fac = 3 */
716 31063 : max_fac_s = 2;
717 31063 : move16();
718 31063 : if ( hTcxEnc->tcx_lpc_shaped_ari )
719 : {
720 : /* max_fac = 1.5 */
721 13411 : max_fac_s = 1;
722 13411 : move16();
723 : }
724 :
725 31063 : sf_width = shr( L_frame, 1 );
726 :
727 31063 : max_low2 = 0;
728 31063 : move32();
729 31063 : dist_low = 0;
730 31063 : move16();
731 4077719 : FOR( i = 0; i < sf_width; i++ )
732 : {
733 4046656 : Word32 tmp = L_abs( spectrum[L_frame - 1 - i] );
734 4046656 : IF( GT_32( tmp, max_low2 ) )
735 : {
736 187534 : max_low2 = tmp;
737 187534 : move32();
738 187534 : dist_low = i;
739 187534 : move16();
740 : }
741 : }
742 :
743 31063 : max_low1 = 0;
744 31063 : move32();
745 4077719 : FOR( i = 0; i < sub( L_frame, sf_width ); i++ )
746 : {
747 4046656 : Word32 tmp = L_abs( spectrum[L_frame - sf_width - 1 - i] );
748 4046656 : if ( GT_32( tmp, max_low1 ) )
749 : {
750 285527 : max_low1 = tmp;
751 285527 : move32();
752 : }
753 4046656 : if ( GT_32( tmp, max_low2 ) )
754 : {
755 554834 : dist_low = add( sf_width, i );
756 : }
757 : }
758 :
759 31063 : max_low = L_max( max_low1, max_low2 );
760 :
761 31063 : max_high = 0;
762 31063 : move32();
763 31063 : dist_high = 0;
764 31063 : move16();
765 12171031 : FOR( i = 0; i < ( L_spec - L_frame ); i++ )
766 : {
767 12139968 : Word32 tmp = L_abs( spectrum[L_frame + i] );
768 12139968 : IF( GT_32( tmp, max_high ) )
769 : {
770 2470 : max_high = tmp;
771 2470 : move32();
772 2470 : dist_high = i;
773 2470 : move16();
774 : }
775 : }
776 :
777 : /* at least 9 bits headroom are needed for below multiplicitions */
778 31063 : shift = 0;
779 31063 : move16();
780 31063 : headroom = 31;
781 31063 : move16();
782 :
783 31063 : tmp16 = norm_l( max_low );
784 31063 : if ( max_low != 0 )
785 31059 : headroom = s_min( headroom, tmp16 );
786 :
787 31063 : tmp16 = norm_l( max_low2 );
788 31063 : if ( max_low2 != 0 )
789 31059 : headroom = s_min( headroom, tmp16 );
790 :
791 31063 : tmp16 = norm_l( max_high );
792 31063 : if ( max_high != 0 )
793 841 : headroom = s_min( headroom, tmp16 );
794 :
795 31063 : if ( LT_16( headroom, 9 ) )
796 : {
797 29997 : shift = sub( 9, headroom );
798 : }
799 31063 : max_low = L_shr( max_low, shift );
800 31063 : max_low2 = L_shr( max_low2, shift );
801 31063 : max_high = L_shr( max_high, shift );
802 :
803 31063 : test();
804 31063 : test();
805 31063 : IF( GT_32( imult3216( max_high, dist_high ), imult3216( L_shr( max_low, 2 ), dist_low ) ) && ( GT_32( max_low_pre, L_shr( max_high_pre, 4 ) ) ) && ( GT_32( max_high, L_shl( Mpy_32_16_r( max_low2, max_fac_m ), max_fac_s ) ) ) )
806 : {
807 : Word16 fac;
808 605 : fac = divide3232( max_low2, max_high );
809 605 : IF( GE_16( norm_s( fac ), max_fac_s ) )
810 : {
811 537 : fac = shl( mult_r( fac, max_fac_m ), max_fac_s );
812 211641 : FOR( i = 0; i < ( L_spec - L_frame ); i++ )
813 : {
814 211104 : spectrum[L_frame + i] = Mpy_32_16_1( spectrum[L_frame + i], fac );
815 211104 : move32();
816 : }
817 : }
818 : ELSE
819 : {
820 68 : fac = mult_r( fac, max_fac_m );
821 26852 : FOR( i = 0; i < ( L_spec - L_frame ); i++ )
822 : {
823 26784 : spectrum[L_frame + i] = L_shl( Mpy_32_16_1( spectrum[L_frame + i], fac ), max_fac_s );
824 26784 : move32();
825 : }
826 : }
827 : }
828 : }
829 :
830 :
831 1476874 : test();
832 1476874 : test();
833 1476874 : test();
834 1476874 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) && st->tcxonly && hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !pfUseTns )
835 : {
836 3730 : PsychAdaptLowFreqEmph_fx( spectrum, gainlpc, gainlpc_e );
837 : }
838 1476874 : }
839 :
840 : /*-------------------------------------------------------------------*
841 : * GetTransWidth()
842 : *
843 : *
844 : *-------------------------------------------------------------------*/
845 :
846 1076529 : static Word16 GetTransWidth_ivas_fx(
847 : const Word16 tcxonly,
848 : const Word16 tcx10,
849 : const Word16 tcxltp_gain, // Q15
850 : const Word16 hm_active )
851 : {
852 1076529 : Word16 noiseTransWidth = MIN_NOISE_FILLING_HOLE;
853 1076529 : move16();
854 :
855 1076529 : IF( tcxonly )
856 : {
857 817911 : IF( hm_active )
858 : {
859 8954 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 10240 /*0.3125f Q15*/ ) );
860 : }
861 : ELSE
862 : {
863 808957 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( tcxltp_gain, 0 ) );
864 : }
865 :
866 817911 : if ( tcx10 )
867 : {
868 35281 : noiseTransWidth = 3; /* minimum transition for noise filling in TCX-10 */
869 35281 : move16();
870 : }
871 : }
872 :
873 1076529 : return noiseTransWidth;
874 : }
875 :
876 : /*-----------------------------------------------------------*
877 : * EstimateTCXNoiseLevel()
878 : *
879 : * Estimate and quantize noise factor *
880 : *-----------------------------------------------------------*/
881 :
882 238490 : static void EstimateTCXNoiseLevel_ivas_fx(
883 : Encoder_State *st, /* i : encoder state handle */
884 : Word32 x_orig[], /* i : shaped MDCT spectrum Q(31-x_orig_e) */
885 : Word16 x_orig_e, /* i : shaped MDCT spectrum exponent */
886 : Word32 spectrum[], /* i/o: quantized MDCT spectrum */
887 : const Word16 gain_tcx, /* i : global gain Q(15-gain_tcx_e) */
888 : const Word16 gain_tcx_e, /* i : global gain exponent */
889 : const Word16 L_frame, /* i : frame length */
890 : const Word16 noiseFillingBorder, /* i : noise filling border */
891 : const Word16 hm_active, /* i : flag indicating if the harmonic model is active */
892 : Word16 *fac_ns, /* o : noise filling level, fac_ns_q */
893 : Word16 *fac_ns_q /* o : quantized noise filling level, Q0 */
894 : )
895 : {
896 : Word16 maxNfCalcBw, iStart, noiseTransWidth;
897 238490 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
898 :
899 238490 : maxNfCalcBw = s_min( noiseFillingBorder, round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame ), 1 ) ) );
900 :
901 238490 : IF( GE_32( st->total_brate, HQ_96k ) )
902 : {
903 18139 : *fac_ns = 0;
904 18139 : *fac_ns_q = 0;
905 18139 : move16();
906 18139 : move16();
907 : }
908 : ELSE
909 : {
910 : Word16 minLevel;
911 220351 : minLevel = 1;
912 220351 : move16();
913 220351 : test();
914 220351 : if ( hTcxEnc->tcx_lpc_shaped_ari && GT_16( st->element_mode, IVAS_SCE ) )
915 : {
916 4721 : minLevel = 0;
917 4721 : move16();
918 : }
919 :
920 : /* noise filling start bin */
921 220351 : iStart = shr( L_frame, 3 );
922 220351 : test();
923 220351 : IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
924 : {
925 187186 : iStart = idiv1616U( L_frame, 6 );
926 : }
927 :
928 220351 : noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), st->hTcxEnc->tcxltp_gain, ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active ) );
929 :
930 220351 : tcx_noise_factor_ivas_fx( x_orig, x_orig_e, spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame, gain_tcx, gain_tcx_e, hTcxEnc->noiseTiltFactor, fac_ns, fac_ns_q, st->element_mode );
931 :
932 : /* hysteresis for very tonal passages (more stationary noise filling level) */
933 220351 : IF( EQ_16( *fac_ns_q, minLevel ) )
934 : {
935 11405 : hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ) ); /* update counter */
936 11405 : move16();
937 : }
938 : ELSE
939 : {
940 208946 : test();
941 208946 : IF( EQ_16( *fac_ns_q, add( minLevel, 1 ) ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
942 : {
943 728 : *fac_ns_q = minLevel; /* reduce noise filling level by one step */
944 728 : *fac_ns = 0;
945 728 : move16();
946 728 : move16();
947 728 : IF( minLevel != 0 )
948 : {
949 728 : *fac_ns = shr( 0x6000, NBITS_NOISE_FILL_LEVEL );
950 728 : move16();
951 : }
952 : /* signal that noise level is changed by inverting sign of level memory */
953 728 : IF( hTcxEnc->noiseLevelMemory_cnt < 0 )
954 : {
955 235 : hTcxEnc->noiseLevelMemory_cnt = 5;
956 235 : move16();
957 : }
958 : ELSE
959 : {
960 493 : hTcxEnc->noiseLevelMemory_cnt = negate( add( 1, hTcxEnc->noiseLevelMemory_cnt ) );
961 493 : move16();
962 : }
963 : }
964 : ELSE
965 : {
966 208218 : hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
967 208218 : move16();
968 : }
969 : }
970 : } /* bitrate */
971 :
972 238490 : return;
973 : }
974 :
975 :
976 : /*-------------------------------------------------------------------*
977 : * QuantizeSpectrum()
978 : *
979 : *
980 : *-------------------------------------------------------------------*/
981 :
982 238490 : void QuantizeSpectrum_ivas_fx(
983 : Encoder_State *st, /* i/o: encoder state structure */
984 : const Word16 A_fx[], /* i : quantized coefficients NxAz_q[M+1], Q = 14 - norm_s(A_fx[0]) */
985 : const Word16 Aqind[], /* i : frame-independent quantized coefficients (M+1) */
986 : Word16 gainlpc_fx[], /* i : MDCT gains of the previous frame Q(15-gainlpc_e) */
987 : Word16 gainlpc_e[], /* i : exponents of MDCT gains of the previous frame */
988 : Word16 synth[], /* o : synthesis buffer, Q0 */
989 : const Word16 nb_bits, /* i : bit budget */
990 : const Word16 tnsSize, /* i : number of tns parameters put into prm */
991 : Word16 prm[], /* o : tcx parameters */
992 : const Word16 frame_cnt, /* i : frame counter in the super_frame */
993 : CONTEXT_HM_CONFIG *hm_cfg, /* i : HM configuration */
994 : const Word16 vad_hover_flag /* i : VAD hangover flag */
995 : )
996 : {
997 : Word16 L_frameTCX; /* full frame length */
998 : Word16 L_frame; /* frame length */
999 : Word16 L_spec; /* length of the coded spectrum */
1000 : Word16 tcx_offset; /* folding point offset relative to the end of the previous frame */
1001 : Word16 noiseFillingBorder; /* noise filling border */
1002 : Word32 quantized_spectrum_fx[N_MAX]; /* quantized MDCT spectrum */
1003 : Word16 quantized_spectrum_e; /* quantized MDCT spectrum */
1004 : Word16 lf_deemph_fact_fx[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX]; /* low frequency deemphasis factors */
1005 : Word16 hm_active; /* flag indicating if the harmonic model is active */
1006 : Word16 fac_ns_fx; /* noise filling level, Q15 */
1007 : Word16 nf_seed; /* noise filling random seed */
1008 : Word32 ener_fx; /* energy of the quantized spectrum */
1009 : Word16 ener_e; /* energy of the quantized spectrum */
1010 : Word16 gain_tcx_fx; /* global gain */
1011 : Word16 gain_tcx_e; /* global gain */
1012 :
1013 238490 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
1014 :
1015 238490 : set32_fx( quantized_spectrum_fx, 0, N_MAX );
1016 :
1017 : /*-----------------------------------------------------------*
1018 : * Quantize the MDCT spectrum *
1019 : *-----------------------------------------------------------*/
1020 :
1021 238490 : QuantizeTCXSpectrum_fx( st, frame_cnt, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], gainlpc_fx, gainlpc_e, Aqind, tnsSize, nb_bits, vad_hover_flag,
1022 : &L_frameTCX, &L_frame, &L_spec, &tcx_offset, &noiseFillingBorder, quantized_spectrum_fx, &quantized_spectrum_e, hm_cfg, &hm_active, lf_deemph_fact_fx, &nf_seed, &ener_fx, &ener_e, &gain_tcx_fx, &gain_tcx_e, prm );
1023 238490 : if ( hTcxEnc->spectrum_e[frame_cnt] < 0 )
1024 : {
1025 : /*buffer is already scaled inside QuantizeTCXSpectrum_fx*/
1026 0 : hTcxEnc->spectrum_e[frame_cnt] = 0;
1027 0 : move16();
1028 : }
1029 :
1030 238490 : Word16 s1 = sub( getScaleFactor32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame ), 6 );
1031 238490 : Word16 s2 = getScaleFactor32( quantized_spectrum_fx, s_max( L_frame, L_spec ) );
1032 238490 : Word16 max_e = s_max( sub( hTcxEnc->spectrum_e[frame_cnt], s1 ), sub( quantized_spectrum_e, s2 ) );
1033 :
1034 238490 : scale_sig32( quantized_spectrum_fx, s_max( L_frame, L_spec ), sub( quantized_spectrum_e, max_e ) ); // max_e
1035 238490 : scale_sig32( st->hTcxEnc->spectrum_fx[frame_cnt], L_frame, sub( hTcxEnc->spectrum_e[frame_cnt], max_e ) ); // max_e
1036 238490 : hTcxEnc->spectrum_e[frame_cnt] = max_e;
1037 238490 : move16();
1038 :
1039 : /*-----------------------------------------------------------*
1040 : * Estimate and quantize noise factor *
1041 : *-----------------------------------------------------------*/
1042 :
1043 238490 : EstimateTCXNoiseLevel_ivas_fx( st, hTcxEnc->spectrum_fx[frame_cnt], hTcxEnc->spectrum_e[frame_cnt], quantized_spectrum_fx, gain_tcx_fx, gain_tcx_e, L_frame, noiseFillingBorder, hm_active, &fac_ns_fx, &prm[1] );
1044 :
1045 : /*-----------------------------------------------------------*
1046 : * Internal decoder *
1047 : *-----------------------------------------------------------*/
1048 :
1049 238490 : InternalTCXDecoder_fx( st, frame_cnt, L_frameTCX, L_frame, L_spec, tcx_offset, noiseFillingBorder, quantized_spectrum_fx, ener_fx, ener_e, lf_deemph_fact_fx, fac_ns_fx, nf_seed, A_fx, gainlpc_fx, gainlpc_e, hm_active, gain_tcx_fx, &gain_tcx_e, hTcxEnc->spectrum_fx[frame_cnt], &hTcxEnc->spectrum_e[frame_cnt], synth, &prm[0] );
1050 :
1051 : /* Update L_frame_past */
1052 238490 : st->L_frame_past = L_frame;
1053 238490 : move16();
1054 :
1055 : /* Update overlap */
1056 238490 : test();
1057 238490 : test();
1058 238490 : test();
1059 238490 : if ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) || EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
1060 : {
1061 8907 : st->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
1062 8907 : move16();
1063 : }
1064 :
1065 :
1066 238490 : return;
1067 : }
1068 :
1069 354091 : void EstimateStereoTCXNoiseLevel_fx(
1070 : Encoder_State **sts, /* i : state handle */
1071 : Word32 *q_spectrum[CPE_CHANNELS][NB_DIV], /* i : quantized MDCT spectrum Qx */
1072 : Word16 gain_tcx[][NB_DIV], /* i : global gain Q(15-gain_tcx_e) */
1073 : Word16 gain_tcx_e[][NB_DIV], /* i : global gain exponent */
1074 : Word16 L_frame[][NB_DIV], /* i : frame length */
1075 : Word16 noiseFillingBorder[][NB_DIV], /* i : noise filling border */
1076 : Word16 hm_active[][NB_DIV], /* i : flag indicating if the harmonic model is active */
1077 : const Word16 ignore_chan[], /* i : flag indicating whether the channel should be ignored */
1078 : Word16 fac_ns[][NB_DIV], /* o : noise filling level Q15 */
1079 : Word16 param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */
1080 : const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */
1081 : )
1082 : {
1083 : Word16 ch, n, i;
1084 : Word16 nSubframes, maxNfCalcBw, iStart, noiseTransWidth;
1085 : Word16 smooth_gain;
1086 : Word32 combined_q_spectrum[N_MAX];
1087 : Word16 *fac_ns_q;
1088 : Word32 total_brate;
1089 :
1090 354091 : set32_fx( combined_q_spectrum, 0, N_MAX );
1091 :
1092 1062273 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
1093 : {
1094 708182 : Encoder_State *st = sts[ch];
1095 708182 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
1096 :
1097 708182 : IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
1098 : {
1099 693388 : nSubframes = 1;
1100 693388 : move16();
1101 : }
1102 : ELSE
1103 : {
1104 14794 : nSubframes = NB_DIV;
1105 14794 : move16();
1106 : }
1107 :
1108 708182 : IF( ignore_chan[ch] )
1109 : {
1110 67223 : CONTINUE;
1111 : }
1112 :
1113 640959 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && !MCT_flag )
1114 : {
1115 167566 : total_brate = st->element_brate;
1116 167566 : move32();
1117 : }
1118 : ELSE
1119 : {
1120 473393 : total_brate = st->total_brate;
1121 473393 : move32();
1122 : }
1123 :
1124 1296706 : FOR( n = 0; n < nSubframes; n++ )
1125 : {
1126 655747 : fac_ns_q = param_core[ch] + add( i_mult( n, NPRM_DIV ), 1 );
1127 :
1128 655747 : maxNfCalcBw = s_min( noiseFillingBorder[ch][n], round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame[ch][n] ), 1 ) ) );
1129 :
1130 655747 : test();
1131 655747 : test();
1132 655747 : test();
1133 655747 : IF( ( GE_32( total_brate, HQ_96k ) && ( LE_16( st->element_mode, IVAS_SCE ) || LT_16( st->bwidth, SWB ) ) ) || GT_32( total_brate, IVAS_192k ) )
1134 : {
1135 19449 : fac_ns[ch][n] = 0;
1136 19449 : move16();
1137 19449 : *fac_ns_q = 0;
1138 19449 : move16();
1139 : }
1140 : ELSE
1141 : {
1142 636298 : test();
1143 636298 : IF( GE_32( total_brate, ACELP_13k20 ) && !st->rf_mode )
1144 : {
1145 614181 : iStart = idiv1616( L_frame[ch][n], 6 );
1146 : }
1147 : ELSE
1148 : {
1149 22117 : iStart = shr( L_frame[ch][n], 3 );
1150 : }
1151 :
1152 636298 : IF( n == 0 )
1153 : {
1154 621961 : Copy( hTcxEnc->ltpGainMemory_fx, &hTcxEnc->ltpGainMemory_fx[1], N_LTP_GAIN_MEMS - 1 );
1155 621961 : hTcxEnc->ltpGainMemory_fx[0] = st->hTcxEnc->tcxltp_gain;
1156 621961 : move16();
1157 : }
1158 :
1159 636298 : Word32 temp = L_mult0( hTcxEnc->ltpGainMemory_fx[0], nf_tw_smoothing_coeffs_fx[0] );
1160 :
1161 2545192 : FOR( i = 1; i < N_LTP_GAIN_MEMS; i++ )
1162 : {
1163 1908894 : temp = L_mac0( temp, hTcxEnc->ltpGainMemory_fx[i], nf_tw_smoothing_coeffs_fx[i] );
1164 : }
1165 636298 : smooth_gain = round_fx( L_shl( temp, 1 ) );
1166 636298 : noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame[ch][n], shr( st->L_frame, 1 ) ), smooth_gain, ( st->hTcxCfg->ctx_hm && NE_16( st->last_core, ACELP_CORE ) && hm_active[ch][n] ) );
1167 :
1168 636298 : Copy32( q_spectrum[ch][n], combined_q_spectrum, L_frame[ch][n] );
1169 :
1170 : /* Scaling down 1-bit to resolve crashes during accumulation in tcx_noise_factor_ivas_fx() */
1171 : Word32 L_tmp, L_tmp1;
1172 636298 : maximum_abs_32_fx( hTcxEnc->spectrum_fx[n], L_frame[ch][n], &L_tmp );
1173 636298 : maximum_abs_32_fx( combined_q_spectrum, L_frame[ch][n], &L_tmp1 );
1174 636298 : test();
1175 636298 : IF( L_tmp != 0 || L_tmp1 != 0 )
1176 : {
1177 636109 : scale_sig32( hTcxEnc->spectrum_fx[n], L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1)
1178 636109 : scale_sig32( combined_q_spectrum, L_frame[ch][n], -Q1 ); // Q(31-(spectrum_e+1)
1179 636109 : hTcxEnc->spectrum_e[n] = add( hTcxEnc->spectrum_e[n], Q1 );
1180 636109 : move16();
1181 : }
1182 636298 : tcx_noise_factor_ivas_fx( hTcxEnc->spectrum_fx[n], hTcxEnc->spectrum_e[n], combined_q_spectrum, iStart, maxNfCalcBw, noiseTransWidth, L_frame[ch][n], gain_tcx[ch][n], gain_tcx_e[ch][n], hTcxEnc->noiseTiltFactor, &fac_ns[ch][n], fac_ns_q, st->element_mode );
1183 :
1184 : /* hysteresis for very tonal passages (more stationary noise filling level) */
1185 636298 : IF( EQ_16( *fac_ns_q, 1 ) )
1186 : {
1187 74199 : hTcxEnc->noiseLevelMemory_cnt = s_min( INT16_MAX, 1 + abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
1188 74199 : move16();
1189 : }
1190 : ELSE
1191 : {
1192 562099 : test();
1193 562099 : IF( EQ_16( *fac_ns_q, 2 ) && GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) )
1194 : {
1195 5882 : *fac_ns_q = 1; /* reduce noise filling level by one step */
1196 5882 : fac_ns[ch][n] = 3072; /* 0.75f / ( 1 << NBITS_NOISE_FILL_LEVEL ) in Q15*/
1197 5882 : move16();
1198 5882 : move16();
1199 : /* signal that noise level is changed by inverting sign of level memory */
1200 5882 : IF( ( hTcxEnc->noiseLevelMemory_cnt < 0 ) )
1201 : {
1202 1968 : hTcxEnc->noiseLevelMemory_cnt = 5;
1203 1968 : move16();
1204 : }
1205 : ELSE
1206 : {
1207 3914 : hTcxEnc->noiseLevelMemory_cnt = sub( -1, hTcxEnc->noiseLevelMemory_cnt );
1208 3914 : move16();
1209 : }
1210 : }
1211 : ELSE
1212 : {
1213 556217 : hTcxEnc->noiseLevelMemory_cnt = 0; /* reset memory since level is too different */
1214 556217 : move16();
1215 : }
1216 : }
1217 : } /* bitrate */
1218 : }
1219 : }
1220 :
1221 354091 : return;
1222 : }
1223 :
1224 634 : void QuantizeSpectrum_fx(
1225 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
1226 : Word16 A[], /* input: quantized coefficients NxAz_q[M+1] */
1227 : Word16 Aqind[], /* input: frame-independent quantized coefficients (M+1) */
1228 : Word16 gainlpc[], /* input: MDCT gains of the previous frame Q(15-gainlpc_e)*/
1229 : Word16 gainlpc_e[], /* input: MDCT gains exponents */
1230 : Word16 synth[],
1231 : Word16 L_frame_glob, /* input: frame length */
1232 : Word16 L_frameTCX_glob,
1233 : Word16 L_spec,
1234 : Word16 nb_bits, /*input: bit budget*/
1235 : Word8 tcxonly, /*input: only TCX flag*/
1236 : Word32 spectrum[], /* i/o: MDCT spectrum, input is shaped MDCT spectrum Q(31-spectrum_e) */
1237 : Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */
1238 : STnsData *pTnsData, /* input: Tns data */
1239 : Word8 fUseTns, /* input: Flag indicating if TNS is used */
1240 : Word16 tnsSize, /* input: number of tns parameters put into prm */
1241 : Word16 prm[], /* output: tcx parameters */
1242 : Word16 frame_cnt, /* input: frame counter in the super_frame */
1243 : Encoder_State *st,
1244 : CONTEXT_HM_CONFIG *hm_cfg )
1245 : {
1246 : Word16 i, L_frame, tcx_offset;
1247 : Word16 stop;
1248 : Word16 tmp1, tmp2, tmp3, tmp4, s;
1249 : Word32 tmp32;
1250 : Word8 tmp8;
1251 : Word16 *tmpP16;
1252 : Word16 L_frameTCX;
1253 : Word16 fac_ns;
1254 : Word16 nf_seed;
1255 : Word32 ener;
1256 : Word16 ener_e;
1257 : Word16 gain_tcx, gain_tcx_e;
1258 : Word16 sqBits;
1259 : Word16 overlap;
1260 : Word16 noiseFillingSize;
1261 : Word16 noiseTransWidth;
1262 : Word32 *OriginalSpectrum;
1263 : Word16 OriginalSpectrum_e;
1264 : Word16 ctxHmBits;
1265 : Word16 resQBits;
1266 : Word16 *signs;
1267 : Word16 signaling_bits;
1268 : Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *prm_target;
1269 : Word16 Aq_old[M + 1];
1270 : Word32 SFM;
1271 : Word32 K, K2;
1272 : Word16 aldo; /* ALDO flag in current frame*/
1273 : Word16 nz; /* non-zero length in ALDO window*/
1274 : CONTEXT_HM_CONFIG *phm_cfg;
1275 634 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
1276 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1277 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
1278 : Flag Overflow = 0;
1279 : Flag Carry = 0;
1280 : #endif
1281 : #endif
1282 :
1283 : /* Stack memory is split between encoder and internal decoder to reduce max
1284 : stack memory usage. */
1285 : {
1286 : Word16 sqTargetBits;
1287 : Word16 gain_tcx_opt, gain_tcx_opt_e;
1288 : Word16 sqGain, sqGain_e;
1289 : Word16 sqBits_noStop;
1290 : Word16 nEncoded;
1291 : Word16 maxNfCalcBw;
1292 : Word16 PeriodicityIndex;
1293 : Word16 NumIndexBits;
1294 : Word16 nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
1295 : Word16 lastnz, lastnzCtxHm;
1296 : Word16 RelativeScore;
1297 : Word32 x_orig[N_MAX];
1298 : Word16 x_orig_e;
1299 : Word16 resQTargetBits;
1300 : Word16 xn_buf16[L_FRAME_PLUS];
1301 : Word16 *sqQ;
1302 : Word16 LtpPitchLag;
1303 :
1304 :
1305 634 : sqGain = 0x4000;
1306 634 : move16();
1307 634 : sqGain_e = 1;
1308 634 : move16();
1309 634 : noiseTransWidth = MIN_NOISE_FILLING_HOLE;
1310 634 : move16();
1311 634 : resQTargetBits = 0;
1312 634 : move16();
1313 :
1314 : /*-----------------------------------------------------------*
1315 : * Init *
1316 : *-----------------------------------------------------------*/
1317 :
1318 : /* Init lengths */
1319 634 : L_frame = L_frame_glob;
1320 634 : move16();
1321 634 : L_frameTCX = L_frameTCX_glob;
1322 634 : move16();
1323 634 : overlap = hTcxCfg->tcx_mdct_window_length;
1324 634 : move16();
1325 634 : aldo = 0;
1326 634 : move16();
1327 634 : nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
1328 634 : move16();
1329 : /* Modified the overlap to the delay in case of short blocks*/
1330 634 : tcx_offset = hTcxCfg->tcx_offset;
1331 634 : move16();
1332 :
1333 634 : OriginalSpectrum = NULL;
1334 634 : signs = NULL; /* silence warning */
1335 634 : NumIndexBits = 0;
1336 634 : move16();
1337 634 : sqBits = 0;
1338 634 : move16();
1339 634 : ctxHmBits = 0;
1340 634 : move16();
1341 634 : resQBits = 0;
1342 634 : move16();
1343 634 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
1344 634 : move16();
1345 634 : prm_tns = prm_ltp + LTPSIZE;
1346 634 : move16();
1347 634 : prm_hm = prm_tns + tnsSize;
1348 634 : move16();
1349 634 : prm_lastnz = prm_hm + 2;
1350 634 : move16();
1351 634 : sqQ = prm_hm + NPRM_CTX_HM;
1352 634 : move16();
1353 :
1354 : /* if past frame is ACELP */
1355 :
1356 634 : IF( st->last_core == ACELP_CORE )
1357 : {
1358 38 : hTcxCfg->last_aldo = 0;
1359 38 : move16();
1360 :
1361 38 : L_frame = add( L_frame, tcx_offset );
1362 38 : L_frameTCX = add( L_frameTCX, hTcxCfg->tcx_offsetFB );
1363 38 : L_spec = add( L_spec, shr( hTcxCfg->tcx_coded_lines, 2 ) );
1364 38 : tcx_offset = 0;
1365 38 : move16();
1366 38 : IF( hTcxCfg->lfacNext < 0 )
1367 : {
1368 38 : L_frame = sub( L_frame, hTcxCfg->lfacNext );
1369 38 : L_frameTCX = sub( L_frameTCX, hTcxCfg->lfacNextFB );
1370 38 : tcx_offset = hTcxCfg->lfacNext;
1371 38 : move16();
1372 : }
1373 38 : hTcxEnc->noiseLevelMemory_cnt = 0;
1374 38 : move16();
1375 : }
1376 :
1377 :
1378 634 : E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old, M );
1379 :
1380 : /* target bitrate for SQ */
1381 634 : sqTargetBits = sub( nb_bits, 7 + NBITS_NOISE_FILL_LEVEL );
1382 :
1383 : /*Unquantized spectrum here*/
1384 634 : IF( st->enablePlcWaveadjust )
1385 : {
1386 :
1387 :
1388 0 : SFM = SFM_Cal_fx( spectrum, s_min( 200, L_frame_glob ) );
1389 0 : test();
1390 0 : IF( LE_16( L_frame_glob, 256 ) )
1391 : {
1392 0 : K = 0x33333333;
1393 0 : move32();
1394 0 : K2 = 0xCCCCCCD;
1395 0 : move32();
1396 : }
1397 0 : ELSE IF( EQ_16( L_frame_glob, 320 ) || EQ_16( L_frame_glob, 512 ) )
1398 : {
1399 0 : K = 0x33333333;
1400 0 : move32();
1401 0 : K2 = 0xCCCCCCD;
1402 0 : move32();
1403 : }
1404 : ELSE /*FrameSize_Core == 640*/
1405 : {
1406 0 : K = 0x2CCCCCCD;
1407 0 : move32();
1408 0 : K2 = 0x51EB852;
1409 0 : move32();
1410 : }
1411 :
1412 :
1413 0 : IF( LT_32( SFM, K ) )
1414 : {
1415 0 : st->Tonal_SideInfo = 1;
1416 0 : move16();
1417 : }
1418 : ELSE
1419 : {
1420 0 : st->Tonal_SideInfo = 0;
1421 0 : move16();
1422 : }
1423 :
1424 0 : if ( LT_32( hTcxCfg->SFM2, K2 ) )
1425 : {
1426 0 : st->Tonal_SideInfo = 1;
1427 0 : move16();
1428 : }
1429 : }
1430 :
1431 : /* Save pre-shaped spectrum*/
1432 634 : Copy32( spectrum, x_orig, L_spec );
1433 634 : x_orig_e = *spectrum_e;
1434 634 : move16();
1435 :
1436 : /*-----------------------------------------------------------*
1437 : * Bandwidth Limitation *
1438 : *-----------------------------------------------------------*/
1439 :
1440 634 : noiseFillingSize = L_spec;
1441 634 : move16();
1442 634 : IF( st->igf != 0 )
1443 : {
1444 634 : noiseFillingSize = st->hIGFEnc->infoStartLine;
1445 634 : move16();
1446 : }
1447 : ELSE
1448 : {
1449 0 : st->hIGFEnc->infoStopLine = noiseFillingSize;
1450 0 : move16();
1451 : }
1452 :
1453 141172 : FOR( i = st->hIGFEnc->infoStopLine; i < L_frameTCX; i++ )
1454 : {
1455 140538 : spectrum[i] = L_deposit_l( 0 );
1456 140538 : move32();
1457 : }
1458 :
1459 : /*-----------------------------------------------------------*
1460 : * Quantization *
1461 : *-----------------------------------------------------------*/
1462 :
1463 634 : IF( hTcxEnc->tcx_lpc_shaped_ari == 0 ) /* old arithmetic coder */
1464 : {
1465 :
1466 : /* Fast estimation of the scalar quantizer step size */
1467 634 : test();
1468 634 : IF( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) )
1469 : {
1470 596 : LtpPitchLag = -1;
1471 596 : move16();
1472 :
1473 596 : test();
1474 596 : IF( ( tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
1475 : {
1476 432 : tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
1477 432 : tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
1478 432 : LtpPitchLag = div_l( tmp32, tmp1 );
1479 : }
1480 :
1481 596 : ctxHmBits = add( ctxHmBits, 1 ); /* ContextHM flag */
1482 596 : sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
1483 :
1484 596 : OriginalSpectrum = spectrum;
1485 596 : OriginalSpectrum_e = *spectrum_e;
1486 596 : move16();
1487 :
1488 596 : tmp1 = -1;
1489 596 : move16();
1490 596 : if ( hTcxEnc->tcxltp != 0 )
1491 : {
1492 596 : tmp1 = hTcxEnc->tcxltp_gain;
1493 596 : move16();
1494 : }
1495 596 : PeriodicityIndex = SearchPeriodicityIndex_fx(
1496 : OriginalSpectrum,
1497 : NULL,
1498 : L_spec,
1499 : sqTargetBits,
1500 : LtpPitchLag,
1501 : tmp1,
1502 : &RelativeScore );
1503 :
1504 596 : ConfigureContextHm(
1505 : L_spec,
1506 : sqTargetBits,
1507 : PeriodicityIndex,
1508 : LtpPitchLag,
1509 : hm_cfg );
1510 :
1511 596 : tmp1 = 1;
1512 596 : move16();
1513 596 : if ( LT_16( L_spec, 256 ) )
1514 : {
1515 0 : tmp1 = 0;
1516 0 : move16();
1517 : }
1518 596 : NumIndexBits = CountIndexBits( tmp1, PeriodicityIndex );
1519 :
1520 :
1521 : /* Quantize original spectrum */
1522 :
1523 596 : sqGain = SQ_gain_fx( OriginalSpectrum, OriginalSpectrum_e,
1524 596 : shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
1525 : L_spec,
1526 : &sqGain_e );
1527 :
1528 596 : tcx_scalar_quantization_fx( OriginalSpectrum, OriginalSpectrum_e,
1529 : sqQ,
1530 : L_spec,
1531 : sqGain, sqGain_e,
1532 596 : hTcxCfg->sq_rounding,
1533 596 : hTcxEnc->memQuantZeros,
1534 : tcxonly );
1535 :
1536 : /* Estimate original bitrate */
1537 596 : stop = 0;
1538 596 : move16();
1539 :
1540 596 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1541 : L_spec,
1542 : &lastnz,
1543 : &nEncoded,
1544 : sqTargetBits,
1545 : &stop,
1546 : NULL );
1547 :
1548 : /* Estimate context mapped bitrate */
1549 :
1550 596 : stopCtxHm = 0;
1551 596 : move16();
1552 :
1553 : /* Context Mapping */
1554 596 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1555 : L_spec,
1556 : &lastnzCtxHm,
1557 : &nEncodedCtxHm,
1558 596 : sub( sqTargetBits, NumIndexBits ),
1559 : &stopCtxHm,
1560 : hm_cfg );
1561 :
1562 : /* Decide whether or not to use context mapping */
1563 596 : Selector = sub( s_max( stop, sqBits ), add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) );
1564 :
1565 596 : test();
1566 596 : test();
1567 596 : IF( ( GT_16( Selector, 2 ) ) || ( ( LE_16( abs_s( Selector ), 2 ) ) &&
1568 : ( LT_16( kCtxHmOlRSThr, RelativeScore ) ) ) )
1569 : {
1570 : /* CtxHm is likely better */
1571 47 : sqTargetBits = sub( sqTargetBits, NumIndexBits );
1572 47 : ctxHmBits = add( ctxHmBits, NumIndexBits );
1573 47 : prm_hm[0] = 1;
1574 47 : move16();
1575 47 : prm_hm[1] = PeriodicityIndex;
1576 47 : move16();
1577 47 : *prm_lastnz = lastnzCtxHm;
1578 47 : move16();
1579 47 : sqBits_noStop = sqBits = sqBitsCtxHm;
1580 47 : move16();
1581 47 : move16();
1582 47 : nEncoded = nEncodedCtxHm;
1583 47 : move16();
1584 47 : stop = stopCtxHm;
1585 47 : move16();
1586 : }
1587 : ELSE /* Original is better or not much difference */
1588 : {
1589 549 : prm_hm[0] = 0;
1590 549 : move16();
1591 549 : prm_hm[1] = PeriodicityIndex;
1592 549 : move16();
1593 549 : *prm_lastnz = lastnz;
1594 549 : move16();
1595 549 : PeriodicityIndex = -1;
1596 549 : move16();
1597 :
1598 549 : sqBits_noStop = sqBits;
1599 549 : move16();
1600 : }
1601 :
1602 :
1603 596 : if ( stop != 0 )
1604 : {
1605 :
1606 216 : sqBits = stop;
1607 216 : move16();
1608 : }
1609 : }
1610 : ELSE /* no context hm*/
1611 : {
1612 38 : PeriodicityIndex = -1;
1613 38 : move16();
1614 :
1615 38 : sqGain = SQ_gain_fx( spectrum, *spectrum_e,
1616 38 : shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ),
1617 : L_spec,
1618 : &sqGain_e );
1619 :
1620 : /* Quantize spectrum */
1621 :
1622 38 : tcx_scalar_quantization_fx( spectrum, *spectrum_e,
1623 : sqQ,
1624 : L_spec,
1625 : sqGain, sqGain_e,
1626 38 : hTcxCfg->sq_rounding,
1627 38 : hTcxEnc->memQuantZeros,
1628 : tcxonly );
1629 :
1630 : /* Estimate bitrate */
1631 38 : stop = 0;
1632 38 : move16();
1633 38 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1634 : L_spec,
1635 : prm_lastnz, /* lastnz */
1636 : &nEncoded,
1637 : sqTargetBits,
1638 : &stop,
1639 : NULL );
1640 :
1641 38 : sqBits_noStop = sqBits;
1642 38 : move16();
1643 :
1644 38 : if ( stop != 0 )
1645 : {
1646 7 : sqBits = stop;
1647 7 : move16();
1648 : }
1649 : } /* end of if (ctx_hm) */
1650 :
1651 : /* Adjust correction factor */
1652 634 : tmp1 = sqBits;
1653 634 : move16();
1654 :
1655 634 : if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
1656 : {
1657 0 : tmp1 = add( tmp1, 1 );
1658 : }
1659 :
1660 634 : tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
1661 : BASOP_SATURATE_WARNING_OFF_EVS
1662 634 : hTcxEnc->tcx_target_bits_fac = shl_sat( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 );
1663 634 : move16();
1664 : BASOP_SATURATE_WARNING_ON_EVS
1665 :
1666 634 : if ( GT_16( hTcxEnc->tcx_target_bits_fac, 0x5000 ) )
1667 : {
1668 205 : hTcxEnc->tcx_target_bits_fac = 0x5000;
1669 205 : move16();
1670 : }
1671 634 : if ( LT_16( hTcxEnc->tcx_target_bits_fac, 0x3000 ) )
1672 : {
1673 0 : hTcxEnc->tcx_target_bits_fac = 0x3000;
1674 0 : move16();
1675 : }
1676 :
1677 : /* Refine quantizer step size with a rate-control-loop (optional) */
1678 634 : phm_cfg = NULL;
1679 634 : move16();
1680 634 : if ( PeriodicityIndex >= 0 )
1681 : {
1682 47 : phm_cfg = hm_cfg;
1683 47 : move16();
1684 : }
1685 1268 : sqBits = tcx_scalar_quantization_rateloop_fx( spectrum, *spectrum_e,
1686 : sqQ,
1687 : L_spec,
1688 : &sqGain, &sqGain_e,
1689 634 : hTcxCfg->sq_rounding,
1690 634 : hTcxEnc->memQuantZeros,
1691 : prm_lastnz, /* lastnz */
1692 : sqTargetBits,
1693 : &nEncoded,
1694 : &stop,
1695 : sqBits_noStop,
1696 : sqBits,
1697 634 : hTcxCfg->tcxRateLoopOpt,
1698 : tcxonly,
1699 : phm_cfg );
1700 :
1701 634 : IF( ctxHmBits > 0 ) /* Mapping tool is enabled */
1702 : {
1703 : /* Truncate spectrum */
1704 596 : set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
1705 :
1706 596 : IF( PeriodicityIndex >= 0 ) /* Mapping is used */
1707 : {
1708 : /* Estimate non-mapped bitrate */
1709 47 : stopCtxHm = 1;
1710 47 : move16();
1711 :
1712 47 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1713 : L_spec,
1714 : &lastnz,
1715 : &nEncodedCtxHm,
1716 : sqTargetBits,
1717 : &stopCtxHm,
1718 : NULL );
1719 :
1720 : /* Decide whether or not to revert mapping */
1721 47 : Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
1722 :
1723 47 : test();
1724 47 : IF( stopCtxHm == 0 && Selector > 0 ) /* Non-mapped is better */
1725 : {
1726 1 : sqTargetBits = add( sqTargetBits, NumIndexBits );
1727 1 : ctxHmBits = sub( ctxHmBits, NumIndexBits );
1728 1 : prm_hm[0] = 0;
1729 1 : move16();
1730 1 : *prm_lastnz = lastnz;
1731 1 : move16();
1732 1 : PeriodicityIndex = -1;
1733 1 : move16();
1734 1 : sqBits_noStop = sqBits = sqBitsCtxHm;
1735 1 : move16();
1736 1 : move16();
1737 1 : nEncoded = nEncodedCtxHm;
1738 1 : move16();
1739 1 : stop = stopCtxHm;
1740 1 : move16();
1741 : }
1742 : }
1743 : ELSE /* Mapping is not used */
1744 : {
1745 : /* Estimate mapped bitrate */
1746 549 : stopCtxHm = 1;
1747 549 : move16();
1748 549 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1749 : L_spec,
1750 : &lastnzCtxHm,
1751 : &nEncodedCtxHm,
1752 549 : sub( sqTargetBits, NumIndexBits ),
1753 : &stopCtxHm,
1754 : hm_cfg );
1755 :
1756 : /* Decide whether or not to use mapping */
1757 549 : Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
1758 :
1759 549 : test();
1760 549 : IF( stopCtxHm == 0 && Selector > 0 ) /* Mapped is better */
1761 : {
1762 8 : sqTargetBits = sub( sqTargetBits, NumIndexBits );
1763 8 : ctxHmBits = add( ctxHmBits, NumIndexBits );
1764 8 : prm_hm[0] = 1;
1765 8 : move16();
1766 8 : *prm_lastnz = lastnzCtxHm;
1767 8 : move16();
1768 8 : PeriodicityIndex = prm_hm[1];
1769 8 : move16();
1770 8 : sqBits_noStop = sqBits = sqBitsCtxHm;
1771 8 : move16();
1772 8 : move16();
1773 8 : nEncoded = nEncodedCtxHm;
1774 8 : move16();
1775 8 : stop = stopCtxHm;
1776 8 : move16();
1777 : }
1778 : }
1779 : }
1780 :
1781 : /* Limit low sqGain for avoiding saturation of the gain quantizer*/
1782 634 : tmp1 = mult_r( shl_sat( L_spec, 5 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
1783 634 : s = 15 - 5 - 7;
1784 634 : IF( L_spec >= 1024 )
1785 : {
1786 : /*reduce precision for avoiding overflow*/
1787 0 : tmp1 = mult_r( shl( L_spec, 4 ), 26214 /*128.f/NORM_MDCT_FACTOR Q15*/ );
1788 0 : s = 15 - 4 - 7;
1789 : }
1790 634 : tmp1 = ISqrt16( tmp1, &s );
1791 :
1792 634 : tmp2 = sub( sqGain_e, s );
1793 634 : IF( tmp2 >= 0 )
1794 : {
1795 : BASOP_SATURATE_WARNING_OFF_EVS;
1796 634 : tmp2 = sub_sat( sqGain, shr_sat( tmp1, tmp2 ) );
1797 : BASOP_SATURATE_WARNING_ON_EVS;
1798 : }
1799 : ELSE
1800 : {
1801 0 : tmp2 = sub( shl( sqGain, s_max( -15, tmp2 ) ), tmp1 );
1802 : }
1803 :
1804 634 : IF( tmp2 < 0 )
1805 : {
1806 0 : sqGain = tmp1;
1807 0 : sqGain_e = s;
1808 :
1809 0 : tcx_scalar_quantization_fx( spectrum, *spectrum_e,
1810 : sqQ,
1811 : L_spec,
1812 : sqGain, sqGain_e,
1813 0 : hTcxCfg->sq_rounding,
1814 0 : hTcxEnc->memQuantZeros,
1815 : tcxonly );
1816 :
1817 0 : move16();
1818 0 : stop = 1;
1819 :
1820 0 : phm_cfg = NULL;
1821 0 : move16();
1822 0 : if ( PeriodicityIndex >= 0 )
1823 : {
1824 0 : phm_cfg = hm_cfg;
1825 0 : move16();
1826 : }
1827 0 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ,
1828 : L_spec,
1829 : prm_lastnz,
1830 : &nEncoded,
1831 : sqTargetBits,
1832 : &stop,
1833 : phm_cfg );
1834 : }
1835 :
1836 : /* Truncate spectrum (for CBR) */
1837 634 : IF( stop != 0 )
1838 : {
1839 63 : set16_fx( sqQ + nEncoded, 0, sub( L_spec, nEncoded ) );
1840 : }
1841 :
1842 : /* Save quantized Values */
1843 634 : tmp32 = L_deposit_l( 0 );
1844 634 : move16();
1845 : #ifdef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
1846 634 : Word64 seed = 0;
1847 634 : move64();
1848 : #endif
1849 412474 : FOR( i = 0; i < L_spec; i++ )
1850 : {
1851 411840 : spectrum[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
1852 411840 : move32();
1853 : /* noise filling seed */
1854 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
1855 : tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow );
1856 : #else
1857 411840 : seed = W_mac_16_16( seed, abs_s( sqQ[i] ), i );
1858 : #endif
1859 : }
1860 634 : *spectrum_e = SPEC_EXP_DEC;
1861 634 : move16();
1862 :
1863 : #ifdef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
1864 634 : nf_seed = extract_l( W_extract_l( seed ) ); // Q0
1865 : #else
1866 : nf_seed = extract_l( tmp32 );
1867 : #endif
1868 : }
1869 : ELSE /* low rates: new arithmetic coder */
1870 : {
1871 0 : AdaptLowFreqEmph_fx( spectrum, *spectrum_e,
1872 : NULL,
1873 : 0, 0,
1874 0 : hTcxEnc->tcx_lpc_shaped_ari,
1875 : gainlpc, gainlpc_e,
1876 : L_frame );
1877 :
1878 0 : prm_target = sqQ;
1879 0 : move16();
1880 0 : sqQ = prm_target + 1;
1881 0 : move16();
1882 0 : signs = hm_cfg->indexBuffer;
1883 0 : move16();
1884 :
1885 0 : LtpPitchLag = -1;
1886 0 : move16();
1887 :
1888 0 : IF( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) )
1889 : {
1890 0 : tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
1891 0 : tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
1892 0 : LtpPitchLag = div_l( tmp32, tmp1 );
1893 : }
1894 :
1895 0 : tmp8 = 1;
1896 0 : move16();
1897 0 : if ( st->last_core == ACELP_CORE )
1898 : {
1899 0 : tmp8 = 0;
1900 0 : move16();
1901 : }
1902 :
1903 0 : tcx_arith_encode_envelope_fx(
1904 : spectrum,
1905 : spectrum_e,
1906 : signs,
1907 : L_frame,
1908 : L_spec,
1909 : st,
1910 : Aqind,
1911 : sqTargetBits,
1912 : sqQ,
1913 : tmp8,
1914 : prm_hm, /* HM parameter area */
1915 : LtpPitchLag,
1916 : &sqBits,
1917 : &signaling_bits,
1918 0 : &nf_seed, shr( st->bwidth, 1 ) /* equivalent to: (st->bwidth > WB)?1:0 */
1919 : );
1920 :
1921 0 : sqTargetBits = sub( sqTargetBits, signaling_bits );
1922 0 : *prm_target = sqTargetBits;
1923 0 : move16();
1924 : }
1925 :
1926 : /*-----------------------------------------------------------*
1927 : * Compute optimal TCX gain. *
1928 : *-----------------------------------------------------------*/
1929 : /* initialize LF deemphasis factors in xn_buf */
1930 634 : set16_fx( xn_buf16, 0x4000, L_spec );
1931 :
1932 634 : IF( tcxonly == 0 )
1933 : {
1934 :
1935 634 : AdaptLowFreqDeemph( spectrum, *spectrum_e,
1936 634 : hTcxEnc->tcx_lpc_shaped_ari,
1937 : gainlpc, gainlpc_e,
1938 : L_frame,
1939 : xn_buf16 /* LF deemphasis factors */
1940 : );
1941 : }
1942 :
1943 634 : tcx_get_gain( x_orig, x_orig_e,
1944 634 : spectrum, *spectrum_e,
1945 : L_spec,
1946 : &gain_tcx_opt, &gain_tcx_opt_e,
1947 : &ener, &ener_e );
1948 :
1949 634 : IF( gain_tcx_opt <= 0 )
1950 : {
1951 0 : gain_tcx_opt = sqGain;
1952 0 : move16();
1953 0 : gain_tcx_opt_e = sqGain_e;
1954 0 : move16();
1955 : }
1956 634 : gain_tcx = gain_tcx_opt;
1957 634 : move16();
1958 634 : gain_tcx_e = gain_tcx_opt_e;
1959 634 : move16();
1960 :
1961 : /* Save gains for FAC and Residual Q*/
1962 :
1963 : /*-----------------------------------------------------------*
1964 : * Quantize TCX gain *
1965 : *-----------------------------------------------------------*/
1966 634 : test();
1967 634 : IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
1968 : {
1969 634 : QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] );
1970 : }
1971 :
1972 :
1973 : /*-----------------------------------------------------------*
1974 : * Residual Quantization *
1975 : *-----------------------------------------------------------*/
1976 :
1977 634 : IF( hTcxCfg->resq )
1978 : {
1979 :
1980 634 : resQTargetBits = sub( sqTargetBits, sqBits );
1981 :
1982 634 : IF( hTcxEnc->tcx_lpc_shaped_ari ) /* new arithmetic coder */
1983 : {
1984 : Word16 *prm_resq;
1985 :
1986 0 : prm_resq = sqQ + sqTargetBits - resQTargetBits;
1987 :
1988 0 : resQBits = tcx_ari_res_Q_spec_fx( x_orig, x_orig_e, signs, spectrum, *spectrum_e, L_spec, gain_tcx, gain_tcx_e,
1989 : prm_resq,
1990 : resQTargetBits,
1991 : resQBits,
1992 0 : hTcxCfg->sq_rounding,
1993 : xn_buf16 /* LF deemphasis factors */ );
1994 :
1995 : /* Transmit zeros when there bits remain after RESQ */
1996 0 : set16_fx( prm_resq + resQBits, 0, sub( resQTargetBits, resQBits ) );
1997 : }
1998 : ELSE /* old arithmetic coder */
1999 : {
2000 634 : move16();
2001 634 : tmpP16 = NULL;
2002 634 : if ( tcxonly == 0 )
2003 : {
2004 634 : move16();
2005 634 : tmpP16 = xn_buf16;
2006 : }
2007 :
2008 634 : resQBits = tcx_res_Q_gain_fx( gain_tcx_opt, gain_tcx_opt_e,
2009 : &gain_tcx, &gain_tcx_e,
2010 634 : &sqQ[L_spec],
2011 : resQTargetBits );
2012 :
2013 634 : resQBits = tcx_res_Q_spec_fx( x_orig, x_orig_e,
2014 634 : spectrum, *spectrum_e,
2015 : L_spec,
2016 : gain_tcx, gain_tcx_e,
2017 634 : &sqQ[L_spec],
2018 : resQTargetBits,
2019 : resQBits,
2020 634 : hTcxCfg->sq_rounding,
2021 : tmpP16 /* LF deemphasis factors */ );
2022 : }
2023 : }
2024 :
2025 :
2026 : /*-----------------------------------------------------------*
2027 : * ALFE tcx only bitrates *
2028 : *-----------------------------------------------------------*/
2029 :
2030 634 : IF( st->tcxonly != 0 )
2031 : {
2032 0 : test();
2033 0 : test();
2034 0 : IF( hTcxEnc->tcxltp != 0 && ( hTcxEnc->tcxltp_gain > 0 ) && fUseTns == 0 )
2035 : {
2036 :
2037 0 : PsychAdaptLowFreqDeemph( spectrum, gainlpc, gainlpc_e, NULL );
2038 : }
2039 : }
2040 :
2041 : /*-----------------------------------------------------------*
2042 : * TCX SNR for Analysis purposes *
2043 : *-----------------------------------------------------------*/
2044 :
2045 : {
2046 634 : maxNfCalcBw = s_min( noiseFillingSize, round_fx( L_shl( L_mult( hTcxEnc->measuredBwRatio, L_frame ), 1 ) ) );
2047 :
2048 : /*-----------------------------------------------------------*
2049 : * Estimate and quantize noise factor *
2050 : *-----------------------------------------------------------*/
2051 :
2052 634 : IF( GE_32( st->total_brate, HQ_96k ) )
2053 : {
2054 0 : fac_ns = 0;
2055 0 : move16();
2056 0 : prm[1] = 0;
2057 0 : move16();
2058 : }
2059 : ELSE
2060 : {
2061 : /* noise filling start bin */
2062 634 : i = shr( L_frame, 3 );
2063 634 : test();
2064 634 : IF( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
2065 : {
2066 634 : i = idiv1616U( L_frame, 6 );
2067 : }
2068 :
2069 634 : IF( tcxonly )
2070 : {
2071 0 : tmp1 = 0;
2072 0 : move16();
2073 0 : test();
2074 0 : test();
2075 0 : if ( ( hTcxCfg->ctx_hm != 0 ) && ( st->last_core != ACELP_CORE ) && ( prm_hm[0] != 0 ) )
2076 : {
2077 0 : tmp1 = 10240 /*0.3125f Q15*/;
2078 0 : move16();
2079 : }
2080 0 : noiseTransWidth = HOLE_SIZE_FROM_LTP( s_max( hTcxEnc->tcxltp_gain, tmp1 ) );
2081 :
2082 0 : if ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) )
2083 : {
2084 : /* minimum transition for noise filling in TCX-10 */
2085 0 : noiseTransWidth = 3;
2086 0 : move16();
2087 : }
2088 : }
2089 :
2090 634 : tcx_noise_factor_fx( x_orig, x_orig_e,
2091 : spectrum,
2092 : i,
2093 : maxNfCalcBw,
2094 : noiseTransWidth,
2095 : L_frame,
2096 : gain_tcx, gain_tcx_e,
2097 634 : hTcxEnc->noiseTiltFactor,
2098 : &fac_ns, &prm[NOISE_FILL_RANGES] );
2099 :
2100 : /* hysteresis for very tonal passages (more stationary noise filling level) */
2101 :
2102 634 : IF( EQ_16( prm[NOISE_FILL_RANGES], 1 ) )
2103 : {
2104 55 : hTcxEnc->noiseLevelMemory_cnt = add( 1, abs_s( hTcxEnc->noiseLevelMemory_cnt ) ); /* update counter */
2105 55 : move16();
2106 : }
2107 : ELSE
2108 : {
2109 579 : test();
2110 579 : IF( ( EQ_16( prm[NOISE_FILL_RANGES], 2 ) ) &&
2111 : ( GT_16( abs_s( hTcxEnc->noiseLevelMemory_cnt ), 5 ) ) )
2112 : {
2113 : /* reduce noise filling level by one step */
2114 3 : prm[NOISE_FILL_RANGES] = 1;
2115 3 : move16();
2116 3 : fac_ns = shr( 0x6000, NBITS_NOISE_FILL_LEVEL );
2117 :
2118 : /* signal that noise level is changed by inverting sign of level memory */
2119 3 : tmp1 = 5;
2120 3 : move16();
2121 3 : if ( hTcxEnc->noiseLevelMemory_cnt >= 0 )
2122 : {
2123 3 : tmp1 = sub( -1, hTcxEnc->noiseLevelMemory_cnt );
2124 : }
2125 3 : hTcxEnc->noiseLevelMemory_cnt = tmp1;
2126 3 : move16();
2127 : }
2128 : ELSE
2129 : {
2130 : /* reset memory since level is too different */
2131 576 : hTcxEnc->noiseLevelMemory_cnt = 0;
2132 576 : move16();
2133 : }
2134 : }
2135 :
2136 : } /* bitrate */
2137 : }
2138 :
2139 : /* Free encoder specific stack to use it below for the internal TCX decoder. */
2140 : }
2141 :
2142 : /*-----------------------------------------------------------*
2143 : * Internal TCX decoder *
2144 : *-----------------------------------------------------------*/
2145 : {
2146 : /* Overlay of a 16-bit buffer xn_buf16 with a 32-bit buffer xn_buf32 */
2147 : /* The size is determined by the requirements of the 16-bit buffer. */
2148 : Word32 xn_buf32[( L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2149 634 : Word16 *xn_buf16 = (Word16 *) xn_buf32;
2150 :
2151 : /*Enable internal TCX decoder to run always to update LPD memory for rate switching */
2152 :
2153 : IF( tcxonly == 0 )
2154 : {
2155 : }
2156 :
2157 : /*-----------------------------------------------------------*
2158 : * Noise Filling. *
2159 : *-----------------------------------------------------------*/
2160 :
2161 634 : test();
2162 : /* Replication of ACELP formant enhancement for low rates */
2163 634 : IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
2164 : {
2165 0 : tcxFormantEnhancement( xn_buf16, gainlpc, gainlpc_e, spectrum, spectrum_e, L_frame, L_spec );
2166 : }
2167 :
2168 634 : IF( fac_ns > 0 )
2169 : {
2170 634 : tmp1 = 0;
2171 634 : move16();
2172 634 : test();
2173 634 : if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
2174 : {
2175 634 : tmp1 = 1;
2176 634 : move16();
2177 : }
2178 :
2179 634 : i = tcxGetNoiseFillingTilt( A,
2180 : M,
2181 : L_frame,
2182 : tmp1,
2183 : &hTcxEnc->noiseTiltFactor );
2184 :
2185 634 : tcx_noise_filling( spectrum, *spectrum_e, nf_seed /* seed */, i, noiseFillingSize, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns, NULL, st->element_mode );
2186 : }
2187 634 : test();
2188 634 : IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
2189 : {
2190 : /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
2191 0 : s = sub( getScaleFactor32( spectrum, L_spec ), 4 );
2192 0 : tmp32 = L_deposit_l( 1 );
2193 :
2194 0 : FOR( i = 0; i < L_spec; i++ )
2195 : {
2196 0 : tmp1 = round_fx( L_shl( spectrum[i], s ) );
2197 0 : tmp32 = L_mac0( tmp32, tmp1, tmp1 );
2198 : }
2199 :
2200 0 : tmp1 = BASOP_Util_Divide3232_Scale( ener, tmp32, &tmp2 );
2201 0 : tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) );
2202 0 : tmp1 = Sqrt16( tmp1, &tmp2 );
2203 :
2204 0 : gain_tcx = mult( gain_tcx, tmp1 );
2205 0 : gain_tcx_e = add( gain_tcx_e, tmp2 );
2206 :
2207 0 : QuantizeGain( L_spec, &gain_tcx, &gain_tcx_e, &prm[0] );
2208 : }
2209 :
2210 : /*end of noise filling*/
2211 :
2212 : /*-----------------------------------------------------------*
2213 : * Noise shaping in frequency domain (1/Wz) *
2214 : *-----------------------------------------------------------*/
2215 :
2216 : /* LPC gains already available */
2217 634 : mdct_shaping( spectrum, L_frame, gainlpc, gainlpc_e );
2218 :
2219 : /*-----------------------------------------------------------*
2220 : * Apply gain *
2221 : *-----------------------------------------------------------*/
2222 634 : IF( st->hTcxCfg->coder_type == INACTIVE )
2223 : {
2224 10 : gain_tcx = mult_r( gain_tcx, hTcxCfg->na_scale );
2225 : }
2226 :
2227 412474 : FOR( i = 0; i < L_spec; i++ )
2228 : {
2229 411840 : spectrum[i] = Mpy_32_16_1( spectrum[i], gain_tcx ); // Q(31-(spectrum_e+gain_tcx_e))
2230 411840 : move32();
2231 : }
2232 634 : *spectrum_e = add( *spectrum_e, gain_tcx_e );
2233 634 : move16();
2234 :
2235 634 : stop = hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
2236 634 : move16();
2237 :
2238 634 : test();
2239 634 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
2240 : {
2241 0 : Word16 L = L_frame;
2242 0 : move16();
2243 :
2244 0 : test();
2245 0 : test();
2246 0 : if ( ( ( hTcxCfg->fIsTNSAllowed != 0 ) && ( fUseTns != 0 ) ) || ( GT_16( L_spec, L_frame ) ) )
2247 : {
2248 0 : L = L_spec;
2249 0 : move16();
2250 : }
2251 :
2252 0 : tcxInvertWindowGrouping( hTcxCfg,
2253 : xn_buf32,
2254 : spectrum,
2255 : L,
2256 : fUseTns,
2257 0 : st->last_core,
2258 : stop,
2259 : frame_cnt,
2260 : 0 );
2261 : }
2262 :
2263 : /*-----------------------------------------------------------*
2264 : * Temporal Noise Shaping Synthesis *
2265 : *-----------------------------------------------------------*/
2266 :
2267 634 : IF( hTcxCfg->fIsTNSAllowed != 0 )
2268 : {
2269 372 : test();
2270 372 : SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
2271 :
2272 : /* Apply TNS to get the reconstructed signal */
2273 372 : IF( fUseTns != 0 )
2274 : {
2275 4 : ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, pTnsData, spectrum, 0 );
2276 :
2277 4 : test();
2278 4 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
2279 : {
2280 0 : test();
2281 0 : test();
2282 0 : test();
2283 0 : IF( ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
2284 : ( ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( stop == 0 ) ) )
2285 : {
2286 0 : tmp1 = shr( L_spec, 1 );
2287 : /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
2288 0 : assert( L_frame <= L_spec );
2289 0 : Copy32( spectrum + 8, xn_buf32, 8 );
2290 0 : Copy32( spectrum + 16, spectrum + 8, sub( tmp1, 8 ) );
2291 0 : Copy32( xn_buf32, spectrum + tmp1, 8 );
2292 : }
2293 : }
2294 : }
2295 : }
2296 :
2297 : {
2298 : /* normalize spectrum to minimize IMDCT noise */
2299 634 : s = getScaleFactor32( spectrum, L_frame );
2300 189546 : FOR( i = 0; i < L_frame; i++ )
2301 : {
2302 188912 : spectrum[i] = L_shl( spectrum[i], s ); // Q(31-(spectrum_e-s))
2303 188912 : move32();
2304 : }
2305 634 : *spectrum_e = sub( *spectrum_e, s );
2306 :
2307 : /*-----------------------------------------------------------*
2308 : * Compute inverse MDCT of spectrum[]. *
2309 : *-----------------------------------------------------------*/
2310 634 : test();
2311 634 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( tcxonly != 0 ) )
2312 : {
2313 0 : IF( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
2314 : {
2315 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2316 : Word16 L_win, L_spec_TCX5, L_ola, w;
2317 :
2318 : /* minimum or half overlap, two transforms, grouping into one window */
2319 0 : L_win = shr( L_frame, 1 );
2320 0 : L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
2321 0 : L_ola = hTcxCfg->tcx_mdct_window_half_length;
2322 0 : move16();
2323 0 : if ( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
2324 : {
2325 0 : L_ola = hTcxCfg->tcx_mdct_window_min_length;
2326 0 : move16();
2327 : }
2328 :
2329 0 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
2330 0 : set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
2331 :
2332 0 : FOR( w = 0; w < 2; w++ )
2333 : {
2334 :
2335 0 : IF( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
2336 : {
2337 0 : TCX_MDCT_Inverse( spectrum + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2338 0 : win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
2339 : }
2340 : ELSE
2341 : {
2342 0 : TCX_MDCT_Inverse( spectrum + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win,
2343 0 : L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
2344 : }
2345 :
2346 0 : tmp1 = hTcxCfg->tcx_last_overlap_mode;
2347 0 : move16();
2348 0 : test();
2349 0 : test();
2350 0 : if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( stop, 2 ) ) ) )
2351 : {
2352 0 : tmp1 = MIN_OVERLAP;
2353 0 : move16();
2354 : }
2355 :
2356 0 : tmp2 = 0;
2357 0 : move16();
2358 0 : test();
2359 0 : if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) )
2360 : {
2361 0 : tmp2 = 1;
2362 0 : move16();
2363 : }
2364 :
2365 0 : tmp3 = st->last_core;
2366 0 : move16();
2367 0 : if ( w > 0 )
2368 : {
2369 0 : tmp3 = 1;
2370 0 : move16();
2371 : }
2372 :
2373 0 : tmp4 = 0;
2374 0 : move16();
2375 0 : if ( tcx_offset < 0 )
2376 : {
2377 0 : tmp4 = negate( tcx_offset );
2378 : }
2379 :
2380 0 : tcx_windowing_synthesis_current_frame( win,
2381 0 : hTcxCfg->tcx_aldo_window_2,
2382 0 : hTcxCfg->tcx_mdct_window_half,
2383 0 : hTcxCfg->tcx_mdct_window_minimum,
2384 : L_ola,
2385 0 : hTcxCfg->tcx_mdct_window_half_length,
2386 0 : hTcxCfg->tcx_mdct_window_min_length,
2387 : tmp2,
2388 : tmp1,
2389 : hTcxEnc->acelp_zir,
2390 0 : hTcxEnc->Txnq,
2391 : NULL,
2392 : Aq_old,
2393 0 : hTcxCfg->tcx_mdct_window_trans,
2394 : L_win,
2395 : tmp4,
2396 : tmp3,
2397 : 0,
2398 : 0 );
2399 :
2400 0 : tmp1 = add( tcx_offset, imult1616( w, L_win ) );
2401 0 : move16();
2402 0 : tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) );
2403 :
2404 0 : IF( w > 0 )
2405 : {
2406 0 : tcx_windowing_synthesis_past_frame( tmpP16,
2407 0 : hTcxCfg->tcx_aldo_window_1_trunc,
2408 0 : hTcxCfg->tcx_mdct_window_half,
2409 0 : hTcxCfg->tcx_mdct_window_minimum,
2410 : L_ola,
2411 0 : hTcxCfg->tcx_mdct_window_half_length,
2412 0 : hTcxCfg->tcx_mdct_window_min_length,
2413 : 2 );
2414 : }
2415 : /* add part of current sub-window overlapping with previous window */
2416 0 : FOR( i = 0; i < L_ola; i++ )
2417 : {
2418 0 : tmpP16[i] = add_sat( tmpP16[i], win[i] );
2419 0 : move16();
2420 : }
2421 : /* copy new sub-window region not overlapping with previous window */
2422 0 : Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win );
2423 : }
2424 : /* To assure that no garbage values are copied to hLPDmem->Txnq */
2425 0 : set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ),
2426 0 : 0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) );
2427 : }
2428 0 : ELSE IF( s_and( frame_cnt == 0, ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) )
2429 : {
2430 : /* special overlap attempt, two transforms, grouping into one window */
2431 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
2432 : Word16 L_win, L_spec_TCX5, L_ola, w;
2433 :
2434 0 : L_win = shr( L_frame, 1 );
2435 0 : L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
2436 0 : L_ola = hTcxCfg->tcx_mdct_window_min_length;
2437 0 : move16();
2438 :
2439 0 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
2440 :
2441 : /* Resize overlap (affect only asymmetric window)*/
2442 0 : overlap = st->hTcxCfg->tcx_mdct_window_delay;
2443 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
2444 0 : TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2445 0 : win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
2446 :
2447 : /* copy new sub-window region not overlapping with previous window */
2448 0 : Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
2449 :
2450 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
2451 :
2452 0 : TCX_MDCT_Inverse( spectrum + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2453 0 : win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
2454 :
2455 0 : tmp4 = 0;
2456 0 : move16();
2457 0 : if ( tcx_offset < 0 )
2458 : {
2459 0 : tmp4 = negate( tcx_offset );
2460 : }
2461 0 : tcx_windowing_synthesis_current_frame( win,
2462 0 : hTcxCfg->tcx_aldo_window_2,
2463 0 : hTcxCfg->tcx_mdct_window_half,
2464 0 : hTcxCfg->tcx_mdct_window_minimum,
2465 : L_ola,
2466 0 : hTcxCfg->tcx_mdct_window_half_length,
2467 0 : hTcxCfg->tcx_mdct_window_min_length,
2468 : 0, /* left_rect */
2469 : 2, /* left_mode */
2470 : hTcxEnc->acelp_zir,
2471 0 : hTcxEnc->Txnq,
2472 : NULL,
2473 : Aq_old,
2474 0 : hTcxCfg->tcx_mdct_window_trans,
2475 : L_win,
2476 : tmp4,
2477 : 1, /* not LPDmem->mode */
2478 : 0,
2479 : 0 );
2480 :
2481 :
2482 0 : tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
2483 :
2484 0 : tcx_windowing_synthesis_past_frame( tmpP16,
2485 0 : hTcxCfg->tcx_aldo_window_1_trunc,
2486 0 : hTcxCfg->tcx_mdct_window_half,
2487 0 : hTcxCfg->tcx_mdct_window_minimum,
2488 : L_ola,
2489 0 : hTcxCfg->tcx_mdct_window_half_length,
2490 0 : hTcxCfg->tcx_mdct_window_min_length,
2491 : 2 );
2492 :
2493 : /* add part of current sub-window overlapping with previous window */
2494 0 : FOR( i = 0; i < L_ola; i++ )
2495 : {
2496 0 : tmpP16[i] = add_sat( tmpP16[i], win[i] );
2497 0 : move16();
2498 : }
2499 :
2500 : /* copy new sub-window region not overlapping with previous window */
2501 0 : Copy( win + L_ola,
2502 0 : xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
2503 : L_win );
2504 :
2505 : /* extra folding-out on left side of win, for perfect reconstruction */
2506 0 : FOR( w = overlap / 2; w < overlap; w++ )
2507 : {
2508 0 : xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] );
2509 0 : move16();
2510 : }
2511 :
2512 0 : tmp4 = 0;
2513 0 : move16();
2514 0 : if ( tcx_offset < 0 )
2515 : {
2516 0 : tmp4 = negate( tcx_offset );
2517 : }
2518 0 : tcx_windowing_synthesis_current_frame( xn_buf16,
2519 0 : hTcxCfg->tcx_aldo_window_2,
2520 0 : hTcxCfg->tcx_mdct_window_half,
2521 0 : hTcxCfg->tcx_mdct_window_minimum,
2522 : overlap,
2523 0 : hTcxCfg->tcx_mdct_window_half_length,
2524 0 : hTcxCfg->tcx_mdct_window_min_length,
2525 0 : st->last_core == ACELP_CORE,
2526 : 0,
2527 : hTcxEnc->acelp_zir,
2528 0 : hTcxEnc->Txnq,
2529 : NULL,
2530 : Aq_old,
2531 0 : hTcxCfg->tcx_mdct_window_trans,
2532 : L_win,
2533 : tmp4,
2534 0 : st->last_core,
2535 : 0,
2536 : 0 );
2537 : }
2538 : ELSE /* default, i.e. maximum overlap, single transform, no grouping */
2539 : {
2540 :
2541 0 : TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2542 0 : xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
2543 :
2544 0 : tmp1 = stop;
2545 0 : move16();
2546 0 : test();
2547 0 : test();
2548 0 : if ( ( frame_cnt > 0 ) && ( stop == 0 ) && ( st->last_core != ACELP_CORE ) )
2549 : {
2550 0 : tmp1 = 2;
2551 0 : move16();
2552 : }
2553 :
2554 0 : tmp4 = 0;
2555 0 : move16();
2556 0 : if ( tcx_offset < 0 )
2557 : {
2558 0 : tmp4 = negate( tcx_offset );
2559 : }
2560 0 : tcx_windowing_synthesis_current_frame( xn_buf16,
2561 0 : hTcxCfg->tcx_aldo_window_2,
2562 0 : hTcxCfg->tcx_mdct_window_half,
2563 0 : hTcxCfg->tcx_mdct_window_minimum,
2564 : overlap, /*hTcxCfg->tcx_mdct_window_length*/
2565 0 : hTcxCfg->tcx_mdct_window_half_length,
2566 0 : hTcxCfg->tcx_mdct_window_min_length,
2567 0 : st->last_core == ACELP_CORE,
2568 : tmp1,
2569 : hTcxEnc->acelp_zir,
2570 0 : hTcxEnc->Txnq,
2571 : NULL,
2572 : Aq_old,
2573 0 : hTcxCfg->tcx_mdct_window_trans,
2574 0 : shr( L_frame_glob, 1 ),
2575 : tmp4,
2576 0 : st->last_core,
2577 : 0,
2578 : 0 );
2579 :
2580 : } /* tcx_last_overlap_mode > 0 */
2581 : }
2582 : ELSE /* frame is TCX-20 or not TCX-only */
2583 : {
2584 634 : IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
2585 : {
2586 : Word32 tmp_buf[L_FRAME_PLUS];
2587 : Word16 Q;
2588 :
2589 : /* DCT */
2590 596 : Q = sub( 31, *spectrum_e );
2591 596 : edct_fx( spectrum, tmp_buf, L_frame, &Q );
2592 :
2593 : /* scale by sqrt(L / NORM_MDCT_FACTOR) */
2594 596 : tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
2595 596 : tmp2 = 4;
2596 596 : move16();
2597 596 : tmp1 = Sqrt16( tmp1, &tmp2 );
2598 :
2599 175508 : FOR( i = 0; i < L_frame; i++ )
2600 : {
2601 174912 : tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
2602 174912 : move32();
2603 : }
2604 596 : Q = sub( Q, tmp2 );
2605 :
2606 :
2607 596 : window_ola_fx( tmp_buf,
2608 : xn_buf16,
2609 : &Q,
2610 596 : hTcxEnc->old_out_fx,
2611 : &hTcxEnc->Q_old_out,
2612 : L_frame,
2613 596 : hTcxCfg->tcx_last_overlap_mode,
2614 596 : hTcxCfg->tcx_curr_overlap_mode,
2615 : 0,
2616 : 0,
2617 : NULL );
2618 :
2619 : /* scale output */
2620 175508 : FOR( i = 0; i < L_frame; i++ )
2621 : {
2622 174912 : xn_buf16[i] = shr_sat( xn_buf16[i], Q );
2623 174912 : move16();
2624 : }
2625 :
2626 596 : aldo = 1;
2627 596 : move16();
2628 : }
2629 : ELSE
2630 : {
2631 :
2632 38 : TCX_MDCT_Inverse( spectrum, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
2633 38 : xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
2634 :
2635 : /*-----------------------------------------------------------*
2636 : * Windowing, overlap and add *
2637 : *-----------------------------------------------------------*/
2638 :
2639 : /* Window current frame */
2640 38 : tmp4 = 0;
2641 38 : move16();
2642 38 : if ( tcx_offset < 0 )
2643 : {
2644 38 : tmp4 = negate( tcx_offset );
2645 : }
2646 76 : tcx_windowing_synthesis_current_frame( xn_buf16,
2647 38 : hTcxCfg->tcx_aldo_window_2,
2648 38 : hTcxCfg->tcx_mdct_window_half,
2649 38 : hTcxCfg->tcx_mdct_window_minimum,
2650 : overlap, /*hTcxCfg->tcx_mdct_window_length*/
2651 38 : hTcxCfg->tcx_mdct_window_half_length,
2652 38 : hTcxCfg->tcx_mdct_window_min_length,
2653 38 : st->last_core == ACELP_CORE,
2654 38 : hTcxCfg->tcx_last_overlap_mode, /*left mode*/
2655 : hTcxEnc->acelp_zir,
2656 38 : hTcxEnc->Txnq,
2657 : NULL,
2658 : Aq_old,
2659 38 : hTcxCfg->tcx_mdct_window_trans,
2660 38 : shr( L_frame_glob, 1 ),
2661 : tmp4,
2662 38 : st->last_core,
2663 : 0,
2664 : 0 );
2665 : }
2666 : } /* TCX-10 and TCX-only */
2667 :
2668 : /* Window and overlap-add past frame if past frame is TCX */
2669 634 : test();
2670 634 : test();
2671 634 : test();
2672 634 : IF( ( st->last_core > ACELP_CORE ) && ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
2673 : {
2674 :
2675 0 : IF( hTcxCfg->last_aldo != 0 )
2676 : {
2677 0 : tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
2678 :
2679 0 : tmp1 = sub( overlap, hTcxCfg->tcx_mdct_window_min_length );
2680 0 : FOR( i = 0; i < tmp1; i++ )
2681 : {
2682 0 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
2683 0 : move16();
2684 : }
2685 :
2686 : /* fade truncated ALDO window */
2687 0 : tmp1 = sub( overlap, shr( hTcxCfg->tcx_mdct_window_min_length, 1 ) );
2688 0 : FOR( ; i < tmp1; i++ )
2689 : {
2690 0 : tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[i - overlap + hTcxCfg->tcx_mdct_window_min_length].v.re );
2691 0 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
2692 0 : move16();
2693 : }
2694 0 : FOR( ; i < overlap; i++ )
2695 : {
2696 0 : tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
2697 0 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
2698 0 : move16();
2699 : }
2700 :
2701 0 : FOR( ; i < L_frame; i++ )
2702 : {
2703 0 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
2704 0 : move16();
2705 : }
2706 : }
2707 : ELSE
2708 : {
2709 0 : test();
2710 0 : test();
2711 0 : test();
2712 0 : if ( ( frame_cnt > 0 ) && ( stop == 0 ) && ( hTcxCfg->tcx_curr_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
2713 : {
2714 0 : stop = 2; /* use minimum overlap between the two TCX-10 windows */
2715 0 : move16();
2716 : }
2717 :
2718 0 : tmp1 = stop;
2719 0 : move16();
2720 0 : test();
2721 0 : if ( ( stop == 0 ) || ( EQ_16( hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
2722 : {
2723 0 : tmp1 = hTcxCfg->tcx_last_overlap_mode;
2724 0 : move16();
2725 : }
2726 :
2727 0 : tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_mdct_window_half,
2728 0 : hTcxCfg->tcx_mdct_window_minimum, overlap, hTcxCfg->tcx_mdct_window_half_length, hTcxCfg->tcx_mdct_window_min_length, tmp1 );
2729 :
2730 : BASOP_SATURATE_WARNING_OFF_EVS;
2731 0 : FOR( i = 0; i < overlap; i++ )
2732 : {
2733 0 : xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
2734 0 : move16();
2735 : }
2736 :
2737 0 : IF( LT_16( i, L_frame ) )
2738 : {
2739 0 : FOR( ; i < L_frame; i++ )
2740 : {
2741 0 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
2742 0 : move16();
2743 : }
2744 : }
2745 : BASOP_SATURATE_WARNING_ON_EVS;
2746 : }
2747 : }
2748 : ELSE
2749 : {
2750 634 : IF( aldo == 0 )
2751 : {
2752 : BASOP_SATURATE_WARNING_OFF_EVS;
2753 14038 : FOR( i = 0; i < L_frame; i++ )
2754 : {
2755 14000 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
2756 14000 : move16();
2757 : }
2758 : BASOP_SATURATE_WARNING_ON_EVS;
2759 : }
2760 : }
2761 :
2762 634 : test();
2763 634 : test();
2764 634 : test();
2765 634 : IF( ( aldo == 0 ) &&
2766 : ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
2767 : NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
2768 : {
2769 : /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
2770 3188 : FOR( i = 0; i < nz; i++ )
2771 : {
2772 3150 : hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
2773 3150 : move16();
2774 : }
2775 38 : Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
2776 38 : set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
2777 :
2778 38 : tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
2779 38 : hTcxCfg->tcx_aldo_window_1_trunc,
2780 38 : hTcxCfg->tcx_mdct_window_half,
2781 38 : hTcxCfg->tcx_mdct_window_minimum,
2782 : overlap,
2783 38 : hTcxCfg->tcx_mdct_window_half_length,
2784 38 : hTcxCfg->tcx_mdct_window_min_length,
2785 38 : hTcxCfg->tcx_curr_overlap_mode );
2786 :
2787 : /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
2788 38 : IF( EQ_16( hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
2789 : {
2790 3188 : FOR( i = 0; i < nz; i++ )
2791 : {
2792 3150 : hTcxEnc->old_out_fx[nz + overlap + i] = shr( mult_r( xn_buf16[L_frame - 1 - i], hTcxCfg->tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
2793 3150 : move16();
2794 : }
2795 38 : hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW;
2796 38 : move16();
2797 : }
2798 :
2799 38 : hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
2800 38 : move16();
2801 : }
2802 634 : hTcxCfg->last_aldo = aldo;
2803 634 : move16();
2804 :
2805 : /* Update Txnq */
2806 634 : IF( hTcxCfg->last_aldo == 0 )
2807 : {
2808 38 : Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
2809 : }
2810 :
2811 :
2812 : /* Output */
2813 634 : Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, L_frame_glob );
2814 : }
2815 :
2816 : /* Free internal TCX decoder stack memory */
2817 : }
2818 :
2819 : /* Update L_frame_past */
2820 634 : st->L_frame_past = L_frame;
2821 634 : move16();
2822 634 : }
2823 :
2824 0 : static Word16 DecideTonalSideInfo_fx(
2825 : Word32 spectrum[], // Qx
2826 : const Word16 L_frame_glob,
2827 : Word32 SFM2 )
2828 : {
2829 : Word32 SFM, K, K2;
2830 : Word16 Tonal_SideInfo;
2831 :
2832 0 : SFM = SFM_Cal_fx( spectrum, s_min( 200, L_frame_glob ) );
2833 0 : test();
2834 0 : IF( LE_16( L_frame_glob, 256 ) )
2835 : {
2836 0 : K = 0x33333333;
2837 0 : move32();
2838 0 : K2 = 0xCCCCCCD;
2839 0 : move32();
2840 : }
2841 0 : ELSE IF( EQ_16( L_frame_glob, 320 ) || EQ_16( L_frame_glob, 512 ) )
2842 : {
2843 0 : K = 0x33333333;
2844 0 : move32();
2845 0 : K2 = 0xCCCCCCD;
2846 0 : move32();
2847 : }
2848 : ELSE /*FrameSize_Core == 640*/
2849 : {
2850 0 : K = 0x2CCCCCCD;
2851 0 : move32();
2852 0 : K2 = 0x51EB852;
2853 0 : move32();
2854 : }
2855 :
2856 :
2857 0 : Tonal_SideInfo = 0;
2858 0 : move16();
2859 0 : if ( LT_32( SFM, K ) )
2860 : {
2861 0 : Tonal_SideInfo = 1;
2862 0 : move16();
2863 : }
2864 0 : if ( LT_32( SFM2, K2 ) )
2865 : {
2866 0 : Tonal_SideInfo = 1;
2867 0 : move16();
2868 : }
2869 :
2870 0 : return Tonal_SideInfo;
2871 : }
2872 :
2873 894237 : void QuantizeTCXSpectrum_fx(
2874 : Encoder_State *st, /* i : state handle */
2875 : const Word16 frame_cnt, /* i : frame counter in the super_frame Q0 */
2876 : Word32 *x_orig_fx, /* i : shaped MDCT spectrum Q(31-x_orig_e)*/
2877 : Word16 x_orig_e, /* i : exp of shaped MDCT spectrum */
2878 : Word16 *gainlpc_fx, /* i : FDNS gains Q(15-gainlpc_e)*/
2879 : Word16 *gainlpc_e, /* i : exp of FDNS gains */
2880 : const Word16 *Aqind, /* i : frame-independent quantized coefficients (M+1) Q0 */
2881 : const Word16 tnsSize, /* i : number of tns parameters put into prm Q0 */
2882 : const Word16 nb_bits, /* i : bit budget Q0 */
2883 : const Word16 vad_hover_flag, /* i : VAD hangover flag Q0 */
2884 : Word16 *pL_frameTCX, /* o : full frame length Q0 */
2885 : Word16 *pL_frame, /* o : frame length Q0 */
2886 : Word16 *pL_spec, /* o : length of the coded spectrum Q0 */
2887 : Word16 *ptcx_offset, /* o : folding point offset relative to the end of the previous frame Q0 */
2888 : Word16 *pnoiseFillingBorder, /* o : noise filling border Q0 */
2889 : Word32 spectrum_fx[], /* o : quantized MDCT spectrum Q(31-spectrum_e)*/
2890 : Word16 *spectrum_e, /* o : exp of quantized MDCT spectrum */
2891 : CONTEXT_HM_CONFIG *hm_cfg, /* o : Context-based harmonic model configuration */
2892 : Word16 *hm_active, /* o : flag indicating if the harmonic model is active */
2893 : Word16 lf_deemph_fact_fx[], /* o : low frequency deemphasis factors Q14*/
2894 : Word16 *nf_seed, /* o : noise filling random seed Q0*/
2895 : Word32 *ener_fx, /* o : energy of the quantized spectrum Q(31-ener_e) */
2896 : Word16 *ener_e, /* o : exp of energy of the quantized spectrum */
2897 : Word16 *gain_tcx_fx, /* o : global gain Q(15-gain_tcx_e) */
2898 : Word16 *gain_tcx_e, /* o : exp of global gain */
2899 : Word16 prm[] /* o : tcx parameters Q0 */
2900 : )
2901 : {
2902 894237 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
2903 : Word16 i, L_frame, L_frameTCX, L_spec, tcx_offset;
2904 : Word16 noiseFillingBorder, LtpPitchLag, PeriodicityIndex;
2905 : Word16 lastnzCtxHm, lastnz;
2906 : Word16 stop;
2907 : Word16 nEncodedCtxHm, stopCtxHm, sqBitsCtxHm, Selector;
2908 : Word16 nEncoded, sqBits_noStop;
2909 : Word16 NumIndexBits, signaling_bits, sqTargetBits, sqBits, ctxHmBits, resQBits, resQTargetBits;
2910 : Word16 *prm_ltp, *prm_tns, *prm_hm, *prm_lastnz, *sqQ, *prm_target;
2911 : Word32 total_brate, tmp32;
2912 : Word16 RelativeScore_fx, sqGain_fx, sqGain_e, gain_tcx_opt_fx, gain_tcx_opt_e;
2913 : Word16 tmp1, tmp2, max_iter, minSqGain;
2914 : CONTEXT_HM_CONFIG *phm_cfg;
2915 894237 : Word16 att_fx = 0;
2916 894237 : move16();
2917 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2918 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
2919 : Flag Overflow = 0;
2920 : move16();
2921 : Flag Carry = 0;
2922 : move16();
2923 : #endif
2924 : #endif
2925 : /*-----------------------------------------------------------*
2926 : * Init *
2927 : *-----------------------------------------------------------*/
2928 :
2929 894237 : sqGain_fx = MAX_16;
2930 894237 : move16();
2931 894237 : sqGain_e = 0;
2932 894237 : move16();
2933 894237 : minSqGain = 0;
2934 894237 : move16();
2935 894237 : resQTargetBits = 0;
2936 894237 : move16();
2937 :
2938 894237 : NumIndexBits = 0;
2939 894237 : move16();
2940 894237 : sqBits = 0;
2941 894237 : move16();
2942 894237 : ctxHmBits = 0;
2943 894237 : move16();
2944 894237 : resQBits = 0;
2945 894237 : move16();
2946 894237 : prm_ltp = &prm[1 + NOISE_FILL_RANGES];
2947 894237 : prm_tns = prm_ltp + LTPSIZE;
2948 894237 : prm_hm = prm_tns + tnsSize;
2949 894237 : prm_lastnz = prm_hm + 2;
2950 894237 : sqQ = prm_hm + NPRM_CTX_HM;
2951 :
2952 894237 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
2953 : {
2954 655747 : total_brate = st->element_brate;
2955 : }
2956 : ELSE
2957 : {
2958 238490 : total_brate = st->total_brate;
2959 : }
2960 894237 : move32();
2961 : /*-----------------------------------------------------------*
2962 : * Init lengths *
2963 : *-----------------------------------------------------------*/
2964 :
2965 : /******************************************************************************************/
2966 :
2967 894237 : L_frame = st->L_frame;
2968 894237 : move16();
2969 894237 : L_frameTCX = hTcxEnc->L_frameTCX;
2970 894237 : move16();
2971 894237 : L_spec = st->hTcxCfg->tcx_coded_lines;
2972 894237 : move16();
2973 894237 : tcx_offset = st->hTcxCfg->tcx_offset;
2974 894237 : move16();
2975 :
2976 894237 : IF( EQ_16( st->core, TCX_10_CORE ) )
2977 : {
2978 33694 : L_frame = shr( L_frame, 1 );
2979 33694 : L_frameTCX = shr( L_frameTCX, 1 );
2980 33694 : L_spec = shr( L_spec, 1 );
2981 : }
2982 860543 : ELSE IF( st->last_core == ACELP_CORE )
2983 : {
2984 9260 : st->hTcxCfg->last_aldo = 0;
2985 9260 : move16();
2986 9260 : L_frame = add( L_frame, tcx_offset );
2987 9260 : L_frameTCX = add( L_frameTCX, st->hTcxCfg->tcx_offsetFB );
2988 9260 : L_spec = add( L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) );
2989 :
2990 9260 : IF( st->hTcxCfg->lfacNext < 0 )
2991 : {
2992 9260 : L_frame = sub( L_frame, st->hTcxCfg->lfacNext );
2993 9260 : L_frameTCX = sub( L_frameTCX, st->hTcxCfg->lfacNextFB );
2994 9260 : tcx_offset = st->hTcxCfg->lfacNext;
2995 9260 : move16();
2996 : }
2997 : ELSE
2998 : {
2999 0 : tcx_offset = 0;
3000 0 : move16();
3001 : }
3002 9260 : hTcxEnc->noiseLevelMemory_cnt = 0;
3003 9260 : move16();
3004 : }
3005 :
3006 894237 : *pL_frameTCX = L_frameTCX;
3007 894237 : move16();
3008 894237 : *pL_frame = L_frame;
3009 894237 : move16();
3010 894237 : *pL_spec = L_spec;
3011 894237 : move16();
3012 894237 : *ptcx_offset = tcx_offset;
3013 894237 : move16();
3014 :
3015 : /* target bitrate for SQ */
3016 894237 : sqTargetBits = sub( nb_bits, NBITS_TCX_GAIN + NBITS_NOISE_FILL_LEVEL );
3017 :
3018 894237 : IF( st->enablePlcWaveadjust )
3019 : {
3020 : Word16 L_frame_glob;
3021 0 : IF( EQ_16( st->core, TCX_20_CORE ) )
3022 : {
3023 0 : L_frame_glob = st->L_frame;
3024 0 : move16();
3025 : }
3026 : ELSE
3027 : {
3028 0 : L_frame_glob = shr( st->L_frame, 1 );
3029 : }
3030 0 : move16();
3031 0 : st->Tonal_SideInfo = DecideTonalSideInfo_fx( x_orig_fx, L_frame_glob, st->hTcxCfg->SFM2 );
3032 : }
3033 :
3034 : /* Start with the pre-shaped spectrum*/
3035 :
3036 : /*scaling buffer to Q31 if exp < 0 to avoid overflow while scaling constants*/
3037 894237 : IF( x_orig_e < 0 )
3038 : {
3039 747 : scale_sig32( x_orig_fx, L_spec, x_orig_e );
3040 747 : x_orig_e = 0;
3041 747 : move16();
3042 : }
3043 :
3044 894237 : Copy32( x_orig_fx, spectrum_fx, L_spec );
3045 894237 : *spectrum_e = x_orig_e;
3046 894237 : move16();
3047 :
3048 : /*-----------------------------------------------------------*
3049 : * Bandwidth Limitation *
3050 : *-----------------------------------------------------------*/
3051 :
3052 894237 : noiseFillingBorder = L_spec;
3053 894237 : move16();
3054 894237 : IF( st->igf )
3055 : {
3056 613793 : noiseFillingBorder = st->hIGFEnc->infoStartLine;
3057 613793 : move16();
3058 : }
3059 894237 : *pnoiseFillingBorder = noiseFillingBorder;
3060 894237 : move16();
3061 :
3062 894237 : IF( st->igf )
3063 : {
3064 92048341 : FOR( i = st->hIGFEnc->infoStopLine; i < s_max( L_frame, L_frameTCX ); i++ )
3065 : {
3066 91434548 : spectrum_fx[i] = 0;
3067 91434548 : move32();
3068 : }
3069 : }
3070 : ELSE
3071 : {
3072 16534444 : FOR( i = noiseFillingBorder; i < s_max( L_frame, L_frameTCX ); i++ )
3073 : {
3074 16254000 : spectrum_fx[i] = 0;
3075 16254000 : move32();
3076 : }
3077 : }
3078 :
3079 : /*-----------------------------------------------------------*
3080 : * Quantization *
3081 : *-----------------------------------------------------------*/
3082 :
3083 894237 : IF( !hTcxEnc->tcx_lpc_shaped_ari )
3084 : {
3085 : /* context based arithmetic coder */
3086 :
3087 : /* initialize signaling to default, i.e. context based AC is inactive */
3088 876812 : prm_hm[0] = 0;
3089 876812 : move16();
3090 876812 : prm_hm[1] = -1;
3091 876812 : move16();
3092 :
3093 : /* Fast estimation of the scalar quantizer step size */
3094 876812 : test();
3095 876812 : IF( st->hTcxCfg->ctx_hm && ( st->last_core != ACELP_CORE ) )
3096 181315 : {
3097 181315 : LtpPitchLag = -1;
3098 181315 : move16();
3099 :
3100 181315 : test();
3101 181315 : IF( ( st->tcxonly == 0 ) && ( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) ) )
3102 : {
3103 50694 : tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
3104 50694 : tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
3105 50694 : LtpPitchLag = div_l( tmp32, tmp1 );
3106 : }
3107 :
3108 181315 : ctxHmBits = add( ctxHmBits, 1 ); /* ContextHM flag */
3109 181315 : sqTargetBits = sub( sqTargetBits, 1 ); /* ContextHM flag */
3110 :
3111 : Word16 LtpGain;
3112 181315 : IF( hTcxEnc->tcxltp )
3113 : {
3114 108305 : LtpGain = hTcxEnc->tcxltp_gain;
3115 : }
3116 : ELSE
3117 : {
3118 73010 : LtpGain = -MAX_16;
3119 : }
3120 181315 : move16();
3121 181315 : PeriodicityIndex = SearchPeriodicityIndex_fx( spectrum_fx, NULL, L_spec, sqTargetBits, LtpPitchLag, LtpGain, &RelativeScore_fx );
3122 :
3123 181315 : NumIndexBits = CountIndexBits( (Word16) GE_16( L_spec, (Word16) 256 ), PeriodicityIndex );
3124 :
3125 181315 : IF( st->element_mode > EVS_MONO )
3126 : {
3127 181315 : ConfigureContextHm( L_spec, sub( sqTargetBits, NumIndexBits ), PeriodicityIndex, LtpPitchLag, hm_cfg );
3128 : }
3129 : ELSE
3130 : {
3131 0 : ConfigureContextHm( L_spec, sqTargetBits, PeriodicityIndex, LtpPitchLag, hm_cfg );
3132 : }
3133 :
3134 : /* Quantize original spectrum */
3135 181315 : sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, ( mult( hTcxEnc->tcx_target_bits_fac, shl( sqTargetBits, 1 ) ) ), L_spec, &sqGain_e );
3136 :
3137 181315 : tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
3138 :
3139 : /* Estimate original bitrate */
3140 181315 : stop = 0;
3141 181315 : move16();
3142 181315 : IF( st->element_mode > EVS_MONO )
3143 : {
3144 181315 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
3145 : }
3146 : ELSE
3147 : {
3148 0 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncoded, sqTargetBits, &stop, NULL );
3149 : }
3150 :
3151 : /* Estimate context mapped bitrate */
3152 181315 : stopCtxHm = 0;
3153 181315 : move16();
3154 :
3155 : /* Context Mapping */
3156 181315 : IF( st->element_mode > EVS_MONO )
3157 : {
3158 181315 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
3159 : }
3160 : ELSE
3161 : {
3162 0 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
3163 : }
3164 :
3165 : /* Decide whether or not to use context mapping */
3166 181315 : Selector = sub( s_max( stop, sqBits ), ( add( s_max( stopCtxHm, sqBitsCtxHm ), NumIndexBits ) ) );
3167 :
3168 181315 : test();
3169 181315 : test();
3170 181315 : IF( GT_16( Selector, 2 ) || ( LE_16( abs_s( Selector ), 2 ) && LT_16( kCtxHmOlRSThr, RelativeScore_fx ) ) )
3171 : {
3172 : /* CtxHm is likely better */
3173 12411 : sqTargetBits = sub( sqTargetBits, NumIndexBits );
3174 12411 : ctxHmBits = add( ctxHmBits, NumIndexBits );
3175 12411 : prm_hm[0] = 1;
3176 12411 : move16();
3177 12411 : prm_hm[1] = PeriodicityIndex;
3178 12411 : move16();
3179 12411 : *prm_lastnz = lastnzCtxHm;
3180 12411 : move16();
3181 12411 : sqBits_noStop = sqBits = sqBitsCtxHm;
3182 12411 : move16();
3183 12411 : move16();
3184 12411 : nEncoded = nEncodedCtxHm;
3185 12411 : move16();
3186 12411 : stop = stopCtxHm;
3187 12411 : move16();
3188 : }
3189 : ELSE
3190 : {
3191 : /* Original is better or not much difference */
3192 168904 : prm_hm[0] = 0;
3193 168904 : move16();
3194 168904 : prm_hm[1] = PeriodicityIndex;
3195 168904 : move16();
3196 168904 : *prm_lastnz = lastnz;
3197 168904 : move16();
3198 168904 : PeriodicityIndex = -1;
3199 168904 : move16();
3200 :
3201 168904 : sqBits_noStop = sqBits;
3202 168904 : move16();
3203 : }
3204 :
3205 181315 : if ( stop != 0 )
3206 : {
3207 66749 : sqBits = stop;
3208 66749 : move16();
3209 : }
3210 : }
3211 : ELSE
3212 : {
3213 : /* no context hm*/
3214 695497 : PeriodicityIndex = -1;
3215 695497 : move16();
3216 :
3217 695497 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
3218 : {
3219 655747 : Word16 scale = sub( L_norm_arr( spectrum_fx, L_spec ), 2 );
3220 655747 : scale_sig32( spectrum_fx, L_spec, scale );
3221 655747 : *spectrum_e = sub( *spectrum_e, scale );
3222 655747 : sqGain_fx = SQ_gain_estimate_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
3223 : }
3224 : ELSE
3225 : {
3226 39750 : sqGain_fx = SQ_gain_ivas_fx( spectrum_fx, *spectrum_e, shl( mult( hTcxEnc->tcx_target_bits_fac, sqTargetBits ), 1 ), L_spec, &sqGain_e );
3227 : }
3228 : /* Quantize spectrum */
3229 695497 : tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
3230 :
3231 : /* Estimate bitrate */
3232 695497 : stop = 0;
3233 695497 : move16();
3234 :
3235 695497 : IF( st->element_mode > EVS_MONO )
3236 : {
3237 695497 : sqBits_noStop = sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
3238 695497 : move16();
3239 : }
3240 : ELSE
3241 : {
3242 0 : sqBits_noStop = sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, NULL );
3243 0 : move16();
3244 : }
3245 :
3246 695497 : if ( stop != 0 )
3247 : {
3248 361622 : sqBits = stop;
3249 361622 : move16();
3250 : }
3251 : } /* end of if (ctx_hm) */
3252 :
3253 : /* Adjust correction factor */
3254 876812 : tmp1 = sqBits;
3255 876812 : move16();
3256 :
3257 876812 : if ( s_and( L_spec, sub( L_spec, 1 ) ) == 0 ) /* power-of-2 */
3258 : {
3259 0 : tmp1 = add( tmp1, 1 );
3260 : }
3261 :
3262 876812 : tmp1 = BASOP_Util_Divide1616_Scale( sqTargetBits, tmp1, &tmp2 );
3263 : BASOP_SATURATE_WARNING_OFF_EVS
3264 876812 : hTcxEnc->tcx_target_bits_fac = shl_sat( mult( hTcxEnc->tcx_target_bits_fac, tmp1 ), tmp2 );
3265 : BASOP_SATURATE_WARNING_ON_EVS
3266 :
3267 876812 : if ( GT_16( hTcxEnc->tcx_target_bits_fac, 20480 /*1.25 in Q14*/ ) )
3268 : {
3269 89848 : hTcxEnc->tcx_target_bits_fac = 20480;
3270 89848 : move16();
3271 : }
3272 876812 : if ( LT_16( hTcxEnc->tcx_target_bits_fac, 12288 /*.75 in Q14*/ ) )
3273 : {
3274 57539 : hTcxEnc->tcx_target_bits_fac = 12288;
3275 57539 : move16();
3276 : }
3277 :
3278 : /* Refine quantizer step size with a rate-control-loop (optional) */
3279 876812 : phm_cfg = NULL;
3280 876812 : move16();
3281 876812 : if ( PeriodicityIndex >= 0 )
3282 : {
3283 12411 : phm_cfg = hm_cfg;
3284 12411 : move16();
3285 : }
3286 :
3287 876812 : max_iter = 4;
3288 876812 : move16();
3289 876812 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
3290 : {
3291 655747 : max_iter = 2;
3292 655747 : move16();
3293 : }
3294 876812 : sqBits = tcx_scalar_quantization_rateloop_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, &sqGain_fx, &sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, prm_lastnz, /* lastnz */ sqTargetBits, &nEncoded, &stop, sqBits_noStop, sqBits, st->hTcxCfg->tcxRateLoopOpt, st->tcxonly, phm_cfg, max_iter, st->element_mode );
3295 :
3296 876812 : IF( ctxHmBits > 0 )
3297 : {
3298 : /* Mapping tool is enabled */
3299 : /* Truncate spectrum */
3300 181315 : FOR( i = nEncoded; i < L_spec; i++ )
3301 : {
3302 179847 : IF( st->element_mode > EVS_MONO )
3303 : {
3304 179847 : break;
3305 : }
3306 : ELSE
3307 : {
3308 0 : sqQ[i] = 0;
3309 0 : move16();
3310 : }
3311 : }
3312 :
3313 181315 : IF( PeriodicityIndex >= 0 )
3314 : {
3315 : /* Mapping is used */
3316 : /* Estimate non-mapped bitrate */
3317 12411 : stopCtxHm = 1;
3318 12411 : move16();
3319 12411 : IF( st->element_mode > EVS_MONO )
3320 : {
3321 : /* Fix: Use updated value for target bits (sqTargetBits + NumIndexBits) before computing non-mapped estimate */
3322 12411 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits + NumIndexBits, &stopCtxHm, 0, NULL );
3323 : }
3324 : ELSE
3325 : {
3326 0 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnz, &nEncodedCtxHm, sqTargetBits, &stopCtxHm, NULL );
3327 : }
3328 :
3329 : /* Decide whether or not to revert mapping */
3330 12411 : Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
3331 :
3332 12411 : IF( st->element_mode > EVS_MONO )
3333 : {
3334 12411 : test();
3335 12411 : test();
3336 12411 : IF( ( stopCtxHm == 0 && Selector > 0 ) || stop ) /* If overflow occured with mapped, select non-mapped */
3337 : {
3338 : /* Non-mapped is better */
3339 481 : sqTargetBits = add( sqTargetBits, NumIndexBits );
3340 481 : ctxHmBits = sub( ctxHmBits, NumIndexBits );
3341 481 : prm_hm[0] = 0;
3342 481 : move16();
3343 481 : *prm_lastnz = lastnz;
3344 481 : move16();
3345 481 : PeriodicityIndex = -1;
3346 481 : move16();
3347 481 : sqBits_noStop = sqBits = sqBitsCtxHm;
3348 481 : move16();
3349 481 : move16();
3350 481 : nEncoded = nEncodedCtxHm;
3351 481 : move16();
3352 481 : stop = stopCtxHm;
3353 481 : move16();
3354 : }
3355 : }
3356 : ELSE
3357 : {
3358 0 : test();
3359 0 : IF( stopCtxHm == 0 && Selector > 0 )
3360 : {
3361 : /* Non-mapped is better */
3362 0 : sqTargetBits = add( sqTargetBits, NumIndexBits );
3363 0 : ctxHmBits = sub( ctxHmBits, NumIndexBits );
3364 0 : prm_hm[0] = 0;
3365 0 : move16();
3366 0 : *prm_lastnz = lastnz;
3367 0 : move16();
3368 0 : PeriodicityIndex = -1;
3369 0 : move16();
3370 0 : sqBits_noStop = sqBits = sqBitsCtxHm;
3371 0 : move16();
3372 0 : move16();
3373 0 : nEncoded = nEncodedCtxHm;
3374 0 : move16();
3375 0 : stop = stopCtxHm;
3376 0 : move16();
3377 : }
3378 : }
3379 : }
3380 : ELSE
3381 : {
3382 : /* Mapping is not used */
3383 168904 : IF( st->element_mode > EVS_MONO )
3384 : {
3385 : /* Truncate Spectrum */
3386 87685154 : FOR( i = nEncoded; i < L_spec; i++ )
3387 : {
3388 87516250 : sqQ[i] = 0;
3389 87516250 : move16();
3390 : }
3391 : }
3392 : /* Estimate mapped bitrate */
3393 168904 : stopCtxHm = 1;
3394 168904 : move16();
3395 168904 : IF( st->element_mode > EVS_MONO )
3396 : {
3397 168904 : sqBitsCtxHm = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, 0, hm_cfg );
3398 : }
3399 : ELSE
3400 : {
3401 0 : sqBitsCtxHm = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, &lastnzCtxHm, &nEncodedCtxHm, sqTargetBits - NumIndexBits, &stopCtxHm, hm_cfg );
3402 : }
3403 :
3404 : /* Decide whether or not to use mapping */
3405 168904 : Selector = sub( sqBits, add( sqBitsCtxHm, NumIndexBits ) );
3406 168904 : test();
3407 168904 : IF( stopCtxHm == 0 && Selector > 0 )
3408 : {
3409 : /* Mapped is better */
3410 770 : sqTargetBits = sub( sqTargetBits, NumIndexBits );
3411 770 : ctxHmBits = add( ctxHmBits, NumIndexBits );
3412 770 : prm_hm[0] = 1;
3413 770 : move16();
3414 770 : *prm_lastnz = lastnzCtxHm;
3415 770 : move16();
3416 770 : PeriodicityIndex = prm_hm[1];
3417 770 : move16();
3418 770 : sqBits_noStop = sqBits = sqBitsCtxHm;
3419 770 : move16();
3420 770 : move16();
3421 770 : nEncoded = nEncodedCtxHm;
3422 770 : move16();
3423 770 : stop = stopCtxHm;
3424 770 : move16();
3425 : }
3426 : }
3427 : }
3428 :
3429 : /* Limit low sqGain for avoiding saturation of the gain quantizer*/
3430 : /*(float) sqrt( (float) NORM_MDCT_FACTOR / (float) L_spec ) in Q14 */
3431 876812 : SWITCH( L_spec )
3432 : {
3433 0 : case 80:
3434 0 : minSqGain = 23170;
3435 0 : BREAK;
3436 0 : case 100:
3437 0 : minSqGain = 20724;
3438 0 : BREAK;
3439 2446 : case 160:
3440 2446 : minSqGain = 16384;
3441 2446 : BREAK;
3442 0 : case 200:
3443 0 : minSqGain = 14654;
3444 0 : BREAK;
3445 0 : case 240:
3446 0 : minSqGain = 13377;
3447 0 : BREAK;
3448 0 : case 300:
3449 0 : minSqGain = 11965;
3450 0 : BREAK;
3451 77618 : case 320:
3452 77618 : minSqGain = 11585;
3453 77618 : BREAK;
3454 444 : case 400:
3455 444 : minSqGain = 10362;
3456 444 : BREAK;
3457 23156 : case 480:
3458 23156 : minSqGain = 9459;
3459 23156 : BREAK;
3460 0 : case 600:
3461 0 : minSqGain = 8461;
3462 0 : BREAK;
3463 215105 : case 640:
3464 215105 : minSqGain = 8192;
3465 215105 : BREAK;
3466 3155 : case 800:
3467 3155 : minSqGain = 7327;
3468 3155 : BREAK;
3469 550877 : case 960:
3470 550877 : minSqGain = 6689;
3471 550877 : BREAK;
3472 4011 : case 1200:
3473 4011 : minSqGain = 5983;
3474 4011 : BREAK;
3475 0 : case 1440:
3476 0 : minSqGain = 5461;
3477 0 : BREAK;
3478 0 : case 1800:
3479 0 : minSqGain = 4885;
3480 0 : BREAK;
3481 0 : case 2048:
3482 0 : minSqGain = 4579;
3483 0 : BREAK;
3484 0 : default:
3485 0 : assert( 0 );
3486 : }
3487 876812 : move16();
3488 876812 : Word16 shift_tmp = s_max( sqGain_e, 1 );
3489 876812 : test();
3490 876812 : IF( LT_16( st->hTcxCfg->tcxRateLoopOpt, 3 ) && LT_16( shl( sqGain_fx, sub( sqGain_e, shift_tmp ) ), shl( minSqGain, sub( 1, shift_tmp ) ) ) )
3491 : {
3492 5028 : sqGain_fx = minSqGain;
3493 5028 : move16();
3494 5028 : sqGain_e = 1;
3495 5028 : move16();
3496 :
3497 5028 : tcx_scalar_quantization_ivas_fx( spectrum_fx, *spectrum_e, sqQ, L_spec, sqGain_fx, sqGain_e, st->hTcxCfg->sq_rounding, hTcxEnc->memQuantZeros, st->tcxonly );
3498 5028 : stop = 1;
3499 5028 : IF( st->element_mode > EVS_MONO )
3500 : {
3501 : /* Ensure non-mapped estimation is used for limiting low sqGain considering that this refinement occurs very rarely */
3502 5028 : PeriodicityIndex = -1;
3503 5028 : move16();
3504 5028 : IF( prm_hm[0] == 1 )
3505 : {
3506 0 : prm_hm[0] = 0;
3507 0 : move16();
3508 0 : sqTargetBits = add( sqTargetBits, NumIndexBits );
3509 0 : ctxHmBits = sub( ctxHmBits, NumIndexBits );
3510 : }
3511 5028 : sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, 0, NULL );
3512 : }
3513 : ELSE
3514 : {
3515 0 : sqBits = ACcontextMapping_encode2_estimate_no_mem_s17_LC_fx( sqQ, L_spec, prm_lastnz, &nEncoded, sqTargetBits, &stop, PeriodicityIndex >= 0 ? hm_cfg : NULL );
3516 : }
3517 : }
3518 :
3519 : /* Truncate spectrum (for CBR) */
3520 876812 : IF( stop )
3521 : {
3522 66352227 : FOR( i = nEncoded; i < L_spec; i++ )
3523 : {
3524 66223972 : sqQ[i] = 0;
3525 66223972 : move16();
3526 : }
3527 : }
3528 :
3529 : /* Save quantized Values */
3530 876812 : *nf_seed = 0;
3531 876812 : move16();
3532 711244732 : FOR( i = 0; i < L_spec; i++ )
3533 : {
3534 710367920 : spectrum_fx[i] = (Word32) sqQ[i];
3535 710367920 : move32();
3536 : /* noise filling seed */
3537 710367920 : *nf_seed = (Word16) L_add( *nf_seed, L_mult0( abs_s( sqQ[i] ), shl( i, 1 ) ) );
3538 710367920 : move16();
3539 : }
3540 :
3541 876812 : tmp32 = L_deposit_l( 0 );
3542 711244732 : FOR( i = 0; i < L_spec; i++ )
3543 : {
3544 710367920 : spectrum_fx[i] = L_mult( sqQ[i], 1 << ( 30 - SPEC_EXP_DEC ) );
3545 710367920 : move32();
3546 : /* noise filling seed */
3547 : #ifndef FIX_ISSUE_1965_REPLACE_CARRY_OVERFLOW
3548 : tmp32 = L_macNs_co( tmp32, abs_s( sqQ[i] ), i, &Carry, &Overflow );
3549 : #else
3550 710367920 : tmp32 = L_macNs( tmp32, abs_s( sqQ[i] ), i );
3551 : #endif
3552 : }
3553 876812 : *spectrum_e = SPEC_EXP_DEC;
3554 876812 : move16();
3555 :
3556 876812 : *nf_seed = extract_l( tmp32 );
3557 : }
3558 : ELSE
3559 : {
3560 : /* low rates: envelope based arithmetic coder */
3561 :
3562 17425 : AdaptLowFreqEmph_fx( spectrum_fx, *spectrum_e, NULL, 0, 0, 1, gainlpc_fx, gainlpc_e, L_frame );
3563 :
3564 17425 : prm_target = sqQ;
3565 17425 : sqQ = prm_target + 1;
3566 :
3567 17425 : LtpPitchLag = -1;
3568 17425 : move16();
3569 :
3570 17425 : IF( LT_16( hTcxEnc->tcxltp_pitch_int, st->L_frame ) )
3571 : {
3572 7687 : tmp32 = L_shl( L_mult0( st->L_frame, st->pit_res_max ), 1 + kLtpHmFractionalResolution + 1 );
3573 7687 : tmp1 = add( imult1616( hTcxEnc->tcxltp_pitch_int, st->pit_res_max ), hTcxEnc->tcxltp_pitch_fr );
3574 7687 : LtpPitchLag = div_l( tmp32, tmp1 );
3575 : }
3576 :
3577 17425 : Word8 tmp8 = 1;
3578 17425 : move16();
3579 17425 : if ( st->last_core == ACELP_CORE )
3580 : {
3581 1650 : tmp8 = 0;
3582 1650 : move16();
3583 : }
3584 17425 : Word16 low_complexiety = 0;
3585 17425 : move16();
3586 17425 : if ( GT_16( st->bwidth, WB ) )
3587 : {
3588 16136 : low_complexiety = 1;
3589 16136 : move16();
3590 : }
3591 17425 : tcx_arith_encode_envelope_ivas_fx( spectrum_fx, spectrum_e, hm_cfg->indexBuffer, L_frame, L_spec, st, Aqind, sqTargetBits, sqQ, tmp8, prm_hm, /* HM parameter area */ LtpPitchLag, &sqBits, &signaling_bits, low_complexiety );
3592 :
3593 17425 : sqTargetBits = sub( sqTargetBits, signaling_bits );
3594 17425 : *prm_target = sqTargetBits;
3595 17425 : move16();
3596 :
3597 : /* Noise filling seed */
3598 17425 : Word64 seed = 0;
3599 17425 : move64();
3600 3645093 : FOR( i = 0; i < noiseFillingBorder; ++i )
3601 : {
3602 : /* *nf_seed += (int16_t) ( abs( (int16_t) spectrum[i] ) * i * 2 ); */
3603 3627668 : seed = W_mac_32_32( seed, L_abs( spectrum_fx[i] ), i ); // exp: spectrum_e
3604 : }
3605 17425 : *nf_seed = extract_l( W_extract_l( W_shr( seed, sub( 31, *spectrum_e ) ) ) ); // Q0
3606 17425 : move16();
3607 : }
3608 :
3609 894237 : *hm_active = prm_hm[0];
3610 894237 : move16();
3611 :
3612 : /*-----------------------------------------------------------*
3613 : * Compute optimal TCX gain. *
3614 : *-----------------------------------------------------------*/
3615 :
3616 894237 : IF( lf_deemph_fact_fx != NULL )
3617 : {
3618 : /* initialize LF deemphasis factors in lf_deemph_fact */
3619 198974810 : FOR( i = 0; i < L_spec; i++ )
3620 : {
3621 198736320 : lf_deemph_fact_fx[i] = ONE_IN_Q14;
3622 198736320 : move16();
3623 : }
3624 : }
3625 :
3626 894237 : IF( !st->tcxonly )
3627 : {
3628 129542 : AdaptLowFreqDeemph( spectrum_fx, *spectrum_e, hTcxEnc->tcx_lpc_shaped_ari, gainlpc_fx, gainlpc_e, L_frame, lf_deemph_fact_fx );
3629 : }
3630 :
3631 894237 : assert( x_orig_fx != spectrum_fx );
3632 :
3633 894237 : tcx_get_gain( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, &gain_tcx_opt_fx, &gain_tcx_opt_e, ener_fx, ener_e );
3634 :
3635 894237 : IF( gain_tcx_opt_fx <= 0 )
3636 : {
3637 2330 : gain_tcx_opt_fx = sqGain_fx;
3638 2330 : move16();
3639 2330 : gain_tcx_opt_e = sqGain_e;
3640 2330 : move16();
3641 : }
3642 894237 : *gain_tcx_fx = gain_tcx_opt_fx;
3643 894237 : move16();
3644 894237 : *gain_tcx_e = gain_tcx_opt_e;
3645 894237 : move16();
3646 :
3647 894237 : test();
3648 894237 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) || EQ_16( st->element_mode, IVAS_CPE_TD ) )
3649 : {
3650 14424 : calculate_hangover_attenuation_gain_ivas_fx( st, &att_fx, vad_hover_flag );
3651 14424 : *gain_tcx_fx = mult( *gain_tcx_fx, att_fx );
3652 14424 : move16();
3653 : }
3654 :
3655 : /*-----------------------------------------------------------*
3656 : * Quantize TCX gain *
3657 : *-----------------------------------------------------------*/
3658 :
3659 : /* gain quantization here in case of VBR unvoiced coding; fixes problems of uninitialized global gain values */
3660 894237 : test();
3661 894237 : IF( GE_32( total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
3662 : {
3663 861072 : QuantizeGain( L_spec, gain_tcx_fx, gain_tcx_e, &prm[0] );
3664 : }
3665 :
3666 : /*-----------------------------------------------------------*
3667 : * Residual Quantization *
3668 : *-----------------------------------------------------------*/
3669 :
3670 894237 : IF( st->hTcxCfg->resq )
3671 : {
3672 396033 : resQTargetBits = sub( sqTargetBits, sqBits );
3673 :
3674 396033 : IF( hTcxEnc->tcx_lpc_shaped_ari )
3675 : {
3676 : /* envelope based arithmetic coder */
3677 : Word16 *prm_resq;
3678 :
3679 17425 : prm_resq = sqQ + sub( sqTargetBits, resQTargetBits );
3680 :
3681 17425 : resQBits = tcx_ari_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, hm_cfg->indexBuffer, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, prm_resq, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact_fx );
3682 :
3683 : /* Transmit zeros when there bits remain after RESQ */
3684 18626 : FOR( i = resQBits; i < resQTargetBits; ++i )
3685 : {
3686 1201 : prm_resq[i] = 0;
3687 1201 : move16();
3688 : }
3689 : }
3690 : ELSE
3691 : {
3692 : /* context based arithmetic coder */
3693 378608 : resQBits = tcx_res_Q_gain_fx( gain_tcx_opt_fx, gain_tcx_opt_e, gain_tcx_fx, gain_tcx_e, sqQ + L_spec, resQTargetBits );
3694 378608 : IF( st->tcxonly )
3695 : {
3696 266491 : resQBits = tcx_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, NULL );
3697 : }
3698 : ELSE
3699 : {
3700 112117 : resQBits = tcx_res_Q_spec_ivas_fx( x_orig_fx, x_orig_e, spectrum_fx, *spectrum_e, L_spec, *gain_tcx_fx, *gain_tcx_e, sqQ + L_spec, resQTargetBits, resQBits, st->hTcxCfg->sq_rounding, lf_deemph_fact_fx );
3701 : }
3702 : }
3703 : }
3704 :
3705 894237 : tmp1 = norm_s( *gain_tcx_fx );
3706 894237 : *gain_tcx_fx = shl( *gain_tcx_fx, tmp1 );
3707 894237 : move16();
3708 894237 : *gain_tcx_e = sub( *gain_tcx_e, tmp1 );
3709 894237 : move16();
3710 :
3711 : /*-----------------------------------------------------------*
3712 : * ALFE tcx only bitrates *
3713 : *-----------------------------------------------------------*/
3714 :
3715 894237 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
3716 : {
3717 238490 : IF( st->tcxonly )
3718 : {
3719 108948 : test();
3720 108948 : test();
3721 108948 : IF( hTcxEnc->tcxltp && ( hTcxEnc->tcxltp_gain > 0 ) && !hTcxEnc->fUseTns[frame_cnt] )
3722 : {
3723 3730 : PsychAdaptLowFreqDeemph( spectrum_fx, gainlpc_fx, gainlpc_e, NULL );
3724 : }
3725 : }
3726 : }
3727 :
3728 894237 : return;
3729 : }
3730 :
3731 634 : void coder_tcx_fx(
3732 : Word16 n,
3733 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
3734 : Word16 A[], /* input: quantized coefficients NxAz_q[M+1] */
3735 : Word16 Aqind[], /* input: frame-independent quantized coefficients (M+1) */
3736 : Word16 synth[], /*Qx*/
3737 : Word16 L_frame_glob, /* input: frame length */
3738 : Word16 L_frameTCX_glob,
3739 : Word16 L_spec,
3740 : Word16 nb_bits, /*input: bit budget*/
3741 : Word8 tcxonly, /*input: only TCX flag*/
3742 : Word32 spectrum[], /* i/o: MDCT spectrum Q(31-spectrum_e)*/
3743 : Word16 *spectrum_e, /* i/o: MDCT spectrum exponent */
3744 : Word16 prm[], /* output: tcx parameters */
3745 : Encoder_State *st,
3746 : CONTEXT_HM_CONFIG *hm_cfg )
3747 : {
3748 : Word16 L_frame;
3749 : Word16 left_overlap, right_overlap;
3750 : Word16 tnsSize; /* number of tns parameters put into prm */
3751 : Word16 tnsBits; /* number of tns bits in the frame */
3752 : Word16 ltpBits;
3753 : Word16 gainlpc[FDNS_NPTS], gainlpc_e[FDNS_NPTS];
3754 : Word16 win[N_MAX + L_MDCT_OVLP_MAX];
3755 : Word32 powerSpec[N_MAX];
3756 : Word16 powerSpec_e;
3757 : Word16 winMDST[N_MAX + L_MDCT_OVLP_MAX];
3758 : Word16 *pWinMDST;
3759 : Word16 left_overlap_mode, right_overlap_mode;
3760 634 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
3761 :
3762 634 : left_overlap = right_overlap = -1;
3763 634 : move16();
3764 634 : move16();
3765 634 : tnsSize = 0;
3766 634 : move16();
3767 634 : tnsBits = 0;
3768 634 : move16();
3769 634 : ltpBits = 0;
3770 634 : move16();
3771 :
3772 634 : L_frame = L_frameTCX_glob;
3773 634 : move16();
3774 :
3775 : /*-----------------------------------------------------------*
3776 : * Windowing *
3777 : *-----------------------------------------------------------*/
3778 634 : IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
3779 : {
3780 :
3781 38 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, &left_overlap, &right_overlap,
3782 38 : hTcxEnc->speech_TCX, &L_frame, win, 1, 1 );
3783 :
3784 : /*-----------------------------------------------------------*
3785 : * Compute MDCT *
3786 : *-----------------------------------------------------------*/
3787 :
3788 38 : *spectrum_e = 16;
3789 38 : move16();
3790 38 : TCX_MDCT( win, spectrum, spectrum_e, left_overlap, sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
3791 : }
3792 : ELSE
3793 : {
3794 : Word32 tmp_buf[L_FRAME_PLUS];
3795 : Word16 Q, tmp1, tmp2, i;
3796 :
3797 596 : Q = 0;
3798 596 : move16();
3799 :
3800 596 : wtda_fx( hTcxEnc->new_speech_TCX, &Q, tmp_buf, NULL, NULL, hTcxCfg->tcx_last_overlap_mode, hTcxCfg->tcx_curr_overlap_mode, L_frame );
3801 :
3802 596 : left_overlap_mode = hTcxCfg->tcx_last_overlap_mode;
3803 596 : move16();
3804 596 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
3805 : {
3806 588 : left_overlap_mode = FULL_OVERLAP;
3807 588 : move16();
3808 : }
3809 596 : right_overlap_mode = hTcxCfg->tcx_curr_overlap_mode;
3810 596 : move16();
3811 596 : if ( EQ_16( right_overlap_mode, ALDO_WINDOW ) )
3812 : {
3813 585 : right_overlap_mode = FULL_OVERLAP;
3814 585 : move16();
3815 : }
3816 :
3817 596 : WindowSignal( hTcxCfg, hTcxCfg->tcx_offsetFB, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, hTcxEnc->speech_TCX, &L_frame, winMDST, 1, 1 );
3818 :
3819 : /* scale by NORM_MDCT_FACTOR / L */
3820 596 : tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
3821 596 : tmp2 = 4;
3822 596 : move16();
3823 596 : tmp1 = ISqrt16( tmp1, &tmp2 );
3824 :
3825 493716 : FOR( i = 0; i < L_frame; i++ )
3826 : {
3827 493120 : tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
3828 493120 : move32();
3829 : }
3830 596 : Q = sub( Q, tmp2 );
3831 :
3832 : /* DCT */
3833 596 : edct_fx( tmp_buf, spectrum, L_frame, &Q );
3834 596 : *spectrum_e = sub( 31, Q );
3835 596 : move16();
3836 : }
3837 :
3838 :
3839 : /*-----------------------------------------------------------*
3840 : * Attenuate upper end of NB spectrum, *
3841 : * to simulate ACELP behavior *
3842 : *-----------------------------------------------------------*/
3843 :
3844 634 : IF( st->narrowBand != 0 )
3845 : {
3846 0 : attenuateNbSpectrum_fx( L_frame, spectrum );
3847 : }
3848 :
3849 : /*-----------------------------------------------------------*
3850 : * Compute noise-measure flags for spectrum filling *
3851 : * and quantization (0: tonal, 1: noise-like). *
3852 : * Detect low pass if present. *
3853 : *-----------------------------------------------------------*/
3854 :
3855 634 : pWinMDST = winMDST;
3856 634 : move16();
3857 634 : if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
3858 : {
3859 38 : pWinMDST = win;
3860 38 : move16();
3861 : }
3862 :
3863 634 : AnalyzePowerSpectrum_fx( st,
3864 634 : round_fx( L_shl( Mpy_32_16_1( L_mult0( L_frame, st->L_frame ) /*Q0*/,
3865 634 : getInvFrameLen( hTcxEnc->L_frameTCX ) /*Q21*/ ) /*Q6*/,
3866 : 16 - 6 ) ),
3867 : L_frame,
3868 : left_overlap, right_overlap,
3869 634 : spectrum, *spectrum_e,
3870 : pWinMDST,
3871 : powerSpec, &powerSpec_e );
3872 634 : IF( hTcxCfg->fIsTNSAllowed != 0 )
3873 : {
3874 :
3875 372 : SetTnsConfig( hTcxCfg, sub( L_frame_glob, st->L_frame ) == 0, st->last_core == 0 );
3876 :
3877 372 : TNSAnalysis_fx( hTcxCfg, L_frame, L_spec, TCX_20, st->last_core == 0, spectrum, hTcxEnc->tnsData, hTcxEnc->fUseTns, &st->hIGFEnc->tns_predictionGain );
3878 : }
3879 : ELSE
3880 : {
3881 262 : hTcxEnc->fUseTns[0] = hTcxEnc->fUseTns[1] = 0;
3882 262 : move16();
3883 262 : move16();
3884 : }
3885 :
3886 634 : IF( st->igf )
3887 : {
3888 634 : ProcessIGF_fx( st->hIGFEnc, st, spectrum, spectrum_e, powerSpec, &powerSpec_e, 1, hTcxEnc->fUseTns[0], ( st->last_core == ACELP_CORE ), 0 );
3889 : }
3890 :
3891 634 : ShapeSpectrum_fx( hTcxCfg, A, gainlpc, gainlpc_e,
3892 : L_frame_glob,
3893 : L_spec,
3894 : spectrum,
3895 634 : hTcxEnc->fUseTns[0],
3896 : st );
3897 634 : if ( st->igf )
3898 : {
3899 634 : nb_bits = sub( nb_bits, st->hIGFEnc->infoTotalBitsPerFrameWritten );
3900 : }
3901 634 : IF( hTcxCfg->fIsTNSAllowed != 0 )
3902 : {
3903 372 : EncodeTnsData_fx( hTcxCfg->pCurrentTnsConfig, hTcxEnc->tnsData, prm + 1 + NOISE_FILL_RANGES + LTPSIZE, &tnsSize, &tnsBits );
3904 : }
3905 :
3906 634 : QuantizeSpectrum_fx( hTcxCfg,
3907 : A,
3908 : Aqind,
3909 : gainlpc, gainlpc_e,
3910 : synth,
3911 : L_frame_glob,
3912 : L_frameTCX_glob,
3913 : L_spec,
3914 634 : sub( sub( nb_bits, tnsBits ), ltpBits ),
3915 : tcxonly,
3916 : spectrum, spectrum_e,
3917 634 : hTcxEnc->tnsData,
3918 634 : hTcxEnc->fUseTns[0],
3919 : tnsSize,
3920 : prm,
3921 : n,
3922 : st,
3923 : hm_cfg );
3924 634 : }
3925 :
3926 :
3927 : /*-------------------------------------------------------------------*
3928 : * coder_tcx_post_fx()
3929 : *
3930 : *
3931 : *-------------------------------------------------------------------*/
3932 :
3933 634 : void coder_tcx_post_fx(
3934 : Encoder_State *st,
3935 : LPD_state *LPDmem,
3936 : TCX_CONFIG_HANDLE hTcxCfg,
3937 : /* i : configuration of TCX */ Word16 *synth,
3938 : const Word16 *A,
3939 : const Word16 *Ai,
3940 : Word16 *wsig,
3941 : Word16 Q_new,
3942 : Word16 shift )
3943 : {
3944 : Word16 xn_buf[L_FRAME_MAX];
3945 :
3946 : /* TCX output */
3947 634 : Copy( synth, xn_buf, st->L_frame );
3948 :
3949 :
3950 : /*-----------------------------------------------------------*
3951 : * Memory update *
3952 : *-----------------------------------------------------------*/
3953 :
3954 : /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
3955 634 : tcx_encoder_memory_update_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new, shift );
3956 :
3957 634 : return;
3958 : }
3959 236431 : void coder_tcx_post_ivas_fx(
3960 : Encoder_State *st,
3961 : LPD_state *LPDmem,
3962 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
3963 : Word16 *synth,
3964 : const Word16 *A,
3965 : const Word16 *Ai,
3966 : Word16 *wsig,
3967 : Word16 Q_new )
3968 : {
3969 : Word16 xn_buf[L_FRAME_MAX];
3970 :
3971 : /* TCX output */
3972 236431 : Copy( synth, xn_buf, st->L_frame );
3973 :
3974 :
3975 : /*-----------------------------------------------------------*
3976 : * Memory update *
3977 : *-----------------------------------------------------------*/
3978 :
3979 : /* Update LPDmem (Txnq,syn,syn_pe,old_exc,wsyn,Ai,Aq) */
3980 236431 : tcx_encoder_memory_update_ivas_fx( wsig, xn_buf, st->L_frame, Ai, A, hTcxCfg->preemph_fac, LPDmem, st, synth, Q_new );
3981 :
3982 236431 : return;
3983 : }
3984 :
3985 :
3986 : /*-------------------------------------------------------------------*
3987 : * InternalTCXDecoder_fx()
3988 : *
3989 : *
3990 : *-------------------------------------------------------------------*/
3991 :
3992 238490 : void InternalTCXDecoder_fx(
3993 : Encoder_State *st, /* i/o: state handle */
3994 : const Word16 frame_cnt, /* i : frame counter in the super_frame */
3995 : const Word16 L_frameTCX, /* i : full frame length */
3996 : const Word16 L_frame, /* i : frame length */
3997 : const Word16 L_spec, /* i : length of the coded spectrum */
3998 : const Word16 tcx_offset, /* i : folding point offset relative to the end of the previous frame */
3999 : const Word16 noiseFillingBorder, /* i : noise filling border */
4000 : const Word32 *x_quant_fx, /* i : quantized spectrum, exponent same as spectrum_e */
4001 : const Word32 ener_fx, /* i : energy of the quantized spectrum Q(31-ener_e) */
4002 : const Word16 ener_e, /* i : exponent of energy of the quantized spectrum */
4003 : Word16 lf_deemph_fact_fx[], /* i/o: low frequency deemphasis factors */
4004 : const Word16 fac_ns_fx, /* i : noise filling level, Q15 */
4005 : const Word16 nf_seed, /* i : noise filling random seed, Q0 */
4006 : const Word16 *A_fx, /* i : LPC representation of the FDNS gains, Q = 14 - norm_s(A_fx[0]) */
4007 : Word16 gainlpc_fx[], /* i/o: FDNS gains Q(15-gainlpc_e) */
4008 : Word16 gainlpc_e[], /* i/o: FDNS gains exponents */
4009 : const Word16 hm_active, /* i : flag indicating if the harmonic model is active */
4010 : Word16 gain_tcx_fx, /* i/o: global gain / quantized global gain Q(15-gain_tcx_e) */
4011 : Word16 *gain_tcx_e, /* i/o: global gain / quantized global gain exponent */
4012 : Word32 spectrum_fx[], /* o : dequantized spectrum Q(31-spectrum_e) */
4013 : Word16 *spectrum_e, /* o : exponent of dequantized spectrum */
4014 : Word16 synth[], /* o : time domain signal */
4015 : Word16 *gain_tcx_q /* o : quantized global gain (at low bitrates), Q0 */
4016 : )
4017 : {
4018 238490 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
4019 : Word16 i, iStart, noiseTransWidth;
4020 : Word16 tcx_last_overlap_mode, overlap;
4021 : Word16 nz; /* non-zero length in ALDO window*/
4022 : Word16 aldo; /* ALDO flag in current frame*/
4023 : Word16 tmp1, tmp2, tmp3, tmp4, s;
4024 : Word16 *tmpP16;
4025 : Word16 q_spec, len;
4026 : Word32 tmp32;
4027 : Word32 xn_buf32[L_MDCT_OVLP_MAX + L_FRAME_PLUS + L_MDCT_OVLP_MAX];
4028 : Word16 Aq_old_fx[M + 1];
4029 : Word32 sns_interpolated_scalefactors_fx[FDNS_NPTS], A_fx32[M + 1];
4030 238490 : Word16 *xn_buf16 = (Word16 *) xn_buf32;
4031 :
4032 238490 : Copy32( x_quant_fx, spectrum_fx, s_max( L_frame, L_spec ) );
4033 :
4034 : /* Replication of ACELP formant enhancement for low rates */
4035 238490 : test();
4036 238490 : IF( st->total_brate < ACELP_13k20 || st->rf_mode )
4037 : {
4038 33165 : tcxFormantEnhancement( lf_deemph_fact_fx, gainlpc_fx, gainlpc_e, spectrum_fx, spectrum_e, L_frame, L_spec );
4039 : }
4040 :
4041 : /*-----------------------------------------------------------*
4042 : * Noise Filling. *
4043 : *-----------------------------------------------------------*/
4044 :
4045 238490 : IF( fac_ns_fx > 0 )
4046 : {
4047 219880 : tmp1 = 0;
4048 219880 : move16();
4049 219880 : test();
4050 219880 : if ( GE_32( st->total_brate, ACELP_13k20 ) && st->rf_mode == 0 )
4051 : {
4052 186878 : tmp1 = 1;
4053 186878 : move16();
4054 : }
4055 219880 : iStart = tcxGetNoiseFillingTilt( A_fx, M, L_frame, tmp1, &hTcxEnc->noiseTiltFactor );
4056 :
4057 219880 : tmp1 = 0;
4058 219880 : move16();
4059 219880 : test();
4060 219880 : test();
4061 219880 : if ( st->hTcxCfg->ctx_hm && st->last_core != ACELP_CORE && hm_active )
4062 : {
4063 12643 : tmp1 = 1;
4064 12643 : move16();
4065 : }
4066 219880 : noiseTransWidth = GetTransWidth_ivas_fx( st->tcxonly, (Word16) EQ_16( L_frame, shr( st->L_frame, 1 ) ), hTcxEnc->tcxltp_gain, tmp1 );
4067 219880 : assert( st->element_mode != IVAS_CPE_MDCT );
4068 219880 : tcx_noise_filling( spectrum_fx, *spectrum_e, nf_seed, iStart, noiseFillingBorder, noiseTransWidth, L_frame, hTcxEnc->noiseTiltFactor, fac_ns_fx, NULL, st->element_mode );
4069 : }
4070 :
4071 238490 : test();
4072 238490 : IF( LT_32( st->total_brate, ACELP_13k20 ) || st->rf_mode != 0 )
4073 : {
4074 : /* partially recompute global gain (energy part), taking noise filling and formant enhancement into account */
4075 33165 : s = sub( getScaleFactor32( spectrum_fx, L_spec ), 4 );
4076 33165 : tmp32 = L_deposit_l( 1 );
4077 :
4078 21383405 : FOR( i = 0; i < L_spec; i++ )
4079 : {
4080 21350240 : tmp1 = round_fx( L_shl( spectrum_fx[i], s ) );
4081 21350240 : tmp32 = L_mac0( tmp32, tmp1, tmp1 );
4082 : }
4083 :
4084 33165 : tmp1 = BASOP_Util_Divide3232_Scale( ener_fx, tmp32, &tmp2 );
4085 33165 : tmp2 = add( tmp2, sub( ener_e, add( shl( sub( *spectrum_e, s ), 1 ), 1 ) ) );
4086 33165 : tmp1 = Sqrt16( tmp1, &tmp2 );
4087 :
4088 33165 : gain_tcx_fx = mult( gain_tcx_fx, tmp1 ); // Q(15-(gain_tcx_e+tmp2))
4089 33165 : *gain_tcx_e = add( *gain_tcx_e, tmp2 );
4090 33165 : move16();
4091 :
4092 33165 : QuantizeGain( L_spec, &gain_tcx_fx, gain_tcx_e, gain_tcx_q );
4093 : }
4094 :
4095 : /*end of noise filling*/
4096 :
4097 : /*-----------------------------------------------------------*
4098 : * Noise shaping in frequency domain (1/Wz) *
4099 : *-----------------------------------------------------------*/
4100 :
4101 238490 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
4102 : {
4103 0 : Copy_Scale_sig_16_32_DEPREC( A_fx, A_fx32, M + 1, add( norm_s( A_fx[0] ), 2 ) ); // Copying the Word16 A_fx buffer to a temporary Word32 buffer in Q16
4104 :
4105 0 : q_spec = sub( 31, *spectrum_e );
4106 0 : sns_interpolate_scalefactors_fx( sns_interpolated_scalefactors_fx, A_fx32, DEC );
4107 0 : sns_shape_spectrum_fx( spectrum_fx, &q_spec, st->hTcxCfg->psychParamsCurrent, sns_interpolated_scalefactors_fx, Q16, L_frame, &len );
4108 :
4109 0 : test();
4110 0 : test();
4111 0 : IF( NE_16( len, L_frame ) && LT_16( q_spec, sub( 31, *spectrum_e ) ) )
4112 : {
4113 0 : scale_sig32( spectrum_fx + len, sub( L_frame, len ), sub( q_spec, sub( 15, *spectrum_e ) ) ); // q_spec
4114 : }
4115 0 : ELSE IF( NE_16( len, L_frame ) && GT_16( q_spec, sub( 31, *spectrum_e ) ) )
4116 : {
4117 0 : scale_sig32( spectrum_fx, len, sub( sub( 15, *spectrum_e ), q_spec ) ); // Q(31-spectrum_e)
4118 0 : q_spec = sub( 31, *spectrum_e );
4119 : }
4120 0 : *spectrum_e = sub( 31, q_spec );
4121 0 : move16();
4122 : }
4123 : ELSE
4124 : {
4125 238490 : mdct_noiseShaping_ivas_fx( spectrum_fx, spectrum_e, L_frame, gainlpc_fx, gainlpc_e );
4126 : }
4127 : /*-----------------------------------------------------------*
4128 : * Apply gain *
4129 : *-----------------------------------------------------------*/
4130 :
4131 238490 : IF( st->hTcxCfg->coder_type == INACTIVE )
4132 : {
4133 13505 : gain_tcx_fx = mult_r( gain_tcx_fx, st->hTcxCfg->na_scale );
4134 : }
4135 :
4136 198974810 : FOR( i = 0; i < L_spec; i++ )
4137 : {
4138 198736320 : spectrum_fx[i] = Mpy_32_16_1( spectrum_fx[i], gain_tcx_fx );
4139 198736320 : move32();
4140 : }
4141 238490 : *spectrum_e = add( *spectrum_e, *gain_tcx_e );
4142 238490 : move16();
4143 :
4144 238490 : tcx_last_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /* backup last TCX overlap mode */
4145 238490 : move16();
4146 :
4147 238490 : test();
4148 238490 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
4149 : {
4150 4118 : Word16 L = L_frame;
4151 4118 : move16();
4152 :
4153 4118 : test();
4154 4118 : test();
4155 4118 : if ( ( ( st->hTcxCfg->fIsTNSAllowed != 0 ) && ( hTcxEnc->fUseTns[frame_cnt] != 0 ) ) || ( GT_16( L_spec, L_frame ) ) )
4156 : {
4157 4018 : L = L_spec;
4158 4018 : move16();
4159 : }
4160 :
4161 4118 : tcxInvertWindowGrouping( st->hTcxCfg,
4162 : xn_buf32,
4163 : spectrum_fx,
4164 : L,
4165 4118 : hTcxEnc->fUseTns[frame_cnt],
4166 4118 : st->last_core,
4167 : tcx_last_overlap_mode,
4168 : frame_cnt,
4169 : 0 );
4170 : }
4171 :
4172 : /*-----------------------------------------------------------*
4173 : * Temporal Noise Shaping Synthesis *
4174 : *-----------------------------------------------------------*/
4175 :
4176 238490 : IF( st->hTcxCfg->fIsTNSAllowed )
4177 : {
4178 161621 : test();
4179 161621 : SetTnsConfig( st->hTcxCfg, (Word16) EQ_16( st->core, TCX_20_CORE ), ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) );
4180 :
4181 : /* Apply TNS to get the reconstructed signal */
4182 161621 : IF( hTcxEnc->fUseTns[frame_cnt] != 0 )
4183 : {
4184 17629 : ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frame_cnt], spectrum_fx, 0 );
4185 :
4186 17629 : test();
4187 17629 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
4188 : {
4189 2365 : test();
4190 2365 : test();
4191 2365 : test();
4192 2365 : IF( ( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) ||
4193 : ( ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( frame_cnt == 0 ) && ( tcx_last_overlap_mode == 0 ) ) )
4194 : {
4195 1717 : const Word16 L_win = shr( L_spec, 1 );
4196 : /* undo rearrangement of LF sub-window lines for TNS synthesis filter */
4197 1717 : IF( GT_16( L_frame, L_spec ) )
4198 : {
4199 0 : assert( 0 );
4200 : }
4201 : ELSE
4202 : {
4203 1717 : Copy32( spectrum_fx + 8, xn_buf32, L_win );
4204 1717 : Copy32( xn_buf32, spectrum_fx + L_win, 8 );
4205 1717 : Copy32( xn_buf32 + 8, spectrum_fx + 8, L_win - 8 );
4206 : }
4207 : }
4208 : }
4209 : }
4210 : }
4211 :
4212 :
4213 : /*-----------------------------------------------------------*
4214 : * Compute inverse MDCT of spectrum[]. *
4215 : *-----------------------------------------------------------*/
4216 :
4217 238490 : E_LPC_f_lsp_a_conversion( st->lsp_old_fx, Aq_old_fx, M );
4218 238490 : overlap = st->hTcxCfg->tcx_mdct_window_length;
4219 238490 : nz = NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS );
4220 238490 : aldo = 0;
4221 238490 : move16();
4222 238490 : move16();
4223 :
4224 : /* normalize spectrum to minimize IMDCT noise */
4225 238490 : s = getScaleFactor32( spectrum_fx, L_frame );
4226 106113610 : FOR( i = 0; i < L_frame; i++ )
4227 : {
4228 105875120 : spectrum_fx[i] = L_shl( spectrum_fx[i], s );
4229 105875120 : move32();
4230 : }
4231 238490 : *spectrum_e = sub( *spectrum_e, s );
4232 238490 : move16();
4233 :
4234 238490 : test();
4235 238490 : IF( ( EQ_16( L_frame, shr( st->L_frame, 1 ) ) ) && ( st->tcxonly != 0 ) )
4236 : {
4237 4118 : IF( st->hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP )
4238 : {
4239 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
4240 : Word16 L_win, L_spec_TCX5, L_ola, w;
4241 :
4242 : /* minimum or half overlap, two transforms, grouping into one window */
4243 1601 : L_win = shr( L_frame, 1 );
4244 1601 : L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
4245 1601 : L_ola = st->hTcxCfg->tcx_mdct_window_half_length;
4246 1601 : move16();
4247 1601 : if ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
4248 : {
4249 770 : L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
4250 770 : move16();
4251 : }
4252 :
4253 1601 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
4254 1601 : set16_fx( xn_buf16, 0, add( tcx_offset, shr( L_ola, 1 ) ) ); /* zero left end of buffer */
4255 :
4256 4803 : FOR( w = 0; w < 2; w++ )
4257 : {
4258 :
4259 3202 : IF( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) )
4260 : {
4261 1540 : TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
4262 1540 : win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
4263 : }
4264 : ELSE
4265 : {
4266 1662 : TCX_MDCT_Inverse( spectrum_fx + L_mult0( w, L_spec_TCX5 ), sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ), win,
4267 1662 : L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
4268 : }
4269 :
4270 3202 : tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
4271 3202 : move16();
4272 3202 : test();
4273 3202 : test();
4274 3202 : if ( ( w > 0 ) || ( ( w == 0 ) && ( EQ_16( tcx_last_overlap_mode, 2 ) ) ) )
4275 : {
4276 1942 : tmp1 = MIN_OVERLAP;
4277 1942 : move16();
4278 : }
4279 :
4280 3202 : tmp2 = 0;
4281 3202 : move16();
4282 3202 : test();
4283 3202 : if ( ( w == 0 ) && ( st->last_core == ACELP_CORE ) )
4284 : {
4285 0 : tmp2 = 1;
4286 0 : move16();
4287 : }
4288 :
4289 3202 : tmp3 = st->last_core;
4290 3202 : move16();
4291 3202 : if ( w > 0 )
4292 : {
4293 1601 : tmp3 = 1;
4294 1601 : move16();
4295 : }
4296 :
4297 3202 : tmp4 = 0;
4298 3202 : move16();
4299 3202 : if ( tcx_offset < 0 )
4300 : {
4301 0 : tmp4 = negate( tcx_offset );
4302 : }
4303 :
4304 3202 : tcx_windowing_synthesis_current_frame( win,
4305 3202 : st->hTcxCfg->tcx_aldo_window_2,
4306 3202 : st->hTcxCfg->tcx_mdct_window_half,
4307 3202 : st->hTcxCfg->tcx_mdct_window_minimum,
4308 : L_ola,
4309 3202 : st->hTcxCfg->tcx_mdct_window_half_length,
4310 3202 : st->hTcxCfg->tcx_mdct_window_min_length,
4311 : tmp2,
4312 : tmp1,
4313 : hTcxEnc->acelp_zir,
4314 3202 : hTcxEnc->Txnq,
4315 : NULL,
4316 : Aq_old_fx,
4317 3202 : st->hTcxCfg->tcx_mdct_window_trans,
4318 : L_win,
4319 : tmp4,
4320 : tmp3,
4321 : 0,
4322 : 0 );
4323 :
4324 3202 : tmp1 = add( tcx_offset, imult1616( w, L_win ) );
4325 3202 : move16();
4326 3202 : tmpP16 = xn_buf16 + sub( tmp1, shr( L_ola, 1 ) );
4327 :
4328 3202 : IF( w > 0 )
4329 : {
4330 1601 : tcx_windowing_synthesis_past_frame( tmpP16,
4331 1601 : st->hTcxCfg->tcx_aldo_window_1_trunc,
4332 1601 : st->hTcxCfg->tcx_mdct_window_half,
4333 1601 : st->hTcxCfg->tcx_mdct_window_minimum,
4334 : L_ola,
4335 1601 : st->hTcxCfg->tcx_mdct_window_half_length,
4336 1601 : st->hTcxCfg->tcx_mdct_window_min_length,
4337 : 2 );
4338 : }
4339 : /* add part of current sub-window overlapping with previous window */
4340 263522 : FOR( i = 0; i < L_ola; i++ )
4341 : {
4342 260320 : tmpP16[i] = add_sat( tmpP16[i], win[i] );
4343 260320 : move16();
4344 : }
4345 : /* copy new sub-window region not overlapping with previous window */
4346 3202 : Copy( win + L_ola, xn_buf16 + add( tmp1, shr( L_ola, 1 ) ), L_win );
4347 : }
4348 : /* To assure that no garbage values are copied to hLPDmem->Txnq */
4349 1601 : set16_fx( xn_buf16 + add( add( L_frame, tcx_offset ), shr( L_ola, 1 ) ),
4350 1601 : 0, sub( sub( overlap, tcx_offset ), shr( L_ola, 1 ) ) );
4351 : }
4352 2517 : ELSE IF( s_and( frame_cnt == 0, ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) ) )
4353 : {
4354 : /* special overlap attempt, two transforms, grouping into one window */
4355 : Word16 win[( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2];
4356 : Word16 L_win, L_spec_TCX5, L_ola, w;
4357 :
4358 596 : L_win = shr( L_frame, 1 );
4359 596 : L_spec_TCX5 = shr( s_max( L_frame, L_spec ), 1 );
4360 596 : L_ola = st->hTcxCfg->tcx_mdct_window_min_length;
4361 596 : move16();
4362 :
4363 596 : set16_fx( win, 0, ( L_FRAME_PLUS + L_MDCT_OVLP_MAX ) / 2 );
4364 :
4365 : /* Resize overlap (affect only asymmetric window)*/
4366 596 : overlap = st->hTcxCfg->tcx_mdct_window_delay;
4367 : /* 1st TCX-5 window, special MDCT with minimum overlap on right side */
4368 596 : TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
4369 596 : win + L_win, 0, sub( L_win, shr( L_ola, 1 ) ), L_ola, st->element_mode );
4370 :
4371 : /* copy new sub-window region not overlapping with previous window */
4372 596 : Copy( win + L_win, xn_buf16 + shr( overlap, 1 ), add( L_win, shr( L_ola, 1 ) ) );
4373 :
4374 : /* 2nd TCX-5 window, regular MDCT with minimum overlap on both sides */
4375 :
4376 596 : TCX_MDCT_Inverse( spectrum_fx + L_spec_TCX5, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
4377 596 : win, L_ola, sub( L_win, L_ola ), L_ola, st->element_mode );
4378 :
4379 596 : tmp4 = 0;
4380 596 : move16();
4381 596 : if ( tcx_offset < 0 )
4382 : {
4383 0 : tmp4 = negate( tcx_offset );
4384 : }
4385 596 : tcx_windowing_synthesis_current_frame( win,
4386 596 : st->hTcxCfg->tcx_aldo_window_2,
4387 596 : st->hTcxCfg->tcx_mdct_window_half,
4388 596 : st->hTcxCfg->tcx_mdct_window_minimum,
4389 : L_ola,
4390 596 : st->hTcxCfg->tcx_mdct_window_half_length,
4391 596 : st->hTcxCfg->tcx_mdct_window_min_length,
4392 : 0, /* left_rect */
4393 : 2, /* left_mode */
4394 : hTcxEnc->acelp_zir,
4395 596 : hTcxEnc->Txnq,
4396 : NULL,
4397 : Aq_old_fx,
4398 596 : st->hTcxCfg->tcx_mdct_window_trans,
4399 : L_win,
4400 : tmp4,
4401 : 1, /* not LPDmem->mode */
4402 : 0,
4403 : 0 );
4404 :
4405 :
4406 596 : tmpP16 = xn_buf16 + add( sub( L_win, shr( L_ola, 1 ) ), shr( overlap, 1 ) );
4407 :
4408 596 : tcx_windowing_synthesis_past_frame( tmpP16,
4409 596 : st->hTcxCfg->tcx_aldo_window_1_trunc,
4410 596 : st->hTcxCfg->tcx_mdct_window_half,
4411 596 : st->hTcxCfg->tcx_mdct_window_minimum,
4412 : L_ola,
4413 596 : st->hTcxCfg->tcx_mdct_window_half_length,
4414 596 : st->hTcxCfg->tcx_mdct_window_min_length,
4415 : 2 );
4416 :
4417 : /* add part of current sub-window overlapping with previous window */
4418 24316 : FOR( i = 0; i < L_ola; i++ )
4419 : {
4420 23720 : tmpP16[i] = add_sat( tmpP16[i], win[i] );
4421 23720 : move16();
4422 : }
4423 :
4424 : /* copy new sub-window region not overlapping with previous window */
4425 1192 : Copy( win + L_ola,
4426 596 : xn_buf16 + add( add( shr( overlap, 1 ), shr( L_ola, 1 ) ), L_win ),
4427 : L_win );
4428 :
4429 : /* extra folding-out on left side of win, for perfect reconstruction */
4430 83616 : FOR( w = shr( overlap, 1 ); w < overlap; w++ )
4431 : {
4432 83020 : xn_buf16[overlap - 1 - w] = negate( xn_buf16[w] );
4433 83020 : move16();
4434 : }
4435 :
4436 596 : tmp4 = 0;
4437 596 : move16();
4438 596 : if ( tcx_offset < 0 )
4439 : {
4440 0 : tmp4 = negate( tcx_offset );
4441 : }
4442 596 : tcx_windowing_synthesis_current_frame( xn_buf16,
4443 596 : st->hTcxCfg->tcx_aldo_window_2,
4444 596 : st->hTcxCfg->tcx_mdct_window_half,
4445 596 : st->hTcxCfg->tcx_mdct_window_minimum,
4446 : overlap,
4447 596 : st->hTcxCfg->tcx_mdct_window_half_length,
4448 596 : st->hTcxCfg->tcx_mdct_window_min_length,
4449 596 : st->last_core == ACELP_CORE,
4450 : 0,
4451 : hTcxEnc->acelp_zir,
4452 596 : hTcxEnc->Txnq,
4453 : NULL,
4454 : Aq_old_fx,
4455 596 : st->hTcxCfg->tcx_mdct_window_trans,
4456 : L_win,
4457 : tmp4,
4458 596 : st->last_core,
4459 : 0,
4460 : 0 );
4461 : }
4462 : ELSE /* default, i.e. maximum overlap, single transform, no grouping */
4463 : {
4464 :
4465 1921 : TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
4466 1921 : xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
4467 :
4468 1921 : tmp1 = tcx_last_overlap_mode;
4469 1921 : move16();
4470 1921 : test();
4471 1921 : test();
4472 1921 : if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->last_core != ACELP_CORE ) )
4473 : {
4474 596 : tmp1 = 2;
4475 596 : move16();
4476 : }
4477 :
4478 1921 : tmp4 = 0;
4479 1921 : move16();
4480 1921 : if ( tcx_offset < 0 )
4481 : {
4482 0 : tmp4 = negate( tcx_offset );
4483 : }
4484 3842 : tcx_windowing_synthesis_current_frame( xn_buf16,
4485 1921 : st->hTcxCfg->tcx_aldo_window_2,
4486 1921 : st->hTcxCfg->tcx_mdct_window_half,
4487 1921 : st->hTcxCfg->tcx_mdct_window_minimum,
4488 : overlap, /*hTcxCfg->tcx_mdct_window_length*/
4489 1921 : st->hTcxCfg->tcx_mdct_window_half_length,
4490 1921 : st->hTcxCfg->tcx_mdct_window_min_length,
4491 1921 : st->last_core == ACELP_CORE,
4492 : tmp1,
4493 : hTcxEnc->acelp_zir,
4494 1921 : hTcxEnc->Txnq,
4495 : NULL,
4496 : Aq_old_fx,
4497 1921 : st->hTcxCfg->tcx_mdct_window_trans,
4498 1921 : shr( st->L_frame, 2 ),
4499 : tmp4,
4500 1921 : st->last_core,
4501 : 0,
4502 : 0 );
4503 :
4504 : } /* tcx_last_overlap_mode > 0 */
4505 : }
4506 : ELSE /* frame is TCX-20 or not TCX-only */
4507 : {
4508 234372 : IF( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
4509 : {
4510 : Word32 tmp_buf[L_FRAME_PLUS];
4511 : Word16 Q;
4512 :
4513 : /* DCT */
4514 226441 : Q = sub( 31, *spectrum_e );
4515 226441 : edct_ivas_fx( spectrum_fx, tmp_buf, L_frame, &Q );
4516 :
4517 : /* scale by sqrt(L / NORM_MDCT_FACTOR) */
4518 226441 : tmp1 = mult_r( shl( L_frame, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
4519 226441 : tmp2 = 4;
4520 226441 : move16();
4521 226441 : tmp1 = Sqrt16( tmp1, &tmp2 );
4522 :
4523 101797001 : FOR( i = 0; i < L_frame; i++ )
4524 : {
4525 101570560 : tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 );
4526 101570560 : move32();
4527 : }
4528 226441 : Q = sub( Q, tmp2 );
4529 :
4530 :
4531 226441 : window_ola_fx( tmp_buf,
4532 : xn_buf16,
4533 : &Q,
4534 226441 : hTcxEnc->old_out_fx,
4535 : &hTcxEnc->Q_old_out,
4536 : L_frame,
4537 226441 : st->hTcxCfg->tcx_last_overlap_mode,
4538 226441 : st->hTcxCfg->tcx_curr_overlap_mode,
4539 : 0,
4540 : 0,
4541 : NULL );
4542 :
4543 : /* scale output */
4544 101797001 : FOR( i = 0; i < L_frame; i++ )
4545 : {
4546 101570560 : xn_buf16[i] = shr_sat( xn_buf16[i], Q );
4547 101570560 : move16();
4548 : }
4549 :
4550 226441 : aldo = 1;
4551 226441 : move16();
4552 : }
4553 : ELSE
4554 : {
4555 :
4556 7931 : TCX_MDCT_Inverse( spectrum_fx, sub( *spectrum_e, TCX_IMDCT_SCALE + TCX_IMDCT_HEADROOM ),
4557 7931 : xn_buf16, overlap, sub( L_frame, overlap ), overlap, st->element_mode );
4558 :
4559 : /*-----------------------------------------------------------*
4560 : * Windowing, overlap and add *
4561 : *-----------------------------------------------------------*/
4562 :
4563 : /* Window current frame */
4564 7931 : tmp4 = 0;
4565 7931 : move16();
4566 7931 : if ( tcx_offset < 0 )
4567 : {
4568 7931 : tmp4 = negate( tcx_offset );
4569 : }
4570 15862 : tcx_windowing_synthesis_current_frame( xn_buf16,
4571 7931 : st->hTcxCfg->tcx_aldo_window_2,
4572 7931 : st->hTcxCfg->tcx_mdct_window_half,
4573 7931 : st->hTcxCfg->tcx_mdct_window_minimum,
4574 : overlap, /*hTcxCfg->tcx_mdct_window_length*/
4575 7931 : st->hTcxCfg->tcx_mdct_window_half_length,
4576 7931 : st->hTcxCfg->tcx_mdct_window_min_length,
4577 7931 : st->last_core == ACELP_CORE,
4578 7931 : st->hTcxCfg->tcx_last_overlap_mode, /*left mode*/
4579 : hTcxEnc->acelp_zir,
4580 7931 : hTcxEnc->Txnq,
4581 : NULL,
4582 : Aq_old_fx,
4583 7931 : st->hTcxCfg->tcx_mdct_window_trans,
4584 7931 : shr( st->L_frame, 1 ),
4585 : tmp4,
4586 7931 : st->last_core,
4587 : 0,
4588 : 0 );
4589 : }
4590 : } /* TCX-10 and TCX-only */
4591 :
4592 : /* Window and overlap-add past frame if past frame is TCX */
4593 238490 : test();
4594 238490 : test();
4595 238490 : test();
4596 238490 : IF( ( st->last_core > ACELP_CORE ) && ( ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) && ( st->tcxonly != 0 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
4597 : {
4598 :
4599 4118 : IF( st->hTcxCfg->last_aldo != 0 )
4600 : {
4601 1922 : tmp2 = add( hTcxEnc->Q_old_out, TCX_IMDCT_HEADROOM );
4602 :
4603 1922 : tmp1 = sub( overlap, st->hTcxCfg->tcx_mdct_window_min_length );
4604 461522 : FOR( i = 0; i < tmp1; i++ )
4605 : {
4606 459600 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], shr_sat( hTcxEnc->old_out_fx[i + nz], tmp2 ) ), TCX_IMDCT_HEADROOM );
4607 459600 : move16();
4608 : }
4609 :
4610 : /* fade truncated ALDO window */
4611 1922 : tmp1 = sub( overlap, shr( st->hTcxCfg->tcx_mdct_window_min_length, 1 ) );
4612 40222 : FOR( ; i < tmp1; i++ )
4613 : {
4614 38300 : tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[i - overlap + st->hTcxCfg->tcx_mdct_window_min_length].v.re );
4615 38300 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
4616 38300 : move16();
4617 : }
4618 40222 : FOR( ; i < overlap; i++ )
4619 : {
4620 38300 : tmp3 = mult_r( shr( hTcxEnc->old_out_fx[i + nz], tmp2 ), st->hTcxCfg->tcx_mdct_window_minimum[overlap - 1 - i].v.im );
4621 38300 : xn_buf16[i] = shl_sat( add_sat( xn_buf16[i], tmp3 ), TCX_IMDCT_HEADROOM );
4622 38300 : move16();
4623 : }
4624 :
4625 78522 : FOR( ; i < L_frame; i++ )
4626 : {
4627 76600 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
4628 76600 : move16();
4629 : }
4630 : }
4631 : ELSE
4632 : {
4633 2196 : test();
4634 2196 : test();
4635 2196 : test();
4636 2196 : if ( ( frame_cnt > 0 ) && ( tcx_last_overlap_mode == 0 ) && ( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) && ( st->last_core != ACELP_CORE ) )
4637 : {
4638 596 : tcx_last_overlap_mode = 2; /* use minimum overlap between the two TCX-10 windows */
4639 596 : move16();
4640 : }
4641 :
4642 2196 : tmp1 = tcx_last_overlap_mode;
4643 2196 : move16();
4644 2196 : test();
4645 2196 : if ( ( tcx_last_overlap_mode == 0 ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, MIN_OVERLAP ) ) )
4646 : {
4647 1056 : tmp1 = st->hTcxCfg->tcx_last_overlap_mode;
4648 1056 : move16();
4649 : }
4650 :
4651 2196 : tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq, st->hTcxCfg->tcx_aldo_window_1_trunc, st->hTcxCfg->tcx_mdct_window_half,
4652 2196 : st->hTcxCfg->tcx_mdct_window_minimum, overlap, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, tmp1 );
4653 :
4654 : BASOP_SATURATE_WARNING_OFF_EVS;
4655 615116 : FOR( i = 0; i < overlap; i++ )
4656 : {
4657 612920 : xn_buf16[i] = shl_sat( add( xn_buf16[i], hTcxEnc->Txnq[i] ), TCX_IMDCT_HEADROOM );
4658 612920 : move16();
4659 : }
4660 :
4661 2196 : IF( LT_16( i, L_frame ) )
4662 : {
4663 89756 : FOR( ; i < L_frame; i++ )
4664 : {
4665 87560 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
4666 87560 : move16();
4667 : }
4668 : }
4669 : BASOP_SATURATE_WARNING_ON_EVS;
4670 : }
4671 : }
4672 : ELSE
4673 : {
4674 234372 : IF( aldo == 0 )
4675 : {
4676 : BASOP_SATURATE_WARNING_OFF_EVS;
4677 2999211 : FOR( i = 0; i < L_frame; i++ )
4678 : {
4679 2991280 : xn_buf16[i] = shl_sat( xn_buf16[i], TCX_IMDCT_HEADROOM );
4680 2991280 : move16();
4681 : }
4682 : BASOP_SATURATE_WARNING_ON_EVS;
4683 : }
4684 : }
4685 :
4686 238490 : test();
4687 238490 : test();
4688 238490 : test();
4689 238490 : IF( ( aldo == 0 ) &&
4690 : ( ( EQ_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) && frame_cnt > 0 ) ||
4691 : NE_16( L_frameTCX, shr( hTcxEnc->L_frameTCX, 1 ) ) ) )
4692 : {
4693 : /*Compute windowed synthesis in case of switching to ALDO windows in next frame*/
4694 1052388 : FOR( i = 0; i < nz; i++ )
4695 : {
4696 1042398 : hTcxEnc->old_out_fx[i] = shr( xn_buf16[L_frame - nz + i], TCX_IMDCT_HEADROOM );
4697 1042398 : move16();
4698 : }
4699 9990 : Copy( xn_buf16 + L_frame, hTcxEnc->old_out_fx + nz, overlap );
4700 9990 : set16_fx( hTcxEnc->old_out_fx + nz + overlap, 0, nz );
4701 :
4702 9990 : tcx_windowing_synthesis_past_frame( hTcxEnc->old_out_fx + nz,
4703 9990 : st->hTcxCfg->tcx_aldo_window_1_trunc,
4704 9990 : st->hTcxCfg->tcx_mdct_window_half,
4705 9990 : st->hTcxCfg->tcx_mdct_window_minimum,
4706 : overlap,
4707 9990 : st->hTcxCfg->tcx_mdct_window_half_length,
4708 9990 : st->hTcxCfg->tcx_mdct_window_min_length,
4709 9990 : st->hTcxCfg->tcx_curr_overlap_mode );
4710 :
4711 : /* If current overlap mode = FULL_OVERLAP -> ALDO_WINDOW */
4712 9990 : IF( st->hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP )
4713 : {
4714 862485 : FOR( i = 0; i < nz; i++ )
4715 : {
4716 853578 : hTcxEnc->old_out_fx[nz + overlap + i] = shr( mult_r( xn_buf16[L_frame - 1 - i], st->hTcxCfg->tcx_aldo_window_1[nz - 1 - i] ), TCX_IMDCT_HEADROOM );
4717 853578 : move16();
4718 : }
4719 : }
4720 :
4721 9990 : hTcxEnc->Q_old_out = -TCX_IMDCT_HEADROOM;
4722 9990 : move16();
4723 : }
4724 238490 : st->hTcxCfg->last_aldo = aldo;
4725 238490 : move16();
4726 :
4727 : /* Update Txnq */
4728 238490 : IF( st->hTcxCfg->last_aldo == 0 )
4729 : {
4730 12049 : Copy( xn_buf16 + L_frame, hTcxEnc->Txnq, overlap );
4731 : }
4732 :
4733 238490 : tmp1 = L_frame;
4734 238490 : move16();
4735 238490 : if ( EQ_16( st->core, TCX_20_CORE ) )
4736 : {
4737 234372 : tmp1 = st->L_frame;
4738 234372 : move16();
4739 : }
4740 :
4741 : /* Output */
4742 238490 : Copy( xn_buf16 + shr( overlap, 1 ) - tcx_offset, synth, tmp1 );
4743 :
4744 238490 : return;
4745 : }
4746 :
4747 :
4748 708182 : void TNSAnalysisStereo_fx(
4749 : Encoder_State **sts, /* i : encoder state handle */
4750 : Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/
4751 : const Word16 bWhitenedDomain, /* i : whitened domain flag Q0*/
4752 : Word16 tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm Q0*/
4753 : Word16 tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame Q0*/
4754 : Word16 param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters Q0*/
4755 : const Word16 mct_on /* i : flag mct block (1) or stereo (0) Q0*/
4756 : )
4757 : {
4758 : Word16 ch, k, L_spec, L_frame, nSubframes, iFilter;
4759 : Word32 *spectrum_fx, sum;
4760 708182 : Encoder_State *st = NULL;
4761 708182 : TCX_ENC_HANDLE hTcxEnc = NULL;
4762 : Word16 individual_decision[NB_DIV];
4763 708182 : Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx;
4764 708182 : move32();
4765 708182 : Word16 maxPredictionGain_e = 0, meanPredictionGain_e;
4766 708182 : move16();
4767 708182 : Word16 sum_e = 0;
4768 708182 : move16();
4769 708182 : individual_decision[0] = 0;
4770 708182 : move16();
4771 708182 : individual_decision[1] = 0;
4772 708182 : move16();
4773 708182 : L_spec = -1;
4774 708182 : move16();
4775 708182 : L_frame = -1;
4776 708182 : move16();
4777 :
4778 : /* TNS filter analysis, loop over channels */
4779 2124546 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
4780 : {
4781 1416364 : st = sts[ch];
4782 1416364 : IF( EQ_16( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
4783 : {
4784 126194 : CONTINUE;
4785 : }
4786 :
4787 1290170 : hTcxEnc = st->hTcxEnc;
4788 :
4789 1290170 : IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) )
4790 : {
4791 1260594 : nSubframes = 1;
4792 : }
4793 : ELSE
4794 : {
4795 29576 : nSubframes = NB_DIV;
4796 : }
4797 1290170 : move16();
4798 :
4799 2609916 : FOR( k = 0; k < nSubframes; k++ )
4800 : {
4801 : /* reset tns on whitened domain flag */
4802 1319746 : IF( !bWhitenedDomain )
4803 : {
4804 664141 : hTcxEnc->bTnsOnWhithenedSpectra[k] = 0;
4805 664141 : move16();
4806 664141 : hTcxEnc->fUseTns[k] = 0;
4807 664141 : move16();
4808 : }
4809 1319746 : test();
4810 1319746 : test();
4811 1319746 : IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
4812 : {
4813 1297542 : spectrum_fx = hTcxEnc->spectrum_fx[k];
4814 :
4815 1297542 : L_frame = hTcxEnc->L_frameTCX;
4816 1297542 : move16();
4817 1297542 : st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
4818 1297542 : L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
4819 1297542 : move16();
4820 : /*-----------------------------------------------------------*
4821 : * Temporal Noise Shaping analysis *
4822 : *-----------------------------------------------------------*/
4823 :
4824 1297542 : IF( EQ_16( hTcxEnc->transform_type[k], TCX_5 ) )
4825 : {
4826 : /* rearrange LF sub-window lines prior to TNS analysis & filtering */
4827 15278 : tcx5TnsGrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), spectrum_fx );
4828 : }
4829 :
4830 : /* WMOPS: All initializations are either for safety or static (tables) and thus not to be counted */
4831 :
4832 1297542 : ResetTnsData( &hTcxEnc->tnsData[k] );
4833 1297542 : IF( st->hTcxCfg->pCurrentTnsConfig->maxOrder <= 0 )
4834 : {
4835 0 : BREAK;
4836 : }
4837 :
4838 1297542 : CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] );
4839 : }
4840 : }
4841 : }
4842 :
4843 708182 : IF( !mct_on )
4844 : {
4845 : /* TNS decision */
4846 : /* if framing differs between channels, keep the filter decision per channel */
4847 167566 : test();
4848 167566 : test();
4849 167566 : IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) &&
4850 : NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) ||
4851 : NE_16( sts[0]->hTcxCfg->fIsTNSAllowed, sts[1]->hTcxCfg->fIsTNSAllowed ) )
4852 : {
4853 1258 : individual_decision[0] = individual_decision[1] = 1;
4854 1258 : move16();
4855 1258 : move16();
4856 : }
4857 166308 : ELSE IF( bWhitenedDomain )
4858 : {
4859 83154 : IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
4860 : {
4861 81394 : nSubframes = 1;
4862 : }
4863 : ELSE
4864 : {
4865 1760 : nSubframes = NB_DIV;
4866 : }
4867 83154 : move16();
4868 168068 : FOR( k = 0; k < nSubframes; k++ )
4869 : {
4870 84914 : IF( NE_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
4871 : {
4872 427 : individual_decision[k] = 1;
4873 427 : move16();
4874 : }
4875 : }
4876 : }
4877 :
4878 : /* framing equal, check for similar filters, if very similar (also indicator for and M signal),
4879 : * use at least the same decision, maybe use the same filter
4880 : */
4881 : {
4882 : Word8 isTCX10;
4883 :
4884 167566 : IF( EQ_16( sts[0]->hTcxEnc->tcxMode, TCX_20 ) )
4885 : {
4886 163444 : nSubframes = 1;
4887 163444 : isTCX10 = 0;
4888 : }
4889 : ELSE
4890 : {
4891 4122 : nSubframes = NB_DIV;
4892 4122 : isTCX10 = 1;
4893 : }
4894 167566 : move16();
4895 167566 : move16();
4896 339254 : FOR( k = 0; k < nSubframes; k++ )
4897 : {
4898 171688 : test();
4899 171688 : test();
4900 171688 : test();
4901 171688 : IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
4902 : {
4903 167088 : Word32 maxPredGain_fx = -ONE_IN_Q31;
4904 167088 : move32();
4905 167088 : Word16 maxPredGain_e = 0;
4906 167088 : move16();
4907 167088 : sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )];
4908 167088 : sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )];
4909 :
4910 479753 : FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
4911 : {
4912 : STnsFilter *pFilter[2];
4913 : struct TnsParameters const *pTnsParameters[2];
4914 312665 : pFilter[0] = sts[0]->hTcxEnc->tnsData[k].filter + iFilter;
4915 312665 : pTnsParameters[0] = sts[0]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
4916 312665 : pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter;
4917 312665 : pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
4918 :
4919 : /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of
4920 : * both filters for the decision
4921 : */
4922 :
4923 312665 : meanPredictionGain_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[0]->predictionGain_e, Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain_e, &meanPredictionGain_e ); // meanPredictionGain_e
4924 :
4925 : /* maxPredictionGain = max( maxPredictionGain, meanPredictionGain );*/
4926 312665 : IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, meanPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
4927 : {
4928 207250 : maxPredictionGain_fx = meanPredictionGain_fx;
4929 207250 : maxPredictionGain_e = meanPredictionGain_e;
4930 207250 : move32();
4931 207250 : move16();
4932 : }
4933 :
4934 312665 : test();
4935 312665 : test();
4936 312665 : test();
4937 312665 : IF( GT_32( pFilter[0]->predictionGain32, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[0]->predictionGain_e ) ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) &&
4938 : GT_32( pFilter[1]->predictionGain32, L_shl_sat( ( pTnsParameters[1]->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter[1]->predictionGain_e ) ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
4939 : {
4940 4926 : pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */
4941 4926 : move32();
4942 4926 : move32();
4943 4926 : pFilter[0]->predictionGain_e = pFilter[1]->predictionGain_e = meanPredictionGain_e; /* more TNS filter sync at 48kbps */
4944 4926 : move16();
4945 4926 : move16();
4946 4926 : pFilter[0]->predictionGain = pFilter[1]->predictionGain = shl_sat( extract_h( meanPredictionGain_fx ), sub( meanPredictionGain_e, PRED_GAIN_E ) ); /* Q7 */
4947 4926 : move16();
4948 : }
4949 312665 : sum_e = s_max( pFilter[0]->predictionGain_e, pFilter[1]->predictionGain_e );
4950 312665 : sum = L_abs( L_sub_sat( L_shl( pFilter[0]->predictionGain32, sub( pFilter[0]->predictionGain_e, sum_e ) ), L_shl( pFilter[1]->predictionGain32, sub( pFilter[1]->predictionGain_e, sum_e ) ) ) ); // sum_e
4951 :
4952 312665 : IF( LT_32( L_shl_sat( sum, sub( sum_e, meanPredictionGain_e ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) &&
4953 : ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) )
4954 207561 : {
4955 :
4956 207561 : Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15
4957 207561 : Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) );
4958 :
4959 : /* maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); */
4960 207561 : IF( GT_32( meanPredictionGain_fx, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, maxPredictionGain_e ) ) ) ) /* exp: meanPredictionGain_e */
4961 : {
4962 155968 : maxPredGain_fx = meanPredictionGain_fx;
4963 155968 : maxPredGain_e = meanPredictionGain_e;
4964 155968 : move32();
4965 155968 : move16();
4966 : }
4967 :
4968 207561 : test();
4969 207561 : test();
4970 207561 : IF( GT_32( meanPredictionGain_fx, L_shl_sat( ( pTnsParameters[0]->minPredictionGain_32 ), sub( PRED_GAIN_E, meanPredictionGain_e ) ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) )
4971 : {
4972 7215 : test();
4973 7215 : test();
4974 7215 : test();
4975 7215 : IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 || sts[1]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( meanLtpGain_fx, 19660 /* 0.6 in Q15*/ ) )
4976 : {
4977 :
4978 6553 : sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
4979 6553 : move16();
4980 : /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
4981 : this may result in crash later. Changing the filter type here so the order is taken here in further section */
4982 6553 : IF( pFilter[0]->order != 0 )
4983 : {
4984 6553 : pFilter[0]->filterType = TNS_FILTER_ON;
4985 6553 : move16();
4986 : }
4987 : ELSE
4988 : {
4989 0 : pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
4990 0 : move16();
4991 : }
4992 6553 : sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
4993 6553 : move16();
4994 6553 : IF( pFilter[1]->order != 0 )
4995 : {
4996 6553 : pFilter[1]->filterType = TNS_FILTER_ON;
4997 6553 : move16();
4998 : }
4999 : ELSE
5000 : {
5001 0 : pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
5002 0 : move16();
5003 : }
5004 : }
5005 : ELSE
5006 : {
5007 : Word16 maxEnergyChange_fx;
5008 662 : maxEnergyChange_fx = mac_r( L_mult( GetTCXMaxenergyChange_ivas_fx( sts[0]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 ), GetTCXMaxenergyChange_ivas_fx( sts[1]->hTranDet, isTCX10, NSUBBLOCKS, 3 ), 16384 );
5009 :
5010 662 : IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters[0]->minEnergyChange, Q3 - Q7 ) ) )
5011 : {
5012 652 : sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
5013 652 : move16();
5014 : /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
5015 : this may result in crash later. Changing the filter type here so the order is taken here in further section */
5016 652 : IF( pFilter[0]->order != 0 )
5017 : {
5018 652 : pFilter[0]->filterType = TNS_FILTER_ON;
5019 652 : move16();
5020 : }
5021 : ELSE
5022 : {
5023 0 : pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
5024 0 : move16();
5025 : }
5026 652 : sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
5027 652 : move16();
5028 652 : IF( pFilter[1]->order != 0 )
5029 : {
5030 652 : pFilter[1]->filterType = TNS_FILTER_ON;
5031 652 : move16();
5032 : }
5033 : ELSE
5034 : {
5035 0 : pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
5036 0 : move16();
5037 : }
5038 : }
5039 : ELSE
5040 : {
5041 10 : pFilter[0]->filterType = TNS_FILTER_OFF;
5042 10 : move16();
5043 10 : pFilter[1]->filterType = TNS_FILTER_OFF;
5044 10 : move16();
5045 : }
5046 : }
5047 : }
5048 200346 : ELSE IF( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 && sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
5049 : {
5050 226 : pFilter[0]->filterType = TNS_FILTER_ON_ZERO;
5051 226 : pFilter[1]->filterType = TNS_FILTER_ON_ZERO;
5052 226 : move16();
5053 226 : move16();
5054 226 : sts[0]->hTcxEnc->tnsData[k].nFilters = add( sts[0]->hTcxEnc->tnsData[k].nFilters, 1 );
5055 226 : move16();
5056 226 : sts[1]->hTcxEnc->tnsData[k].nFilters = add( sts[1]->hTcxEnc->tnsData[k].nFilters, 1 );
5057 226 : move16();
5058 : }
5059 200120 : ELSE IF( NE_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) /* sanity check */
5060 : {
5061 0 : assert( 0 );
5062 : }
5063 : ELSE
5064 : {
5065 200120 : pFilter[0]->filterType = TNS_FILTER_OFF;
5066 200120 : move16();
5067 200120 : pFilter[1]->filterType = TNS_FILTER_OFF;
5068 200120 : move16();
5069 : }
5070 :
5071 207561 : test();
5072 207561 : test();
5073 207561 : IF( EQ_16( pFilter[0]->filterType, TNS_FILTER_ON ) && EQ_16( pFilter[1]->filterType, TNS_FILTER_ON ) && LT_32( sts[0]->element_brate, IVAS_80k ) )
5074 : {
5075 6088 : Word16 tmpIntValue = 0;
5076 6088 : move16();
5077 : Word16 tmpCoeff[TNS_MAX_FILTER_ORDER];
5078 6088 : Word16 i, maxOrder = s_max( pFilter[0]->order, pFilter[1]->order );
5079 :
5080 6088 : set16_fx( tmpCoeff, 0, TNS_MAX_FILTER_ORDER );
5081 46256 : FOR( i = 0; i < maxOrder; i++ )
5082 : {
5083 40168 : tmpIntValue = s_max( tmpIntValue, abs_s( sub( pFilter[0]->coefIndex[i], pFilter[1]->coefIndex[i] ) ) );
5084 : }
5085 :
5086 6088 : IF( EQ_16( tmpIntValue, 1 ) ) /* the TNS coefficients are sufficiently similar to equalize the two filters */
5087 : {
5088 27837 : FOR( i = maxOrder - 1; i >= 0; i-- )
5089 : {
5090 24196 : IF( LT_16( abs_s( pFilter[0]->coefIndex[i] ), abs_s( pFilter[1]->coefIndex[i] ) ) )
5091 : {
5092 4448 : tmpCoeff[i] = pFilter[0]->coefIndex[i];
5093 : }
5094 : ELSE
5095 : {
5096 19748 : tmpCoeff[i] = pFilter[1]->coefIndex[i];
5097 : }
5098 24196 : move16();
5099 24196 : IF( ( tmpIntValue > 0 ) && ( tmpCoeff[i] == 0 ) )
5100 : {
5101 5922 : maxOrder = sub( maxOrder, 1 );
5102 : }
5103 : ELSE
5104 : {
5105 18274 : tmpIntValue = 0;
5106 18274 : move16();
5107 : }
5108 : }
5109 : /* make sure that maxOrder is non zero and not all coefficients are zero (could happen in rare cases) */
5110 3641 : IF( maxOrder > 0 )
5111 : {
5112 32769 : FOR( i = TNS_MAX_FILTER_ORDER - 1; i >= 0; i-- )
5113 : {
5114 29128 : pFilter[0]->coefIndex[i] = pFilter[1]->coefIndex[i] = tmpCoeff[i];
5115 29128 : move16();
5116 29128 : move16();
5117 : }
5118 :
5119 3641 : pFilter[0]->order = pFilter[1]->order = maxOrder;
5120 3641 : move16();
5121 3641 : move16();
5122 : }
5123 : }
5124 : }
5125 : }
5126 : ELSE
5127 : {
5128 105104 : individual_decision[k] = 1;
5129 105104 : move16();
5130 : }
5131 : }
5132 :
5133 167088 : IF( individual_decision[k] == 0 )
5134 : {
5135 82922 : IF( ( sts[0]->hTcxEnc->tnsData[k].nFilters > 0 ) )
5136 : {
5137 3496 : sts[0]->hTcxEnc->fUseTns[k] = 1;
5138 : }
5139 : ELSE
5140 : {
5141 79426 : sts[0]->hTcxEnc->fUseTns[k] = 0;
5142 : }
5143 82922 : move16();
5144 :
5145 82922 : IF( ( sts[1]->hTcxEnc->tnsData[k].nFilters > 0 ) )
5146 : {
5147 3496 : sts[1]->hTcxEnc->fUseTns[k] = 1;
5148 : }
5149 : ELSE
5150 : {
5151 79426 : sts[1]->hTcxEnc->fUseTns[k] = 0;
5152 : }
5153 82922 : move16();
5154 : }
5155 : ELSE
5156 : {
5157 84166 : sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
5158 84166 : move16();
5159 84166 : sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
5160 84166 : move16();
5161 84166 : sts[0]->hTcxEnc->fUseTns[k] = 0;
5162 84166 : move16();
5163 84166 : sts[1]->hTcxEnc->fUseTns[k] = 0;
5164 84166 : move16();
5165 245057 : FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5166 : {
5167 160891 : sts[0]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
5168 160891 : move16();
5169 160891 : sts[1]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
5170 160891 : move16();
5171 : }
5172 : }
5173 :
5174 167088 : test();
5175 167088 : test();
5176 167088 : test();
5177 167088 : IF( !bWhitenedDomain && individual_decision[k] == 0 &&
5178 : LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) &&
5179 : NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) )
5180 : {
5181 40797 : sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
5182 40797 : move16();
5183 40797 : sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
5184 40797 : move16();
5185 40797 : sts[0]->hTcxEnc->tnsData[k].nFilters = 0;
5186 40797 : move16();
5187 40797 : sts[1]->hTcxEnc->tnsData[k].nFilters = 0;
5188 40797 : move16();
5189 40797 : sts[0]->hTcxEnc->fUseTns[k] = 0;
5190 40797 : move16();
5191 40797 : sts[1]->hTcxEnc->fUseTns[k] = 0;
5192 40797 : move16();
5193 115483 : FOR( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5194 : {
5195 74686 : ClearTnsFilterCoefficients( sts[0]->hTcxEnc->tnsData[k].filter + iFilter );
5196 74686 : ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter );
5197 : }
5198 : }
5199 :
5200 : /* maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); */
5201 167088 : IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* exp: maxPredGain_e */
5202 : {
5203 0 : maxPredictionGain_fx = maxPredGain_fx;
5204 0 : maxPredictionGain_e = maxPredGain_e;
5205 0 : move32();
5206 0 : move16();
5207 : }
5208 : }
5209 : }
5210 : }
5211 : }
5212 :
5213 : /* individual decision for each channel */
5214 2124546 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5215 : {
5216 1416364 : IF( EQ_32( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
5217 : {
5218 126194 : CONTINUE;
5219 : }
5220 :
5221 : Word8 isTCX10;
5222 :
5223 1290170 : IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
5224 : {
5225 1260594 : nSubframes = 1;
5226 1260594 : isTCX10 = 0;
5227 : }
5228 : ELSE
5229 : {
5230 29576 : nSubframes = NB_DIV;
5231 29576 : isTCX10 = 1;
5232 : }
5233 1290170 : move16();
5234 1290170 : move16();
5235 :
5236 2609916 : FOR( k = 0; k < nSubframes; k++ )
5237 : {
5238 1319746 : test();
5239 1319746 : test();
5240 1319746 : test();
5241 1319746 : test();
5242 1319746 : IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) &&
5243 : ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
5244 : {
5245 1131698 : Word32 maxPredGain_fx = -ONE_IN_Q31; // Q31
5246 1131698 : move32();
5247 1131698 : Word16 maxPredGain_e = 0;
5248 1131698 : move16();
5249 1131698 : sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
5250 :
5251 3302257 : FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5252 : {
5253 : STnsFilter *pFilter;
5254 : struct TnsParameters const *pTnsParameters;
5255 2170559 : pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
5256 2170559 : pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter;
5257 :
5258 : // maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 );
5259 2170559 : IF( GT_32( pFilter->predictionGain32, L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, pFilter->predictionGain_e ) ) ) ) /* pFilter->predictionGain_e */
5260 : {
5261 1479597 : maxPredGain_fx = pFilter->predictionGain32;
5262 1479597 : maxPredGain_e = pFilter->predictionGain_e;
5263 1479597 : move32();
5264 1479597 : move16();
5265 : }
5266 :
5267 2170559 : test();
5268 2170559 : IF( GT_32( pFilter->predictionGain32, L_shl_sat( ( pTnsParameters->minPredictionGain_32 ), sub( PRED_GAIN_E, pFilter->predictionGain_e ) ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) )
5269 : {
5270 134174 : test();
5271 134174 : test();
5272 134174 : IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 || isTCX10 || LT_16( sts[ch]->hTcxEnc->tcxltp_gain, 19660 /*.6f in Q15*/ ) )
5273 : {
5274 115241 : sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
5275 115241 : move16();
5276 : /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
5277 : this may result in crash later. Changing the filter type here so the order is taken here in further section */
5278 115241 : IF( pFilter->order != 0 )
5279 : {
5280 115241 : pFilter->filterType = TNS_FILTER_ON;
5281 115241 : move16();
5282 : }
5283 : ELSE
5284 : {
5285 0 : pFilter->filterType = TNS_FILTER_ON_ZERO;
5286 0 : move16();
5287 : }
5288 : }
5289 : ELSE
5290 : {
5291 18933 : Word16 maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( sts[ch]->hTranDet, isTCX10, NSUBBLOCKS, 3 );
5292 :
5293 18933 : IF( GE_16( maxEnergyChange_fx, shl( pTnsParameters->minEnergyChange, Q3 - Q7 ) ) )
5294 : {
5295 17836 : sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
5296 17836 : move16();
5297 : /* When order parameter is evaluated as 0 and change in precision causes the flow to reach here,
5298 : this may result in crash later. Changing the filter type here so the order is taken here in further section */
5299 17836 : IF( pFilter->order != 0 )
5300 : {
5301 17836 : pFilter->filterType = TNS_FILTER_ON;
5302 17836 : move16();
5303 : }
5304 : ELSE
5305 : {
5306 0 : pFilter->filterType = TNS_FILTER_ON_ZERO;
5307 0 : move16();
5308 : }
5309 : }
5310 : ELSE
5311 : {
5312 1097 : pFilter->filterType = TNS_FILTER_OFF;
5313 1097 : move16();
5314 : }
5315 : }
5316 : }
5317 2036385 : ELSE IF( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 ) /* If a previous filter is turned on */
5318 : {
5319 12863 : pFilter->filterType = TNS_FILTER_ON_ZERO;
5320 12863 : move16();
5321 12863 : sts[ch]->hTcxEnc->tnsData[k].nFilters = add( sts[ch]->hTcxEnc->tnsData[k].nFilters, 1 );
5322 12863 : move16();
5323 : }
5324 : ELSE
5325 : {
5326 2023522 : pFilter->filterType = TNS_FILTER_OFF;
5327 2023522 : move16();
5328 : }
5329 : }
5330 :
5331 1131698 : sts[ch]->hTcxEnc->fUseTns[k] = 0;
5332 1131698 : move16();
5333 1131698 : if ( sts[ch]->hTcxEnc->tnsData[k].nFilters > 0 )
5334 : {
5335 122508 : sts[ch]->hTcxEnc->fUseTns[k] = 1;
5336 122508 : move16();
5337 : }
5338 :
5339 1131698 : test();
5340 1131698 : test();
5341 1131698 : IF( !bWhitenedDomain && LT_32( L_shl_sat( maxPredGain_fx, sub( maxPredGain_e, PRED_GAIN_E ) ), TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) )
5342 : {
5343 560343 : sts[ch]->hTcxEnc->fUseTns[k] = 0;
5344 560343 : move16();
5345 560343 : sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1;
5346 560343 : move16();
5347 560343 : sts[ch]->hTcxEnc->tnsData[k].nFilters = 0;
5348 560343 : move16();
5349 1634179 : FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5350 : {
5351 1073836 : ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
5352 1073836 : sts[ch]->hTcxEnc->tnsData[k].filter[iFilter].filterType = TNS_FILTER_OFF;
5353 1073836 : move16();
5354 : }
5355 : }
5356 :
5357 : // maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx );
5358 1131698 : IF( GT_32( maxPredGain_fx, L_shl_sat( maxPredictionGain_fx, sub( maxPredictionGain_e, maxPredGain_e ) ) ) ) /* maxPredGain_e */
5359 : {
5360 815428 : maxPredictionGain_fx = maxPredGain_fx;
5361 815428 : maxPredictionGain_e = maxPredGain_e;
5362 815428 : move32();
5363 815428 : move16();
5364 : }
5365 : }
5366 : }
5367 : }
5368 :
5369 :
5370 : /* we have the decision, set filter data accordingly */
5371 2124546 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5372 : {
5373 1416364 : IF( EQ_16( sts[ch]->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
5374 : {
5375 126194 : CONTINUE;
5376 : }
5377 :
5378 1290170 : IF( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
5379 : {
5380 1260594 : nSubframes = 1;
5381 : }
5382 : ELSE
5383 : {
5384 29576 : nSubframes = NB_DIV;
5385 : }
5386 1290170 : move16();
5387 2609916 : FOR( k = 0; k < nSubframes; k++ )
5388 : {
5389 1319746 : test();
5390 1319746 : test();
5391 1319746 : IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
5392 : {
5393 1297542 : sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )];
5394 :
5395 3771649 : FOR( iFilter = sts[ch]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5396 : {
5397 : STnsFilter *pFilter;
5398 2474107 : pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter;
5399 2474107 : SWITCH( pFilter->filterType )
5400 : {
5401 2379766 : case TNS_FILTER_OFF:
5402 2379766 : ClearTnsFilterCoefficients( sts[ch]->hTcxEnc->tnsData[k].filter + iFilter );
5403 2379766 : BREAK;
5404 9819 : case TNS_FILTER_ON_ZERO:
5405 : /* Since TNS filter of order 0 is not allowed we have to signal in the stream filter of order 1 with the 0th coefficient equal to 0 */
5406 9819 : ClearTnsFilterCoefficients( pFilter );
5407 9819 : pFilter->order = 1;
5408 9819 : move16();
5409 9819 : BREAK;
5410 : }
5411 2474107 : }
5412 : }
5413 : }
5414 : }
5415 :
5416 : /* Apply filters, loop over channels */
5417 2124546 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5418 : {
5419 1416364 : st = sts[ch];
5420 1416364 : IF( EQ_32( st->mct_chan_mode, MCT_CHAN_MODE_IGNORE ) )
5421 : {
5422 126194 : CONTINUE;
5423 : }
5424 :
5425 1290170 : IF( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
5426 : {
5427 1260594 : nSubframes = 1;
5428 : }
5429 : ELSE
5430 : {
5431 29576 : nSubframes = NB_DIV;
5432 : }
5433 1290170 : move16();
5434 :
5435 2609916 : FOR( k = 0; k < nSubframes; k++ )
5436 : {
5437 1319746 : test();
5438 1319746 : test();
5439 1319746 : test();
5440 1319746 : test();
5441 1319746 : test();
5442 1319746 : IF( bWhitenedDomain && ( ch > 0 ) && /* test for identical TNS filter data in both channels */
5443 : sts[0]->hTcxCfg->fIsTNSAllowed && sts[0]->hTcxEnc->fUseTns[k] &&
5444 : sts[1]->hTcxCfg->fIsTNSAllowed && sts[1]->hTcxEnc->fUseTns[k] )
5445 : {
5446 18843 : Word16 equalFilterData = 0;
5447 18843 : move16();
5448 18843 : test();
5449 18843 : test();
5450 37672 : if ( EQ_16( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters, sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ) &&
5451 35349 : EQ_16( sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k], sts[1]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) &&
5452 16520 : EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) )
5453 : {
5454 15129 : equalFilterData = 1;
5455 15129 : move16();
5456 : }
5457 :
5458 18843 : IF( equalFilterData )
5459 : {
5460 31093 : FOR( iFilter = st->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
5461 : {
5462 26807 : const Word16 *pDataCh0 = (const Word16 *) &sts[0]->hTcxEnc->tnsData[k].filter[iFilter];
5463 26807 : const Word16 *pDataCh1 = (const Word16 *) &sts[1]->hTcxEnc->tnsData[k].filter[iFilter];
5464 26807 : Word16 i = 2 + TNS_MAX_FILTER_ORDER; /* excl. informative float data. Portable? */
5465 :
5466 26807 : move16();
5467 26807 : test();
5468 226442 : WHILE( ( i >= 0 ) && EQ_16( pDataCh0[i], pDataCh1[i] ) )
5469 : {
5470 199635 : test();
5471 199635 : i = sub( i, 1 );
5472 : }
5473 26807 : IF( i >= 0 )
5474 : {
5475 10843 : equalFilterData = 0;
5476 10843 : move16();
5477 10843 : BREAK;
5478 : }
5479 : }
5480 15129 : IF( equalFilterData )
5481 : {
5482 4286 : st->hTcxEnc->tnsData[k].nFilters = i_mult( st->hTcxEnc->tnsData[k].nFilters, -1 ); /* signals common TNS */
5483 4286 : move16();
5484 : }
5485 : }
5486 : }
5487 1319746 : test();
5488 1319746 : test();
5489 1319746 : IF( st->hTcxCfg->fIsTNSAllowed && ( !bWhitenedDomain || st->hTcxEnc->bTnsOnWhithenedSpectra[k] ) )
5490 : {
5491 1297542 : L_spec = st->hTcxCfg->pCurrentTnsConfig->iFilterBorders[0];
5492 1297542 : move16();
5493 1297542 : spectrum_fx = st->hTcxEnc->spectrum_fx[k];
5494 : /* If TNS should be used then get the residual after applying it inplace in the spectrum */
5495 1297542 : IF( st->hTcxEnc->fUseTns[k] )
5496 : {
5497 72826 : st->hTcxCfg->pCurrentTnsConfig = &st->hTcxCfg->tnsConfig[st->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( st->last_core == ACELP_CORE )];
5498 :
5499 72826 : ApplyTnsFilter( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], spectrum_fx, 1 );
5500 : }
5501 :
5502 1297542 : IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
5503 : {
5504 15278 : tcx5TnsUngrouping_fx( shr( L_frame, 2 ), shr( L_spec, 1 ), st->hTcxEnc->spectrum_fx[k], ENC );
5505 : }
5506 :
5507 1297542 : st->hTcxEnc->tnsData[k].tnsOnWhitenedSpectra = st->hTcxEnc->bTnsOnWhithenedSpectra[k];
5508 1297542 : move16();
5509 1297542 : EncodeTnsData_ivas_fx( st->hTcxCfg->pCurrentTnsConfig, &st->hTcxEnc->tnsData[k], param_core[ch] + k * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, tnsSize[ch] + k, tnsBits[ch] + k );
5510 : }
5511 :
5512 1319746 : IF( EQ_16( st->hTcxEnc->transform_type[k], TCX_5 ) )
5513 : {
5514 30556 : tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[k] );
5515 30556 : tcx5SpectrumInterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][k] );
5516 : }
5517 : }
5518 : }
5519 708182 : return;
5520 : }
|