Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include "options.h"
7 : #include "cnst.h"
8 : #include "rom_com.h"
9 : #include "prot_fx.h"
10 : #include "basop_util.h" /* Function prototypes */
11 : /*-------------------------------------------------------------------*
12 : * amr_wb_dec_fx()
13 : *
14 : * AMR-WB decoder
15 : *-------------------------------------------------------------------*/
16 :
17 0 : ivas_error amr_wb_dec_fx(
18 : Word16 output_sp[], /* o : synthesis output Q_syn2*/
19 : Decoder_State *st_fx /* o : Decoder static variables structure */
20 : )
21 : {
22 : Word16 i;
23 : Word16 vad_flag;
24 : Word16 output_frame; /* frame length at output sampling freq. */
25 : Word16 allow_cn_step;
26 : Word16 locattack, amr_io_class;
27 : Word16 tmps;
28 : Word16 synth_out_fx[L_FRAME48k];
29 :
30 : Word16 class_para_fx, hf_gain_fx[NB_SUBFR] /*Q0*/, voice_factors_fx[NB_SUBFR] /*Q15*/;
31 : Word16 delay_comp;
32 : Word16 last_core_ori;
33 : Word16 tmp_buffer_fx[L_FRAME48k];
34 : Word16 dct_buffer_fx[DCT_L_POST]; /*Qdct*/
35 : Word16 frame_e_fx;
36 : Word16 exc_buffer_fx[DCT_L_POST]; /*Q_exc*/
37 : Word16 lsp_new_fx[M]; /* LSPs at the end of the frame Q15 */
38 : Word16 lsf_new_fx[M]; /* LSFs at the end of the frame Qlog2(2.56)*/
39 : Word16 xsp_tmp[M];
40 : Word16 Aq_fx[NB_SUBFR * ( M + 1 )]; /* A(q) quantized for the 4 subframes Q12*/
41 : Word16 exc2_fx[L_FRAME]; /* total excitation buffer Q_exc*/
42 : Word16 mem_tmp_fx[M]; /* temporary synthesis filter memory Q_syn*/
43 : Word32 L_enr_q_fx; /* E information for FER protection */
44 : Word16 tmp_noise_fx; /* Long term temporary noise energy */
45 : Word16 FEC_pitch_fx; /* FEC pitch */
46 : Word16 dummy_buf_fx[L_FRAME32k]; /* dummy buffer - no usage Q_syn*/
47 : Word16 old_exc_fx[L_EXC_DEC], *exc_fx; /* excitation signal buffer Q_exc*/
48 : Word16 syn_tmp_fx[L_FRAME + 2], *syn_fx; /* synthesis signal buffer Q_syn*/
49 : Word32 L_tmp, L_tmp1;
50 : Word16 pitch_buf_fx[NB_SUBFR], Qdct, tmp_coder_type; /* Word16 pitch for each subframe (Q6) */
51 : Word16 tmp16;
52 0 : Word16 sid_bw = 0;
53 0 : move16();
54 : Word32 L_Ng_ener;
55 : Word16 exp2, ng_ener;
56 :
57 : Word16 bpf_error_signal[L_FRAME]; /*Q_syn*/
58 : CLDFB_SCALE_FACTOR scaleFactor;
59 : Word32 workBuffer[128 * 3];
60 : Word32 q_env[20];
61 : Word16 exc3[L_FRAME]; /*Q_exc*/
62 : Word16 gain_buf[NB_SUBFR16k]; /*Q14*/
63 :
64 : Word32 *realBuffer[CLDFB_NO_COL_MAX], *imagBuffer[CLDFB_NO_COL_MAX];
65 : Word32 realBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
66 : Word16 syn_fx_tmp2[L_FRAME]; /*Q0*/
67 :
68 : Word16 pitch_buf_tmp[NB_SUBFR]; /*Q6*/
69 : Word16 update_flg;
70 : Word8 flag_cna;
71 :
72 0 : Word8 waveadj_rec = 0;
73 0 : move16();
74 :
75 : Word16 avoid_lpc_burst_on_recovery;
76 : Word16 delta_mem_scale;
77 : MUSIC_POSTFILT_HANDLE hMusicPF;
78 : TCX_DEC_HANDLE hTcxDec;
79 : HQ_DEC_HANDLE hHQ_core;
80 : TCX_LTP_DEC_HANDLE hTcxLtpDec;
81 : BPF_DEC_HANDLE hBPF;
82 : ivas_error error;
83 :
84 0 : hMusicPF = st_fx->hMusicPF;
85 0 : hBPF = st_fx->hBPF;
86 0 : hHQ_core = st_fx->hHQ_core;
87 0 : hTcxLtpDec = st_fx->hTcxLtpDec;
88 0 : hTcxDec = st_fx->hTcxDec;
89 :
90 0 : push_wmops( "amr_wb_dec_fx" );
91 :
92 0 : error = IVAS_ERR_OK;
93 0 : st_fx->idchan = 0;
94 0 : move16();
95 0 : move16();
96 :
97 : /*------------------------------------------------------------------*
98 : * Initialization
99 : *------------------------------------------------------------------*/
100 :
101 0 : syn_tmp_fx[0] = 0;
102 0 : move16();
103 0 : syn_tmp_fx[1] = 0;
104 0 : move16();
105 0 : syn_fx = syn_tmp_fx + 2;
106 :
107 0 : FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ )
108 : {
109 0 : set32_fx( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX );
110 0 : set32_fx( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX );
111 0 : realBuffer[i] = realBufferTmp[i];
112 0 : imagBuffer[i] = imagBufferTmp[i];
113 : }
114 0 : set16_fx( gain_buf, 0, NB_SUBFR16k );
115 :
116 0 : st_fx->use_partial_copy = 0;
117 0 : move16();
118 0 : st_fx->rf_frame_type = RF_NO_DATA;
119 0 : move16();
120 0 : st_fx->rf_flag = 0;
121 0 : move16();
122 0 : st_fx->rf_flag_last = 0;
123 0 : move16();
124 :
125 0 : st_fx->L_frame = L_FRAME;
126 0 : move16();
127 0 : st_fx->nb_subfr = NB_SUBFR;
128 0 : move16();
129 0 : st_fx->core = AMR_WB_CORE;
130 0 : move16();
131 0 : st_fx->core_brate = st_fx->total_brate;
132 0 : move16();
133 0 : st_fx->extl = -1;
134 0 : move16();
135 0 : st_fx->bwidth = WB;
136 0 : move16();
137 0 : st_fx->coder_type = GENERIC;
138 0 : move16();
139 0 : output_frame = st_fx->output_frame_fx; /*Q0*/
140 0 : move16(); /* frame length of the input signal */
141 :
142 0 : st_fx->bpf_off = 0;
143 0 : move16();
144 0 : IF( EQ_16( st_fx->last_core, HQ_CORE ) )
145 : {
146 0 : st_fx->bpf_off = 1;
147 0 : move16();
148 0 : st_fx->hPFstat->on = 0;
149 0 : move16();
150 : }
151 0 : st_fx->igf = 0;
152 0 : move16();
153 :
154 0 : st_fx->sr_core = i_mult( st_fx->L_frame, 50 /*FRAMES_PER_SEC*/ );
155 0 : st_fx->fscale_old = st_fx->fscale;
156 0 : move16();
157 0 : st_fx->fscale = sr2fscale_fx( st_fx->sr_core );
158 :
159 : /* Initialization in case that the first frame is the good received AMR-WB (IO) frame */
160 0 : IF( st_fx->ini_frame == 0 )
161 : {
162 0 : st_fx->last_core = AMR_WB_CORE;
163 0 : move16();
164 0 : Copy( mean_isf_amr_wb_fx, st_fx->lsf_old_fx, M ); /*Qlog2(2.56)*/
165 0 : E_LPC_isf_isp_conversion( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M );
166 : }
167 :
168 : /* Updates in case of EVS primary mode -> AMR-WB IO mode switching */
169 0 : IF( NE_16( st_fx->last_core, AMR_WB_CORE ) )
170 : {
171 0 : updt_IO_switch_dec_fx( output_frame, st_fx );
172 : }
173 :
174 : /* Updates in case of EVS -> AMR-WB IO switching */
175 0 : IF( NE_32( ( error = core_switching_pre_dec_fx( st_fx, output_frame ) ), IVAS_ERR_OK ) )
176 : {
177 0 : return error;
178 : }
179 :
180 0 : last_core_ori = st_fx->last_core;
181 0 : move16();
182 0 : set16_fx( hf_gain_fx, 0, NB_SUBFR );
183 :
184 0 : amr_io_class = UNVOICED_CLAS;
185 0 : move16();
186 0 : L_enr_q_fx = L_deposit_l( 0 );
187 0 : tmp_noise_fx = 0;
188 0 : move16();
189 :
190 0 : Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); /*Q_exc*/
191 0 : exc_fx = old_exc_fx + L_EXC_MEM_DEC;
192 : /* reset post-filter in case of switching */
193 0 : IF( st_fx->hPFstat->on == 0 )
194 : {
195 0 : st_fx->hPFstat->reset = 1;
196 0 : move16();
197 : }
198 0 : IF( st_fx->bfi > 0 )
199 : {
200 0 : st_fx->nbLostCmpt = add( st_fx->nbLostCmpt, 1 );
201 0 : move16();
202 : }
203 : ELSE
204 : {
205 0 : st_fx->nbLostCmpt = 0;
206 0 : move16();
207 : }
208 :
209 : /* PLC: [TCX: Fade-out-recovery]
210 : * PLC: overlapping part needs to be attenuated for first good frame */
211 0 : test();
212 0 : test();
213 0 : test();
214 0 : test();
215 0 : IF( !st_fx->bfi && st_fx->prev_bfi && ( 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 ) ) )
216 : {
217 : /* v_multc(st_fx->old_out_fx, st_fx->hPlcInfo.recovery_gain, st_fx->old_out_fx, st_fx->L_frameTCX); */
218 0 : FOR( i = 0; i < hTcxDec->L_frameTCX; i++ )
219 : {
220 0 : hHQ_core->old_out_fx[i] = shl( mult_r( hHQ_core->old_out_fx[i], st_fx->hPlcInfo->recovery_gain ), 1 );
221 0 : move16();
222 : }
223 : }
224 :
225 0 : avoid_lpc_burst_on_recovery = 0;
226 0 : move16();
227 0 : test();
228 0 : test();
229 0 : IF( st_fx->last_con_tcx && ( NE_16( st_fx->L_frameTCX_past, st_fx->L_frame ) ) && ( st_fx->last_core != 0 ) )
230 : {
231 0 : avoid_lpc_burst_on_recovery = 1;
232 0 : move16();
233 : }
234 :
235 : /*-----------------------------------------------------------------*
236 : * switching from ACELP@16k core to AMR-WB IO mode
237 : *-----------------------------------------------------------------*/
238 0 : st_fx->rate_switching_reset = 0;
239 0 : move16();
240 0 : test();
241 0 : test();
242 0 : IF( NE_16( st_fx->last_core, AMR_WB_CORE ) && EQ_16( st_fx->last_L_frame, L_FRAME16k ) && NE_16( st_fx->last_core, HQ_CORE ) )
243 : {
244 : /* in case of switching, do not apply BPF */
245 0 : st_fx->bpf_off = 1;
246 0 : move16();
247 0 : IF( st_fx->hPFstat->on )
248 : {
249 : Word16 mem_syn_r_size_old, mem_syn_r_size_new;
250 :
251 0 : mem_syn_r_size_old = shr( st_fx->last_L_frame, 4 );
252 0 : mem_syn_r_size_new = shr( st_fx->L_frame, 4 );
253 0 : lerp( st_fx->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_old, st_fx->hPFstat->mem_stp + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old );
254 0 : lerp( st_fx->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_old, st_fx->hPFstat->mem_pf_in + L_SYN_MEM - mem_syn_r_size_new, mem_syn_r_size_new, mem_syn_r_size_old );
255 : }
256 0 : st_fx->rate_switching_reset = lsp_convert_poly_fx( st_fx->lsp_old_fx, L_FRAME, 1 );
257 : /* convert old quantized LSF vector */
258 0 : lsp2lsf_fx( st_fx->lsp_old_fx, st_fx->lsf_old_fx, M, INT_FS_FX );
259 :
260 : /* FEC - update adaptive LSF mean vector */
261 0 : Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi1_fx, M ); /*Qlog2(2.56)*/
262 0 : Copy( st_fx->lsf_old_fx, st_fx->lsfoldbfi0_fx, M ); /*Qlog2(2.56)*/
263 0 : Copy( st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, M ); /*Qlog2(2.56)*/
264 :
265 : /* Reset LPC mem */
266 0 : Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); /*Qlog2(2.56)*/
267 0 : set16_fx( st_fx->mem_MA_fx, 0, M );
268 :
269 : /* update synthesis filter memories */
270 0 : synth_mem_updt2( L_FRAME, st_fx->last_L_frame, st_fx->old_exc_fx, st_fx->mem_syn_r, st_fx->mem_syn2_fx, NULL, DEC );
271 0 : Copy( st_fx->old_exc_fx, old_exc_fx, L_EXC_MEM_DEC ); /*Q_exc*/
272 0 : Copy_Scale_sig( st_fx->mem_syn2_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/
273 0 : Copy( st_fx->mem_syn2_fx, st_fx->mem_syn3_fx, M ); /*Q_syn*/
274 :
275 : /* LSP -> ISP */
276 0 : Copy( stable_ISP_fx, xsp_tmp, M ); /*Q15*/
277 0 : lsp2isp_fx( st_fx->lsp_old_fx, st_fx->lsp_old_fx, xsp_tmp, M ); /*Q15*/
278 : }
279 :
280 : /* update buffer of old subframe pitch values */
281 0 : IF( NE_16( st_fx->last_L_frame, L_FRAME ) )
282 : {
283 0 : move16();
284 0 : IF( EQ_16( st_fx->last_L_frame, L_FRAME32k ) )
285 : {
286 : /* (float)12800/(float)32000; */
287 0 : tmp16 = 13107; /*Q15*/
288 0 : move16();
289 : }
290 0 : ELSE IF( EQ_16( st_fx->last_L_frame, 512 ) )
291 : {
292 : /* (float)12800/(float)25600; */
293 0 : tmp16 = 16384; /*Q15*/
294 0 : move16();
295 : }
296 : ELSE /* st->last_L_frame == L_FRAME16k */
297 : {
298 : /* (float)12800/(float)16000; */
299 0 : tmp16 = 26214; /*Q15*/
300 0 : move16();
301 : }
302 :
303 0 : FOR( i = sub( NB_SUBFR16k, NB_SUBFR ); i < NB_SUBFR16k; i++ )
304 : {
305 0 : st_fx->old_pitch_buf_fx[i - 1] = Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], tmp16 ); /*15Q16*/
306 0 : move32();
307 : }
308 :
309 0 : FOR( i = sub( shl( NB_SUBFR16k, 1 ), NB_SUBFR ); i < shl( NB_SUBFR16k, 1 ); i++ )
310 : {
311 0 : st_fx->old_pitch_buf_fx[i - 2] = Mpy_32_16_1( st_fx->old_pitch_buf_fx[i], tmp16 ); /*15Q16*/
312 0 : move32();
313 : }
314 : }
315 :
316 0 : IF( NE_16( st_fx->bfi_pitch_frame, L_FRAME ) )
317 : {
318 0 : move16();
319 0 : IF( EQ_16( st_fx->bfi_pitch_frame, L_FRAME32k ) )
320 : {
321 : /* (float)12800/(float)32000; */
322 0 : tmp16 = 13107; /*Q15*/
323 0 : move16();
324 : }
325 0 : ELSE IF( EQ_16( st_fx->bfi_pitch_frame, 512 ) )
326 : {
327 : /* (float)12800/(float)25600; */
328 0 : tmp16 = 16384; /*Q15*/
329 0 : move16();
330 : }
331 : ELSE /* st->bfi_pitch_frame == L_FRAME16k */
332 : {
333 : /* (float)12800/(float)16000; */
334 0 : tmp16 = 26214; /*Q15*/
335 0 : move16();
336 : }
337 0 : st_fx->bfi_pitch_fx = mult_r( tmp16, st_fx->bfi_pitch_fx ); /*Q0*/
338 0 : move16();
339 0 : st_fx->bfi_pitch_frame = L_FRAME;
340 0 : move16();
341 : }
342 : #ifdef _DIFF_FLOAT_FIX_
343 : PMT( "the code below has been removed in IVAS float (or moved somewhere else), is it ok?" )
344 : #endif
345 0 : IF( NE_16( st_fx->last_core, AMR_WB_CORE ) )
346 : {
347 : /* reset the unvoiced/audio signal improvement memories */
348 0 : E_LPC_f_isp_a_conversion( st_fx->lsp_old_fx, st_fx->hAmrwb_IO->old_Aq_fx, M );
349 0 : Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + M + 1, M + 1 ); /*Q12*/
350 0 : Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + i_mult( 2, M + 1 ), M + 1 ); /*Q12*/
351 0 : Copy( st_fx->hAmrwb_IO->old_Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx + i_mult( 3, M + 1 ), M + 1 ); /*Q12*/
352 : }
353 : /*End of _DIFF_FLOAT_FIX_*/
354 0 : test();
355 0 : if ( EQ_16( st_fx->last_bwidth, NB ) && st_fx->ini_frame != 0 )
356 : {
357 0 : st_fx->rate_switching_reset = 1;
358 0 : move16();
359 : }
360 :
361 : /*----------------------------------------------------------------------*
362 : * GOOD frame
363 : *----------------------------------------------------------------------*/
364 :
365 0 : IF( !st_fx->bfi )
366 : {
367 : /*----------------------------------------------------------------*
368 : * Processing of FRAME_NO_DATA frames
369 : * Decoding of SID frames
370 : *----------------------------------------------------------------*/
371 :
372 0 : test();
373 0 : IF( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_1k75 ) )
374 : {
375 : /* decode CNG parameters */
376 : #ifdef REMOVE_EVS_DUPLICATES
377 0 : CNG_dec_ivas_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env );
378 : #else
379 : CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env );
380 : #endif
381 :
382 : /* comfort noise generation */
383 0 : CNG_exc_fx( st_fx->core_brate, L_FRAME, &st_fx->hTdCngDec->Enew_fx, &st_fx->hTdCngDec->cng_seed, exc_fx, exc2_fx, &st_fx->lp_ener_fx, st_fx->last_core_brate,
384 0 : &st_fx->first_CNG, &st_fx->hTdCngDec->cng_ener_seed, dummy_buf_fx, allow_cn_step, &st_fx->hTdCngDec->last_allow_cn_step, st_fx->prev_Q_exc, st_fx->Q_exc, st_fx->hTdCngDec->num_ho,
385 0 : q_env, st_fx->hTdCngDec->lp_env_fx, st_fx->hTdCngDec->old_env_fx, st_fx->hTdCngDec->exc_mem_fx, st_fx->hTdCngDec->exc_mem1_fx, &sid_bw, &st_fx->hTdCngDec->cng_ener_seed1, exc3, st_fx->Opt_AMR_WB, st_fx->element_mode );
386 :
387 0 : set16_fx( voice_factors_fx, 32767 /*1.0f in Q15*/, NB_SUBFR );
388 0 : class_para_fx = 0;
389 0 : move16();
390 :
391 0 : delta_mem_scale = 3;
392 0 : move16();
393 :
394 0 : IF( LT_32( st_fx->lp_ener_fx, 40 ) ) /* very low energy frames, less than 0.3125 */
395 : {
396 0 : delta_mem_scale = 0;
397 0 : move16();
398 : }
399 :
400 0 : i = st_fx->Q_exc;
401 0 : move16();
402 0 : Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame,
403 0 : st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE );
404 0 : Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, delta_mem_scale,
405 0 : &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 0, 0, NULL );
406 0 : Copy_Scale_sig( exc2_fx, exc2_fx, st_fx->L_frame, sub( st_fx->Q_exc, i ) );
407 :
408 : /* update past excitation signals for LD music post-filter */
409 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
410 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
411 :
412 : /* synthesis at 12k8 Hz sampling rate */
413 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn );
414 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, dummy_buf_fx, st_fx->mem_syn3_fx, 1, st_fx->Q_exc, st_fx->Q_syn );
415 :
416 : /* reset the decoder */
417 0 : CNG_reset_dec_fx( st_fx, pitch_buf_fx, dummy_buf_fx + L_FRAME );
418 :
419 : /* update st_fx->mem_syn1 for ACELP core switching */
420 0 : Copy_Scale_sig( st_fx->mem_syn3_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/
421 0 : IF( NE_16( output_frame, L_FRAME8k ) )
422 : {
423 : Word16 pitch_temp[4];
424 0 : pitch_temp[2] = shl( L_FRAME, 6 );
425 0 : move16();
426 0 : pitch_temp[3] = shl( L_FRAME, 6 );
427 0 : move16();
428 0 : frame_energy_fx( L_FRAME, pitch_temp, syn_fx, 0, &frame_e_fx, st_fx->Q_syn );
429 : /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */
430 0 : st_fx->psf_lp_noise_fx = round_fx( L_mac( L_mult( 32440 /*Q15*/, st_fx->psf_lp_noise_fx ), 328 /*Q15*/, frame_e_fx ) ); /*Q8*/
431 0 : move16();
432 : }
433 : /* update old synthesis for classification */
434 0 : Copy( syn_fx + L_FRAME - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); /*Q_syn*/
435 :
436 : /* Update music post processing values */
437 : /* Filter energies update */
438 0 : FOR( i = 0; i < DCT_L_POST; i++ )
439 : {
440 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/
441 0 : hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_deposit_h( 1229 /*Q12*/ ), 22938 /*Q15*/, hMusicPF->filt_lfE_fx[i] ) ); /*Q12*/
442 : }
443 :
444 0 : vad_flag = 0;
445 0 : move16();
446 : }
447 :
448 : /*----------------------------------------------------------------*
449 : * Decoding of all other frames
450 : *----------------------------------------------------------------*/
451 :
452 : ELSE
453 : {
454 : /*-----------------------------------------------------------------*
455 : * After CNG period, use the most up-to-date ISPs
456 : *-----------------------------------------------------------------*/
457 :
458 0 : test();
459 0 : IF( EQ_32( st_fx->last_core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->last_core_brate, SID_1k75 ) )
460 : {
461 0 : Copy( st_fx->lspCNG_fx, st_fx->lsp_old_fx, M ); /*Q15*/
462 0 : E_LPC_isp_isf_conversion( st_fx->lspCNG_fx, st_fx->lsf_old_fx, M ); /*Qx1.28*/
463 0 : set16_fx( old_exc_fx, 0, L_EXC_MEM_DEC );
464 : }
465 :
466 : /*------------------------------------------------------------*
467 : * Extracts VAD information from the bitstream in AMR-WB IO mode
468 : *------------------------------------------------------------*/
469 :
470 0 : vad_flag = (Word16) get_next_indice( st_fx, 1 );
471 0 : move16();
472 :
473 0 : st_fx->coder_type = GENERIC;
474 0 : move16();
475 0 : IF( vad_flag == 0 )
476 : {
477 0 : st_fx->coder_type = INACTIVE;
478 0 : move16();
479 : }
480 :
481 : /*-----------------------------------------------------------------*
482 : * ISF de-quantization and interpolation
483 : *-----------------------------------------------------------------*/
484 :
485 0 : isf_dec_amr_wb_fx( st_fx, Aq_fx, lsf_new_fx, lsp_new_fx );
486 :
487 : /*------------------------------------------------------------*
488 : * Decode excitation
489 : *------------------------------------------------------------*/
490 :
491 0 : decod_amr_wb_fx( st_fx, Aq_fx, pitch_buf_fx, exc_fx, exc2_fx, hf_gain_fx, voice_factors_fx, gain_buf );
492 :
493 : /* synthesis for ACELP core switching and SWB BWE */
494 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 );
495 :
496 : /*------------------------------------------------------------*
497 : * Update long-term energies for FEC
498 : * Update ISP vector for CNG
499 : *------------------------------------------------------------*/
500 :
501 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
502 : {
503 0 : IF( GT_16( st_fx->unv_cnt, 20 ) )
504 : {
505 : /*ftmp = st->lp_gainc * st->lp_gainc;*/
506 0 : L_tmp1 = L_mult0( st_fx->lp_gainc_fx, st_fx->lp_gainc_fx ); /* Q3*Q3 -> Q6*/
507 : /*st->lp_ener = 0.7f * st->lp_ener + 0.3f * ftmp;*/
508 0 : L_tmp = Mult_32_16( st_fx->lp_ener_fx, 22938 );
509 0 : st_fx->lp_ener_fx = L_add( L_tmp, Mult_32_16( L_tmp1, 9830 ) ); /*Q6 + Q6*/
510 0 : move32();
511 0 : FOR( i = 0; i < M; i++ )
512 : {
513 0 : L_tmp = L_mult( 3277 /*0.1f in Q15*/, lsp_new_fx[i] );
514 0 : st_fx->lspCNG_fx[i] = round_fx( L_mac( L_tmp, 29491 /*0.9f in Q15*/, st_fx->lspCNG_fx[i] ) ); /*Q15*/
515 0 : move16();
516 : }
517 : }
518 : ELSE
519 : {
520 0 : st_fx->unv_cnt = add( st_fx->unv_cnt, 1 );
521 0 : move16();
522 : }
523 : }
524 : ELSE
525 : {
526 0 : st_fx->unv_cnt = 0;
527 0 : move16();
528 : }
529 :
530 : /*------------------------------------------------------------*
531 : * Save filter memory in case the synthesis is redone after scaling
532 : * Core synthesis at 12k8 Hz
533 : *------------------------------------------------------------*/
534 :
535 : /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */
536 0 : tmp16 = 0;
537 0 : move16();
538 0 : test();
539 0 : test();
540 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) && st_fx->flag_cna && GE_16( st_fx->psf_lp_noise_fx, shl( 15, 7 ) ) )
541 : {
542 0 : tmp16 = 1;
543 0 : move16();
544 : }
545 0 : Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 5, &st_fx->mem_deemph_fx,
546 0 : hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, vad_flag, tmp16, tmp_buffer_fx );
547 0 : Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/
548 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn );
549 :
550 : /*------------------------------------------------------------*
551 : * FEC - Estimate the classification information
552 : *------------------------------------------------------------*/
553 :
554 0 : FEC_clas_estim_fx( st_fx, 1, L_FRAME, &st_fx->clas_dec, st_fx->coder_type, pitch_buf_fx,
555 : syn_fx, &st_fx->lp_ener_FER_fx,
556 0 : &st_fx->decision_hyst, &st_fx->hAmrwb_IO->UV_cnt_fx, &st_fx->hAmrwb_IO->LT_UV_cnt_fx, &st_fx->hAmrwb_IO->Last_ener_fx, &locattack, st_fx->hAmrwb_IO->lt_diff_etot_fx,
557 0 : &amr_io_class, st_fx->Q_syn, &class_para_fx, st_fx->mem_syn_clas_estim_fx, &st_fx->classifier_Q_mem_syn,
558 : 0, 0, 0, st_fx->last_core_brate, -1 );
559 : /* update past excitation signals for LD music post-filter */
560 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
561 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
562 0 : Copy( hMusicPF->dct_post_old_exc_fx, exc_buffer_fx, DCT_L_POST - OFFSET2 ); /*Q_exc*/
563 :
564 0 : IF( NE_16( output_frame, L_FRAME8k ) )
565 : {
566 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
567 : {
568 0 : frame_energy_fx( L_FRAME, pitch_buf_fx, syn_fx, 0, &frame_e_fx, st_fx->Q_syn );
569 : /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */
570 0 : st_fx->psf_lp_noise_fx = round_fx( L_mac( L_mult( 32440, st_fx->psf_lp_noise_fx ), 328, frame_e_fx ) ); /*Q8*/
571 0 : move16();
572 : }
573 : }
574 :
575 0 : test();
576 0 : test();
577 0 : IF( NE_16( amr_io_class, UNVOICED_CLAS ) && NE_16( st_fx->coder_type, INACTIVE ) && LT_16( st_fx->psf_lp_noise_fx, 15 << 8 ) )
578 : {
579 0 : tmp_coder_type = AUDIO;
580 0 : move16();
581 0 : test();
582 0 : IF( EQ_16( st_fx->last_coder_type, INACTIVE ) || EQ_16( st_fx->last_coder_type, UNVOICED ) )
583 : {
584 0 : tmp_coder_type = INACTIVE;
585 0 : move16();
586 : }
587 : /* Extrapolation of the last future part, windowing and high resolution DCT transform */
588 0 : Prep_music_postP_fx( exc_buffer_fx, dct_buffer_fx, hMusicPF->filt_lfE_fx, st_fx->last_core, st_fx->element_mode, pitch_buf_fx, hMusicPF->LDm_enh_lp_gbin_fx, st_fx->Q_exc, &Qdct );
589 :
590 : /* LD music post-filter */
591 0 : LD_music_post_filter_fx( hMusicPF, dct_buffer_fx, dct_buffer_fx, st_fx->core_brate, &hMusicPF->Old_ener_Q, -1, tmp_coder_type, Qdct );
592 :
593 : /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */
594 0 : Post_music_postP_fx( dct_buffer_fx, exc2_fx, mem_tmp_fx, st_fx->mem_syn2_fx, Aq_fx, syn_fx, &st_fx->Q_exc, &st_fx->prev_Q_syn,
595 0 : &st_fx->Q_syn, st_fx->mem_syn_clas_estim_fx, 1, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx,
596 0 : &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, NULL, NULL );
597 : }
598 : ELSE
599 : {
600 : /*------------------------------------------------------------*
601 : * Improvement for unvoiced and audio signals
602 : *------------------------------------------------------------*/
603 :
604 0 : improv_amr_wb_gs_fx( amr_io_class, st_fx->coder_type, st_fx->core_brate, &st_fx->hGSCDec->seed_tcx, st_fx->hAmrwb_IO->old_Aq_fx, st_fx->mem_syn2_fx, st_fx->hAmrwb_IO->lt_voice_fac_fx,
605 0 : locattack, Aq_fx, exc2_fx, st_fx->Q_exc, mem_tmp_fx, syn_fx, st_fx->Q_syn, pitch_buf_fx, st_fx->hAmrwb_IO->Last_ener_fx, st_fx->rate_switching_reset, st_fx->last_coder_type );
606 :
607 0 : FOR( i = 0; i < DCT_L_POST; i++ )
608 : {
609 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i] ;*/
610 0 : hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_deposit_h( 1229 /*0.3f in Q12*/ ), 22938 /*Q15*/, hMusicPF->filt_lfE_fx[i] ) ); /*Q12*/
611 0 : move16();
612 : }
613 : }
614 :
615 : /*------------------------------------------------------------*
616 : * FEC - Estimate pitch
617 : *------------------------------------------------------------*/
618 :
619 0 : FEC_pitch_estim_fx( 1, st_fx->last_core, L_FRAME, st_fx->clas_dec, st_fx->last_good, pitch_buf_fx, st_fx->old_pitch_buf_fx, &st_fx->bfi_pitch_fx,
620 0 : &st_fx->bfi_pitch_frame, &st_fx->upd_cnt, GENERIC, st_fx->element_mode );
621 :
622 : /*------------------------------------------------------------*
623 : * FEC - Smooth the speech energy evolution when recovering after a BAD frame
624 : * (smoothing is performed in the excitation domain and signal is resynthesized after)
625 : *------------------------------------------------------------*/
626 :
627 0 : FOR( i = 0; i < NB_SUBFR; i++ )
628 : {
629 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
630 0 : move16();
631 : }
632 :
633 : #ifdef REMOVE_EVS_DUPLICATES
634 0 : FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE,
635 0 : &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate,
636 0 : exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, avoid_lpc_burst_on_recovery, 0 );
637 : #else
638 : FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1, MOVING_AVERAGE,
639 : &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate, st_fx->prev_bfi, st_fx->last_core_brate,
640 : exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx, st_fx->Q_exc, st_fx->Q_syn, avoid_lpc_burst_on_recovery, 0 );
641 : #endif
642 :
643 0 : frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, pitch_buf_tmp[3], &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 );
644 : }
645 :
646 : } /* End of GOOD FRAME */
647 :
648 : /*----------------------------------------------------------------*
649 : * BAD frame
650 : *----------------------------------------------------------------*/
651 : ELSE
652 : {
653 : /* long burst frame erasures */
654 0 : test();
655 0 : IF( GT_16( st_fx->nbLostCmpt, 5 ) && GE_16( st_fx->clas_dec, VOICED_CLAS ) )
656 : {
657 0 : st_fx->last_good = VOICED_TRANSITION;
658 0 : move16();
659 : }
660 0 : vad_flag = st_fx->last_vad_fx;
661 0 : move16();
662 0 : amr_io_class = st_fx->last_good;
663 0 : move16();
664 0 : class_para_fx = 0;
665 0 : move16();
666 :
667 : /* LSF estimation and A(z) calculation */
668 0 : lsf_dec_bfi( MODE1, lsf_new_fx, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx,
669 0 : st_fx->stab_fac_fx, st_fx->last_coder_type, st_fx->L_frame, st_fx->last_good,
670 0 : st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth );
671 :
672 0 : FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx );
673 : /* calculation of excitation signal */
674 0 : FEC_exc_estim_fx( st_fx, L_FRAME, exc_fx, exc2_fx, tmp_buffer_fx, pitch_buf_fx, voice_factors_fx,
675 : &FEC_pitch_fx, dummy_buf_fx, lsf_new_fx, &st_fx->Q_exc, &tmp_noise_fx );
676 :
677 : /* synthesis for ACELP core switching and SWB BWE */
678 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 );
679 :
680 : /* update past excitation signals */
681 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
682 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
683 :
684 : /* Update music post processing values */
685 : /* Update circular buffer, keep last energy difference unchanged */
686 0 : FOR( i = 1; i < MAX_LT; i++ )
687 : {
688 0 : hMusicPF->LDm_lt_diff_etot_fx[i - 1] = hMusicPF->LDm_lt_diff_etot_fx[i];
689 0 : move16();
690 : }
691 : /* Filter energies update */
692 0 : FOR( i = 0; i < DCT_L_POST; i++ )
693 : {
694 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/
695 0 : hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_deposit_h( 1229 ), 22938, hMusicPF->filt_lfE_fx[i] ) );
696 0 : move16();
697 : }
698 :
699 0 : Rescale_mem( st_fx->Q_exc, &st_fx->prev_Q_syn, &st_fx->Q_syn, st_fx->mem_syn2_fx, st_fx->mem_syn_clas_estim_fx, 4, &st_fx->mem_deemph_fx,
700 0 : hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, 0, tmp_buffer_fx );
701 0 : Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/
702 : /* synthesis at 12k8 Hz sampling rate */
703 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc2_fx, syn_fx, st_fx->mem_syn2_fx, 1, st_fx->Q_exc, st_fx->Q_syn );
704 :
705 : /* update old synthesis for classification */
706 0 : Copy( syn_fx + L_FRAME - L_SYN_MEM_CLAS_ESTIM, st_fx->mem_syn_clas_estim_fx, L_SYN_MEM_CLAS_ESTIM ); /*Q_syn*/
707 :
708 :
709 0 : FOR( i = 0; i < NB_SUBFR; i++ )
710 : {
711 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
712 0 : move16();
713 : }
714 :
715 : /*------------------------------------------------------------*
716 : * FEC - Smooth the speech energy evolution when recovering after a BAD frame
717 : * (smoothing is performed in the excitation domain and signal is resynthesized after)
718 : *------------------------------------------------------------*/
719 :
720 : #ifdef REMOVE_EVS_DUPLICATES
721 0 : FEC_scale_syn_ivas_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1,
722 0 : MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate,
723 0 : st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx,
724 0 : st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, 0, 0 );
725 : #else
726 : FEC_scale_syn_fx( L_FRAME, &update_flg, st_fx->clas_dec, st_fx->last_good, syn_fx, pitch_buf_tmp, st_fx->enr_old_fx, L_enr_q_fx, -1,
727 : MOVING_AVERAGE, &st_fx->scaling_flag, &st_fx->lp_ener_FEC_av, &st_fx->lp_ener_FEC_max, st_fx->bfi, st_fx->total_brate,
728 : st_fx->prev_bfi, st_fx->last_core_brate, exc_fx, exc2_fx, Aq_fx, &st_fx->old_enr_LP, mem_tmp_fx, st_fx->mem_syn2_fx,
729 : st_fx->Q_exc, st_fx->Q_syn, 0, 0 );
730 : #endif
731 :
732 : /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */
733 0 : frame_ener_fx( L_FRAME, st_fx->last_good, syn_fx, shr( FEC_pitch_fx, 6 ), &st_fx->enr_old_fx, L_FRAME, st_fx->Q_syn, 3, 0 );
734 : }
735 :
736 : /*--------------------------------------------------------*
737 : * NB post-filter
738 : *--------------------------------------------------------*/
739 0 : test();
740 0 : IF( EQ_16( output_frame, L_FRAME8k ) || EQ_16( st_fx->last_bwidth, NB ) )
741 : {
742 0 : FOR( i = 0; i < NB_SUBFR; i++ )
743 : {
744 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
745 0 : move16();
746 : }
747 0 : IF( EQ_16( output_frame, L_FRAME8k ) )
748 : {
749 0 : st_fx->hPFstat->on = 1;
750 0 : move16();
751 0 : nb_post_filt_fx( L_FRAME, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, st_fx->coder_type, st_fx->BER_detect, 0 );
752 : }
753 : ELSE
754 : {
755 0 : st_fx->hPFstat->on = 0;
756 0 : move16();
757 0 : nb_post_filt_fx( L_FRAME, st_fx->hPFstat, &st_fx->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, AUDIO, st_fx->BER_detect, 0 );
758 : }
759 : }
760 :
761 : /*------------------------------------------------------------------*
762 : * Perform fixed deemphasis through 1/(1 - g*z^-1)
763 : *-----------------------------------------------------------------*/
764 :
765 : /* update old synthesis buffer - needed for ACELP internal sampling rate switching */
766 0 : Copy( syn_fx + L_FRAME - L_SYN_MEM, st_fx->mem_syn_r, L_SYN_MEM ); /*Q_syn*/
767 :
768 0 : deemph_fx( syn_fx, PREEMPH_FAC, L_FRAME, &( st_fx->mem_deemph_fx ) );
769 :
770 0 : unscale_AGC( syn_fx, st_fx->Q_syn, syn_fx_tmp2, st_fx->agc_mem_fx, L_FRAME );
771 0 : Copy( syn_fx_tmp2, syn_fx, L_FRAME ); /*Q0*/
772 :
773 : /* TCX=Q-1, ACELP2 Q0 */
774 0 : Copy_Scale_sig( syn_fx + L_FRAME / 2, hTcxDec->old_syn_Overl, L_FRAME / 2, sub( -1, st_fx->Q_syn ) );
775 0 : hTcxDec->Q_old_syn_Overl = -1;
776 0 : Copy_Scale_sig( syn_fx + L_FRAME - M - 1, st_fx->syn, M + 1, sub( 0, st_fx->Q_syn ) );
777 :
778 : /*------------------------------------------------------------------*
779 : * Formant post-filter
780 : *-----------------------------------------------------------------*/
781 :
782 0 : Copy( syn_fx, tmp_buffer_fx + L_SYN_MEM, L_FRAME ); /*Q0*/
783 0 : IF( NE_16( output_frame, L_FRAME8k ) && NE_16( st_fx->last_bwidth, NB ) )
784 : {
785 0 : st_fx->hPFstat->on = 1;
786 0 : move16();
787 0 : test();
788 : #ifdef REMOVE_EVS_DUPLICATES
789 0 : formant_post_filt_ivas_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 );
790 : #else
791 : formant_post_filt_fx( st_fx->hPFstat, tmp_buffer_fx + L_SYN_MEM, Aq_fx, syn_fx, L_FRAME, L_shl( st_fx->psf_lp_noise_fx, 15 ), st_fx->total_brate, sub( amr_io_class, AUDIO_CLAS ) == 0 );
792 : #endif
793 : }
794 :
795 : /*----------------------------------------------------------------*
796 : * Comfort Noise Addition
797 : *----------------------------------------------------------------*/
798 :
799 0 : flag_cna = 0;
800 0 : move16();
801 0 : test();
802 0 : IF( ( GE_16( st_fx->psf_lp_noise_fx, ( 15 * ONE_IN_Q8 ) ) ) || EQ_16( st_fx->coder_type, INACTIVE ) )
803 : {
804 : /*VAD only for non inactive frame*/
805 0 : test();
806 0 : IF( EQ_16( st_fx->VAD, 1 ) && st_fx->coder_type != INACTIVE )
807 : {
808 0 : st_fx->VAD = 1;
809 0 : move16();
810 : }
811 : ELSE
812 : {
813 0 : st_fx->VAD = 0;
814 0 : move16();
815 : }
816 : #ifdef REMOVE_EVS_DUPLICATES
817 0 : ApplyFdCng_ivas_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 );
818 : #else
819 : ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, NULL, NULL, st_fx, 0, 0 );
820 : #endif
821 0 : st_fx->hFdCngDec->hFdCngCom->frame_type_previous = st_fx->m_frame_type;
822 0 : move16();
823 :
824 : /*Noisy speech detector*/
825 0 : noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD, syn_fx, st_fx->Q_syn );
826 :
827 0 : st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ );
828 0 : IF( st_fx->hFdCngDec->hFdCngCom->flag_noisy_speech != 0 )
829 : {
830 0 : st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 328 /*0.01 Q15*/ );
831 0 : move16();
832 : }
833 0 : st_fx->lp_noise = st_fx->hFdCngDec->lp_noise;
834 0 : move16();
835 :
836 0 : test();
837 0 : IF( st_fx->flag_cna && GE_16( st_fx->psf_lp_noise_fx, 15 << 8 ) )
838 : {
839 0 : flag_cna = 1;
840 0 : move16();
841 0 : generate_masking_noise_fx( syn_fx, st_fx->Q_syn, st_fx->hFdCngDec->hFdCngCom, st_fx->hFdCngDec->hFdCngCom->frameSize, AMR_WB_CORE );
842 : }
843 0 : ELSE IF( st_fx->flag_cna )
844 : {
845 0 : generate_masking_noise_update_seed_fx( st_fx->hFdCngDec->hFdCngCom );
846 : }
847 :
848 : /*Copy(syn+L_FRAME-M-1, st_fx->syn, M+1);*/
849 : }
850 0 : ELSE IF( st_fx->flag_cna )
851 : {
852 0 : generate_masking_noise_update_seed_fx( st_fx->hFdCngDec->hFdCngCom );
853 : }
854 :
855 0 : IF( !flag_cna )
856 : {
857 0 : test();
858 0 : test();
859 0 : test();
860 0 : IF( EQ_16( st_fx->last_flag_cna, 1 ) && ( ( EQ_16( st_fx->last_core, ACELP_CORE ) && NE_16( st_fx->last_coder_type, AUDIO ) ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) )
861 : {
862 0 : FOR( i = 0; i < L_FRAME / 2; i++ )
863 : {
864 0 : syn_fx[i] = add( syn_fx[i], shr_r( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2[( i + shr( ( 5 * L_FRAME ), 2 ) )], -st_fx->Q_syn ) ); /*Q_syn*/
865 0 : move16();
866 : }
867 : }
868 0 : set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, shl( L_FRAME, 1 ) );
869 : }
870 :
871 : /*----------------------------------------------------------------*
872 : * Change the sampling frequency to 8/16/32 kHz
873 : * Bass post-filter
874 : *----------------------------------------------------------------*/
875 :
876 : /* check if the CLDFB works on the right sample rate */
877 0 : IF( NE_16( i_mult( st_fx->cldfbAna->usb, st_fx->cldfbAna->no_col ), L_FRAME ) )
878 : {
879 : /* resample to ACELP internal sampling rate */
880 0 : Word16 newCldfbBands = CLDFB_getNumChannels( INT_FS_FX );
881 :
882 0 : resampleCldfb( st_fx->cldfbAna, newCldfbBands, L_FRAME, 0 );
883 0 : resampleCldfb( st_fx->cldfbBPF, newCldfbBands, L_FRAME, 0 );
884 :
885 0 : IF( st_fx->ini_frame > 0 )
886 : {
887 0 : st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels );
888 0 : move16();
889 : }
890 : }
891 :
892 0 : bass_psfilter_fx( st_fx->hBPF, st_fx->Opt_AMR_WB, syn_fx, L_FRAME, pitch_buf_fx, st_fx->bpf_off, st_fx->stab_fac_fx,
893 0 : &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal );
894 :
895 0 : cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer );
896 :
897 0 : scaleFactor.hb_scale = scaleFactor.lb_scale;
898 0 : move16();
899 :
900 : /* CLDFB analysis and add the BPF error signal */
901 0 : i = 0;
902 0 : move16();
903 0 : if ( st_fx->bpf_off == 0 )
904 : {
905 0 : i = CLDFB_NO_COL_MAX;
906 0 : move16();
907 : }
908 0 : addBassPostFilter_fx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate( st_fx->Q_syn ),
909 0 : i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor );
910 0 : st_fx->Q_syn2 = st_fx->Q_syn;
911 0 : move16();
912 :
913 0 : IF( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ) ) )
914 : {
915 : /* in case of BW switching, re-init to default */
916 0 : st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels );
917 0 : move16();
918 : }
919 0 : cldfb_synth_set_bandsToZero( st_fx, realBuffer, imagBuffer, CLDFB_NO_COL_MAX, scaleFactor );
920 :
921 : /* CLDFB synthesis of the combined signal */
922 0 : cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer );
923 :
924 : /* Bring CLDFB output to Q-1 */
925 0 : Scale_sig( synth_out_fx, output_frame, negate( st_fx->Q_syn2 ) );
926 0 : st_fx->Q_syn2 = 0;
927 0 : move16();
928 :
929 : /* save synthesis - needed in case of core switching */
930 0 : Copy( synth_out_fx, st_fx->previoussynth_fx, output_frame );
931 0 : st_fx->Q_syn2 = 0;
932 0 : move16();
933 :
934 : /*--------------------------------------------------------*
935 : * calculate the average frame energy
936 : *--------------------------------------------------------*/
937 0 : frame_ener_fx( L_FRAME, st_fx->clas_dec, syn_fx, mult_r( pitch_buf_fx[3], 512 ), &L_Ng_ener, L_FRAME, st_fx->Q_syn, 3, 0 );
938 : /*--------------------------------------------------------*
939 : * optimized for NO_S@-26dBov with street noise @ SNR=25dB
940 : *--------------------------------------------------------*/
941 :
942 : /* ng_ener = 10.0f * (float)log10(ng_ener + 0.01f) - 90.3087f + 15; */
943 0 : L_Ng_ener = L_max( 1, L_Ng_ener );
944 0 : tmp16 = norm_l( L_Ng_ener );
945 0 : exp2 = Log2_norm_lc( L_shl( L_Ng_ener, tmp16 ) );
946 0 : tmp16 = sub( 30, tmp16 );
947 0 : ng_ener = mac_r( L_shl( L_mac( -1233858L, tmp16, 24660 /*10/log2(10) in Q13*/ ), 10 ), exp2, 771 ); /*Q8*/
948 : /* st_fx->ng_ener_ST = 0.7f * st_fx->ng_ener_ST + 0.3f * ng_ener; */
949 0 : st_fx->Ng_ener_ST_fx = mac_r( L_mult( st_fx->Ng_ener_ST_fx, 22938 /*0.7f in Q15*/ ), ng_ener, 9830 /*0.3f in Q15*/ ); /*Q8*/
950 0 : move16();
951 :
952 : /*-----------------------------------------------------------------*
953 : * Bandwidth extension 6kHz-8kHz
954 : *-----------------------------------------------------------------*/
955 :
956 0 : test();
957 0 : test();
958 0 : IF( GE_16( output_frame, L_FRAME16k ) && ( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, 10 ) ) || NE_16( st_fx->last_flag_filter_NB, 1 ) ) )
959 : {
960 0 : hf_synth_amr_wb_fx( st_fx->hAmrwb_IO, st_fx->hBWE_zero,
961 : st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, &amr_io_class, synth_out_fx,
962 0 : class_para_fx, hf_gain_fx, voice_factors_fx, pitch_buf_fx, st_fx->Ng_ener_ST_fx, lsf_new_fx,
963 0 : st_fx->Q_exc, st_fx->Q_syn2 );
964 : }
965 : ELSE
966 : {
967 0 : hf_synth_amr_wb_reset_fx( st_fx->hBWE_zero, st_fx->hAmrwb_IO );
968 : }
969 :
970 : /*----------------------------------------------------------------------*
971 : * Updates
972 : *----------------------------------------------------------------------*/
973 :
974 0 : updt_dec_fx( st_fx, old_exc_fx, pitch_buf_fx, 0, Aq_fx, lsf_new_fx, lsp_new_fx, voice_factors_fx, dummy_buf_fx, gain_buf );
975 : /* update old_Aq[] - needed in improv_amr_wb_gs_fx() */
976 0 : Copy( Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx, NB_SUBFR * ( M + 1 ) ); /*Q12*/
977 :
978 0 : test();
979 0 : test();
980 0 : test();
981 0 : test();
982 0 : test();
983 0 : test();
984 0 : test();
985 :
986 0 : 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 ) )
987 : {
988 0 : waveadj_rec = 1;
989 0 : move16();
990 : }
991 :
992 : /* update main codec parameters */
993 0 : st_fx->last_core = st_fx->core;
994 0 : move16();
995 0 : st_fx->last_extl = -1;
996 0 : move16();
997 0 : st_fx->last_codec_mode = st_fx->codec_mode;
998 0 : move16();
999 0 : st_fx->last_L_frame = L_FRAME;
1000 0 : move16();
1001 0 : st_fx->last_core_brate = st_fx->core_brate;
1002 0 : move16();
1003 0 : st_fx->last_codec_mode = st_fx->codec_mode;
1004 0 : move16();
1005 0 : st_fx->last_bwidth = WB;
1006 0 : move16();
1007 0 : st_fx->last_total_brate_ber = st_fx->total_brate;
1008 0 : move32();
1009 0 : st_fx->prev_Q_exc = st_fx->Q_exc;
1010 0 : move16();
1011 0 : IF( !st_fx->bfi )
1012 : {
1013 0 : st_fx->last_total_brate = st_fx->total_brate;
1014 0 : move32();
1015 0 : st_fx->last_good = st_fx->clas_dec;
1016 0 : move16();
1017 : }
1018 0 : st_fx->last_vad_fx = vad_flag;
1019 0 : move16();
1020 0 : st_fx->last_flag_cna = flag_cna;
1021 0 : move16();
1022 :
1023 0 : updt_dec_common_fx( st_fx, -1, -1, NULL, 0 );
1024 :
1025 : /*----------------------------------------------------------------*
1026 : * Overlap of ACELP synthesis with old MDCT memory
1027 : *----------------------------------------------------------------*/
1028 :
1029 0 : IF( st_fx->bfi )
1030 : {
1031 : /* calculate another loss frame to fill gap in case of switching frame loss */
1032 0 : IF( NE_32( ( error = acelp_core_switch_dec_bfi_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type ) ), IVAS_ERR_OK ) )
1033 : {
1034 0 : return error;
1035 : }
1036 : }
1037 :
1038 0 : delay_comp = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS );
1039 0 : Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( st_fx->Q_syn2, hHQ_core->Q_old_postdec ) ); /*Q_syn2 - Q_old_postdec*/
1040 0 : hHQ_core->Q_old_postdec = st_fx->Q_syn2;
1041 0 : move16();
1042 0 : IF( EQ_16( last_core_ori, HQ_CORE ) )
1043 : {
1044 : Word16 step, alpha, nz;
1045 :
1046 0 : Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( st_fx->Q_syn2, hHQ_core->Q_old_wtda ) );
1047 0 : hHQ_core->Q_old_wtda = st_fx->Q_syn2;
1048 0 : move16();
1049 :
1050 0 : Copy( st_fx->delay_buf_out_fx, synth_out_fx, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame Q0*/
1051 :
1052 0 : i = 15;
1053 0 : move16();
1054 0 : tmps = NS2SA_FX2( st_fx->output_Fs, 6000000L );
1055 0 : nz = NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS );
1056 0 : step = Inv16( tmps, &i );
1057 0 : step = shl( step, i );
1058 0 : alpha = 0;
1059 0 : move16();
1060 :
1061 0 : test();
1062 0 : IF( st_fx->prev_bfi && hHQ_core->HqVoicing )
1063 : {
1064 0 : Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nz], tmps, negate( st_fx->Q_syn2 ) );
1065 : }
1066 :
1067 0 : FOR( i = 0; i < tmps; i++ )
1068 : {
1069 0 : synth_out_fx[( i + delay_comp )] = msu_r_sat( L_mult( synth_out_fx[( i + delay_comp )], alpha ), hHQ_core->old_out_fx[( i + nz )], add( alpha, -32768 ) );
1070 0 : move16();
1071 0 : alpha = add( alpha, step );
1072 : }
1073 : }
1074 :
1075 : /*----------------------------------------------------------------*
1076 : * HP filtering
1077 : * Final synthesis output
1078 : *----------------------------------------------------------------*/
1079 :
1080 : /* Delay ACELP synthesis by DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS delay */
1081 0 : IF( GE_16( output_frame, L_FRAME16k ) )
1082 : {
1083 0 : tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS );
1084 0 : Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1085 0 : delay_signal_fx( synth_out_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps );
1086 : }
1087 :
1088 0 : IF( waveadj_rec )
1089 : {
1090 0 : tmps = 0;
1091 0 : move16();
1092 0 : IF( GE_16( output_frame, L_FRAME16k ) )
1093 : {
1094 0 : tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS );
1095 0 : move16();
1096 : }
1097 :
1098 0 : waveform_adj2_fix( st_fx->hPlcInfo, st_fx->hTonalMDCTConc->secondLastPcmOut, synth_out_fx + tmps, tmps, add( extract_l( st_fx->hPlcInfo->nbLostCmpt ), 1 ), st_fx->bfi );
1099 : }
1100 :
1101 : /* HP filter */
1102 0 : Scale_sig32( st_fx->L_mem_hp_out_fx, 4, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1103 0 : st_fx->Qprev_synth_buffer_fx = st_fx->Q_syn2;
1104 0 : move16();
1105 0 : hp20( synth_out_fx, 1 /*stride*/, output_frame, st_fx->L_mem_hp_out_fx, L_mult0( output_frame, 50 ) );
1106 :
1107 : /* save synthesis for core switching */
1108 0 : Copy_Scale_sig( synth_out_fx + NS2SA_FX2( st_fx->output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ), st_fx->old_synth_sw_fx, NS2SA_FX2( st_fx->output_Fs, FRAME_SIZE_NS - ACELP_LOOK_NS - DELAY_BWE_TOTAL_NS ), sub( hHQ_core->Q_old_postdec, st_fx->Q_syn2 ) );
1109 :
1110 : {
1111 : /* TCX-LTP Postfilter: used in AMR-WB IO to update memories and to avoid discontinuities when the past frame was TCX */
1112 0 : Word16 delta = NS2SA_FX2( st_fx->output_Fs, TCXLTP_DELAY_NS );
1113 0 : move16();
1114 0 : Scale_sig( hTcxLtpDec->tcxltp_mem_in, delta, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1115 0 : Scale_sig( hTcxLtpDec->tcxltp_mem_out, output_frame, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1116 0 : tcx_ltp_post_fx( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out_fx, NULL );
1117 : }
1118 : /* final output of synthesis signal */
1119 0 : syn_output_fx( st_fx->codec_mode, synth_out_fx, output_frame, output_sp, st_fx->Q_syn2 );
1120 :
1121 0 : pop_wmops();
1122 :
1123 0 : return error;
1124 : }
1125 : /*------------------------------------------------------------------*
1126 : * amr_wb_dec_init_fx()
1127 : *
1128 : * AMR-WB decoder initialization
1129 : *------------------------------------------------------------------*/
1130 :
1131 3 : void amr_wb_dec_init_fx(
1132 : AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */
1133 : )
1134 : {
1135 : Word16 i;
1136 : /* gain quantization memory (used in AMR-WB IO mode) */
1137 15 : FOR( i = 0; i < GAIN_PRED_ORDER; i++ )
1138 : {
1139 12 : hAmrwb_IO->past_qua_en_fx[i] = -14336; /*-14.0f in Q10*/
1140 12 : move16(); /* Q10; */ /* gain quantization memory (used also in AMR-WB IO mode) */
1141 : }
1142 : /* Improvement of unvoiced and audio signals in AMR-WB IO mode */
1143 3 : hAmrwb_IO->UV_cnt_fx = 30;
1144 3 : move16();
1145 3 : hAmrwb_IO->LT_UV_cnt_fx = ( 60 << 6 ); /*Q6*/
1146 3 : move16();
1147 3 : set16_fx( hAmrwb_IO->lt_diff_etot_fx, 0, MAX_LT );
1148 3 : hAmrwb_IO->Last_ener_fx = 0;
1149 3 : move16();
1150 :
1151 3 : set16_fx( hAmrwb_IO->old_Aq_fx, 0, i_mult( NB_SUBFR, M + 1 ) );
1152 3 : hAmrwb_IO->old_Aq_fx[0] = 16384; /*1.0f in Q14*/
1153 3 : hAmrwb_IO->old_Aq_fx[M + 1] = 16384; /*1.0f in Q14*/
1154 3 : hAmrwb_IO->old_Aq_fx[2 * ( M + 1 )] = 16384; /*1.0f in Q14*/
1155 3 : hAmrwb_IO->old_Aq_fx[3 * ( M + 1 )] = 16384; /*1.0f in Q14*/
1156 3 : move16();
1157 3 : move16();
1158 3 : move16();
1159 3 : move16();
1160 3 : hAmrwb_IO->lt_voice_fac_fx = 0;
1161 3 : move16();
1162 3 : return;
1163 : }
|