Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "prot_fx.h" /* Function prototypes */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "ivas_prot_fx.h"
10 : /*--------------------------------------------------------------------------
11 : * hq_core_dec()
12 : *
13 : * HQ core decoder
14 : *--------------------------------------------------------------------------*/
15 :
16 429 : void hq_core_dec_fx(
17 : Decoder_State *st_fx, /* i/o: decoder state structure fx */
18 : Word16 synth[], /* o : output synthesis Q_synth*/
19 : Word16 *Q_synth, /* o : Q value of synth */
20 : const Word16 output_frame, /* i : output frame length Q0*/
21 : const Word16 hq_core_type, /* i : HQ core type Q0*/
22 : const Word16 core_switching_flag /* i : ACELP->HQ switching frame flag Q0*/
23 : )
24 : {
25 : Word16 num_bits, is_transient, hqswb_clas, inner_frame;
26 : Word16 i, j, flag_uv, num_Sb, nb_sfm;
27 : Word16 ynrm[NB_SFM], num_bands_p[MAX_SB_NB];
28 : Word16 ener_match; /* Q13 */
29 : Word32 t_audio_q[L_FRAME48k_EXT]; /* Q12 */
30 : Word16 Q_audio;
31 : Word32 wtda_audio[2 * L_FRAME48k];
32 : Word16 delay_comp;
33 : Word32 normq_fx[NB_SFM];
34 : Word16 mean_en_high_fx;
35 : Word16 SWB_fenv_fx[SWB_FENV + DIM_FB];
36 : const Word16 *sfmsize, *sfm_start, *sfm_end;
37 : Word16 gapsynth_fx[L_FRAME48k];
38 : Word16 tmp, tmp_loop;
39 : Word32 L_tmp;
40 : UWord16 lsb;
41 : Word16 L_spec;
42 : HQ_NBFEC_HANDLE hHQ_nbfec;
43 : HQ_DEC_HANDLE hHQ_core;
44 429 : hHQ_nbfec = st_fx->hHQ_nbfec;
45 429 : hHQ_core = st_fx->hHQ_core;
46 :
47 : /*--------------------------------------------------------------------------
48 : * Initializations
49 : *--------------------------------------------------------------------------*/
50 :
51 429 : set32_fx( t_audio_q, 0, L_FRAME48k_EXT );
52 429 : set16_fx( gapsynth_fx, 0, L_FRAME48k );
53 429 : set16_fx( num_bands_p, 0, MAX_SB_NB );
54 429 : set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */
55 429 : mean_en_high_fx = 0;
56 429 : move16();
57 429 : Q_audio = 12;
58 429 : move16();
59 429 : sfm_start = sfm_end = NULL;
60 429 : num_Sb = nb_sfm = 0;
61 429 : move16();
62 429 : move16();
63 :
64 429 : st_fx->hTcxCfg->tcx_last_overlap_mode = st_fx->hTcxCfg->tcx_curr_overlap_mode; /* Q0 */
65 429 : move16();
66 429 : if ( EQ_16( st_fx->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
67 : {
68 1 : st_fx->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; /* Q0 */
69 1 : move16();
70 : }
71 429 : st_fx->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; /* Q0 */
72 429 : move16();
73 : /*--------------------------------------------------------------------------
74 : * Find the number of bits for transform-domain coding
75 : *--------------------------------------------------------------------------*/
76 :
77 : /* set the total bit-budget */
78 : /*num_bits = (short)(st->total_brate / 50); */
79 429 : Mpy_32_16_ss( st_fx->total_brate, 5243, &L_tmp, &lsb ); /* 5243 is 1/50 in Q18. (0+18-15=3) */
80 429 : num_bits = extract_l( L_shr( L_tmp, 3 ) ); /*Q0 */
81 429 : IF( !st_fx->bfi )
82 : {
83 429 : IF( EQ_16( core_switching_flag, 1 ) )
84 : {
85 : {
86 24 : core_switching_hq_prepare_dec_fx( st_fx, &num_bits, output_frame );
87 :
88 : /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */
89 24 : if ( GT_16( num_bits, HQ_48k / 50 ) )
90 : {
91 12 : num_bits = (Word16) ( HQ_48k / 50 );
92 12 : move16();
93 : }
94 : }
95 : }
96 : /* subtract signalling bits */
97 429 : num_bits = sub( num_bits, st_fx->next_bit_pos ); /* Q0 */
98 :
99 : /* set FEC parameters */
100 429 : flag_uv = sub( 1, hHQ_core->HqVoicing ); /* Q0 */
101 :
102 : /* subtract the number of bits for pitch & gain at higher bitrates */
103 429 : test();
104 429 : IF( !( core_switching_flag ) && GT_32( st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) )
105 : {
106 319 : hHQ_core->HqVoicing = get_next_indice( st_fx, 1 ); /* Q0 */
107 319 : move16();
108 319 : num_bits = sub( num_bits, 1 ); /* Q0 */
109 : }
110 : ELSE
111 : {
112 110 : hHQ_core->HqVoicing = 0;
113 110 : move16();
114 110 : if ( GT_32( st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) )
115 : {
116 12 : hHQ_core->HqVoicing = 1; /* Q0 */
117 12 : move16();
118 : }
119 : }
120 : }
121 : ELSE
122 : {
123 0 : flag_uv = 0;
124 0 : move16();
125 : }
126 :
127 : /* set inner frame (== coded bandwidth) length */
128 429 : inner_frame = inner_frame_tbl[st_fx->bwidth]; /* Q0 */
129 429 : move16();
130 429 : L_spec = inner_frame; /* Q0 */
131 429 : move16();
132 :
133 429 : IF( st_fx->bfi == 0 )
134 : {
135 429 : hHQ_core->ph_ecu_HqVoicing = 0;
136 429 : move16();
137 429 : if ( GE_16( output_frame, L_FRAME16k ) )
138 : {
139 429 : hHQ_core->ph_ecu_HqVoicing = hHQ_core->HqVoicing;
140 429 : move16();
141 : }
142 : }
143 :
144 429 : IF( EQ_16( output_frame, L_FRAME8k ) )
145 : {
146 0 : hq_configure_bfi_fx( &nb_sfm, &num_Sb, num_bands_p, &sfmsize, &sfm_start, &sfm_end );
147 : }
148 :
149 : /*--------------------------------------------------------------------------
150 : * transform-domain decoding
151 : *--------------------------------------------------------------------------*/
152 :
153 429 : IF( EQ_16( st_fx->bfi, 1 ) )
154 : {
155 0 : is_transient = hHQ_core->old_is_transient[0]; /* Q0 */
156 0 : move16();
157 0 : IF( GE_16( output_frame, L_FRAME16k ) ) /* Apply phase ecu for WB, SWB and FB */
158 : {
159 : /* ecu_rec sent to OLA, env_stab passed in ph_ecu_st */
160 0 : hq_ecu_fx( st_fx->hTcxDec->prev_good_synth_fx, t_audio_q, &hHQ_core->time_offs, hHQ_core->X_sav_fx, &hHQ_core->Q_X_sav, &hHQ_core->num_p, hHQ_core->plocs, hHQ_core->plocsi_fx, hHQ_core->env_stab_fx,
161 0 : &hHQ_core->last_fec, hHQ_core->ph_ecu_HqVoicing, &hHQ_core->ph_ecu_active, gapsynth_fx, st_fx->prev_bfi, hHQ_core->old_is_transient, hHQ_core->mag_chg_1st_fx,
162 0 : hHQ_core->Xavg_fx, &hHQ_core->beta_mute_fx, output_frame, st_fx );
163 : }
164 : ELSE
165 : {
166 0 : HQ_FEC_processing_fx( st_fx, t_audio_q, is_transient, hHQ_nbfec->ynrm_values_fx, hHQ_nbfec->r_p_values_fx, num_Sb, nb_sfm, num_bands_p,
167 : output_frame, sfm_start, sfm_end );
168 : }
169 :
170 0 : hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1]; /* Q0 */
171 0 : move16();
172 0 : hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0]; /* Q0 */
173 0 : move16();
174 :
175 0 : IF( GE_16( output_frame, L_FRAME16k ) )
176 : {
177 : /* keep st->previoussynth updated as in FEC_HQ_pitch_analysis but no LP analysis */
178 0 : delay_comp = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
179 :
180 0 : Copy( st_fx->previoussynth_fx + delay_comp, st_fx->previoussynth_fx, sub( output_frame, delay_comp ) ); /* Q0 */
181 0 : Copy( st_fx->delay_buf_out_fx, st_fx->previoussynth_fx + output_frame - delay_comp, delay_comp ); /* Q0 */
182 :
183 0 : flag_uv = 1;
184 0 : move16(); /* disable costly pitch out synthesis in bfi frame */
185 0 : hHQ_core->HqVoicing = sub( 1, flag_uv ); /* safety setting for HQ->ACELP switch logic Q0*/
186 0 : set16_fx( hHQ_core->fer_samples_fx, 0, L_FRAME48k ); /* safety, create a known signal state for HQ->ACELP switch logic */
187 : }
188 : }
189 : ELSE
190 : {
191 429 : IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) )
192 : {
193 32 : IF( EQ_16( st_fx->prev_bfi, 1 ) )
194 : {
195 0 : set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX );
196 0 : set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX );
197 0 : hHQ_core->last_max_pos_pulse = 0;
198 0 : move16();
199 : }
200 :
201 : /* HQ low rate decoder */
202 32 : hq_lr_dec_fx( st_fx, t_audio_q, inner_frame, num_bits, &is_transient );
203 32 : hqswb_clas = is_transient; /* Q0 */
204 32 : move16();
205 32 : Q_audio = 12;
206 32 : move16();
207 : }
208 : ELSE
209 : {
210 : /* HQ high rate decoder */
211 397 : hq_hr_dec_fx( st_fx, t_audio_q, L_spec, num_bits, ynrm, &is_transient, &hqswb_clas, SWB_fenv_fx, core_switching_flag );
212 397 : Q_audio = 12;
213 397 : move16();
214 : }
215 :
216 : {
217 : /* scaling (coefficients are in nominal level) */
218 429 : IF( NE_16( output_frame, NORM_MDCT_FACTOR ) )
219 : {
220 429 : IF( EQ_16( output_frame, L_FRAME32k ) )
221 : {
222 32 : Q_audio = sub( Q_audio, 1 ); /* Multiply by 2 */
223 : }
224 : ELSE
225 : {
226 397 : tmp = mult_r( output_frame, 410 / 2 ); /* 1/8000 in Q15 */
227 397 : ener_match = hq_nominal_scaling_inv[tmp]; /* Q13 */
228 397 : move16();
229 254477 : FOR( i = 0; i < inner_frame; i++ )
230 : {
231 : /*t_audio_q[i] *= ener_match;*/
232 254080 : Mpy_32_16_ss( t_audio_q[i], ener_match, &L_tmp, &lsb ); /*12+13-15=10 */
233 254080 : t_audio_q[i] = L_add_sat( L_shl_sat( L_tmp, 2 ), L_shr( lsb, 14 ) );
234 254080 : move16(); /* Q12 */
235 : }
236 : }
237 : }
238 : }
239 429 : HQ_FEC_Mem_update_fx( st_fx, t_audio_q, normq_fx, ynrm, num_bands_p, is_transient, hqswb_clas,
240 : core_switching_flag, nb_sfm, num_Sb, &mean_en_high_fx, hq_core_type, output_frame );
241 : }
242 : /*--------------------------------------------------------------------------
243 : * Attenuate HFs in case of band-width switching (from higher BW to lower BW)
244 : *--------------------------------------------------------------------------*/
245 : /* attenuate HFs in case of band-width switching */
246 429 : IF( st_fx->bws_cnt1 > 0 )
247 : {
248 0 : IF( EQ_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) )
249 : {
250 0 : ener_match = 32767;
251 0 : move16(); /* 1.0f in Q15 */
252 : }
253 : ELSE
254 : {
255 0 : ener_match = div_s( st_fx->bws_cnt1, N_NS2W_FRAMES ); /*Q15*/
256 : }
257 :
258 0 : IF( is_transient )
259 : {
260 0 : FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ )
261 : {
262 0 : tmp_loop = mult( inner_frame, 8192 /* 0.25 in Q15 */ );
263 0 : FOR( j = mult( inner_frame_tbl[st_fx->bwidth - 1], 8192 ); j < tmp_loop; j++ )
264 : {
265 0 : tmp = i_mult( i, inner_frame ); /*Q0*/
266 0 : tmp = mult( tmp, 8192 /* 0.25 in Q15 */ ); /*Q0*/
267 0 : tmp = add( tmp, j );
268 0 : t_audio_q[tmp] = Mult_32_16( t_audio_q[tmp], ener_match );
269 0 : move32(); /*Q12*/
270 : }
271 : }
272 : }
273 : ELSE
274 : {
275 0 : FOR( i = inner_frame_tbl[st_fx->bwidth - 1]; i < inner_frame; i++ )
276 : {
277 0 : t_audio_q[i] = Mult_32_16( t_audio_q[i], ener_match ); /*Q12*/
278 0 : move32();
279 : }
280 : }
281 : }
282 :
283 : /* WB/SWB bandwidth switching */
284 429 : IF( is_transient )
285 : {
286 37 : Copy_Scale_sig_32_16( &t_audio_q[240], st_fx->t_audio_q_fx, 80, -13 ); /* -1Q */
287 : }
288 : ELSE
289 : {
290 392 : Copy_Scale_sig_32_16( t_audio_q, st_fx->t_audio_q_fx, L_FRAME, -13 ); /* -1Q */
291 : }
292 :
293 :
294 : /*--------------------------------------------------------------------------
295 : * Inverse transform
296 : * Overlap-add
297 : * Pre-echo reduction
298 : *--------------------------------------------------------------------------*/
299 : {
300 429 : test();
301 429 : IF( EQ_16( output_frame, L_FRAME8k ) || st_fx->bfi == 0 )
302 : {
303 429 : test();
304 429 : IF( NE_16( inner_frame, output_frame ) && EQ_16( st_fx->bfi, 1 ) )
305 : {
306 0 : Inverse_Transform( t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, output_frame, st_fx->element_mode );
307 : }
308 : ELSE
309 : {
310 429 : Inverse_Transform( t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, inner_frame, st_fx->element_mode );
311 : }
312 429 : *Q_synth = Q_audio;
313 429 : move16();
314 : }
315 : }
316 429 : IF( EQ_16( output_frame, L_FRAME8k ) )
317 : {
318 0 : test();
319 0 : IF( st_fx->bfi == 0 && st_fx->prev_bfi == 0 )
320 : {
321 0 : Copy_Scale_sig( hHQ_core->old_out_fx + N_ZERO_NB, hHQ_nbfec->prev_oldauOut_fx, output_frame - N_ZERO_NB, negate( hHQ_core->Q_old_wtda ) ); /* 15 - exp_old_out - Q_old_wtda */
322 : }
323 0 : ELSE IF( EQ_16( st_fx->prev_bfi, 1 ) )
324 : {
325 0 : set16_fx( hHQ_nbfec->prev_oldauOut_fx, 0, output_frame );
326 : }
327 :
328 0 : test();
329 0 : test();
330 0 : test();
331 0 : test();
332 0 : IF( ( EQ_16( st_fx->prev_bfi, 1 ) || EQ_16( st_fx->bfi, 1 ) ) && hHQ_core->old_is_transient[2] == 0 && EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->last_codec_mode, MODE1 ) )
333 : {
334 0 : time_domain_FEC_HQ_fx( st_fx, wtda_audio, synth, mean_en_high_fx, output_frame, Q_synth );
335 : }
336 : ELSE
337 : {
338 0 : window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
339 0 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
340 0 : hHQ_nbfec->phase_mat_next = 0;
341 0 : move16();
342 : }
343 :
344 0 : test();
345 0 : test();
346 0 : IF( ( st_fx->bfi == 0 && st_fx->prev_bfi == 0 ) || !( GE_16( output_frame, L_FRAME16k ) ) )
347 : {
348 0 : preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth, *Q_synth, output_frame, &hHQ_core->memfilt_lb_fx,
349 0 : &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx, &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag, &hHQ_core->pastpre, st_fx->bwidth );
350 : }
351 : }
352 : ELSE
353 : {
354 429 : test();
355 429 : IF( EQ_16( st_fx->bfi, 1 ) && GE_16( output_frame, L_FRAME16k ) )
356 : {
357 : /* PHASE_ECU active */
358 0 : Q_audio = 15;
359 0 : move16();
360 0 : window_ola_fx( t_audio_q, synth, &Q_audio, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
361 0 : ALDO_WINDOW, ALDO_WINDOW, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
362 0 : *Q_synth = Q_audio;
363 0 : move16();
364 : }
365 : ELSE
366 : {
367 : /* no BFI or baseline PLC active */
368 858 : window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
369 429 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
370 : }
371 429 : test();
372 429 : test();
373 429 : IF( ( st_fx->bfi == 0 && st_fx->prev_bfi == 0 ) || !( GE_16( output_frame, L_FRAME16k ) ) )
374 : {
375 429 : preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth, *Q_synth, output_frame, &hHQ_core->memfilt_lb_fx,
376 : &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx,
377 429 : &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag, &hHQ_core->pastpre, st_fx->bwidth );
378 : }
379 : }
380 :
381 429 : test();
382 429 : test();
383 429 : test();
384 429 : test();
385 429 : test();
386 429 : test();
387 429 : test();
388 429 : test();
389 429 : IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && st_fx->hPlcInfo->concealment_method == TCX_NONTONAL && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) )
390 : {
391 0 : st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q14 + Q_synth */
392 0 : move16();
393 0 : IF( st_fx->hTonalMDCTConc->q_lastPcmOut != 0 )
394 : {
395 0 : Scale_sig( st_fx->hTonalMDCTConc->secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) );
396 0 : Scale_sig( st_fx->hTonalMDCTConc->lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) );
397 0 : st_fx->hTonalMDCTConc->q_lastPcmOut = 0;
398 0 : move16();
399 : }
400 0 : waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi );
401 : }
402 :
403 429 : IF( GE_16( output_frame, L_FRAME16k ) )
404 : {
405 429 : IF( EQ_16( hHQ_core->ph_ecu_HqVoicing, 1 ) )
406 : {
407 12 : hHQ_core->oldHqVoicing = 1;
408 12 : move16();
409 12 : Copy( gapsynth_fx, hHQ_core->oldgapsynth_fx, L_FRAME48k ); /* q_gapsynth */
410 : }
411 : ELSE
412 : {
413 417 : hHQ_core->oldHqVoicing = 0;
414 417 : move16();
415 : }
416 : }
417 : ELSE
418 : {
419 0 : hHQ_core->oldHqVoicing = 0;
420 0 : move16();
421 : }
422 :
423 429 : if ( EQ_16( st_fx->nbLostCmpt, FRAMECTTOSTART_MDCT ) )
424 : {
425 0 : hHQ_core->HqVoicing = 0;
426 0 : move16();
427 : }
428 :
429 429 : IF( EQ_16( output_frame, L_FRAME8k ) )
430 : {
431 0 : Copy32( wtda_audio, hHQ_nbfec->oldIMDCTout_fx, L_FRAME8k / 2 ); /* q_wtda */
432 0 : Copy( &hHQ_nbfec->old_auOut_2fr_fx[output_frame], hHQ_nbfec->old_auOut_2fr_fx, output_frame ); /* q_old_auOut */
433 0 : Copy_Scale_sig( synth, &hHQ_nbfec->old_auOut_2fr_fx[output_frame], output_frame, negate( *Q_synth ) ); /* Q0 */
434 : }
435 :
436 : /* prepare synthesis output buffer (as recent as possible) for HQ FEC */
437 :
438 : {
439 : Word16 nbsubfr;
440 : /*nbsubfr = extract_l(L_mult0(st_fx->L_frame,FL2WORD16(1/L_SUBFR)));*/
441 429 : nbsubfr = 4; /* Q0 */
442 429 : move16();
443 429 : if ( EQ_16( st_fx->L_frame, 320 ) )
444 : {
445 397 : nbsubfr = 5; /* Q0 */
446 397 : move16();
447 : }
448 :
449 : /* update buffer of old subframe pitch values */
450 429 : test();
451 429 : IF( EQ_16( st_fx->last_core, HQ_CORE ) && NE_16( st_fx->L_frame, st_fx->last_L_frame ) )
452 : {
453 0 : set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], ( L_SUBFR << 16 ), nbsubfr );
454 : }
455 429 : Copy32( &st_fx->old_pitch_buf_fx[nbsubfr], &st_fx->old_pitch_buf_fx[0], nbsubfr ); /* 15Q16 */
456 429 : set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], ( L_SUBFR << 16 ), nbsubfr );
457 429 : Copy( &st_fx->mem_pitch_gain[2], &st_fx->mem_pitch_gain[nbsubfr + 2], nbsubfr ); /* Q14 */
458 429 : set16_fx( &st_fx->mem_pitch_gain[2], 0, nbsubfr );
459 : }
460 429 : return;
461 : }
462 :
463 :
464 7475 : void ivas_hq_core_dec_fx(
465 : Decoder_State *st_fx, /* i/o: decoder state structure fx */
466 : Word16 synth[], /* o : output synthesis Q_synth*/
467 : Word16 *Q_synth, /* o : Q value of synth */
468 : const Word16 output_frame, /* i : output frame length Q0*/
469 : const Word16 hq_core_type, /* i : HQ core type Q0*/
470 : const Word16 core_switching_flag, /* i : ACELP->HQ switching frame flag Q0*/
471 : Word16 output[], /* Q_ouput */
472 : Word16 *Q_output )
473 : {
474 : Word16 num_bits, is_transient, hqswb_clas, inner_frame;
475 : Word16 i, j, flag_uv, num_Sb, nb_sfm;
476 : Word16 ynrm[NB_SFM], num_bands_p[MAX_SB_NB];
477 : Word16 ener_match; /* Q13 */
478 : Word32 t_audio_q[L_FRAME48k_EXT]; /* Q12 */
479 : Word16 Q_audio, E_audio, Q_G_audio;
480 : Word32 wtda_audio[2 * L_FRAME48k];
481 : Word16 wtda_audio_16[2 * L_FRAME48k];
482 : Word32 wtda_audio_LB[2 * L_FRAME16k];
483 : Word16 delay_comp;
484 : Word32 normq_fx[NB_SFM];
485 : Word16 mean_en_high_fx;
486 : Word16 SWB_fenv_fx[SWB_FENV + DIM_FB];
487 : const Word16 *sfmsize, *sfm_start, *sfm_end;
488 : Word16 gapsynth_fx[L_FRAME48k];
489 : Word16 tmp, tmp_loop;
490 : Word32 L_tmp;
491 : UWord16 lsb;
492 : Word16 L_spec;
493 : HQ_NBFEC_HANDLE hHQ_nbfec;
494 : HQ_DEC_HANDLE hHQ_core;
495 7475 : hHQ_nbfec = st_fx->hHQ_nbfec;
496 7475 : hHQ_core = st_fx->hHQ_core;
497 :
498 : TCX_DEC_HANDLE hTcxDec;
499 : TCX_CONFIG_HANDLE tcx_cfg;
500 : Word16 index, left_rect, tcx_offsetFB, overlapFB, L_frameTCX;
501 : Word16 tcx_offset, overlap, L_frame;
502 : Word16 L_frameTCX_glob, L_frame_glob;
503 : Word16 acelp_zir[L_FRAME_MAX / 2];
504 : // Word16 encoderLookahead, encoderLookaheadFB;
505 : Word16 hq_recovery_flag;
506 : Word16 mdctWindowLength;
507 : Word16 mdctWindowLengthFB;
508 : Word16 tmp_e;
509 : Word16 tmp_out[L_FRAME48k];
510 :
511 : /*--------------------------------------------------------------------------
512 : * Initializations
513 : *--------------------------------------------------------------------------*/
514 :
515 7475 : set32_fx( t_audio_q, 0, L_FRAME48k_EXT );
516 7475 : set16_fx( gapsynth_fx, 0, L_FRAME48k );
517 7475 : set16_fx( num_bands_p, 0, MAX_SB_NB );
518 7475 : set16_fx( ynrm, 39, NB_SFM ); /* Initialize to the smallest value */
519 7475 : set16_fx( wtda_audio_16, 0, 2 * L_FRAME48k );
520 7475 : mean_en_high_fx = 0;
521 7475 : move16();
522 7475 : Q_audio = 12;
523 7475 : move16();
524 7475 : Q_G_audio = 12;
525 7475 : move16();
526 7475 : sfm_start = sfm_end = NULL;
527 7475 : num_Sb = nb_sfm = 0;
528 7475 : move16();
529 7475 : move16();
530 :
531 7475 : hTcxDec = st_fx->hTcxDec;
532 :
533 7475 : st_fx->hTcxCfg->tcx_last_overlap_mode = st_fx->hTcxCfg->tcx_curr_overlap_mode; /* Q0 */
534 7475 : move16();
535 7475 : if ( EQ_16( st_fx->hTcxCfg->tcx_curr_overlap_mode, FULL_OVERLAP ) )
536 : {
537 241 : st_fx->hTcxCfg->tcx_last_overlap_mode = ALDO_WINDOW; /* Q0 */
538 241 : move16();
539 : }
540 7475 : st_fx->hTcxCfg->tcx_curr_overlap_mode = ALDO_WINDOW; /* Q0 */
541 7475 : move16();
542 7475 : test();
543 7475 : test();
544 7475 : hq_recovery_flag = ( EQ_16( st_fx->last_core, ACELP_CORE ) ) && st_fx->prev_bfi && ( GT_16( st_fx->element_mode, EVS_MONO ) ); /* ACELP -> HQtrans -> HQ; with HQtrans lost */
545 : /*--------------------------------------------------------------------------
546 : * Find the number of bits for transform-domain coding
547 : *--------------------------------------------------------------------------*/
548 :
549 : /* set the total bit-budget */
550 : /*num_bits = (short)(st->total_brate / 50); */
551 7475 : Mpy_32_16_ss( st_fx->total_brate, 5243, &L_tmp, &lsb ); /* 5243 is 1/50 in Q18. (0+18-15=3) */
552 7475 : num_bits = extract_l( L_shr( L_tmp, 3 ) ); /*Q0 */
553 :
554 : /* Set default spectrum length */
555 7475 : L_spec = l_spec_tbl[st_fx->bwidth]; /* Q0 */
556 7475 : move16();
557 7475 : IF( !st_fx->bfi )
558 : {
559 7331 : IF( EQ_16( core_switching_flag, 1 ) )
560 : {
561 185 : IF( NE_16( st_fx->element_mode, EVS_MONO ) )
562 : {
563 185 : L_spec = l_spec_ext_tbl[st_fx->bwidth]; /* Q0 */
564 185 : move16();
565 : }
566 : ELSE
567 : {
568 0 : core_switching_hq_prepare_dec_fx( st_fx, &num_bits, output_frame );
569 :
570 : /* During ACELP->HQ core switching, limit the HQ core bitrate to 48kbps */
571 0 : if ( GT_16( num_bits, HQ_48k / 50 ) )
572 : {
573 0 : num_bits = (Word16) ( HQ_48k / 50 );
574 0 : move16();
575 : }
576 : }
577 : }
578 7331 : IF( hq_recovery_flag )
579 : {
580 0 : acelp_plc_mdct_transition_fx( st_fx );
581 : }
582 : /* subtract signalling bits */
583 7331 : num_bits = sub( num_bits, st_fx->next_bit_pos ); /* Q0 */
584 :
585 : /* set FEC parameters */
586 7331 : flag_uv = sub( 1, hHQ_core->HqVoicing ); /* Q0 */
587 :
588 : /* subtract the number of bits for pitch & gain at higher bitrates */
589 7331 : test();
590 7331 : IF( !( core_switching_flag ) && GT_32( st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) )
591 : {
592 177 : hHQ_core->HqVoicing = get_next_indice_fx( st_fx, 1 ); /* Q0 */
593 177 : move16();
594 177 : num_bits = sub( num_bits, 1 ); /* Q0 */
595 : }
596 : ELSE
597 : {
598 7154 : hHQ_core->HqVoicing = 0;
599 7154 : move16();
600 7154 : if ( GT_32( st_fx->core_brate, MINIMUM_RATE_TO_ENCODE_VOICING_FLAG ) )
601 : {
602 1 : hHQ_core->HqVoicing = 1; /* Q0 */
603 1 : move16();
604 : }
605 : }
606 : }
607 : ELSE
608 : {
609 144 : flag_uv = 0;
610 144 : move16();
611 : }
612 :
613 : /* set inner frame (== coded bandwidth) length */
614 7475 : inner_frame = inner_frame_tbl[st_fx->bwidth]; /* Q0 */
615 7475 : move16();
616 :
617 7475 : IF( EQ_16( st_fx->bfi, 0 ) )
618 : {
619 7331 : hHQ_core->ph_ecu_HqVoicing = 0;
620 7331 : move16();
621 7331 : if ( GE_16( output_frame, L_FRAME16k ) )
622 : {
623 7331 : hHQ_core->ph_ecu_HqVoicing = hHQ_core->HqVoicing; /* Q0 */
624 7331 : move16();
625 : }
626 : }
627 :
628 7475 : IF( EQ_16( output_frame, L_FRAME8k ) )
629 : {
630 0 : hq_configure_bfi_fx( &nb_sfm, &num_Sb, num_bands_p, &sfmsize, &sfm_start, &sfm_end );
631 : }
632 :
633 : /*--------------------------------------------------------------------------
634 : * transform-domain decoding
635 : *--------------------------------------------------------------------------*/
636 :
637 7475 : IF( EQ_16( st_fx->bfi, 1 ) )
638 : {
639 144 : is_transient = hHQ_core->old_is_transient[0]; /* Q0 */
640 144 : move16();
641 144 : IF( GE_16( output_frame, L_FRAME16k ) ) /* Apply phase ecu for WB, SWB and FB */
642 : {
643 : /* ecu_rec sent to OLA, env_stab passed in ph_ecu_st */
644 144 : ivas_hq_ecu_fx( st_fx->hTcxDec->prev_good_synth_fx, t_audio_q, &hHQ_core->time_offs, hHQ_core->X_sav_fx, &hHQ_core->Q_X_sav, &hHQ_core->num_p, hHQ_core->plocs, hHQ_core->plocsi_fx, hHQ_core->env_stab_fx,
645 144 : &hHQ_core->last_fec, hHQ_core->ph_ecu_HqVoicing, &hHQ_core->ph_ecu_active, gapsynth_fx, st_fx->prev_bfi, hHQ_core->old_is_transient, hHQ_core->mag_chg_1st_fx,
646 144 : hHQ_core->Xavg_fx, &hHQ_core->beta_mute_fx, output_frame, st_fx );
647 : }
648 : ELSE
649 : {
650 0 : HQ_FEC_processing_fx( st_fx, t_audio_q, is_transient, hHQ_nbfec->ynrm_values_fx, hHQ_nbfec->r_p_values_fx, num_Sb, nb_sfm, num_bands_p,
651 : output_frame, sfm_start, sfm_end );
652 : }
653 :
654 144 : hHQ_core->old_is_transient[2] = hHQ_core->old_is_transient[1]; /* Q0 */
655 144 : move16();
656 144 : hHQ_core->old_is_transient[1] = hHQ_core->old_is_transient[0]; /* Q0 */
657 144 : move16();
658 :
659 144 : IF( GE_16( output_frame, L_FRAME16k ) )
660 : {
661 : /* keep st->previoussynth updated as in FEC_HQ_pitch_analysis but no LP analysis */
662 144 : delay_comp = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS ); /* Q0 */
663 :
664 144 : Copy( st_fx->previoussynth_fx + delay_comp, st_fx->previoussynth_fx, sub( output_frame, delay_comp ) ); /* q_previoussynth */
665 144 : Copy( st_fx->delay_buf_out_fx, st_fx->previoussynth_fx + output_frame - delay_comp, delay_comp ); /* q_delay_buff */
666 :
667 144 : flag_uv = 1;
668 144 : move16(); /* disable costly pitch out synthesis in bfi frame */
669 144 : hHQ_core->HqVoicing = sub( 1, flag_uv ); /* safety setting for HQ->ACELP switch logic Q0*/
670 144 : move16();
671 144 : set16_fx( hHQ_core->fer_samples_fx, 0, L_FRAME48k ); /* safety, create a known signal state for HQ->ACELP switch logic */
672 : }
673 : }
674 : ELSE
675 : {
676 7331 : IF( EQ_16( hq_core_type, LOW_RATE_HQ_CORE ) )
677 : {
678 0 : IF( EQ_16( st_fx->prev_bfi, 1 ) )
679 : {
680 0 : set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX );
681 0 : set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX );
682 0 : hHQ_core->last_max_pos_pulse = 0;
683 0 : move16();
684 : }
685 :
686 : /* HQ low rate decoder */
687 0 : hq_lr_dec_fx( st_fx, t_audio_q, inner_frame, num_bits, &is_transient );
688 0 : hqswb_clas = is_transient; /* Q0 */
689 0 : move16();
690 0 : Q_audio = 12;
691 0 : move16();
692 0 : Q_G_audio = Q_audio;
693 0 : move16();
694 : }
695 : ELSE
696 : {
697 : /* HQ high rate decoder */
698 7331 : ivas_hq_hr_dec_fx( st_fx, t_audio_q, L_spec, num_bits, ynrm, &is_transient, &hqswb_clas, SWB_fenv_fx, core_switching_flag );
699 7331 : Q_audio = 12;
700 7331 : move16();
701 7331 : Q_G_audio = Q_audio;
702 7331 : move16();
703 : }
704 :
705 7331 : test();
706 7331 : test();
707 7331 : test();
708 7331 : IF( st_fx->element_mode == EVS_MONO || ( !core_switching_flag && !hq_recovery_flag ) )
709 : {
710 : /* scaling (coefficients are in nominal level) */
711 7146 : IF( NE_16( output_frame, NORM_MDCT_FACTOR ) )
712 : {
713 7146 : IF( EQ_16( output_frame, L_FRAME32k ) )
714 : {
715 2215 : Q_audio = sub( Q_audio, 1 ); /* Multiply by 2 */
716 2215 : Q_G_audio = sub( Q_G_audio, 1 );
717 : }
718 : ELSE
719 : {
720 4931 : tmp = mult_r( output_frame, 410 / 2 ); /* 1/8000 in Q15 */
721 4931 : ener_match = hq_nominal_scaling_inv[tmp]; /* Q13 */
722 4931 : move16();
723 4188291 : FOR( i = 0; i < inner_frame; i++ )
724 : {
725 : /*t_audio_q[i] *= ener_match;*/
726 4183360 : Mpy_32_16_ss( t_audio_q[i], ener_match, &L_tmp, &lsb ); /*12+13-15=10 */
727 4183360 : t_audio_q[i] = L_add_sat( L_shl_sat( L_tmp, 2 ), lshr( (Word16) lsb, 14 ) );
728 4183360 : move16(); /* Q12 */
729 : }
730 : }
731 : }
732 : }
733 7331 : ivas_HQ_FEC_Mem_update_fx( st_fx, t_audio_q, normq_fx, ynrm, num_bands_p, is_transient, hqswb_clas,
734 : core_switching_flag, nb_sfm, num_Sb, &mean_en_high_fx, hq_core_type, output_frame );
735 : }
736 : /*--------------------------------------------------------------------------
737 : * Attenuate HFs in case of band-width switching (from higher BW to lower BW)
738 : *--------------------------------------------------------------------------*/
739 : /* attenuate HFs in case of band-width switching */
740 7475 : IF( GT_16( st_fx->bws_cnt1, 0 ) )
741 : {
742 0 : IF( EQ_16( st_fx->bws_cnt1, N_NS2W_FRAMES ) )
743 : {
744 0 : ener_match = 32767;
745 0 : move16(); /* 1.0f in Q15*/
746 : }
747 : ELSE
748 : {
749 0 : ener_match = imult1616( st_fx->bws_cnt1, ONE_BY_N_NS2W_FRAMES_Q15 ); /*Q15*/
750 : }
751 :
752 0 : IF( is_transient )
753 : {
754 0 : FOR( i = 0; i < NUM_TIME_SWITCHING_BLOCKS; i++ )
755 : {
756 0 : tmp_loop = mult( inner_frame, 8192 /* 0.25 in Q15 */ ); /* Q0 */
757 0 : FOR( j = mult( inner_frame_tbl[st_fx->bwidth - 1], 8192 ); j < tmp_loop; j++ )
758 : {
759 0 : tmp = i_mult( i, inner_frame ); /*Q0*/
760 0 : tmp = mult( tmp, 8192 /* 0.25 in Q15 */ ); /*Q0*/
761 0 : tmp = add( tmp, j );
762 0 : t_audio_q[tmp] = Mult_32_16( t_audio_q[tmp], ener_match );
763 0 : move32(); /*Q12*/
764 : }
765 : }
766 : }
767 : ELSE
768 : {
769 0 : FOR( i = inner_frame_tbl[st_fx->bwidth - 1]; i < inner_frame; i++ )
770 : {
771 0 : t_audio_q[i] = Mult_32_16( t_audio_q[i], ener_match ); /*Q12*/
772 0 : move32();
773 : }
774 : }
775 : }
776 :
777 : /* WB/SWB bandwidth switching */
778 7475 : IF( is_transient )
779 : {
780 477 : Copy_Scale_sig_32_16( &t_audio_q[240], st_fx->t_audio_q_fx, 80, -13 ); /* -1Q */
781 : }
782 : ELSE
783 : {
784 6998 : Copy_Scale_sig_32_16( t_audio_q, st_fx->t_audio_q_fx, L_FRAME, -13 ); /* -1Q */
785 : }
786 :
787 :
788 : /*--------------------------------------------------------------------------
789 : * Inverse transform
790 : * Overlap-add
791 : * Pre-echo reduction
792 : *--------------------------------------------------------------------------*/
793 7475 : test();
794 7475 : test();
795 7475 : IF( st_fx->element_mode > EVS_MONO && ( core_switching_flag || hq_recovery_flag ) )
796 185 : {
797 : /* Initializations for TCX MDCT framework, to be used for switching frame */
798 185 : tcx_cfg = st_fx->hTcxCfg;
799 185 : L_frameTCX_glob = hTcxDec->L_frameTCX; /* Q0 */
800 185 : move16();
801 185 : L_frame_glob = st_fx->L_frame; /* Q0 */
802 185 : move16();
803 185 : L_spec = hTcxDec->L_frameTCX; /* Q0 */
804 185 : move16();
805 185 : st_fx->fscale = sr2fscale_fx( st_fx->sr_core ); /* Q0 */
806 : // fscaleFB = sr2fscale( st_fx->output_Fs );
807 : // encoderLookahead = ( L_LOOK_12k8 * st_fx->fscale ) / FSCALE_DENOM;
808 : // encoderLookaheadFB = ( L_LOOK_12k8 * fscaleFB ) / FSCALE_DENOM;
809 185 : mdctWindowLength = getMdctWindowLength_fx( st_fx->fscale ); /* Q0 */
810 : Word16 temp, temp_e;
811 185 : temp = BASOP_Util_Divide3232_Scale( st_fx->output_Fs, st_fx->sr_core, &temp_e );
812 185 : mdctWindowLengthFB = extract_l( L_shr( L_mult0( temp, mdctWindowLength ), sub( 15, temp_e ) ) ); /* Q0 */
813 185 : IF( core_switching_flag )
814 : {
815 185 : tcx_cfg->tcx_last_overlap_mode = TRANSITION_OVERLAP; /* Q0 */
816 185 : move16();
817 185 : tcx_cfg->tcx_curr_overlap_mode = FULL_OVERLAP; /* Q0 */
818 185 : move16();
819 : }
820 : ELSE
821 : {
822 0 : tcx_cfg->tcx_last_overlap_mode = ALDO_WINDOW; /* Q0 */
823 0 : move16();
824 0 : tcx_cfg->tcx_curr_overlap_mode = ALDO_WINDOW; /* Q0 */
825 0 : move16();
826 0 : st_fx->last_core = HQ_CORE; /* Needed to decode non-transition frame Q0*/
827 0 : move16();
828 : }
829 :
830 185 : init_tcx_window_cfg_fx( tcx_cfg, st_fx->sr_core, st_fx->output_Fs, st_fx->L_frame, hTcxDec->L_frameTCX, mdctWindowLength, mdctWindowLengthFB, st_fx->element_mode );
831 :
832 185 : init_tcx_info_fx( st_fx, L_frame_glob, L_frameTCX_glob, 0, st_fx->bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec );
833 :
834 185 : overlap = tcx_cfg->tcx_mdct_window_length; /* Q0 */
835 185 : move16();
836 185 : overlapFB = tcx_cfg->tcx_mdct_window_lengthFB; /* Q0 */
837 185 : move16();
838 185 : index = tcx_cfg->tcx_last_overlap_mode; /* Q0 */
839 185 : move16();
840 :
841 :
842 : /* LB synthesis */
843 185 : E_audio = sub( 31, Q_audio );
844 185 : IMDCT_fx( t_audio_q, E_audio, hTcxDec->syn_Overl, hTcxDec->syn_Overl_TDAC, wtda_audio_16, tcx_cfg->tcx_aldo_window_1, tcx_cfg->tcx_aldo_window_1_trunc, tcx_cfg->tcx_aldo_window_2, tcx_cfg->tcx_mdct_window_half, tcx_cfg->tcx_mdct_window_minimum, tcx_cfg->tcx_mdct_window_trans, tcx_cfg->tcx_mdct_window_half_length, tcx_cfg->tcx_mdct_window_min_length, index,
845 185 : left_rect, tcx_offset, overlap, L_frame, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frame_glob, 0, st_fx->bfi, hHQ_core->old_out_LB_fx, &hHQ_core->Q_old_wtda_LB, st_fx, 0, acelp_zir );
846 :
847 : // values till L_frame same
848 185 : Scale_sig( wtda_audio_16 + L_frame, overlap, Q1 ); /* q_wtda + 1 */
849 :
850 185 : Copy( wtda_audio_16 + sub( shr( overlap, 1 ), tcx_offset ), output, L_frame_glob ); /* q_wtda + 1 */
851 :
852 : /* FB synthesis */
853 185 : temp = BASOP_Util_Divide3232_Scale( L_mult0( FSCALE_DENOM, L_frameTCX_glob ), L_frame_glob, &temp_e );
854 185 : temp = shr( temp, sub( 15, temp_e ) );
855 185 : IMDCT_fx( t_audio_q, E_audio, hTcxDec->syn_OverlFB, hTcxDec->syn_Overl_TDACFB, wtda_audio_16, tcx_cfg->tcx_aldo_window_1_FB, tcx_cfg->tcx_aldo_window_1_FB_trunc, tcx_cfg->tcx_aldo_window_2_FB, tcx_cfg->tcx_mdct_window_halfFB, tcx_cfg->tcx_mdct_window_minimumFB, tcx_cfg->tcx_mdct_window_transFB, tcx_cfg->tcx_mdct_window_half_lengthFB, tcx_cfg->tcx_mdct_window_min_lengthFB, index,
856 185 : left_rect, tcx_offsetFB, overlapFB, L_frameTCX, L_frameTCX, shr( s_max( L_frameTCX, L_spec ), 1 ), L_frameTCX_glob, 0, st_fx->bfi, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, st_fx, temp, acelp_zir );
857 :
858 185 : Scale_sig( wtda_audio_16 + L_frameTCX, overlapFB, Q1 ); /* q_wtda + 1 */
859 :
860 185 : Copy( wtda_audio_16 + sub( shr( overlapFB, 1 ), tcx_offsetFB ), synth, L_frameTCX_glob ); /* q_wtda */
861 :
862 185 : Copy_Scale_sig_16_32_DEPREC( wtda_audio_16, wtda_audio, 2 * L_FRAME48k, 12 ); /* q_wtda + 12 */
863 185 : IF( !core_switching_flag )
864 : {
865 0 : st_fx->last_core = ACELP_CORE; /* Restore last core Q0*/
866 0 : move16();
867 : }
868 : }
869 : ELSE
870 : {
871 7290 : test();
872 7290 : IF( EQ_16( output_frame, L_FRAME8k ) || st_fx->bfi == 0 )
873 : {
874 7146 : test();
875 7146 : Q_audio = Q_G_audio;
876 7146 : move16();
877 7146 : IF( NE_16( inner_frame, output_frame ) && EQ_16( st_fx->bfi, 1 ) )
878 : {
879 0 : Inverse_Transform( t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, output_frame, st_fx->element_mode );
880 : }
881 : ELSE
882 : {
883 7146 : Inverse_Transform( t_audio_q, &Q_audio, wtda_audio, is_transient, output_frame, inner_frame, st_fx->element_mode );
884 : }
885 7146 : *Q_synth = Q_audio;
886 7146 : move16();
887 : }
888 :
889 7290 : IF( st_fx->element_mode > EVS_MONO )
890 : {
891 7290 : IF( st_fx->bfi )
892 : {
893 : /* Rough resampling, but reduces energy loss in case of switch to ACELP in first good frame */
894 144 : L_lerp_fx_q11( t_audio_q, wtda_audio_LB, st_fx->L_frame, inner_frame );
895 144 : v_multc_fixed_16( t_audio_q, ONE_IN_Q14, wtda_audio_LB, st_fx->L_frame );
896 144 : Q_audio = 15;
897 144 : move16();
898 : }
899 : ELSE
900 : {
901 : /* LB synthesis for potential switch to ACELP */
902 7146 : tmp = BASOP_Util_Divide1616_Scale( st_fx->L_frame, output_frame, &tmp_e );
903 7146 : tmp = Sqrt16( tmp, &tmp_e );
904 7146 : ener_match = shr( tmp, sub( 2, tmp_e ) ); // Q13
905 :
906 7146 : v_multc_fixed_16( t_audio_q, ener_match, t_audio_q, inner_frame ); // Q10
907 :
908 7146 : Scale_sig32( t_audio_q, inner_frame, Q2 ); // Q10 + Q2
909 7146 : Q_audio = Q_G_audio;
910 7146 : move16();
911 7146 : Inverse_Transform( t_audio_q, &Q_audio, wtda_audio_LB, is_transient, st_fx->L_frame, inner_frame, st_fx->element_mode );
912 : }
913 7290 : *Q_output = Q_audio;
914 7290 : move16();
915 : }
916 :
917 7290 : IF( EQ_16( output_frame, L_FRAME8k ) )
918 : {
919 0 : test();
920 0 : IF( EQ_16( st_fx->bfi, 0 ) && st_fx->prev_bfi == 0 )
921 : {
922 0 : Copy_Scale_sig( hHQ_core->old_out_fx + N_ZERO_NB, hHQ_nbfec->prev_oldauOut_fx, output_frame - N_ZERO_NB, negate( hHQ_core->Q_old_wtda ) ); /* 31 - exp_old_out - Q_old_wtda */
923 : }
924 0 : ELSE IF( EQ_16( st_fx->prev_bfi, 1 ) )
925 : {
926 0 : set16_fx( hHQ_nbfec->prev_oldauOut_fx, 0, output_frame );
927 : }
928 :
929 0 : test();
930 0 : test();
931 0 : test();
932 0 : test();
933 0 : IF( ( EQ_16( st_fx->prev_bfi, 1 ) || EQ_16( st_fx->bfi, 1 ) ) && EQ_16( hHQ_core->old_is_transient[2], 0 ) && EQ_16( st_fx->last_core, HQ_CORE ) && EQ_16( st_fx->last_codec_mode, MODE1 ) )
934 : {
935 0 : time_domain_FEC_HQ_fx( st_fx, wtda_audio, synth, mean_en_high_fx, output_frame, Q_synth );
936 : }
937 : ELSE
938 : {
939 0 : window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
940 0 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
941 0 : hHQ_nbfec->phase_mat_next = 0;
942 0 : move16();
943 : }
944 :
945 0 : test();
946 0 : test();
947 0 : IF( ( EQ_16( st_fx->bfi, 0 ) && EQ_16( st_fx->prev_bfi, 0 ) ) || !( GE_16( output_frame, L_FRAME16k ) ) )
948 : {
949 0 : preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth, *Q_synth, output_frame, &hHQ_core->memfilt_lb_fx,
950 0 : &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx, &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag, &hHQ_core->pastpre, st_fx->bwidth );
951 : }
952 : }
953 : ELSE
954 : {
955 7290 : test();
956 7290 : IF( EQ_16( st_fx->bfi, 1 ) && GE_16( output_frame, L_FRAME16k ) )
957 : {
958 : /* PHASE_ECU active */
959 144 : Scale_sig32( t_audio_q, L_FRAME48k_EXT, sub( Q15, Q_audio ) );
960 144 : Q_audio = 15;
961 144 : move16();
962 144 : window_ola_fx( t_audio_q, synth, &Q_audio, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
963 144 : ALDO_WINDOW, ALDO_WINDOW, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
964 144 : *Q_synth = Q_audio;
965 144 : move16();
966 : }
967 : ELSE
968 : {
969 : /* no BFI or baseline PLC active */
970 14292 : window_ola_fx( wtda_audio, synth, Q_synth, hHQ_core->old_out_fx, &hHQ_core->Q_old_wtda, output_frame,
971 7146 : st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
972 : }
973 7290 : IF( st_fx->element_mode > EVS_MONO )
974 : {
975 : /* LB synthesis for potential switch to ACELP */
976 7290 : window_ola_fx( wtda_audio_LB, output, Q_output, hHQ_core->old_out_LB_fx, &hHQ_core->Q_old_wtda_LB, L_FRAME16k, st_fx->hTcxCfg->tcx_last_overlap_mode, st_fx->hTcxCfg->tcx_curr_overlap_mode, st_fx->prev_bfi && !hHQ_core->ph_ecu_active, hHQ_core->oldHqVoicing, hHQ_core->oldgapsynth_fx );
977 : }
978 7290 : test();
979 7290 : test();
980 7290 : IF( ( st_fx->bfi == 0 && st_fx->prev_bfi == 0 ) || !( GE_16( output_frame, L_FRAME16k ) ) )
981 : {
982 7087 : preecho_sb_fx( st_fx->core_brate, wtda_audio, Q_audio, synth, *Q_synth, output_frame, &hHQ_core->memfilt_lb_fx,
983 : &hHQ_core->mean_prev_hb_fx, &hHQ_core->smoothmem_fx, &hHQ_core->mean_prev_fx, &hHQ_core->mean_prev_nc_fx,
984 7087 : &hHQ_core->wmold_hb_fx, &hHQ_core->prevflag, &hHQ_core->pastpre, st_fx->bwidth );
985 : }
986 : }
987 : }
988 :
989 7475 : test();
990 7475 : test();
991 7475 : test();
992 7475 : test();
993 7475 : test();
994 7475 : test();
995 7475 : test();
996 7475 : test();
997 7475 : IF( !st_fx->bfi && st_fx->prev_bfi && GE_32( st_fx->last_total_brate, HQ_48k ) && EQ_16( st_fx->last_codec_mode, MODE2 ) && ( EQ_16( st_fx->last_core_bfi, TCX_20_CORE ) || EQ_16( st_fx->last_core_bfi, TCX_10_CORE ) ) && EQ_16( st_fx->hPlcInfo->concealment_method, TCX_NONTONAL ) && LT_32( st_fx->hPlcInfo->nbLostCmpt, 4 ) )
998 : {
999 0 : st_fx->hPlcInfo->recovery_gain = shl_sat( st_fx->hPlcInfo->recovery_gain, *Q_synth ); /* Q15 */
1000 0 : move16();
1001 0 : IF( st_fx->hTonalMDCTConc->q_lastPcmOut != 0 )
1002 : {
1003 0 : Scale_sig( st_fx->hTonalMDCTConc->secondLastPcmOut, shr( st_fx->hPlcInfo->L_frameTCX, 1 ), negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) );
1004 0 : Scale_sig( st_fx->hTonalMDCTConc->lastPcmOut, st_fx->hPlcInfo->L_frameTCX, negate( st_fx->hTonalMDCTConc->q_lastPcmOut ) );
1005 0 : st_fx->hTonalMDCTConc->q_lastPcmOut = 0;
1006 0 : move16();
1007 : }
1008 0 : waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth, 0, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi );
1009 : }
1010 :
1011 7475 : IF( GE_16( output_frame, L_FRAME16k ) )
1012 : {
1013 7475 : IF( EQ_16( hHQ_core->ph_ecu_HqVoicing, 1 ) )
1014 : {
1015 1 : hHQ_core->oldHqVoicing = 1;
1016 1 : move16();
1017 1 : Copy( gapsynth_fx, hHQ_core->oldgapsynth_fx, L_FRAME48k ); /* q_gapsynth */
1018 : }
1019 : ELSE
1020 : {
1021 7474 : hHQ_core->oldHqVoicing = 0;
1022 7474 : move16();
1023 : }
1024 : }
1025 : ELSE
1026 : {
1027 0 : hHQ_core->oldHqVoicing = 0;
1028 0 : move16();
1029 : }
1030 :
1031 7475 : if ( EQ_16( st_fx->nbLostCmpt, FRAMECTTOSTART_MDCT ) )
1032 : {
1033 2 : hHQ_core->HqVoicing = 0;
1034 2 : move16();
1035 : }
1036 :
1037 7475 : IF( EQ_16( output_frame, L_FRAME8k ) )
1038 : {
1039 0 : Copy32( wtda_audio, hHQ_nbfec->oldIMDCTout_fx, L_FRAME8k / 2 ); /* q_wtda */
1040 0 : Copy( &hHQ_nbfec->old_auOut_2fr_fx[output_frame], hHQ_nbfec->old_auOut_2fr_fx, output_frame ); /* Q_old_auOut */
1041 0 : Copy_Scale_sig( synth, &hHQ_nbfec->old_auOut_2fr_fx[output_frame], output_frame, negate( *Q_synth ) ); /* Q0 */
1042 : }
1043 :
1044 : /* prepare synthesis output buffer (as recent as possible) for HQ FEC */
1045 :
1046 : {
1047 : Word16 nbsubfr;
1048 : /*nbsubfr = extract_l(L_mult0(st_fx->L_frame,FL2WORD16(1/L_SUBFR)));*/
1049 7475 : nbsubfr = 4; /* Q0 */
1050 7475 : if ( EQ_16( st_fx->L_frame, 320 ) )
1051 : {
1052 7475 : nbsubfr = 5; /* Q0 */
1053 7475 : move16();
1054 : }
1055 :
1056 : /* update buffer of old subframe pitch values */
1057 7475 : test();
1058 7475 : IF( EQ_16( st_fx->last_core, HQ_CORE ) && NE_16( st_fx->L_frame, st_fx->last_L_frame ) )
1059 : {
1060 0 : set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], ( L_SUBFR << 16 ), nbsubfr );
1061 : }
1062 7475 : Copy32( &st_fx->old_pitch_buf_fx[nbsubfr], &st_fx->old_pitch_buf_fx[0], nbsubfr ); /* 15Q16 */
1063 7475 : set32_fx( &st_fx->old_pitch_buf_fx[nbsubfr], ( L_SUBFR << 16 ), nbsubfr );
1064 7475 : Copy( &st_fx->mem_pitch_gain[2], &st_fx->mem_pitch_gain[nbsubfr + 2], nbsubfr ); /* Q14 */
1065 7475 : set16_fx( &st_fx->mem_pitch_gain[2], 0, nbsubfr );
1066 : }
1067 : /* Move LB excitation to old_exc memory in case of switch HQ->ACELP */
1068 7475 : IF( st_fx->element_mode > EVS_MONO )
1069 : {
1070 7475 : Copy_Scale_sig( output, tmp_out, st_fx->L_frame, negate( *Q_output ) ); /* Q0 */
1071 7475 : Copy( tmp_out, st_fx->old_exc_fx + sub( L_EXC_MEM_DEC, st_fx->L_frame ), st_fx->L_frame ); /* Q0 */
1072 : }
1073 7475 : return;
1074 : }
1075 :
1076 :
1077 : /*-------------------------------------------------------------------*
1078 : * hq_core_dec_init()
1079 : *
1080 : * Initialize HQ core state structure
1081 : *-------------------------------------------------------------------*/
1082 :
1083 7822 : void HQ_core_dec_init_fx(
1084 : HQ_DEC_HANDLE hHQ_core /* i/o: HQ core data handle */
1085 : )
1086 : {
1087 7822 : set16_fx( hHQ_core->old_out_fx, 0, L_FRAME48k );
1088 7822 : set32_fx( hHQ_core->old_out_fx32, 0, L_FRAME48k );
1089 7822 : set16_fx( hHQ_core->old_out_LB_fx, 0, L_FRAME32k );
1090 7822 : set32_fx( hHQ_core->old_out_LB_fx32, 0, L_FRAME32k );
1091 7822 : hHQ_core->Q_old_wtda = 15;
1092 7822 : hHQ_core->Q_old_postdec = 0;
1093 7822 : hHQ_core->Q_old_wtda_LB = 0;
1094 7822 : move16();
1095 7822 : move16();
1096 7822 : move16();
1097 :
1098 7822 : hHQ_core->last_hq_core_type = -1; /* Q0 */
1099 7822 : move16();
1100 7822 : set16_fx( hHQ_core->old_is_transient, 0, 3 );
1101 :
1102 7822 : hHQ_core->mem_norm[0] = 31;
1103 7822 : move16();
1104 7822 : set16_fx( hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 );
1105 7822 : hHQ_core->mem_env_delta = 0;
1106 7822 : hHQ_core->no_att_hangover = 0;
1107 7822 : move16();
1108 7822 : move16();
1109 7822 : move16();
1110 7822 : move16();
1111 7822 : hHQ_core->energy_lt_fx = 2457600; /*300.0f in Q13*/
1112 7822 : hHQ_core->hq_generic_seed = RANDOM_INITSEED;
1113 7822 : set16_fx( hHQ_core->prev_noise_level_fx, 0, 2 );
1114 7822 : hHQ_core->prev_hqswb_clas = HQ_NORMAL;
1115 7822 : hHQ_core->prev_R = 0;
1116 7822 : move16();
1117 7822 : move16();
1118 7822 : set32_fx( hHQ_core->prev_coeff_out_fx, 0, L_HQ_WB_BWE );
1119 7822 : set16_fx( hHQ_core->prev_SWB_peak_pos_fx, 0, SPT_SHORTEN_SBNUM );
1120 :
1121 7822 : hHQ_core->HqVoicing = 0;
1122 7822 : move16();
1123 7822 : set16_fx( hHQ_core->fer_samples_fx, 0, L_FRAME48k );
1124 7822 : set32_fx( hHQ_core->prev_env_fx, 0, SFM_N_WB );
1125 7822 : set32_fx( hHQ_core->prev_normq_fx, 0, SFM_N_WB );
1126 7822 : set16_fx( hHQ_core->prev_env_Q, 0, SFM_N_WB );
1127 :
1128 7822 : set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX );
1129 7822 : set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX );
1130 7822 : hHQ_core->last_max_pos_pulse = 0;
1131 7822 : move16();
1132 7822 : hHQ_core->Q_fer_samples = 0;
1133 7822 : move16();
1134 :
1135 7822 : reset_preecho_dec_fx( hHQ_core );
1136 :
1137 7822 : hHQ_core->prev_frm_hfe2 = 0;
1138 7822 : move16();
1139 7822 : hHQ_core->prev_stab_hfe2 = 0;
1140 7822 : move16();
1141 7822 : hHQ_core->prev_ni_ratio_fx = 16384; /*0.5 in Q15*/
1142 7822 : move16();
1143 7822 : set16_fx( hHQ_core->prev_En_sb_fx, 0, NB_SWB_SUBBANDS );
1144 :
1145 :
1146 : /*----------------------------------------------------------------------------------*
1147 : * HQ FEC
1148 : *----------------------------------------------------------------------------------*/
1149 7822 : hHQ_core->time_offs = 0;
1150 7822 : move16();
1151 7822 : set16_fx( hHQ_core->X_sav_fx, 0, PH_ECU_SPEC_SIZE );
1152 7822 : hHQ_core->Q_X_sav = 0;
1153 7822 : hHQ_core->num_p = 0;
1154 7822 : move16();
1155 7822 : move16();
1156 :
1157 7822 : hHQ_core->env_stab_fx = 0x6000; /*0.75 Q15*/
1158 7822 : hHQ_core->mem_norm_hqfec[0] = 31;
1159 7822 : move16();
1160 7822 : move16();
1161 7822 : set16_fx( hHQ_core->mem_norm_hqfec + 1, 39, SFM_N_ENV_STAB - 1 );
1162 7822 : hHQ_core->mem_env_delta_hqfec = 0;
1163 7822 : hHQ_core->env_stab_plc_fx = 0;
1164 7822 : move16();
1165 7822 : move16();
1166 7822 : set16_fx( hHQ_core->env_stab_state_p_fx, INV_NUM_ENV_STAB_PLC_STATES, NUM_ENV_STAB_PLC_STATES );
1167 7822 : hHQ_core->envstabplc_hocnt = 0;
1168 7822 : move16();
1169 7822 : set16_fx( hHQ_core->mag_chg_1st_fx, 32767 /* 1.0f in Q15 */, LGW_MAX );
1170 7822 : set16_fx( hHQ_core->Xavg_fx, 0, LGW_MAX );
1171 7822 : hHQ_core->beta_mute_fx = BETA_MUTE_FAC_INI; /* Q15 */
1172 7822 : hHQ_core->last_fec = 0;
1173 7822 : hHQ_core->ph_ecu_HqVoicing = 0;
1174 7822 : hHQ_core->oldHqVoicing = 0;
1175 7822 : set16_fx( hHQ_core->oldgapsynth_fx, 0, L_FRAME48k );
1176 7822 : hHQ_core->ph_ecu_active = 0;
1177 7822 : hHQ_core->ni_seed_forfec = 0;
1178 7822 : hHQ_core->ber_occured_in_pvq = 0;
1179 7822 : move16();
1180 7822 : move16();
1181 7822 : move16();
1182 7822 : move16();
1183 7822 : move16();
1184 7822 : move16();
1185 7822 : move16();
1186 :
1187 :
1188 7822 : return;
1189 : }
1190 :
1191 : /*-------------------------------------------------------------------*
1192 : * HQ_nbfec_init_fx()
1193 : *
1194 : * Initialize HQ NB FEC state structure
1195 : *-------------------------------------------------------------------*/
1196 :
1197 3 : void HQ_nbfec_init_fx(
1198 : HQ_NBFEC_HANDLE hHQ_nbfec /* i/o: HQ NB FEC data handle */
1199 : )
1200 : {
1201 : Word16 i, j;
1202 :
1203 3 : hHQ_nbfec->prev_last_core = -1; /* Q0 */
1204 3 : hHQ_nbfec->diff_energy_fx = 0;
1205 3 : hHQ_nbfec->stat_mode_out = 0;
1206 3 : hHQ_nbfec->stat_mode_old = 0;
1207 3 : move16();
1208 3 : move16();
1209 3 : move16();
1210 3 : move16();
1211 3 : hHQ_nbfec->phase_mat_flag = 0;
1212 3 : hHQ_nbfec->phase_mat_next = 0;
1213 3 : hHQ_nbfec->old_Min_ind = 0;
1214 3 : move16();
1215 3 : move16();
1216 3 : move16();
1217 3 : set16_fx( hHQ_nbfec->old_auOut_2fr_fx, 0, L_FRAME8k * 2 );
1218 3 : set16_fx( hHQ_nbfec->old_out_pha_fx[0], 0, N_LEAD_NB );
1219 3 : set16_fx( hHQ_nbfec->old_out_pha_fx[1], 0, N_LEAD_NB );
1220 :
1221 12 : FOR( i = 0; i < MAX_SB_NB; i++ )
1222 : {
1223 72 : FOR( j = 0; j < MAX_PGF; j++ )
1224 : {
1225 63 : hHQ_nbfec->ynrm_values_fx[i][j] = 0;
1226 63 : move16();
1227 : }
1228 27 : FOR( j = 0; j < MAX_ROW; j++ )
1229 : {
1230 18 : hHQ_nbfec->r_p_values_fx[i][j] = 0;
1231 18 : move16();
1232 : }
1233 : }
1234 :
1235 3 : set16_fx( hHQ_nbfec->Norm_gain_fx, 1, SFM_N_NB );
1236 3 : hHQ_nbfec->HQ_FEC_seed = RANDOM_INITSEED;
1237 3 : move16();
1238 3 : set16_fx( hHQ_nbfec->energy_MA_Curr_fx, 100, 2 );
1239 :
1240 3 : set16_fx( hHQ_nbfec->prev_sign_switch, 0, HQ_FEC_SIGN_SFM );
1241 3 : set16_fx( hHQ_nbfec->prev_sign_switch_2, 0, HQ_FEC_SIGN_SFM );
1242 :
1243 3 : set32_fx( hHQ_nbfec->old_coeffs_fx, 0, L_FRAME8k );
1244 3 : set32_fx( hHQ_nbfec->oldIMDCTout_fx, 0, L_FRAME8k / 2 );
1245 3 : set16_fx( hHQ_nbfec->prev_oldauOut_fx, 0, L_FRAME8k );
1246 :
1247 3 : return;
1248 : }
|