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 0 : CNG_dec_fx( st_fx, EVS_MONO, Aq_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, &sid_bw, q_env );
377 :
378 : /* comfort noise generation */
379 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,
380 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,
381 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 );
382 :
383 0 : set16_fx( voice_factors_fx, 32767 /*1.0f in Q15*/, NB_SUBFR );
384 0 : class_para_fx = 0;
385 0 : move16();
386 :
387 0 : delta_mem_scale = 3;
388 0 : move16();
389 :
390 0 : IF( LT_32( st_fx->lp_ener_fx, 40 ) ) /* very low energy frames, less than 0.3125 */
391 : {
392 0 : delta_mem_scale = 0;
393 0 : move16();
394 : }
395 :
396 0 : i = st_fx->Q_exc;
397 0 : move16();
398 0 : Rescale_exc( hMusicPF->dct_post_old_exc_fx, exc_fx, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame,
399 0 : st_fx->L_frame * HIBND_ACB_L_FAC, 0, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, 0, INACTIVE );
400 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,
401 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 );
402 0 : Copy_Scale_sig( exc2_fx, exc2_fx, st_fx->L_frame, sub( st_fx->Q_exc, i ) );
403 :
404 : /* update past excitation signals for LD music post-filter */
405 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
406 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
407 :
408 : /* synthesis at 12k8 Hz sampling rate */
409 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 );
410 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 );
411 :
412 : /* reset the decoder */
413 0 : CNG_reset_dec_fx( st_fx, pitch_buf_fx, dummy_buf_fx + L_FRAME );
414 :
415 : /* update st_fx->mem_syn1 for ACELP core switching */
416 0 : Copy_Scale_sig( st_fx->mem_syn3_fx, st_fx->mem_syn1_fx, M, sub( -1, st_fx->Q_syn ) ); /*Q-1*/
417 0 : IF( NE_16( output_frame, L_FRAME8k ) )
418 : {
419 : Word16 pitch_temp[4];
420 0 : pitch_temp[2] = shl( L_FRAME, 6 );
421 0 : move16();
422 0 : pitch_temp[3] = shl( L_FRAME, 6 );
423 0 : move16();
424 0 : frame_energy_fx( L_FRAME, pitch_temp, syn_fx, 0, &frame_e_fx, st_fx->Q_syn );
425 : /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */
426 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*/
427 0 : move16();
428 : }
429 : /* update old synthesis for classification */
430 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*/
431 :
432 : /* Update music post processing values */
433 : /* Filter energies update */
434 0 : FOR( i = 0; i < DCT_L_POST; i++ )
435 : {
436 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/
437 0 : hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_deposit_h( 1229 /*Q12*/ ), 22938 /*Q15*/, hMusicPF->filt_lfE_fx[i] ) ); /*Q12*/
438 : }
439 :
440 0 : vad_flag = 0;
441 0 : move16();
442 : }
443 :
444 : /*----------------------------------------------------------------*
445 : * Decoding of all other frames
446 : *----------------------------------------------------------------*/
447 :
448 : ELSE
449 : {
450 : /*-----------------------------------------------------------------*
451 : * After CNG period, use the most up-to-date ISPs
452 : *-----------------------------------------------------------------*/
453 :
454 0 : test();
455 0 : IF( EQ_32( st_fx->last_core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->last_core_brate, SID_1k75 ) )
456 : {
457 0 : Copy( st_fx->lspCNG_fx, st_fx->lsp_old_fx, M ); /*Q15*/
458 0 : E_LPC_isp_isf_conversion( st_fx->lspCNG_fx, st_fx->lsf_old_fx, M ); /*Qx1.28*/
459 0 : set16_fx( old_exc_fx, 0, L_EXC_MEM_DEC );
460 : }
461 :
462 : /*------------------------------------------------------------*
463 : * Extracts VAD information from the bitstream in AMR-WB IO mode
464 : *------------------------------------------------------------*/
465 :
466 0 : vad_flag = (Word16) get_next_indice( st_fx, 1 );
467 0 : move16();
468 :
469 0 : st_fx->coder_type = GENERIC;
470 0 : move16();
471 0 : IF( vad_flag == 0 )
472 : {
473 0 : st_fx->coder_type = INACTIVE;
474 0 : move16();
475 : }
476 :
477 : /*-----------------------------------------------------------------*
478 : * ISF de-quantization and interpolation
479 : *-----------------------------------------------------------------*/
480 :
481 0 : isf_dec_amr_wb_fx( st_fx, Aq_fx, lsf_new_fx, lsp_new_fx );
482 :
483 : /*------------------------------------------------------------*
484 : * Decode excitation
485 : *------------------------------------------------------------*/
486 :
487 0 : decod_amr_wb_fx( st_fx, Aq_fx, pitch_buf_fx, exc_fx, exc2_fx, hf_gain_fx, voice_factors_fx, gain_buf );
488 :
489 : /* synthesis for ACELP core switching and SWB BWE */
490 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 );
491 :
492 : /*------------------------------------------------------------*
493 : * Update long-term energies for FEC
494 : * Update ISP vector for CNG
495 : *------------------------------------------------------------*/
496 :
497 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
498 : {
499 0 : IF( GT_16( st_fx->unv_cnt, 20 ) )
500 : {
501 : /*ftmp = st->lp_gainc * st->lp_gainc;*/
502 0 : L_tmp1 = L_mult0( st_fx->lp_gainc_fx, st_fx->lp_gainc_fx ); /* Q3*Q3 -> Q6*/
503 : /*st->lp_ener = 0.7f * st->lp_ener + 0.3f * ftmp;*/
504 0 : L_tmp = Mult_32_16( st_fx->lp_ener_fx, 22938 );
505 0 : st_fx->lp_ener_fx = L_add( L_tmp, Mult_32_16( L_tmp1, 9830 ) ); /*Q6 + Q6*/
506 0 : move32();
507 0 : FOR( i = 0; i < M; i++ )
508 : {
509 0 : L_tmp = L_mult( 3277 /*0.1f in Q15*/, lsp_new_fx[i] );
510 0 : st_fx->lspCNG_fx[i] = round_fx( L_mac( L_tmp, 29491 /*0.9f in Q15*/, st_fx->lspCNG_fx[i] ) ); /*Q15*/
511 0 : move16();
512 : }
513 : }
514 : ELSE
515 : {
516 0 : st_fx->unv_cnt = add( st_fx->unv_cnt, 1 );
517 0 : move16();
518 : }
519 : }
520 : ELSE
521 : {
522 0 : st_fx->unv_cnt = 0;
523 0 : move16();
524 : }
525 :
526 : /*------------------------------------------------------------*
527 : * Save filter memory in case the synthesis is redone after scaling
528 : * Core synthesis at 12k8 Hz
529 : *------------------------------------------------------------*/
530 :
531 : /* add extra headroom in case a CNA addition is likely (i.e. st_fx->psf_lp_noise_fx is close to the threshold) */
532 0 : tmp16 = 0;
533 0 : move16();
534 0 : test();
535 0 : test();
536 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) && st_fx->flag_cna && GE_16( st_fx->psf_lp_noise_fx, shl( 15, 7 ) ) )
537 : {
538 0 : tmp16 = 1;
539 0 : move16();
540 : }
541 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,
542 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 );
543 0 : Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/
544 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 );
545 :
546 : /*------------------------------------------------------------*
547 : * FEC - Estimate the classification information
548 : *------------------------------------------------------------*/
549 :
550 0 : FEC_clas_estim_fx( st_fx, 1, L_FRAME, &st_fx->clas_dec, st_fx->coder_type, pitch_buf_fx,
551 : syn_fx, &st_fx->lp_ener_FER_fx,
552 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,
553 0 : &amr_io_class, st_fx->Q_syn, &class_para_fx, st_fx->mem_syn_clas_estim_fx, &st_fx->classifier_Q_mem_syn,
554 : 0, 0, 0, st_fx->last_core_brate, -1 );
555 : /* update past excitation signals for LD music post-filter */
556 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
557 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
558 0 : Copy( hMusicPF->dct_post_old_exc_fx, exc_buffer_fx, DCT_L_POST - OFFSET2 ); /*Q_exc*/
559 :
560 0 : IF( NE_16( output_frame, L_FRAME8k ) )
561 : {
562 0 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
563 : {
564 0 : frame_energy_fx( L_FRAME, pitch_buf_fx, syn_fx, 0, &frame_e_fx, st_fx->Q_syn );
565 : /*st->psf_lp_noise = 0.99f * st->psf_lp_noise + 0.01f * frame_e; */
566 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*/
567 0 : move16();
568 : }
569 : }
570 :
571 0 : test();
572 0 : test();
573 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 ) )
574 : {
575 0 : tmp_coder_type = AUDIO;
576 0 : move16();
577 0 : test();
578 0 : IF( EQ_16( st_fx->last_coder_type, INACTIVE ) || EQ_16( st_fx->last_coder_type, UNVOICED ) )
579 : {
580 0 : tmp_coder_type = INACTIVE;
581 0 : move16();
582 : }
583 : /* Extrapolation of the last future part, windowing and high resolution DCT transform */
584 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 );
585 :
586 : /* LD music post-filter */
587 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 );
588 :
589 : /* Inverse DCT transform, retrieval of the aligned excitation, re-synthesis */
590 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,
591 0 : &st_fx->Q_syn, st_fx->mem_syn_clas_estim_fx, 1, &st_fx->mem_deemph_fx, hBPF->pst_old_syn_fx,
592 0 : &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, NULL, NULL );
593 : }
594 : ELSE
595 : {
596 : /*------------------------------------------------------------*
597 : * Improvement for unvoiced and audio signals
598 : *------------------------------------------------------------*/
599 :
600 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,
601 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 );
602 :
603 0 : FOR( i = 0; i < DCT_L_POST; i++ )
604 : {
605 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i] ;*/
606 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*/
607 0 : move16();
608 : }
609 : }
610 :
611 : /*------------------------------------------------------------*
612 : * FEC - Estimate pitch
613 : *------------------------------------------------------------*/
614 :
615 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,
616 0 : &st_fx->bfi_pitch_frame, &st_fx->upd_cnt, GENERIC, st_fx->element_mode );
617 :
618 : /*------------------------------------------------------------*
619 : * FEC - Smooth the speech energy evolution when recovering after a BAD frame
620 : * (smoothing is performed in the excitation domain and signal is resynthesized after)
621 : *------------------------------------------------------------*/
622 :
623 0 : FOR( i = 0; i < NB_SUBFR; i++ )
624 : {
625 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
626 0 : move16();
627 : }
628 :
629 0 : 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,
630 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,
631 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 );
632 :
633 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 );
634 : }
635 :
636 : } /* End of GOOD FRAME */
637 :
638 : /*----------------------------------------------------------------*
639 : * BAD frame
640 : *----------------------------------------------------------------*/
641 : ELSE
642 : {
643 : /* long burst frame erasures */
644 0 : test();
645 0 : IF( GT_16( st_fx->nbLostCmpt, 5 ) && GE_16( st_fx->clas_dec, VOICED_CLAS ) )
646 : {
647 0 : st_fx->last_good = VOICED_TRANSITION;
648 0 : move16();
649 : }
650 0 : vad_flag = st_fx->last_vad_fx;
651 0 : move16();
652 0 : amr_io_class = st_fx->last_good;
653 0 : move16();
654 0 : class_para_fx = 0;
655 0 : move16();
656 :
657 : /* LSF estimation and A(z) calculation */
658 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,
659 0 : st_fx->stab_fac_fx, st_fx->last_coder_type, st_fx->L_frame, st_fx->last_good,
660 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 );
661 :
662 0 : FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq_fx, lsf_new_fx, lsp_new_fx );
663 : /* calculation of excitation signal */
664 0 : FEC_exc_estim_fx( st_fx, L_FRAME, exc_fx, exc2_fx, tmp_buffer_fx, pitch_buf_fx, voice_factors_fx,
665 : &FEC_pitch_fx, dummy_buf_fx, lsf_new_fx, &st_fx->Q_exc, &tmp_noise_fx );
666 :
667 : /* synthesis for ACELP core switching and SWB BWE */
668 0 : syn_12k8_fx( L_FRAME, Aq_fx, exc_fx, tmp_buffer_fx, st_fx->mem_syn1_fx, 1, st_fx->Q_exc, -1 );
669 :
670 : /* update past excitation signals */
671 0 : Copy( hMusicPF->dct_post_old_exc_fx + L_FRAME, hMusicPF->dct_post_old_exc_fx, DCT_L_POST - L_FRAME - OFFSET2 ); /*Q_exc*/
672 0 : Copy( exc2_fx, hMusicPF->dct_post_old_exc_fx + ( DCT_L_POST - L_FRAME - OFFSET2 ), L_FRAME ); /*Q_exc*/
673 :
674 : /* Update music post processing values */
675 : /* Update circular buffer, keep last energy difference unchanged */
676 0 : FOR( i = 1; i < MAX_LT; i++ )
677 : {
678 0 : hMusicPF->LDm_lt_diff_etot_fx[i - 1] = hMusicPF->LDm_lt_diff_etot_fx[i];
679 0 : move16();
680 : }
681 : /* Filter energies update */
682 0 : FOR( i = 0; i < DCT_L_POST; i++ )
683 : {
684 : /*st->filt_lfE[i] = 0.3f + 0.7f * st->filt_lfE[i];*/
685 0 : hMusicPF->filt_lfE_fx[i] = round_fx( L_mac( L_deposit_h( 1229 ), 22938, hMusicPF->filt_lfE_fx[i] ) );
686 0 : move16();
687 : }
688 :
689 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,
690 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 );
691 0 : Copy( st_fx->mem_syn2_fx, mem_tmp_fx, M ); /*Q_syn*/
692 : /* synthesis at 12k8 Hz sampling rate */
693 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 );
694 :
695 : /* update old synthesis for classification */
696 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*/
697 :
698 :
699 0 : FOR( i = 0; i < NB_SUBFR; i++ )
700 : {
701 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
702 0 : move16();
703 : }
704 :
705 : /*------------------------------------------------------------*
706 : * FEC - Smooth the speech energy evolution when recovering after a BAD frame
707 : * (smoothing is performed in the excitation domain and signal is resynthesized after)
708 : *------------------------------------------------------------*/
709 :
710 0 : 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,
711 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,
712 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,
713 0 : st_fx->Q_exc, st_fx->Q_syn, EVS_MONO, 0, 0 );
714 :
715 : /* estimate the pitch-synchronous speech energy per sample to be used when normal operation recovers */
716 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 );
717 : }
718 :
719 : /*--------------------------------------------------------*
720 : * NB post-filter
721 : *--------------------------------------------------------*/
722 0 : test();
723 0 : IF( EQ_16( output_frame, L_FRAME8k ) || EQ_16( st_fx->last_bwidth, NB ) )
724 : {
725 0 : FOR( i = 0; i < NB_SUBFR; i++ )
726 : {
727 0 : pitch_buf_tmp[i] = mult_r( pitch_buf_fx[i], 512 ); /*Q0*/
728 0 : move16();
729 : }
730 0 : IF( EQ_16( output_frame, L_FRAME8k ) )
731 : {
732 0 : st_fx->hPFstat->on = 1;
733 0 : move16();
734 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 );
735 : }
736 : ELSE
737 : {
738 0 : st_fx->hPFstat->on = 0;
739 0 : move16();
740 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 );
741 : }
742 : }
743 :
744 : /*------------------------------------------------------------------*
745 : * Perform fixed deemphasis through 1/(1 - g*z^-1)
746 : *-----------------------------------------------------------------*/
747 :
748 : /* update old synthesis buffer - needed for ACELP internal sampling rate switching */
749 0 : Copy( syn_fx + L_FRAME - L_SYN_MEM, st_fx->mem_syn_r, L_SYN_MEM ); /*Q_syn*/
750 :
751 0 : deemph_fx( syn_fx, PREEMPH_FAC, L_FRAME, &( st_fx->mem_deemph_fx ) );
752 :
753 0 : unscale_AGC( syn_fx, st_fx->Q_syn, syn_fx_tmp2, st_fx->agc_mem_fx, L_FRAME );
754 0 : Copy( syn_fx_tmp2, syn_fx, L_FRAME ); /*Q0*/
755 :
756 : /* TCX=Q-1, ACELP2 Q0 */
757 0 : Copy_Scale_sig( syn_fx + L_FRAME / 2, hTcxDec->old_syn_Overl, L_FRAME / 2, sub( -1, st_fx->Q_syn ) );
758 0 : hTcxDec->Q_old_syn_Overl = -1;
759 0 : Copy_Scale_sig( syn_fx + L_FRAME - M - 1, st_fx->syn, M + 1, sub( 0, st_fx->Q_syn ) );
760 :
761 : /*------------------------------------------------------------------*
762 : * Formant post-filter
763 : *-----------------------------------------------------------------*/
764 :
765 0 : Copy( syn_fx, tmp_buffer_fx + L_SYN_MEM, L_FRAME ); /*Q0*/
766 0 : IF( NE_16( output_frame, L_FRAME8k ) && NE_16( st_fx->last_bwidth, NB ) )
767 : {
768 0 : st_fx->hPFstat->on = 1;
769 0 : move16();
770 0 : test();
771 0 : 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 );
772 : }
773 :
774 : /*----------------------------------------------------------------*
775 : * Comfort Noise Addition
776 : *----------------------------------------------------------------*/
777 :
778 0 : flag_cna = 0;
779 0 : move16();
780 0 : test();
781 0 : IF( ( GE_16( st_fx->psf_lp_noise_fx, ( 15 * ONE_IN_Q8 ) ) ) || EQ_16( st_fx->coder_type, INACTIVE ) )
782 : {
783 : /*VAD only for non inactive frame*/
784 0 : test();
785 0 : IF( EQ_16( st_fx->VAD, 1 ) && st_fx->coder_type != INACTIVE )
786 : {
787 0 : st_fx->VAD = 1;
788 0 : move16();
789 : }
790 : ELSE
791 : {
792 0 : st_fx->VAD = 0;
793 0 : move16();
794 : }
795 :
796 0 : ApplyFdCng_fx( syn_fx, st_fx->Q_syn, NULL, 0, NULL, NULL, NULL, st_fx, 0, 0 );
797 :
798 0 : st_fx->hFdCngDec->hFdCngCom->frame_type_previous = st_fx->m_frame_type;
799 0 : move16();
800 :
801 : /*Noisy speech detector*/
802 0 : noisy_speech_detection_fx( st_fx->hFdCngDec, st_fx->VAD, syn_fx, st_fx->Q_syn );
803 :
804 0 : st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = mult_r( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 32440 /*0.99 Q15*/ );
805 0 : IF( st_fx->hFdCngDec->hFdCngCom->flag_noisy_speech != 0 )
806 : {
807 0 : st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( st_fx->hFdCngDec->hFdCngCom->likelihood_noisy_speech, 328 /*0.01 Q15*/ );
808 0 : move16();
809 : }
810 0 : st_fx->lp_noise = st_fx->hFdCngDec->lp_noise;
811 0 : move16();
812 :
813 0 : test();
814 0 : IF( st_fx->flag_cna && GE_16( st_fx->psf_lp_noise_fx, 15 << 8 ) )
815 : {
816 0 : flag_cna = 1;
817 0 : move16();
818 0 : generate_masking_noise_fx( syn_fx, st_fx->Q_syn, st_fx->hFdCngDec->hFdCngCom, st_fx->hFdCngDec->hFdCngCom->frameSize, AMR_WB_CORE );
819 : }
820 0 : ELSE IF( st_fx->flag_cna )
821 : {
822 0 : generate_masking_noise_update_seed_fx( st_fx->hFdCngDec->hFdCngCom );
823 : }
824 :
825 : /*Copy(syn+L_FRAME-M-1, st_fx->syn, M+1);*/
826 : }
827 0 : ELSE IF( st_fx->flag_cna )
828 : {
829 0 : generate_masking_noise_update_seed_fx( st_fx->hFdCngDec->hFdCngCom );
830 : }
831 :
832 0 : IF( !flag_cna )
833 : {
834 0 : test();
835 0 : test();
836 0 : test();
837 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 ) ) )
838 : {
839 0 : FOR( i = 0; i < L_FRAME / 2; i++ )
840 : {
841 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*/
842 0 : move16();
843 : }
844 : }
845 0 : set16_fx( st_fx->hFdCngDec->hFdCngCom->olapBufferSynth2, 0, shl( L_FRAME, 1 ) );
846 : }
847 :
848 : /*----------------------------------------------------------------*
849 : * Change the sampling frequency to 8/16/32 kHz
850 : * Bass post-filter
851 : *----------------------------------------------------------------*/
852 :
853 : /* check if the CLDFB works on the right sample rate */
854 0 : IF( NE_16( i_mult( st_fx->cldfbAna->usb, st_fx->cldfbAna->no_col ), L_FRAME ) )
855 : {
856 : /* resample to ACELP internal sampling rate */
857 0 : Word16 newCldfbBands = CLDFB_getNumChannels( INT_FS_FX );
858 :
859 0 : resampleCldfb( st_fx->cldfbAna, newCldfbBands, L_FRAME, 0 );
860 0 : resampleCldfb( st_fx->cldfbBPF, newCldfbBands, L_FRAME, 0 );
861 :
862 0 : IF( st_fx->ini_frame > 0 )
863 : {
864 0 : st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels );
865 0 : move16();
866 : }
867 : }
868 :
869 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,
870 0 : &st_fx->stab_fac_smooth_fx, GENERIC, st_fx->Q_syn, bpf_error_signal );
871 :
872 0 : cldfbAnalysis_fx( st_fx->cldfbAna, realBuffer, imagBuffer, &scaleFactor, syn_fx, negate( st_fx->Q_syn ), CLDFB_NO_COL_MAX, workBuffer );
873 :
874 0 : scaleFactor.hb_scale = scaleFactor.lb_scale;
875 0 : move16();
876 :
877 : /* CLDFB analysis and add the BPF error signal */
878 0 : i = 0;
879 0 : move16();
880 0 : if ( st_fx->bpf_off == 0 )
881 : {
882 0 : i = CLDFB_NO_COL_MAX;
883 0 : move16();
884 : }
885 0 : addBassPostFilter_fx( bpf_error_signal, realBuffer, imagBuffer, st_fx->cldfbBPF, workBuffer, negate( st_fx->Q_syn ),
886 0 : i, st_fx->cldfbAna->no_col, st_fx->cldfbAna->no_channels, &scaleFactor );
887 0 : st_fx->Q_syn2 = st_fx->Q_syn;
888 0 : move16();
889 :
890 0 : IF( NE_16( st_fx->cldfbSyn->bandsToZero, sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels ) ) )
891 : {
892 : /* in case of BW switching, re-init to default */
893 0 : st_fx->cldfbSyn->bandsToZero = sub( st_fx->cldfbSyn->no_channels, st_fx->cldfbAna->no_channels );
894 0 : move16();
895 : }
896 0 : cldfb_synth_set_bandsToZero( st_fx, realBuffer, imagBuffer, CLDFB_NO_COL_MAX, scaleFactor );
897 :
898 : /* CLDFB synthesis of the combined signal */
899 0 : cldfbSynthesis_fx( st_fx->cldfbSyn, realBuffer, imagBuffer, &scaleFactor, synth_out_fx, negate( st_fx->Q_syn2 ), CLDFB_NO_COL_MAX, workBuffer );
900 :
901 : /* Bring CLDFB output to Q-1 */
902 0 : Scale_sig( synth_out_fx, output_frame, negate( st_fx->Q_syn2 ) );
903 0 : st_fx->Q_syn2 = 0;
904 0 : move16();
905 :
906 : /* save synthesis - needed in case of core switching */
907 0 : Copy( synth_out_fx, st_fx->previoussynth_fx, output_frame );
908 0 : st_fx->Q_syn2 = 0;
909 0 : move16();
910 :
911 : /*--------------------------------------------------------*
912 : * calculate the average frame energy
913 : *--------------------------------------------------------*/
914 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 );
915 : /*--------------------------------------------------------*
916 : * optimized for NO_S@-26dBov with street noise @ SNR=25dB
917 : *--------------------------------------------------------*/
918 :
919 : /* ng_ener = 10.0f * (float)log10(ng_ener + 0.01f) - 90.3087f + 15; */
920 0 : L_Ng_ener = L_max( 1, L_Ng_ener );
921 0 : tmp16 = norm_l( L_Ng_ener );
922 0 : exp2 = Log2_norm_lc( L_shl( L_Ng_ener, tmp16 ) );
923 0 : tmp16 = sub( 30, tmp16 );
924 0 : ng_ener = mac_r( L_shl( L_mac( -1233858L, tmp16, 24660 /*10/log2(10) in Q13*/ ), 10 ), exp2, 771 ); /*Q8*/
925 : /* st_fx->ng_ener_ST = 0.7f * st_fx->ng_ener_ST + 0.3f * ng_ener; */
926 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*/
927 0 : move16();
928 :
929 : /*-----------------------------------------------------------------*
930 : * Bandwidth extension 6kHz-8kHz
931 : *-----------------------------------------------------------------*/
932 :
933 0 : test();
934 0 : test();
935 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 ) ) )
936 : {
937 0 : hf_synth_amr_wb_fx( st_fx->hAmrwb_IO, st_fx->hBWE_zero,
938 : st_fx->core_brate, output_frame, Aq_fx, exc2_fx, syn_fx, &amr_io_class, synth_out_fx,
939 0 : class_para_fx, hf_gain_fx, voice_factors_fx, pitch_buf_fx, st_fx->Ng_ener_ST_fx, lsf_new_fx,
940 0 : st_fx->Q_exc, st_fx->Q_syn2 );
941 : }
942 : ELSE
943 : {
944 0 : hf_synth_amr_wb_reset_fx( st_fx->hBWE_zero, st_fx->hAmrwb_IO );
945 : }
946 :
947 : /*----------------------------------------------------------------------*
948 : * Updates
949 : *----------------------------------------------------------------------*/
950 :
951 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 );
952 : /* update old_Aq[] - needed in improv_amr_wb_gs_fx() */
953 0 : Copy( Aq_fx, st_fx->hAmrwb_IO->old_Aq_fx, NB_SUBFR * ( M + 1 ) ); /*Q12*/
954 :
955 0 : test();
956 0 : test();
957 0 : test();
958 0 : test();
959 0 : test();
960 0 : test();
961 0 : test();
962 :
963 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 ) )
964 : {
965 0 : waveadj_rec = 1;
966 0 : move16();
967 : }
968 :
969 : /* update main codec parameters */
970 0 : st_fx->last_core = st_fx->core;
971 0 : move16();
972 0 : st_fx->last_extl = -1;
973 0 : move16();
974 0 : st_fx->last_codec_mode = st_fx->codec_mode;
975 0 : move16();
976 0 : st_fx->last_L_frame = L_FRAME;
977 0 : move16();
978 0 : st_fx->last_core_brate = st_fx->core_brate;
979 0 : move16();
980 0 : st_fx->last_codec_mode = st_fx->codec_mode;
981 0 : move16();
982 0 : st_fx->last_bwidth = WB;
983 0 : move16();
984 0 : st_fx->last_total_brate_ber = st_fx->total_brate;
985 0 : move32();
986 0 : st_fx->prev_Q_exc = st_fx->Q_exc;
987 0 : move16();
988 0 : IF( !st_fx->bfi )
989 : {
990 0 : st_fx->last_total_brate = st_fx->total_brate;
991 0 : move32();
992 0 : st_fx->last_good = st_fx->clas_dec;
993 0 : move16();
994 : }
995 0 : st_fx->last_vad_fx = vad_flag;
996 0 : move16();
997 0 : st_fx->last_flag_cna = flag_cna;
998 0 : move16();
999 :
1000 0 : updt_dec_common_fx( st_fx, -1, -1, NULL, 0 );
1001 :
1002 : /*----------------------------------------------------------------*
1003 : * Overlap of ACELP synthesis with old MDCT memory
1004 : *----------------------------------------------------------------*/
1005 :
1006 0 : IF( st_fx->bfi )
1007 : {
1008 : /* calculate another loss frame to fill gap in case of switching frame loss */
1009 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 ) )
1010 : {
1011 0 : return error;
1012 : }
1013 : }
1014 :
1015 0 : delay_comp = NS2SA_FX2( st_fx->output_Fs, DELAY_CLDFB_NS );
1016 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*/
1017 0 : hHQ_core->Q_old_postdec = st_fx->Q_syn2;
1018 0 : move16();
1019 0 : IF( EQ_16( last_core_ori, HQ_CORE ) )
1020 : {
1021 : Word16 step, alpha, nz;
1022 :
1023 0 : Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( st_fx->Q_syn2, hHQ_core->Q_old_wtda ) );
1024 0 : hHQ_core->Q_old_wtda = st_fx->Q_syn2;
1025 0 : move16();
1026 :
1027 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*/
1028 :
1029 0 : i = 15;
1030 0 : move16();
1031 0 : tmps = NS2SA_FX2( st_fx->output_Fs, 6000000L );
1032 0 : nz = NS2SA_FX2( st_fx->output_Fs, N_ZERO_MDCT_NS );
1033 0 : step = Inv16( tmps, &i );
1034 0 : step = shl( step, i );
1035 0 : alpha = 0;
1036 0 : move16();
1037 :
1038 0 : test();
1039 0 : IF( st_fx->prev_bfi && hHQ_core->HqVoicing )
1040 : {
1041 0 : Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nz], tmps, negate( st_fx->Q_syn2 ) );
1042 : }
1043 :
1044 0 : FOR( i = 0; i < tmps; i++ )
1045 : {
1046 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 ) );
1047 0 : move16();
1048 0 : alpha = add( alpha, step );
1049 : }
1050 : }
1051 :
1052 : /*----------------------------------------------------------------*
1053 : * HP filtering
1054 : * Final synthesis output
1055 : *----------------------------------------------------------------*/
1056 :
1057 : /* Delay ACELP synthesis by DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS delay */
1058 0 : IF( GE_16( output_frame, L_FRAME16k ) )
1059 : {
1060 0 : tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS );
1061 0 : Scale_sig( st_fx->prev_synth_buffer_fx, tmps, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1062 0 : delay_signal_fx( synth_out_fx, output_frame, st_fx->prev_synth_buffer_fx, tmps );
1063 : }
1064 :
1065 0 : IF( waveadj_rec )
1066 : {
1067 0 : tmps = 0;
1068 0 : move16();
1069 0 : IF( GE_16( output_frame, L_FRAME16k ) )
1070 : {
1071 0 : tmps = NS2SA_FX2( st_fx->output_Fs, DELAY_BWE_TOTAL_NS );
1072 0 : move16();
1073 : }
1074 :
1075 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 );
1076 : }
1077 :
1078 : /* HP filter */
1079 0 : Scale_sig32( st_fx->L_mem_hp_out_fx, 4, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1080 0 : st_fx->Qprev_synth_buffer_fx = st_fx->Q_syn2;
1081 0 : move16();
1082 0 : hp20( synth_out_fx, 1 /*stride*/, output_frame, st_fx->L_mem_hp_out_fx, L_mult0( output_frame, 50 ) );
1083 :
1084 : /* save synthesis for core switching */
1085 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 ) );
1086 :
1087 : {
1088 : /* TCX-LTP Postfilter: used in AMR-WB IO to update memories and to avoid discontinuities when the past frame was TCX */
1089 0 : Word16 delta = NS2SA_FX2( st_fx->output_Fs, TCXLTP_DELAY_NS );
1090 0 : move16();
1091 0 : Scale_sig( hTcxLtpDec->tcxltp_mem_in, delta, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1092 0 : Scale_sig( hTcxLtpDec->tcxltp_mem_out, output_frame, sub( st_fx->Q_syn2, st_fx->Qprev_synth_buffer_fx ) );
1093 0 : tcx_ltp_post_fx( st_fx, hTcxLtpDec, ACELP_CORE, output_frame, 0, synth_out_fx, NULL );
1094 : }
1095 : /* final output of synthesis signal */
1096 0 : syn_output_fx( st_fx->codec_mode, synth_out_fx, output_frame, output_sp, st_fx->Q_syn2 );
1097 :
1098 0 : pop_wmops();
1099 :
1100 0 : return error;
1101 : }
1102 : /*------------------------------------------------------------------*
1103 : * amr_wb_dec_init_fx()
1104 : *
1105 : * AMR-WB decoder initialization
1106 : *------------------------------------------------------------------*/
1107 :
1108 3 : void amr_wb_dec_init_fx(
1109 : AMRWB_IO_DEC_HANDLE hAmrwb_IO /* i/o: AMR-WB IO data handle */
1110 : )
1111 : {
1112 : Word16 i;
1113 : /* gain quantization memory (used in AMR-WB IO mode) */
1114 15 : FOR( i = 0; i < GAIN_PRED_ORDER; i++ )
1115 : {
1116 12 : hAmrwb_IO->past_qua_en_fx[i] = -14336; /*-14.0f in Q10*/
1117 12 : move16(); /* Q10; */ /* gain quantization memory (used also in AMR-WB IO mode) */
1118 : }
1119 : /* Improvement of unvoiced and audio signals in AMR-WB IO mode */
1120 3 : hAmrwb_IO->UV_cnt_fx = 30;
1121 3 : move16();
1122 3 : hAmrwb_IO->LT_UV_cnt_fx = ( 60 << 6 ); /*Q6*/
1123 3 : move16();
1124 3 : set16_fx( hAmrwb_IO->lt_diff_etot_fx, 0, MAX_LT );
1125 3 : hAmrwb_IO->Last_ener_fx = 0;
1126 3 : move16();
1127 :
1128 3 : set16_fx( hAmrwb_IO->old_Aq_fx, 0, i_mult( NB_SUBFR, M + 1 ) );
1129 3 : hAmrwb_IO->old_Aq_fx[0] = 16384; /*1.0f in Q14*/
1130 3 : hAmrwb_IO->old_Aq_fx[M + 1] = 16384; /*1.0f in Q14*/
1131 3 : hAmrwb_IO->old_Aq_fx[2 * ( M + 1 )] = 16384; /*1.0f in Q14*/
1132 3 : hAmrwb_IO->old_Aq_fx[3 * ( M + 1 )] = 16384; /*1.0f in Q14*/
1133 3 : move16();
1134 3 : move16();
1135 3 : move16();
1136 3 : move16();
1137 3 : hAmrwb_IO->lt_voice_fac_fx = 0;
1138 3 : move16();
1139 3 : return;
1140 : }
|