Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <assert.h>
6 : #include <stdint.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : // #include "prot_fx.h"
10 : #include "rom_com.h"
11 : #include "basop_util.h"
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 : #include <stdlib.h>
15 : #include <math.h>
16 :
17 :
18 : /*-------------------------------------------------------------------*
19 : * core_signal_analysis_high_bitrate_fx()
20 : *
21 : *
22 : *-------------------------------------------------------------------*/
23 :
24 0 : void core_signal_analysis_high_bitrate_fx(
25 : const Word16 *new_samples, /*i: 0Q15*/
26 : const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/
27 : Word16 lsp_new[], /* Q15 */
28 : Word16 lsp_mid[], /* Q15 */
29 : Encoder_State *st,
30 : Word16 pTnsSize[], /* Q0 */
31 : Word16 pTnsBits[], /* Q0 */
32 : Word16 param_core[], /* Q0 */
33 : Word16 *ltpBits, /* Q0 */
34 : const Word16 L_frame, /* Q0 */
35 : const Word16 L_frameTCX, /* Q0 */
36 : const Word16 last_element_mode, /* Q0 */
37 : const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/
38 : Word32 **spectrum, /* spectrum_e */
39 : Word16 *spectrum_e,
40 : Word16 *Q_new )
41 : {
42 0 : const Word16 last_overlap = st->hTcxCfg->tcx_last_overlap_mode;
43 0 : const Word16 curr_overlap = st->hTcxCfg->tcx_curr_overlap_mode;
44 : Word16 i, frameno;
45 : Word16 L_subframe;
46 : Word16 left_overlap, right_overlap, folding_offset;
47 : Word32 buf[N_MAX]; /* Buffer for TCX20/TCX10 windowing, power spectrum */
48 : Word16 A[M + 1];
49 : Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */
50 : Word16 *pMdstWin;
51 : Word16 lpc_left_overlap_mode, lpc_right_overlap_mode;
52 0 : Word16 *tcx20Win = (Word16 *) buf;
53 : Word32 powerSpec[N_MAX];
54 : Word16 powerSpec_e;
55 : Word32 interleaveBuf[N_TCX10_MAX];
56 0 : Word16 *tcx5Win = (Word16 *) interleaveBuf; /* Buffer for TCX5 windowing and interleaving. */
57 : Word16 r_h[NB_DIV][M + 1], r_l[NB_DIV][M + 1];
58 : Word32 r[M + 1], epsP[M + 1];
59 : Word16 *lsp[2];
60 : Word8 tmp8;
61 0 : Word16 alw_pitch_lag_12k8[2], alw_pitch_lag_12k8_wc = -1;
62 0 : Word16 alw_voicing[2], alw_voicing_wc = -1;
63 : Word16 nSubframes;
64 : Word16 overlap_mode[3];
65 : Word16 transform_type[2];
66 : Word16 tcx10SizeFB;
67 : Word16 tcx5SizeFB;
68 : Word16 tcx10Size;
69 : Word16 tmp, *tmpP16;
70 : Word32 *tmpP32;
71 : Word16 Q_exp;
72 :
73 0 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
74 :
75 : /* dummy */
76 : (void) vad_hover_flag;
77 : (void) last_element_mode;
78 :
79 0 : left_overlap = -1;
80 0 : move16();
81 0 : right_overlap = -1;
82 0 : move16();
83 :
84 0 : tcx10SizeFB = shl( st->hTcxCfg->tcx5SizeFB, 1 ); /* Q0 */
85 0 : tcx5SizeFB = st->hTcxCfg->tcx5SizeFB; /* Q0 */
86 0 : move16();
87 0 : tcx10Size = shl( st->hTcxCfg->tcx5Size, 1 ); /* Q0 */
88 :
89 : /*--------------------------------------------------------------*
90 : * Input Signal Processing: copy, HP filter, pre-emphasis
91 : *---------------------------------------------------------------*/
92 :
93 : /* Copy Samples */
94 0 : IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
95 : {
96 0 : Copy( new_samples, st->new_speech_enc, L_frame ); /* Q0 */
97 0 : Scale_sig( st->new_speech_enc, L_frame, 1 ); /* Q1 */
98 : }
99 :
100 : /*--------------------------------------------------------------*
101 : * TCX-LTP
102 : *---------------------------------------------------------------*/
103 :
104 0 : tmp8 = 0;
105 0 : move16();
106 0 : if ( GT_32( st->sr_core, 25600 ) )
107 : {
108 0 : tmp8 = 1;
109 0 : move16();
110 : }
111 0 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
112 : {
113 : // PMT("tcx_ltp_encode_fx should be verified for IVAS")
114 0 : tcx_ltp_encode_fx( hTcxEnc->tcxltp, (Word8) st->tcxonly, hTcxEnc->tcxMode,
115 0 : L_frame, L_SUBFR, st->speech_enc + st->encoderLookahead_enc,
116 0 : hTcxEnc->speech_ltp + st->encoderLookahead_enc, st->speech_enc + st->encoderLookahead_enc,
117 0 : T_op[1], ¶m_core[1 + NOISE_FILL_RANGES], ltpBits,
118 : &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &hTcxEnc->tcxltp_gain,
119 : &hTcxEnc->tcxltp_pitch_int_past, &hTcxEnc->tcxltp_pitch_fr_past, &hTcxEnc->tcxltp_gain_past,
120 0 : &hTcxEnc->tcxltp_norm_corr_past, st->last_core, st->pit_min, st->pit_fr1,
121 0 : st->pit_fr2, st->pit_max, st->pit_res_max, &st->transientDetection,
122 : tmp8, NULL, M );
123 : }
124 : ELSE
125 : {
126 0 : tcx_ltp_encode_fx( hTcxEnc->tcxltp, (Word8) st->tcxonly, hTcxEnc->tcxMode,
127 0 : L_frame, L_SUBFR, st->speech_enc + st->encoderLookahead_enc,
128 0 : hTcxEnc->speech_ltp + st->encoderLookahead_enc, st->speech_enc + st->encoderLookahead_enc,
129 0 : T_op[1], ¶m_core[1 + NOISE_FILL_RANGES], ltpBits,
130 : &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &hTcxEnc->tcxltp_gain,
131 : &hTcxEnc->tcxltp_pitch_int_past, &hTcxEnc->tcxltp_pitch_fr_past, &hTcxEnc->tcxltp_gain_past,
132 0 : &hTcxEnc->tcxltp_norm_corr_past, st->last_core, st->pit_min, st->pit_fr1,
133 0 : st->pit_fr2, st->pit_max, st->pit_res_max, &st->transientDetection,
134 : tmp8, NULL, M );
135 : }
136 :
137 0 : test();
138 0 : IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
139 : {
140 0 : Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame );
141 :
142 0 : Preemph_scaled( st->new_speech_enc_pe, Q_new, &( st->mem_preemph_enc ),
143 0 : st->Q_max_enc, st->preemph_fac, 1, 0, 2, L_frame, st->coder_type_raw, 1 );
144 : }
145 0 : Q_exp = sub( *Q_new, st->prev_Q_new );
146 0 : move16();
147 :
148 : /* Rescale Memory */
149 0 : Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( *Q_new, st->Q_old ) ); /* Q_new */
150 0 : IF( Q_exp != 0 )
151 : {
152 0 : Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, Q_exp ); /* Q15 - exp_buf_speech_enc_pe + Q_exp */
153 0 : Scale_sig( &( st->mem_wsp_enc ), 1, Q_exp );
154 : }
155 :
156 0 : IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) )
157 : {
158 0 : Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); /* Q0 */
159 : }
160 :
161 :
162 : /*-------------------------------------------------------------------------*
163 : * Decision matrix for the transform and overlap length
164 : *--------------------------------------------------------------------------*/
165 0 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
166 : {
167 0 : lsp[0] = lsp_new;
168 0 : lsp[1] = lsp_mid;
169 0 : alw_pitch_lag_12k8[0] = st->pitch[0]; /* Q0 */
170 0 : move16();
171 0 : alw_pitch_lag_12k8[1] = st->pitch[1]; /* Q0 */
172 0 : move16();
173 0 : alw_voicing[0] = st->voicing_fx[0]; /* Q15 */
174 0 : move16();
175 0 : alw_voicing[1] = st->voicing_fx[1]; /* Q15 */
176 0 : move16();
177 :
178 0 : alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); /* Q0 */
179 0 : alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); /* Q15 */
180 : }
181 0 : overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame Q0*/
182 0 : move16();
183 :
184 0 : IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) )
185 : {
186 0 : nSubframes = 1;
187 0 : move16();
188 0 : transform_type[0] = TCX_20;
189 0 : transform_type[1] = TCX_20;
190 0 : move16();
191 0 : overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame Q0*/
192 0 : move16();
193 :
194 0 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
195 : {
196 0 : alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; /* Q0 */
197 0 : move16();
198 0 : alw_voicing[0] = alw_voicing_wc; /* Q15 */
199 0 : move16();
200 : }
201 : }
202 : ELSE
203 : {
204 0 : nSubframes = 2;
205 0 : move16();
206 0 : IF( EQ_16( curr_overlap, FULL_OVERLAP ) )
207 : {
208 0 : transform_type[0] = TCX_5;
209 0 : move16();
210 0 : transform_type[1] = TCX_10;
211 0 : move16();
212 :
213 0 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 2nd and 3rd sub-frame */
214 0 : move16();
215 0 : if ( EQ_16( last_overlap, HALF_OVERLAP ) )
216 : {
217 0 : overlap_mode[1] = HALF_OVERLAP;
218 0 : move16();
219 : }
220 : }
221 0 : ELSE IF( EQ_16( last_overlap, FULL_OVERLAP ) )
222 : {
223 0 : transform_type[0] = TCX_10;
224 0 : move16();
225 0 : transform_type[1] = TCX_5;
226 0 : move16();
227 :
228 0 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 1st and 2nd sub-frame */
229 0 : move16();
230 0 : if ( EQ_16( curr_overlap, HALF_OVERLAP ) )
231 : {
232 0 : overlap_mode[1] = HALF_OVERLAP;
233 0 : move16();
234 : }
235 : }
236 : ELSE
237 : {
238 0 : transform_type[0] = transform_type[1] = TCX_5;
239 0 : move16();
240 0 : move16();
241 :
242 0 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 2nd and 3rd sub-frame */
243 0 : move16();
244 0 : test();
245 0 : if ( EQ_16( last_overlap, HALF_OVERLAP ) && EQ_16( curr_overlap, HALF_OVERLAP ) )
246 : {
247 0 : overlap_mode[1] = HALF_OVERLAP;
248 0 : move16();
249 : }
250 : }
251 0 : overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame Q0*/
252 0 : move16();
253 : }
254 0 : IF( NE_16( transform_type[0], TCX_20 ) )
255 : {
256 0 : IGFEncResetTCX10BitCounter_fx( st->hIGFEnc );
257 : }
258 : /*-------------------------------------------------------------------------*
259 : * Get MDCT output and TNS parameters. Apply TNS in the spectrum if needed
260 : *--------------------------------------------------------------------------*/
261 :
262 0 : FOR( frameno = 0; frameno < nSubframes; frameno++ )
263 : {
264 0 : L_subframe = L_frameTCX; /* Q0 */
265 0 : move16();
266 0 : if ( NE_16( nSubframes, 1 ) )
267 0 : L_subframe = shr( L_frameTCX, 1 );
268 :
269 0 : lpc_left_overlap_mode = overlap_mode[frameno]; /* Q0 */
270 0 : move16();
271 0 : lpc_right_overlap_mode = overlap_mode[frameno + 1]; /* Q0 */
272 0 : move16();
273 0 : if ( EQ_16( lpc_left_overlap_mode, ALDO_WINDOW ) )
274 : {
275 0 : lpc_left_overlap_mode = FULL_OVERLAP;
276 0 : move16();
277 : }
278 0 : if ( EQ_16( lpc_right_overlap_mode, ALDO_WINDOW ) )
279 : {
280 0 : lpc_right_overlap_mode = FULL_OVERLAP;
281 0 : move16();
282 : }
283 :
284 0 : test();
285 0 : IF( ( NE_16( transform_type[frameno], TCX_20 ) ) || ( EQ_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) )
286 : {
287 : /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */
288 0 : WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno],
289 0 : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB],
290 0 : &L_subframe, tcx20Win, st->element_mode != IVAS_CPE_MDCT /* truncate_aldo */, 1 );
291 : }
292 :
293 0 : IF( EQ_16( transform_type[frameno], TCX_5 ) )
294 : {
295 0 : folding_offset = shr( left_overlap, 1 );
296 :
297 : /* Outter left folding */
298 0 : FOR( i = 0; i < folding_offset; i++ )
299 : {
300 0 : tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // Q0
301 0 : move16();
302 : }
303 : /* Outter right folding */
304 0 : tmp = shr( right_overlap, 1 );
305 0 : FOR( i = 0; i < tmp; i++ )
306 : {
307 0 : tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // Q0
308 0 : move16();
309 : }
310 : /* 2xTCX5 */
311 0 : L_subframe = tcx5SizeFB; /* Q0 */
312 0 : move16();
313 :
314 0 : tmpP16 = tcx20Win;
315 0 : tmpP32 = spectrum[frameno]; /* exp(spectrum) */
316 0 : assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE );
317 0 : FOR( i = 0; i < 2; i++ )
318 : {
319 0 : test();
320 0 : test();
321 0 : WindowSignal( st->hTcxCfg,
322 : folding_offset,
323 0 : mac_r( -( 1 << 16 ), 3 << 8, shl( i, 7 ) ), /* equivalent to: i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */
324 0 : mac_r( 2 << 16, -( 3 << 8 ), shl( i, 7 ) ), /* equivalent to: sub(i, 1) == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */
325 0 : &left_overlap, &right_overlap, tmpP16, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 );
326 :
327 0 : spectrum_e[frameno] = 16;
328 0 : move16();
329 0 : TCX_MDCT( tcx5Win,
330 : tmpP32,
331 0 : &spectrum_e[frameno],
332 : left_overlap,
333 0 : sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ),
334 0 : right_overlap, st->element_mode );
335 :
336 0 : tmpP16 += tcx5SizeFB;
337 0 : tmpP32 += tcx5SizeFB;
338 : }
339 : }
340 : ELSE /* transform_type[frameno] != TCX_5 */
341 : {
342 0 : assert( transform_type[frameno] == TCX_10 || transform_type[frameno] == TCX_20 );
343 :
344 : /* TCX20/TCX10 */
345 0 : spectrum_e[frameno] = 16;
346 0 : move16();
347 0 : test();
348 0 : test();
349 0 : IF( ( EQ_16( transform_type[frameno], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) && NE_16( st->mct_chan_mode, MCT_CHAN_MODE_LFE ) )
350 0 : {
351 : Word32 tmp_buf[L_FRAME_PLUS];
352 : Word16 Q, tmp1, tmp2;
353 :
354 0 : Q = 0;
355 0 : move16();
356 :
357 0 : wtda_fx( hTcxEnc->new_speech_TCX, &Q, tmp_buf, NULL, NULL, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX );
358 :
359 0 : WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, lpc_left_overlap_mode, lpc_right_overlap_mode, &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, st->element_mode != IVAS_CPE_MDCT, 1 );
360 :
361 : /* scale by NORM_MDCT_FACTOR / L */
362 0 : tmp1 = mult_r( shl( L_subframe, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR Q15*/ ); /* 4Q11 */
363 0 : tmp2 = 4;
364 0 : move16();
365 0 : tmp1 = ISqrt16( tmp1, &tmp2 );
366 :
367 0 : FOR( i = 0; i < L_subframe; i++ )
368 : {
369 0 : tmp_buf[i] = Mpy_32_16_1( tmp_buf[i], tmp1 ); /* Q - 4 */
370 0 : move32();
371 : }
372 0 : Q = sub( Q, tmp2 );
373 :
374 : /* DCT */
375 0 : edct_fx( tmp_buf, spectrum[frameno], L_subframe, &Q );
376 0 : *spectrum_e = sub( 31, Q );
377 : }
378 : ELSE
379 : {
380 0 : TCX_MDCT( tcx20Win, spectrum[frameno], &spectrum_e[frameno], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
381 : }
382 :
383 : /* For TCX20 at bitrates up to 64 kbps we need the power spectrum */
384 :
385 : /* high-band gain control in case of BWS */
386 0 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
387 : {
388 0 : test();
389 0 : test();
390 0 : IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) && ( ( LT_32( st->total_brate, HQ_96k ) ) || st->igf ) )
391 : {
392 :
393 0 : pMdstWin = tcx20Win;
394 0 : test();
395 0 : if ( ( ( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
396 : {
397 0 : pMdstWin = mdstWin;
398 : }
399 :
400 : /* Compute noise-measure flags for spectrum filling and quantization */
401 0 : AnalyzePowerSpectrum_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ),
402 0 : L_subframe, left_overlap, right_overlap, spectrum[frameno], spectrum_e[frameno],
403 : pMdstWin, powerSpec, &powerSpec_e );
404 : }
405 : }
406 : }
407 :
408 0 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
409 : {
410 0 : test();
411 0 : test();
412 0 : TNSAnalysis_fx( st->hTcxCfg, L_frameTCX,
413 0 : st->hTcxCfg->tcx_coded_lines,
414 0 : transform_type[frameno], ( frameno == 0 ) && ( st->last_core == ACELP_CORE ),
415 0 : spectrum[frameno], &hTcxEnc->tnsData[frameno], &hTcxEnc->fUseTns[frameno], NULL );
416 : {
417 0 : EncodeTnsData_fx( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frameno],
418 0 : param_core + frameno * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, pTnsSize + frameno, pTnsBits + frameno );
419 : }
420 0 : IF( EQ_16( transform_type[frameno], TCX_5 ) )
421 : {
422 : /* group sub-windows: interleave bins according to their frequencies */
423 0 : FOR( i = 0; i < tcx5SizeFB; i++ )
424 : {
425 0 : interleaveBuf[2 * i] = spectrum[frameno][i]; /* exp(spectrum_e) */
426 0 : move32();
427 0 : interleaveBuf[2 * i + 1] = spectrum[frameno][tcx5SizeFB + i]; /* exp(spectrum_e) */
428 0 : move32();
429 : }
430 0 : MVR2R_WORD32( interleaveBuf, spectrum[frameno], tcx10SizeFB );
431 : }
432 :
433 : /*--------------------------------------------------------------*
434 : * LPC analysis
435 : *---------------------------------------------------------------*/
436 :
437 : {
438 0 : HBAutocorrelation_fx( st->hTcxCfg, lpc_left_overlap_mode, lpc_right_overlap_mode, &st->speech_enc_pe[frameno * tcx10Size],
439 0 : shr( L_frame, sub( nSubframes, 1 ) ), r, M );
440 :
441 0 : FOR( i = 0; i <= M; i++ )
442 : {
443 0 : move16();
444 0 : move16();
445 0 : r_l[frameno][i] = L_Extract_lc( r[i], &r_h[frameno][i] );
446 : }
447 :
448 0 : adapt_lag_wind( r_h[frameno], r_l[frameno], M, alw_pitch_lag_12k8[frameno], alw_voicing[frameno], st->sr_core );
449 :
450 0 : E_LPC_lev_dur( r_h[frameno], r_l[frameno], A, epsP, M, NULL );
451 :
452 0 : E_LPC_a_lsp_conversion( A, lsp[nSubframes - 1 - frameno], st->lspold_enc_fx, M );
453 : }
454 0 : IF( st->igf )
455 : {
456 0 : ProcessIGF_fx( st->hIGFEnc, st, spectrum[frameno], &( spectrum_e[frameno] ), powerSpec, &powerSpec_e, transform_type[frameno] == TCX_20, hTcxEnc->fUseTns[frameno], ( st->last_core == ACELP_CORE ), frameno );
457 : }
458 :
459 : /* Copy memory */
460 0 : MVR2R_WORD16( lsp_new, st->lspold_enc_fx, M ); /* Q15 */
461 : }
462 : }
463 :
464 0 : return;
465 : }
466 :
467 : /*-------------------------------------------------------------------*
468 : * core_signal_analysis_high_bitrate_ivas_fx()
469 : *
470 : *
471 : *-------------------------------------------------------------------*/
472 :
473 859238 : void core_signal_analysis_high_bitrate_ivas_fx(
474 : const Word16 *new_samples, /*i: Q0 */
475 : const Word16 T_op[3], /* i : open-loop pitch values for quantiz. Q0*/
476 : Word16 lsp_new[], /* Q15 */
477 : Word16 lsp_mid[], /* Q15 */
478 : Encoder_State *st,
479 : Word16 pTnsSize[], /* Q0 */
480 : Word16 pTnsBits[], /* Q0 */
481 : Word16 param_core[], /* Q0 */
482 : Word16 *ltpBits, /* Q0 */
483 : Word32 *windowed_samples, /* q_win */
484 : const Word16 L_frame, /* Q0 */
485 : const Word16 L_frameTCX, /* Q0 */
486 : const Word16 last_element_mode, /* Q0 */
487 : const Word16 vad_hover_flag, /* i : VAD hangover flag Q0*/
488 : Word32 **spectrum, /* exp(spectrum_e) */
489 : Word16 *spectrum_e,
490 : Word16 *Q_new,
491 : Word16 *q_win )
492 : {
493 859238 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
494 859238 : const Word16 last_overlap = st->hTcxCfg->tcx_last_overlap_mode;
495 859238 : const Word16 curr_overlap = st->hTcxCfg->tcx_curr_overlap_mode;
496 859238 : const Word16 minWindowLen = sub( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 );
497 : Word16 i, frameno;
498 : Word16 L_subframe;
499 859238 : Word16 left_overlap = -1, right_overlap = -1, folding_offset;
500 : Word32 buf[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */
501 : Word32 buf_powerSPec[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */
502 : Word16 buf_powerSPec_exp[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */
503 : Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */
504 : Word16 *pMdstWin;
505 : Word16 lpc_left_overlap_mode, lpc_right_overlap_mode;
506 859238 : Word32 *powerSpec = buf_powerSPec;
507 859238 : Word16 *powerSpec_e = buf_powerSPec_exp;
508 859238 : Word16 *tcx20Win = (Word16 *) buf;
509 859238 : Word32 *tcx20Win_32 = buf;
510 : Word32 interleaveBuf[N_TCX10_MAX];
511 859238 : Word16 *tcx5Win = (Word16 *) interleaveBuf; /* Buffer for TCX5 windowing and interleaving. */
512 : Word16 nSubframes;
513 : Word16 overlap_mode[3];
514 859238 : Word16 *transform_type = hTcxEnc->transform_type;
515 : Word32 r[M + 1];
516 : Word16 A[M + 1];
517 : Word16 r_h[NB_DIV][M + 1], r_l[NB_DIV][M + 1];
518 : Word16 *lsp[2];
519 859238 : const Word16 tcx10SizeFB = shl( st->hTcxCfg->tcx5SizeFB, 1 );
520 859238 : const Word16 tcx5SizeFB = st->hTcxCfg->tcx5SizeFB;
521 859238 : const Word16 tcx10Size = shl( st->hTcxCfg->tcx5Size, 1 );
522 859238 : Word16 alw_pitch_lag_12k8[2], alw_pitch_lag_12k8_wc = -1;
523 859238 : Word16 alw_voicing[2], alw_voicing_wc = -1;
524 859238 : Word16 disable_ltp = 0;
525 : Word16 tmp, *tmpP16;
526 859238 : Word16 q_mdstWin = st->q_inp, q_tcx20Win = st->q_inp;
527 : Word32 *tmpP32;
528 : Word16 Q_exp;
529 : Word32 L_tmpbuf[N_MAX + L_MDCT_OVLP_MAX];
530 859238 : move16();
531 859238 : move16();
532 859238 : move16();
533 859238 : move16();
534 859238 : move16();
535 859238 : move16();
536 859238 : move16();
537 859238 : move16();
538 : (void) vad_hover_flag;
539 : Word16 Q_win_temp[2];
540 859238 : Word16 *speech_ltp_fx = NULL;
541 859238 : Word16 *wspeech_fx = NULL;
542 859238 : Word16 *speech_fx = NULL;
543 859238 : Word16 q_out_wtda = st->q_inp;
544 859238 : move16();
545 : Word16 win_len[2];
546 859238 : move16();
547 : Word16 shift;
548 859238 : set32_fx( buf_powerSPec, 0, N_MAX + L_MDCT_OVLP_MAX );
549 859238 : set16_fx( buf_powerSPec_exp, 0, N_MAX + L_MDCT_OVLP_MAX );
550 :
551 859238 : if ( NE_16( last_element_mode, st->element_mode ) )
552 : {
553 1754 : disable_ltp = 1; /* disable TCX-LTP in stereo switching to avoid discontinuities in synthesis */
554 1754 : move16();
555 : }
556 :
557 : /*--------------------------------------------------------------*
558 : * Input Signal Processing: copy, HP filter, pre-emphasis
559 : *---------------------------------------------------------------*/
560 :
561 : /* Copy Samples */
562 859238 : test();
563 859238 : IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
564 : {
565 106874 : Copy_Scale_sig( new_samples, st->new_speech_enc, L_frame, sub( 15, st->exp_buf_speech_enc ) );
566 : /* st->new_speech_enc copied from new_samples in Q st->exp_buf_speech_enc
567 : This is considering new_samples is in q 0 in current code*/
568 : }
569 :
570 : /*--------------------------------------------------------------*
571 : * TCX-LTP
572 : *---------------------------------------------------------------*/
573 :
574 859238 : if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
575 : {
576 14464 : if ( st->element_mode > EVS_MONO )
577 : {
578 14464 : wspeech_fx = st->buf_wspeech_enc + st->L_frame + L_SUBFR;
579 : }
580 : else
581 : {
582 0 : wspeech_fx = st->buf_wspeech_enc + st->L_frame + idiv1616( st->L_frame, st->nb_subfr );
583 : }
584 : }
585 844774 : else if ( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
586 : {
587 221315 : speech_fx = st->buf_speech_enc + st->encoderPastSamples_enc;
588 221315 : speech_ltp_fx = st->hTcxEnc->buf_speech_ltp + st->encoderPastSamples_enc;
589 : }
590 :
591 859238 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
592 : {
593 14464 : tcx_ltp_encode_ivas_fx( st, hTcxEnc->tcxMode, L_frame, wspeech_fx, NULL, wspeech_fx, T_op, ¶m_core[1 + NOISE_FILL_RANGES], ltpBits, NULL, disable_ltp, st->element_mode );
594 : }
595 844774 : ELSE IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
596 : {
597 221315 : tcx_ltp_encode_ivas_fx( st, hTcxEnc->tcxMode, L_frame, speech_fx + st->encoderLookahead_enc, speech_ltp_fx + st->encoderLookahead_enc, speech_fx + st->encoderLookahead_enc, T_op, ¶m_core[1 + NOISE_FILL_RANGES], ltpBits, NULL, disable_ltp, st->element_mode );
598 : }
599 :
600 859238 : test();
601 859238 : IF( st->tcxonly && NE_16( st->element_mode, IVAS_CPE_MDCT ) )
602 : {
603 106874 : Copy( st->speech_enc + st->encoderLookahead_enc, st->new_speech_enc_pe, L_frame ); // Assuming both exp_buf_speech_enc_pe and exp_buf_speech_enc are same
604 :
605 106874 : PREEMPH_FX( st->new_speech_enc_pe, st->preemph_fac, L_frame, &( st->mem_preemph_enc ) ); // using this to keep values alligned in Q-1
606 : }
607 :
608 : /* Rescale Memory */
609 859238 : Q_exp = sub( *Q_new, st->prev_Q_new );
610 859238 : move16();
611 :
612 859238 : Scale_sig( st->old_inp_16k_fx, L_INP_MEM, sub( *Q_new, sub( Q15, st->exp_old_inp_16k ) ) ); // *Q_new
613 859238 : st->exp_old_inp_16k = sub( Q15, *Q_new );
614 859238 : move16();
615 859238 : IF( Q_exp != 0 )
616 : {
617 498 : Scale_sig( st->buf_speech_enc_pe, st->encoderPastSamples_enc + st->encoderLookahead_enc, sub( Q_exp, sub( Q15, st->exp_buf_speech_enc_pe ) ) ); // *Q_new
618 498 : st->exp_buf_speech_enc_pe = sub( Q15, Q_exp );
619 498 : move16();
620 498 : Scale_sig( &( st->mem_wsp_enc ), 1, Q_exp ); // *Q_new
621 : }
622 :
623 859238 : IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) )
624 : {
625 15799 : Copy( ¶m_core[1 + NOISE_FILL_RANGES], ¶m_core[NPRM_DIV + 1 + NOISE_FILL_RANGES], LTPSIZE ); // Q0
626 : }
627 :
628 859238 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
629 : {
630 235779 : lsp[0] = lsp_new; // Q15
631 235779 : move16();
632 235779 : lsp[1] = lsp_mid; // Q15
633 235779 : move16();
634 : }
635 :
636 : /*-------------------------------------------------------------------------*
637 : * Decision matrix for the transform and overlap length
638 : *--------------------------------------------------------------------------*/
639 :
640 859238 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
641 : {
642 235779 : alw_pitch_lag_12k8[0] = st->pitch[0]; // Q0
643 235779 : move16();
644 235779 : alw_pitch_lag_12k8[1] = st->pitch[1]; // Q0
645 235779 : move16();
646 235779 : alw_voicing[0] = st->voicing_fx[0]; // Q15
647 235779 : move16();
648 235779 : alw_voicing[1] = st->voicing_fx[1]; // Q15
649 235779 : move16();
650 235779 : alw_pitch_lag_12k8_wc = s_min( alw_pitch_lag_12k8[0], alw_pitch_lag_12k8[1] ); // Q0
651 235779 : alw_voicing_wc = s_max( alw_voicing[0], alw_voicing[1] ); // Q15
652 : }
653 :
654 859238 : overlap_mode[0] = last_overlap; /* Overlap between the last and the current frame Q0*/
655 859238 : move16();
656 :
657 859238 : IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) )
658 : {
659 843439 : nSubframes = 1;
660 843439 : move16();
661 843439 : transform_type[0] = TCX_20;
662 843439 : move16();
663 843439 : transform_type[1] = TCX_20;
664 843439 : move16();
665 843439 : overlap_mode[1] = curr_overlap; /* Overlap between the current and the next frame Q0*/
666 843439 : move16();
667 :
668 843439 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
669 : {
670 233720 : alw_pitch_lag_12k8[0] = alw_pitch_lag_12k8_wc; // Q0
671 233720 : move16();
672 233720 : alw_voicing[0] = alw_voicing_wc; // Q15
673 233720 : move16();
674 : }
675 : }
676 : ELSE
677 : {
678 15799 : nSubframes = 2;
679 15799 : move16();
680 15799 : IF( curr_overlap == FULL_OVERLAP )
681 : {
682 10262 : transform_type[0] = TCX_5;
683 10262 : move16();
684 10262 : transform_type[1] = TCX_10;
685 10262 : move16();
686 :
687 10262 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 2nd and 3rd sub-frame */
688 10262 : move16();
689 10262 : if ( EQ_16( last_overlap, HALF_OVERLAP ) )
690 : {
691 1892 : overlap_mode[1] = HALF_OVERLAP;
692 1892 : move16();
693 : }
694 : }
695 5537 : ELSE IF( last_overlap == FULL_OVERLAP )
696 : {
697 4926 : transform_type[0] = TCX_10;
698 4926 : move16();
699 4926 : transform_type[1] = TCX_5;
700 4926 : move16();
701 :
702 4926 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 1st and 2nd sub-frame */
703 4926 : move16();
704 4926 : if ( EQ_16( curr_overlap, HALF_OVERLAP ) )
705 : {
706 2525 : overlap_mode[1] = HALF_OVERLAP;
707 2525 : move16();
708 : }
709 : }
710 : ELSE
711 : {
712 611 : transform_type[0] = transform_type[1] = TCX_5;
713 611 : move16();
714 611 : move16();
715 :
716 611 : overlap_mode[1] = MIN_OVERLAP; /* Overlap between 2nd and 3rd sub-frame */
717 611 : move16();
718 611 : test();
719 611 : if ( EQ_16( last_overlap, HALF_OVERLAP ) && EQ_16( curr_overlap, HALF_OVERLAP ) )
720 : {
721 179 : overlap_mode[1] = HALF_OVERLAP;
722 179 : move16();
723 : }
724 : }
725 15799 : overlap_mode[2] = curr_overlap; /* Overlap between the current and the next frame Q0*/
726 15799 : move16();
727 : }
728 :
729 859238 : test();
730 859238 : IF( st->igf && NE_16( transform_type[0], TCX_20 ) )
731 : {
732 11042 : IGFEncResetTCX10BitCounter_fx( st->hIGFEnc );
733 : }
734 :
735 : /*-------------------------------------------------------------------------*
736 : * Get MDCT output and TNS parameters. Apply TNS in the spectrum if needed
737 : *--------------------------------------------------------------------------*/
738 :
739 1734275 : FOR( frameno = 0; frameno < nSubframes; frameno++ )
740 : {
741 875037 : L_subframe = L_frameTCX; // Q0
742 875037 : move16();
743 875037 : IF( NE_16( nSubframes, 1 ) )
744 : {
745 31598 : L_subframe = shr( L_frameTCX, 1 );
746 : }
747 :
748 875037 : lpc_left_overlap_mode = overlap_mode[frameno]; // Q0
749 875037 : move16();
750 875037 : lpc_right_overlap_mode = overlap_mode[frameno + 1]; // Q0
751 875037 : move16();
752 875037 : if ( EQ_16( lpc_left_overlap_mode, ALDO_WINDOW ) )
753 : {
754 823160 : lpc_left_overlap_mode = FULL_OVERLAP;
755 823160 : move16();
756 : }
757 875037 : if ( EQ_16( lpc_right_overlap_mode, ALDO_WINDOW ) )
758 : {
759 824788 : lpc_right_overlap_mode = FULL_OVERLAP;
760 824788 : move16();
761 : }
762 :
763 875037 : test();
764 875037 : IF( ( EQ_16( transform_type[frameno], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) )
765 : {
766 834222 : wtda_fx( hTcxEnc->new_speech_TCX, &q_out_wtda, tcx20Win_32, NULL, NULL, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX );
767 :
768 834222 : IF( windowed_samples != NULL ) /* store overlap data for later */
769 : {
770 608358 : assert( frameno == 0 );
771 608358 : windowed_samples[0] = L_deposit_l( overlap_mode[frameno] ); // Q0
772 608358 : windowed_samples[1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0
773 608358 : *q_win = 0;
774 608358 : move16();
775 : }
776 834222 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
777 : {
778 : Word16 left_overlap_mode, right_overlap_mode;
779 225864 : if ( EQ_16( overlap_mode[frameno], ALDO_WINDOW ) )
780 : {
781 223944 : left_overlap_mode = FULL_OVERLAP;
782 : }
783 : else
784 : {
785 1920 : left_overlap_mode = overlap_mode[frameno]; // Q0
786 : }
787 :
788 225864 : if ( EQ_16( overlap_mode[frameno + 1], ALDO_WINDOW ) )
789 : {
790 224215 : right_overlap_mode = FULL_OVERLAP;
791 : }
792 : else
793 : {
794 1649 : right_overlap_mode = overlap_mode[frameno + 1]; // Q0
795 : }
796 : /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */
797 225864 : WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, left_overlap_mode, right_overlap_mode, &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 1, 1 );
798 : }
799 : }
800 : ELSE
801 : {
802 : /* Windowing of the 2xTCX5 subframes or 1xTCX10 or 1xTCX20 */
803 40815 : WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno],
804 40815 : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB],
805 40815 : &L_subframe, tcx20Win, st->element_mode != IVAS_CPE_MDCT /* truncate_aldo */, 1 );
806 :
807 40815 : IF( windowed_samples != NULL ) /* save windowed speech_TCX samples */
808 : {
809 28841 : assert( L_subframe + ( left_overlap + right_overlap ) / 2 < 2 * L_FRAME_MAX / nSubframes - L_FRAME_MAX / 8 );
810 28841 : win_len[frameno] = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) );
811 28841 : move16();
812 28841 : windowed_samples[frameno * L_FRAME_MAX + 0] = L_deposit_l( overlap_mode[frameno] ); // Q0
813 28841 : move32();
814 28841 : windowed_samples[frameno * L_FRAME_MAX + 1] = L_deposit_l( overlap_mode[frameno + 1] ); // Q0
815 28841 : move32();
816 28841 : Copy_Scale_sig_16_32_DEPREC( tcx20Win, windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), negate( q_tcx20Win ) );
817 28841 : *q_win = s_min( *q_win, sub( L_norm_arr( windowed_samples + add( imult1616( frameno, L_FRAME_MAX ), 2 ), add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ) ), 1 ) );
818 28841 : move16();
819 28841 : Q_win_temp[frameno] = *q_win;
820 28841 : move16();
821 :
822 28841 : Scale_sig32( windowed_samples + frameno * L_FRAME_MAX + 2, win_len[frameno], *q_win ); // q_win
823 :
824 28841 : IF( EQ_16( frameno, 1 ) )
825 : {
826 13740 : Scale_sig32( windowed_samples + 2, win_len[0], sub( *q_win, Q_win_temp[0] ) ); // q_win
827 : }
828 : }
829 : }
830 :
831 875037 : IF( EQ_16( transform_type[frameno], TCX_5 ) )
832 : {
833 16410 : folding_offset = shr( left_overlap, 1 );
834 :
835 : /* Outter left folding */
836 1933780 : FOR( i = 0; i < folding_offset; i++ )
837 : {
838 1917370 : tcx20Win[folding_offset + i] = sub_sat( tcx20Win[folding_offset + i], tcx20Win[folding_offset - 1 - i] ); // q_tcx20Win
839 1917370 : move16();
840 : }
841 :
842 16410 : test();
843 16410 : test();
844 16410 : test();
845 16410 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && frameno == 0 && overlap_mode[0] == FULL_OVERLAP && GT_16( sub( L_subframe, left_overlap ), minWindowLen ) )
846 : {
847 6658 : tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 );
848 : Word32 L_tmp;
849 191508 : FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */
850 : {
851 184850 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win
852 184850 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win
853 184850 : tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win
854 184850 : move32();
855 : }
856 191508 : FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */
857 : {
858 184850 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win
859 184850 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win
860 184850 : tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win
861 184850 : move32();
862 : }
863 : }
864 :
865 : /* Outter right folding */
866 16410 : tmp = shr( right_overlap, 1 );
867 706000 : FOR( i = 0; i < tmp; i++ )
868 : {
869 689590 : tcx20Win[L_subframe + folding_offset - 1 - i] = add_sat( tcx20Win[L_subframe + folding_offset - 1 - i], tcx20Win[L_subframe + folding_offset + i] ); // q_tcx20Win
870 689590 : move16();
871 : }
872 :
873 : /* 2xTCX5 */
874 16410 : L_subframe = tcx5SizeFB;
875 16410 : move16();
876 :
877 16410 : tmpP16 = tcx20Win;
878 16410 : tmpP32 = hTcxEnc->spectrum_fx[frameno];
879 16410 : assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE );
880 : Word16 len[2], exp[2];
881 16410 : hTcxEnc->spectrum_e[frameno] = sub( 16, q_tcx20Win );
882 16410 : exp[0] = exp[1] = hTcxEnc->spectrum_e[frameno];
883 16410 : move16();
884 16410 : move16();
885 16410 : move16();
886 49230 : FOR( i = 0; i < 2; i++ )
887 : {
888 32820 : test();
889 32820 : test();
890 32820 : WindowSignal( st->hTcxCfg,
891 : folding_offset,
892 32820 : mac_r( -( 1 << 16 ), 3 << 8, shl( i, 7 ) ), /* equivalent to: i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */
893 32820 : mac_r( 2 << 16, -( 3 << 8 ), shl( i, 7 ) ), /* equivalent to: sub(i, 1) == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP */
894 32820 : &left_overlap, &right_overlap, tmpP16, &L_subframe, tcx5Win, st->element_mode != IVAS_CPE_MDCT, 1 );
895 :
896 65640 : TCX_MDCT( tcx5Win,
897 : tmpP32,
898 32820 : &exp[i],
899 : left_overlap,
900 32820 : sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ),
901 32820 : right_overlap, st->element_mode );
902 :
903 32820 : tmpP16 += tcx5SizeFB;
904 32820 : tmpP32 += tcx5SizeFB;
905 32820 : len[i] = L_subframe;
906 32820 : move16();
907 :
908 : /* high-band gain control in case of BWS */
909 32820 : IF( st->bwidth_sw_cnt > 0 )
910 : {
911 : Word16 exp_diff;
912 : Word32 factor;
913 :
914 58 : tmp = BASOP_Util_Divide1616_Scale( st->bwidth_sw_cnt, BWS_TRAN_PERIOD, &exp_diff );
915 58 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
916 :
917 58 : v_multc_fixed( hTcxEnc->spectrum_fx[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ),
918 : factor,
919 58 : hTcxEnc->spectrum_fx[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ),
920 58 : L_subframe - L_FRAME16k / ( 2 * nSubframes ) );
921 : }
922 : }
923 16410 : hTcxEnc->spectrum_e[frameno] = s_max( exp[0], exp[1] );
924 16410 : move16();
925 :
926 49230 : FOR( i = 0; i < 2; i++ )
927 : {
928 32820 : scale_sig32( hTcxEnc->spectrum_fx[frameno] + i * L_subframe, len[i], sub( exp[i], hTcxEnc->spectrum_e[frameno] ) );
929 : }
930 : }
931 : ELSE /* transform_type[frameno] != TCX_5 */
932 : {
933 858627 : assert( transform_type[frameno] == TCX_10 || transform_type[frameno] == TCX_20 );
934 :
935 : /* TCX20/TCX10 */
936 858627 : hTcxEnc->spectrum_e[frameno] = 16;
937 858627 : move16();
938 858627 : test();
939 858627 : test();
940 858627 : IF( ( EQ_16( transform_type[frameno], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) )
941 834222 : {
942 : /* DCT */
943 : Word16 Q;
944 :
945 834222 : Q = q_out_wtda;
946 834222 : edct_ivas_fx( tcx20Win_32, hTcxEnc->spectrum_fx[frameno], L_subframe, &Q );
947 834222 : hTcxEnc->spectrum_e[frameno] = sub( 31, Q );
948 834222 : move16();
949 :
950 : Word16 exp_diff;
951 : Word32 factor;
952 :
953 834222 : tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, L_subframe, &exp_diff );
954 834222 : tmp = Sqrt16( tmp, &exp_diff );
955 834222 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
956 :
957 834222 : v_multc_fixed( hTcxEnc->spectrum_fx[frameno], factor, hTcxEnc->spectrum_fx[frameno], L_subframe );
958 : }
959 : ELSE
960 : {
961 24405 : test();
962 24405 : test();
963 24405 : test();
964 24405 : test();
965 24405 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && frameno == 0 && EQ_16( transform_type[0], TCX_10 ) && overlap_mode[0] == FULL_OVERLAP && GT_16( sub( L_subframe, left_overlap ), minWindowLen ) )
966 : {
967 4037 : tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 );
968 : Word32 L_tmp;
969 104737 : FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */
970 : {
971 100700 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win
972 100700 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16, Q15) -> Q16 + q_tcx20Win
973 100700 : tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win
974 100700 : move32();
975 : }
976 104737 : FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */
977 : {
978 100700 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_tcx20Win, Q15) -> Q16 + q_tcx20Win
979 100700 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_tcx20Win, Q15) -> Q16 + q_tcx20Win
980 100700 : tcx20Win[left_overlap + i] = sub_sat( tcx20Win[left_overlap + i], extract_h( L_tmp ) ); // q_tcx20Win
981 100700 : move32();
982 : }
983 : }
984 :
985 24405 : TCX_MDCT( tcx20Win, hTcxEnc->spectrum_fx[frameno], &hTcxEnc->spectrum_e[frameno], left_overlap, sub( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode );
986 24405 : hTcxEnc->spectrum_e[frameno] = sub( hTcxEnc->spectrum_e[frameno], q_tcx20Win );
987 24405 : move16();
988 : }
989 :
990 : /* high-band gain control in case of BWS */
991 858627 : IF( st->bwidth_sw_cnt > 0 )
992 : {
993 : Word16 exp_diff;
994 : Word32 factor;
995 :
996 2337 : tmp = BASOP_Util_Divide1616_Scale( st->bwidth_sw_cnt, BWS_TRAN_PERIOD, &exp_diff );
997 2337 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
998 :
999 2337 : v_multc_fixed( hTcxEnc->spectrum_fx[frameno] + L_FRAME16k / nSubframes,
1000 : factor,
1001 2337 : hTcxEnc->spectrum_fx[frameno] + L_FRAME16k / nSubframes,
1002 2337 : L_subframe - L_FRAME16k / nSubframes );
1003 : }
1004 :
1005 858627 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
1006 : {
1007 : /* For TCX20 at bitrates up to 64 kbps we need the power spectrum */
1008 235641 : test();
1009 235641 : test();
1010 235641 : IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) && ( ( LT_32( st->total_brate, HQ_96k ) ) || st->igf ) )
1011 : {
1012 232556 : pMdstWin = tcx20Win;
1013 232556 : Word16 q_pmdstWin = q_tcx20Win;
1014 232556 : move16();
1015 232556 : test();
1016 232556 : if ( ( ( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) )
1017 : {
1018 224704 : pMdstWin = mdstWin;
1019 224704 : q_pmdstWin = q_mdstWin;
1020 224704 : move16();
1021 : }
1022 :
1023 : /* Compute noise-measure flags for spectrum filling and quantization */
1024 232556 : AnalyzePowerSpectrum_ivas_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ),
1025 232556 : L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno],
1026 : pMdstWin, q_pmdstWin, powerSpec, powerSpec_e );
1027 : }
1028 : }
1029 : }
1030 :
1031 875037 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
1032 : {
1033 : Word16 scale;
1034 637199 : L_subframe = idiv1616( L_frameTCX, nSubframes ); /* Q0 */
1035 :
1036 637199 : test();
1037 637199 : IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
1038 : {
1039 608358 : wtda_ext_fx( hTcxEnc->new_speech_TCX, mdstWin, overlap_mode[frameno], overlap_mode[frameno + 1], L_frameTCX, 3 );
1040 608358 : scale = sub( norm_arr( mdstWin, L_frameTCX ), 1 );
1041 608358 : scale = s_min( 1, scale ); // restricting the Q to zero or less
1042 608358 : scale_sig( mdstWin, L_frameTCX, scale );
1043 608358 : q_mdstWin = add( add( st->q_inp, -1 ), scale );
1044 : }
1045 : ELSE
1046 : {
1047 : Word16 sig_len;
1048 : /* Windowing for the MDST */
1049 28841 : WindowSignal( st->hTcxCfg, st->hTcxCfg->tcx_offsetFB, overlap_mode[frameno] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno], overlap_mode[frameno + 1] == ALDO_WINDOW ? FULL_OVERLAP : overlap_mode[frameno + 1], &left_overlap, &right_overlap, &hTcxEnc->speech_TCX[frameno * tcx10SizeFB], &L_subframe, mdstWin, 0, 1 );
1050 28841 : sig_len = add( L_subframe, shr( add( left_overlap, right_overlap ), 1 ) );
1051 28841 : scale = sub( norm_arr( mdstWin, sig_len ), 1 );
1052 28841 : scale = s_min( 0, scale ); // restricting the Q to zero or less
1053 28841 : scale_sig( mdstWin, sig_len, scale );
1054 28841 : q_mdstWin = add( scale, st->q_inp );
1055 : }
1056 :
1057 637199 : IF( EQ_16( transform_type[frameno], TCX_5 ) )
1058 : {
1059 : /* Outer left folding */
1060 1713373 : FOR( i = 0; i < left_overlap / 2; i++ )
1061 : {
1062 1699160 : mdstWin[left_overlap / 2 + i] = add( mdstWin[left_overlap / 2 + i], mdstWin[left_overlap / 2 - 1 - i] ); // q_mdstWin
1063 : }
1064 :
1065 14213 : test();
1066 14213 : test();
1067 14213 : IF( frameno == 0 && overlap_mode[0] == FULL_OVERLAP && GT_16( sub( L_subframe, left_overlap ), minWindowLen ) )
1068 : {
1069 6658 : tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 );
1070 6658 : shift = sub( q_mdstWin, add( Q16, st->q_inp ) );
1071 : Word32 L_tmp;
1072 191508 : FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */
1073 : {
1074 184850 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp
1075 184850 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp
1076 184850 : L_tmp = L_shl( L_tmp, shift ); // q_mdstWin
1077 184850 : mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin
1078 184850 : move32();
1079 : }
1080 191508 : FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */
1081 : {
1082 184850 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp
1083 184850 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp
1084 184850 : L_tmp = L_shl( L_tmp, shift ); // q_mdstWin
1085 184850 : mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin
1086 184850 : move32();
1087 : }
1088 : }
1089 :
1090 : /* Outer right folding */
1091 590773 : FOR( i = 0; i < right_overlap / 2; i++ )
1092 : {
1093 576560 : mdstWin[L_subframe + left_overlap / 2 - 1 - i] = sub( mdstWin[L_subframe + left_overlap / 2 - 1 - i], mdstWin[L_subframe + left_overlap / 2 + i] ); // q_mdstWin
1094 576560 : move16();
1095 : }
1096 :
1097 : /* 2xTCX5 */
1098 14213 : L_subframe = tcx5SizeFB;
1099 14213 : move16();
1100 14213 : folding_offset = shr( left_overlap, 1 );
1101 14213 : move16();
1102 :
1103 42639 : FOR( i = 0; i < 2; i++ )
1104 : {
1105 28426 : assert( st->mct_chan_mode != MCT_CHAN_MODE_LFE );
1106 28426 : WindowSignal( st->hTcxCfg, folding_offset, i == 0 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, i == 1 ? RECTANGULAR_OVERLAP : MIN_OVERLAP, &left_overlap, &right_overlap, mdstWin + i * tcx5SizeFB, &L_subframe, tcx5Win, 0, 1 );
1107 :
1108 28426 : spectrum_e[frameno] = sub( 16, q_mdstWin );
1109 28426 : move16();
1110 28426 : TCX_MDST( tcx5Win, spectrum[frameno] + i * tcx5SizeFB, &spectrum_e[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode );
1111 : /* high-band gain control in case of BWS */
1112 28426 : IF( st->bwidth_sw_cnt > 0 )
1113 : {
1114 : Word16 exp_diff;
1115 : Word32 factor;
1116 :
1117 56 : tmp = BASOP_Util_Divide1616_Scale( st->bwidth_sw_cnt, BWS_TRAN_PERIOD, &exp_diff );
1118 56 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
1119 :
1120 56 : v_multc_fixed( spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ),
1121 : factor,
1122 56 : spectrum[frameno] + i * tcx5SizeFB + L_FRAME16k / ( 2 * nSubframes ),
1123 56 : L_subframe - L_FRAME16k / ( 2 * nSubframes ) );
1124 : }
1125 : }
1126 : }
1127 : ELSE /* transform_type[frameno] != TCX_5 */
1128 : {
1129 622986 : spectrum_e[frameno] = sub( 16, q_mdstWin );
1130 622986 : test();
1131 622986 : IF( EQ_16( transform_type[frameno], TCX_20 ) && NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) )
1132 608358 : {
1133 : Word16 Q;
1134 608358 : Copy_Scale_sig_16_32_no_sat( mdstWin, L_tmpbuf, N_MAX + L_MDCT_OVLP_MAX, 16 );
1135 :
1136 608358 : Q = add( q_mdstWin, 16 );
1137 608358 : move16();
1138 608358 : edst_fx( L_tmpbuf, spectrum[frameno], L_subframe, &Q );
1139 608358 : spectrum_e[frameno] = 31 - Q;
1140 :
1141 : Word16 exp_diff;
1142 : Word32 factor;
1143 :
1144 608358 : tmp = BASOP_Util_Divide1616_Scale( NORM_MDCT_FACTOR, L_subframe, &exp_diff );
1145 608358 : tmp = Sqrt16( tmp, &exp_diff );
1146 608358 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
1147 :
1148 608358 : v_multc_fixed( spectrum[frameno], factor, spectrum[frameno], L_subframe );
1149 : }
1150 : ELSE
1151 : {
1152 14628 : test();
1153 14628 : test();
1154 14628 : test();
1155 14628 : IF( frameno == 0 && EQ_16( transform_type[0], TCX_10 ) && overlap_mode[0] == FULL_OVERLAP && GT_16( sub( L_subframe, left_overlap ), minWindowLen ) )
1156 : {
1157 4037 : tmp = shr( st->hTcxCfg->tcx_mdct_window_min_lengthFB, 1 );
1158 : Word32 L_tmp;
1159 4037 : shift = sub( q_mdstWin, add( Q16, st->q_inp ) );
1160 104737 : FOR( i = minWindowLen; i >= tmp; i-- ) /* outer left folding of shortened long ALDO slope */
1161 : {
1162 100700 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp
1163 100700 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[minWindowLen - i].v.im ); // (Q16 + q_inp, Q15) -> Q16 + q_inp
1164 100700 : L_tmp = L_shl( L_tmp, shift ); // q_mdstWin
1165 100700 : mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin
1166 100700 : move32();
1167 : }
1168 104737 : FOR( i = tmp - 1; i >= 0; i-- ) /* outer left folding of shortened long ALDO slope */
1169 : {
1170 100700 : L_tmp = L_mult( hTcxEnc->speech_TCX[-1 - i], st->hTcxCfg->tcx_aldo_window_1_FB[left_overlap / 2 + minWindowLen - i] ); // (q_inp, Q15) -> Q16 + q_inp
1171 100700 : L_tmp = Mpy_32_16_1( L_tmp, st->hTcxCfg->tcx_mdct_window_minimumFB[i].v.re ); // (Q16 + q_inp, Q15) -> Q16 + q_inp
1172 100700 : L_tmp = L_shl( L_tmp, shift ); // q_mdstWin
1173 100700 : mdstWin[left_overlap + i] = add( mdstWin[left_overlap + i], extract_l( L_tmp ) ); // q_mdstWin
1174 100700 : move32();
1175 : }
1176 : }
1177 :
1178 14628 : TCX_MDST( mdstWin, spectrum[frameno], &spectrum_e[frameno], left_overlap, L_subframe - ( left_overlap + right_overlap ) / 2, right_overlap, st->element_mode );
1179 : }
1180 :
1181 : /* high-band gain control in case of BWS */
1182 622986 : IF( st->bwidth_sw_cnt > 0 )
1183 : {
1184 : Word16 exp_diff;
1185 : Word32 factor;
1186 :
1187 1340 : tmp = BASOP_Util_Divide1616_Scale( st->bwidth_sw_cnt, BWS_TRAN_PERIOD, &exp_diff );
1188 1340 : factor = L_shl( L_deposit_h( tmp ), exp_diff ); // Q31
1189 :
1190 1340 : v_multc_fixed( spectrum[frameno] + L_FRAME16k / nSubframes, factor, spectrum[frameno] + L_FRAME16k / nSubframes, L_subframe - L_FRAME16k / nSubframes );
1191 : }
1192 : }
1193 : }
1194 :
1195 875037 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
1196 : {
1197 237838 : test();
1198 237838 : IF( ( frameno == 0 ) && ( st->last_core == ACELP_CORE ) )
1199 : {
1200 7856 : TNSAnalysis_ivas_fx( st->hTcxCfg, L_frameTCX, st->hTcxCfg->tcx_coded_lines, transform_type[frameno], 1, hTcxEnc->spectrum_fx[frameno], st->hTranDet, -32768, &hTcxEnc->tnsData[frameno], &hTcxEnc->fUseTns[frameno], NULL );
1201 : }
1202 : ELSE
1203 : {
1204 229982 : TNSAnalysis_ivas_fx( st->hTcxCfg, L_frameTCX, st->hTcxCfg->tcx_coded_lines, transform_type[frameno], 0, hTcxEnc->spectrum_fx[frameno], st->hTranDet, -32768, &hTcxEnc->tnsData[frameno], &hTcxEnc->fUseTns[frameno], NULL );
1205 : }
1206 :
1207 237838 : IF( st->hTcxCfg->fIsTNSAllowed )
1208 : {
1209 161707 : EncodeTnsData_fx( st->hTcxCfg->pCurrentTnsConfig, &hTcxEnc->tnsData[frameno],
1210 161707 : param_core + frameno * NPRM_DIV + 1 + NOISE_FILL_RANGES + LTPSIZE, pTnsSize + frameno, pTnsBits + frameno );
1211 : }
1212 :
1213 237838 : IF( EQ_16( transform_type[frameno], TCX_5 ) )
1214 : {
1215 : /* group sub-windows: interleave bins according to their frequencies */
1216 524837 : FOR( i = 0; i < tcx5SizeFB; i++ )
1217 : {
1218 522640 : interleaveBuf[2 * i] = hTcxEnc->spectrum_fx[frameno][i]; /* hTcxEnc->spectrum_e */
1219 522640 : move32();
1220 522640 : interleaveBuf[2 * i + 1] = hTcxEnc->spectrum_fx[frameno][tcx5SizeFB + i]; /* hTcxEnc->spectrum_e */
1221 522640 : move32();
1222 : }
1223 2197 : MVR2R_WORD32( interleaveBuf, hTcxEnc->spectrum_fx[frameno], tcx10SizeFB );
1224 : }
1225 :
1226 : /*--------------------------------------------------------------*
1227 : * LPC analysis
1228 : *---------------------------------------------------------------*/
1229 :
1230 237838 : IF( st->tcxonly )
1231 : {
1232 108933 : HBAutocorrelation_fx( st->hTcxCfg, lpc_left_overlap_mode, lpc_right_overlap_mode, &st->speech_enc_pe[frameno * tcx10Size],
1233 108933 : shr( L_frame, sub( nSubframes, 1 ) ), r, M );
1234 :
1235 1960794 : FOR( i = 0; i <= M; i++ )
1236 : {
1237 1851861 : r_l[frameno][i] = L_Extract_lc( r[i], &r_h[frameno][i] );
1238 1851861 : move16();
1239 1851861 : move16();
1240 : }
1241 :
1242 108933 : adapt_lag_wind( r_h[frameno], r_l[frameno], M, alw_pitch_lag_12k8[frameno], alw_voicing[frameno], st->sr_core );
1243 :
1244 108933 : E_LPC_lev_dur( r_h[frameno], r_l[frameno], A, NULL, M, NULL );
1245 :
1246 108933 : E_LPC_a_lsp_conversion( A, lsp[nSubframes - 1 - frameno], st->lspold_enc_fx, M );
1247 : }
1248 :
1249 237838 : IF( st->igf )
1250 : {
1251 227097 : Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] );
1252 227097 : ProcessIGF_ivas_fx( st, N_MAX + L_MDCT_OVLP_MAX, hTcxEnc->spectrum_fx[frameno], &q_spectrum, hTcxEnc->spectrum_fx[frameno], q_spectrum, powerSpec, powerSpec_e, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag );
1253 : }
1254 : }
1255 : }
1256 :
1257 :
1258 859238 : IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) )
1259 : {
1260 : /* Copy memory */
1261 235779 : MVR2R_WORD16( lsp_new, st->lspold_enc_fx, M );
1262 : }
1263 :
1264 859238 : return;
1265 : }
|