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