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