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