From 64efb3d5473b66917324ee3f32e8b83052311456 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 21 Mar 2024 21:12:00 +0530 Subject: [PATCH] ISM path fixed functions integration [x] core switching post dec fixed point implementation. [x] Ported ivas_jbm_dec_tc_buffer_playout, ivas_syn_output functions. --- lib_com/cldfb.c | 2 + lib_com/ivas_prot_fx.h | 8 + lib_com/ivas_tools.c | 31 ++ lib_com/prot_fx2.h | 29 +- lib_com/stat_com.h | 1 + lib_com/tools.c | 65 +++ lib_dec/acelp_core_switch_dec_fx.c | 247 ++++++++++ lib_dec/core_switching_dec.c | 114 +++++ lib_dec/core_switching_dec_fx.c | 741 +++++++++++++++++++++++++++++ lib_dec/ivas_core_dec.c | 367 +++++++++++++- lib_dec/ivas_jbm_dec.c | 70 +++ 11 files changed, 1671 insertions(+), 4 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 1fad358a2..5a99b1483 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -1657,6 +1657,7 @@ ivas_error openCldfb_ivas( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for CLDFB" ); } hs->cldfb_state_length = buf_len;//Temporarily added to store the length of buffer + hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ set32_fx(hs->cldfb_state_fx, 0, buf_len); #endif // IVAS_FLOAT_FIXED @@ -1709,6 +1710,7 @@ ivas_error openCldfb_ivas_fx( } hs->cldfb_state_length = buf_len; // Temporarily added to store the length of buffer + hs->cldfb_size = buf_len; /*for having original size at intermediatery conversion, will be removed on removing conversion*/ set32_fx(hs->cldfb_state_fx, 0, buf_len); /* TODO: remove the floating point dependency */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 6a4143b93..360e98ec4 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1725,4 +1725,12 @@ void update_bits_next_block( const Word16 max_k /* i : n umber of subframes */ ); #endif + +UWord32 ivas_syn_output_fx( + Word32 *synth[], /* i/o: float synthesis signal */ + const Word16 q_synth, + const Word16 output_frame, /* i : output frame length (one channel) */ + const Word16 n_channels, /* i : number of output channels */ + Word16 *synth_out /* o : integer 16 bits synthesis signal */ +); #endif diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 0e3bf3f81..ae8b78dfe 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -151,6 +151,37 @@ uint32_t ivas_syn_output( return noClipping; } +#ifdef IVAS_FLOAT_FIXED +UWord32 ivas_syn_output_fx( + Word32 *synth[], /* i/o: float synthesis signal */ + const Word16 q_synth, + const Word16 output_frame, /* i : output frame length (one channel) */ + const Word16 n_channels, /* i : number of output channels */ + Word16 *synth_out /* o : integer 16 bits synthesis signal */ +) +{ + Word16 i, n; + Word16 synth_loc[MAX_JBM_L_FRAME48k]; + UWord32 noClipping = 0; + + /*-----------------------------------------------------------------* + * float to integer conversion with saturation control + *-----------------------------------------------------------------*/ + + FOR ( n = 0; n < n_channels; n++ ) + { + noClipping += mvl2s_r( synth[n], q_synth, synth_loc, output_frame ); + + FOR ( i = 0; i < output_frame; i++ ) + { + synth_out[i * n_channels + n] = synth_loc[i]; + } + } + + return noClipping; +} +#endif + /*-------------------------------------------------------------------* * ivas_syn_output_f() diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index a8a666cc0..e83f04424 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -7421,6 +7421,21 @@ void generate_comfort_noise_dec_hf_ivas_fx( Word16* Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ ); + ivas_error core_switching_post_dec_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth */ + Word32 *output_fx, /* i/o: LB synth/upsampled LB synth */ + Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 output_frame, /* i : frame length */ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + const Word16 nchan_out, /* i : number of output channels */ + const Word16 last_element_mode, /* i : element mode of previous frame */ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ + ); + void core_switching_hq_prepare_dec_fx( Decoder_State *st_fx, /* i/o: encoder state structure */ Word16 *num_bits, /* i/o: bit budget update */ @@ -8939,6 +8954,11 @@ void cldfbAnalysis_ts_fx_fixed_q( Word16* q_cldfb ); +void configureCldfb_ivas_fx( + HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i/o: filter bank handle */ + const Word32 sampling_rate /* i : sampling rate */ +); + // dec4t64.c void dec_acelp_fast_fx( Decoder_State *st, /* i/o: decoder state structure */ @@ -9193,4 +9213,11 @@ void ivas_bw_switching_pre_proc_fx( /* float2fix and fix2float utilities (to be removed) */ void acelp_decoder_state_float2fix(Decoder_State *st, STEREO_CNG_DEC_HANDLE hStereoCng); void acelp_decoder_state_fix2float(Decoder_State *st, STEREO_CNG_DEC_HANDLE hStereoCng); -#endif \ No newline at end of file +#endif + +uint32_t mvl2s_r( + const Word32 x[], /* i : input vector */ + const Word16 q, + int16_t y[], /* o : output vector */ + const int16_t n /* i : vector size */ +); diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 31399a4dd..dde27ce88 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -771,6 +771,7 @@ typedef struct cldfb_filter_bank_struct #ifdef IVAS_FLOAT_FIXED Word32 *cldfb_state_fx; Word16 cldfb_state_length; + Word16 cldfb_size; Word16 Q_cldfb_state; #endif diff --git a/lib_com/tools.c b/lib_com/tools.c index 63d8bc6f8..943507c10 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -491,6 +491,71 @@ uint32_t mvr2s( return noClipping; } +#ifdef IVAS_FLOAT_FIXED +uint32_t mvl2s_r( + const Word32 x[], /* i : input vector */ + const Word16 q_x, + Word16 y[], /* o : output vector */ + const Word16 n /* i : vector size */ +) +{ + Word16 i; + Word32 temp; + uint32_t noClipping = 0; + + IF ( n <= 0 ) + { + /* cannot transfer vectors with size 0 */ + return 0; + } + + IF ( (void *) y <= (const void *) x ) + { + FOR ( i = 0; i < n; i++ ) + { + temp = L_shr(x[i], q_x-1); + temp = L_shr(L_add(temp, 1), 1); + + IF ( temp > MAX16B ) + { + temp = MAX16B; + noClipping++; + } + ELSE IF ( temp < MIN16B ) + { + temp = MIN16B; + noClipping++; + } + + y[i] = (Word16) temp; + } + } + ELSE + { + FOR ( i = n - 1; i >= 0; i-- ) + { + temp = L_shr(x[i], q_x-1); + temp = L_shr(L_add(temp, 1), 1); + + IF ( temp > MAX16B ) + { + temp = MAX16B; + noClipping++; + } + ELSE IF ( temp < MIN16B ) + { + temp = MIN16B; + noClipping++; + } + + y[i] = (Word16) temp; + } + } + + return noClipping; +} +#endif + void mvs2r( const int16_t x[], /* i : input vector */ float y[], /* o : output vector */ diff --git a/lib_dec/acelp_core_switch_dec_fx.c b/lib_dec/acelp_core_switch_dec_fx.c index 6adfb6cdb..4df708639 100644 --- a/lib_dec/acelp_core_switch_dec_fx.c +++ b/lib_dec/acelp_core_switch_dec_fx.c @@ -584,6 +584,253 @@ ivas_error acelp_core_switch_dec_bfi_fx( return error; } +#ifdef DISABLED +ivas_error acelp_core_switch_dec_bfi_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 synth_out[], /* o : synthesis Q_syn */ + const Word16 coder_type /* i : coder type */ +) +{ + Word16 old_exc[L_EXC_DEC], *exc; /* excitation signal buffer */ + Word16 syn[L_FRAME16k]; /* synthesis signal buffer */ + Word32 syn32[L_FRAME16k]; /* synthesis signal buffer */ + Word16 lsf_new[M]; /* LSFs at the end of the frame */ + Word16 lsp_new[M]; /* LSPs at the end of the frame */ + Word16 Aq[NB_SUBFR16k*(M+1)]; /* A(q) quantized for the 4 subframes */ + Word16 old_exc2[L_FRAME16k + L_EXC_MEM], *exc2; /* total excitation buffer */ + Word16 tmp_noise; /* Long term temporary noise energy */ + Word16 FEC_pitch; /* FEC pitch */ + Word16 old_bwe_exc[((PIT16k_MAX + (L_FRAME16k+1) + L_SUBFR16k) * 2)]; /* excitation buffer */ + Word16 *bwe_exc; /* Excitation for SWB TBE */ + Word16 tmp_float[NBPSF_PIT_MAX]; + Word16 tmp_float2[M]; + Word16 tmp_float3; + Word16 tmp_float4[L_TRACK_HIST]; + Word16 tmp_float5[L_TRACK_HIST]; + Word16 tmp_float6[L_TRACK_HIST]; + Word16 tmp_float7; + Word32 tmp_float32; + Word16 voice_factors[NB_SUBFR16k]; + Word16 pitch_buf[NB_SUBFR16k]; + Word16 Q_exc,Qtmp; + Word32 *realBuffer[CLDFB_NO_COL_MAX_SWITCH_BFI], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH_BFI]; + Word32 realBufferTmp[CLDFB_NO_COL_MAX_SWITCH_BFI][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH_BFI][CLDFB_NO_CHANNELS_MAX]; + Word16 i; + CLDFB_SCALE_FACTOR scaleFactor; + Word32 workBuffer[128*3]; + MUSIC_POSTFILT_HANDLE hMusicPF; + BPF_DEC_HANDLE hBPF; + ivas_error error; + + hMusicPF = st_fx->hMusicPF; + hBPF = st_fx->hBPF; + error = IVAS_ERR_OK; + + FOR( i=0; iQ_exc; + move16(); + st_fx->bpf_off = 1; + move16(); + st_fx->clas_dec = st_fx->last_good_fx; + move16(); + tmp_noise = 0; + move16(); + + Copy( st_fx->old_exc_fx, old_exc, L_EXC_MEM_DEC ); + exc = old_exc + L_EXC_MEM_DEC; + IF(st_fx->hWIDec != NULL) + { + Copy(st_fx->hWIDec->old_exc2_fx, old_exc2, L_EXC_MEM); + } + ELSE + { + set16_fx(old_exc2, 0, L_EXC_MEM); + } + exc2 = old_exc2 + L_EXC_MEM; + if (st_fx->hBWE_TD != NULL) + { + Copy(st_fx->hBWE_TD->old_bwe_exc_fx, old_bwe_exc, PIT16k_MAX * 2); + bwe_exc = old_bwe_exc + PIT16k_MAX * 2; + } + else + { + bwe_exc = NULL; + } + + st_fx->GSC_noisy_speech_fx = 0; + move16(); + st_fx->relax_prev_lsf_interp_fx = 0; + move16(); + + /* SC-VBR */ + if( EQ_16(st_fx->last_nelp_mode_dec_fx, 1)) + { + st_fx->nelp_mode_dec_fx = 1; + move16(); + } + + Copy(st_fx->mem_AR_fx,tmp_float,M); + Copy(st_fx->mem_MA_fx,tmp_float2,M); + + /* LSF estimation and A(z) calculation */ + lsf_dec_bfi(MODE1, lsf_new, st_fx->lsf_old_fx, st_fx->lsf_adaptive_mean_fx, NULL, st_fx->mem_MA_fx, st_fx->mem_AR_fx, + st_fx->stab_fac_fx, st_fx->last_coder_type_fx, st_fx->L_frame, st_fx->last_good_fx, + st_fx->nbLostCmpt, 0, NULL, NULL, NULL, st_fx->hGSCDec->Last_GSC_pit_band_idx_fx, st_fx->Opt_AMR_WB, 0, st_fx->bwidth); + + FEC_lsf2lsp_interp( st_fx, st_fx->L_frame, Aq, lsf_new, lsp_new); + + Copy( tmp_float, st_fx->mem_AR_fx, M ); + Copy( tmp_float2, st_fx->mem_MA_fx, M ); + + /*----------------------------------------------------------------* + * Excitation decoding + *----------------------------------------------------------------*/ + + IF( EQ_16(st_fx->nelp_mode_dec_fx, 1)) + { + Word16 gain_buf[NB_SUBFR16k]; + Scale_sig(exc-L_EXC_MEM, L_EXC_MEM, -st_fx->Q_exc); + st_fx->Q_exc = 0; + /* SC-VBR */ + decod_nelp_fx( st_fx, &tmp_noise, pitch_buf, exc, exc2, voice_factors, bwe_exc, &Q_exc, st_fx->bfi, gain_buf ); + FEC_pitch = pitch_buf[3]; + move16(); + Rescale_exc(hMusicPF->dct_post_old_exc_fx, exc, NULL, st_fx->hGSCDec->last_exc_dct_in_fx, L_FRAME, 0, (Word32)0, &Q_exc, st_fx->Q_subfr, exc2, L_FRAME, coder_type); + st_fx->Q_exc = Q_exc; + } + ELSE + { + tmp_float[0] = st_fx->bfi_pitch_fx; + move16(); + tmp_float[1] = st_fx->bfi_pitch_frame; + move16(); + tmp_float[2] = st_fx->lp_gainp_fx; + move16(); + tmp_float[3] = st_fx->lp_gainc_fx; + move16(); + tmp_float[4] = st_fx->upd_cnt; + move16(); + tmp_float[5] = st_fx->seed; + move16(); + + /* calculation of excitation signal */ + FEC_exc_estim_fx( st_fx, st_fx->L_frame, exc, exc2, syn /* dummy buffer */, pitch_buf, voice_factors, &FEC_pitch, bwe_exc, lsf_new, &Q_exc, &tmp_noise ); + Rescale_exc( NULL, exc, bwe_exc, st_fx->hGSCDec->last_exc_dct_in_fx, st_fx->L_frame, L_FRAME32k, (Word32)0, + &Q_exc, st_fx->Q_subfr, exc2, st_fx->L_frame, st_fx->last_coder_type_fx); + + st_fx->seed = tmp_float[5]; + move16(); + st_fx->bfi_pitch_fx = tmp_float[0]; + move16(); + st_fx->bfi_pitch_frame = tmp_float[1]; + move16(); + st_fx->lp_gainp_fx = tmp_float[2]; + move16(); + st_fx->lp_gainc_fx = tmp_float[3]; + move16(); + st_fx->upd_cnt = tmp_float[4]; + move16(); + } + + /*------------------------------------------------------------------* + * Synthesis + *-----------------------------------------------------------------*/ + + Rescale_mem( 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, + hBPF->pst_old_syn_fx, &hBPF->pst_mem_deemp_err_fx, &st_fx->agc_mem_fx[1], st_fx->hPFstat, 1, 0, NULL ); + Copy( st_fx->mem_syn2_fx,tmp_float,M); + syn_12k8_fx( st_fx->L_frame, Aq, exc2, syn, tmp_float, 1, Q_exc, st_fx->Q_syn ); + + tmp_float32 = st_fx->enr_old_fx; + frame_ener_fx( st_fx->L_frame, st_fx->last_good_fx, syn, shr(add(FEC_pitch,32),6), &tmp_float32, st_fx->L_frame, st_fx->Q_syn, 3, 0 ); + + /*------------------------------------------------------------------* + * Perform fixed deemphasis through 1/(1 - g*z^-1) + *-----------------------------------------------------------------*/ + tmp_float[0] = st_fx->mem_deemph_fx; + move16(); /*if in acelp_core_dec_fx deemph_fx is used*/ + /*tmp_float = shr(st_fx->mem_deemph_fx, sub(st_fx->Q_syn,1)); if in acelp_core_dec_fx Deemph2 is used*/ + + IF(EQ_16(st_fx->L_frame,L_FRAME )) + { + deemph_fx( syn, PREEMPH_FAC, L_FRAME, &tmp_float[0] ); /*Q0*/ + } + ELSE + { + deemph_fx( syn, PREEMPH_FAC_16k, L_FRAME16k, &tmp_float[0] ); /*Q0*/ + } + + /*----------------------------------------------------------------* + * Bass post-filter + *----------------------------------------------------------------*/ + + st_fx->bpf_off=1; + move16(); + Copy(hBPF->pst_old_syn_fx,tmp_float,NBPSF_PIT_MAX); + + tmp_float3 = st_fx->stab_fac_smooth_fx; + move16(); + Copy(hBPF->mem_mean_pit_fx,tmp_float4, L_TRACK_HIST); + Copy(hBPF->Track_on_hist_fx,tmp_float5, L_TRACK_HIST); + Copy(hBPF->vibrato_hist_fx,tmp_float6, L_TRACK_HIST); + tmp_float7 = hBPF->psf_att_fx; + move16(); + + bass_psfilter_fx(st_fx->hBPF, st_fx->Opt_AMR_WB, syn, st_fx->L_frame, pitch_buf, + st_fx->bpf_off, st_fx->stab_fac_fx, &tmp_float3, coder_type, st_fx->Q_syn, old_exc /* tmp buffer*/); + + Copy(tmp_float, hBPF->pst_old_syn_fx, NBPSF_PIT_MAX); + Copy(tmp_float4, hBPF->mem_mean_pit_fx, L_TRACK_HIST); + Copy(tmp_float5, hBPF->Track_on_hist_fx, L_TRACK_HIST); + Copy(tmp_float6, hBPF->vibrato_hist_fx, L_TRACK_HIST); + hBPF->psf_att_fx = tmp_float7 ; + /*----------------------------------------------------------------* + * Resamping to the output sampling frequency + *----------------------------------------------------------------*/ + /* CLDFB analysis of the synthesis at internal sampling rate */ + Qtmp = 11 - st_fx->Q_syn; + Copy_Scale_sig_16_32(syn, syn32,L_FRAME16k,Qtmp); + if ((error = cldfb_save_memory_ivas_fx( st_fx->cldfbAna )) != IVAS_ERR_OK) + { + return error; + } + /*cldfbAnalysisFiltering( st_fx->cldfbAna_fx, realBuffer, imagBuffer, &scaleFactor, syn, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer);*/ + cldfbAnalysis_ivas_fx(syn32, realBuffer, imagBuffer, st_fx->L_frame / 2, st_fx->cldfbAna); + cldfb_restore_memory_ivas_fx( st_fx->cldfbAna ); + + //scaleFactor.hb_scale = scaleFactor.lb_scale; + + /* CLDFB synthesis of the combined signal */ + if ((error = cldfb_save_memory_ivas_fx( st_fx->cldfbSyn )) != IVAS_ERR_OK) + { + return error; + } + /*cldfbSynthesisFiltering( st_fx->cldfbSyn_fx, realBuffer, imagBuffer, &scaleFactor, synth_out, + negate(st_fx->Q_syn), CLDFB_NO_COL_MAX_SWITCH_BFI, workBuffer );*/ + Scale_sig32(st_fx->cldfbSyn->cldfb_state,st_fx->cldfbSyn->cldfb_state_length,1); + cldfbSynthesis_ivas_fx(realBuffer, imagBuffer, synth_out, (int16_t)(st_fx->output_Fs * 0.01f), st_fx->cldfbSyn); + Scale_sig32(st_fx->cldfbSyn->cldfb_state, st_fx->cldfbSyn->cldfb_state_length, -1); + + /* output to Q0 */ + Copy_Scale_sig32_16(syn32, synth_out, L_FRAME48k, -5); + //Scale_sig(synth_out,L_FRAME48k, negate(st_fx->Q_syn)); + + cldfb_restore_memory_ivas_fx( st_fx->cldfbSyn ); + + return error; +} +#endif /*-------------------------------------------------------------------* * decod_gen_voic_core_switch() diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index 5163ed75b..add4d2147 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -1813,6 +1813,120 @@ void bandwidth_switching_detect( return; } +#ifdef IVAS_FLOAT_FIXED +void bandwidth_switching_detect_ivas_fx( + Decoder_State *st_fx /* i/o: encoder state structure */ +) +{ + IF ((EQ_16(st_fx->element_mode, IVAS_CPE_TD) && EQ_16(st_fx->idchan, 1) ) || EQ_16(st_fx->element_mode, IVAS_CPE_MDCT)) + { + /* there is no BWE in TD stereo secondary channel and in MDCT stereo, IGF is part of the core decoding -> no BW switching -> reset BWS counters */ + st_fx->prev_bws_cnt = 0; + st_fx->bws_cnt = 0; + st_fx->bws_cnt1 = 0; + move16(); move16(); move16(); + + return; + } + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16(st_fx->bws_cnt1, N_NS2W_FRAMES)) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE IF( GT_32(st_fx->total_brate, ACELP_9k60)&<_32(st_fx->last_core_brate,ACELP_9k60) + && EQ_16(st_fx->bwidth, SWB) && EQ_16(st_fx->last_bwidth, WB) ) + { + st_fx->bws_cnt1 = add(st_fx->bws_cnt1,1); + move16(); + } + ELSE IF( st_fx->bws_cnt1 > 0 ) + { + IF( LT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt = sub( shl(sub(N_NS2W_FRAMES, st_fx->bws_cnt1), 1), 1 ); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + + IF( LT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt1 = 0; + move16(); + } + ELSE + { + IF(EQ_16(st_fx->bwidth, SWB)) + { + st_fx->bws_cnt1 = add(st_fx->bws_cnt1,1); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + } + } + + /* update band-width switching counter */ + test(); + test(); + test(); + IF( GE_16(st_fx->bws_cnt, N_WS2N_FRAMES)) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE IF( LT_32(st_fx->total_brate, ACELP_9k60)&>_32(st_fx->last_core_brate,ACELP_9k60) + && LT_16(st_fx->bwidth, st_fx->last_bwidth) && EQ_16(st_fx->bwidth, WB) ) + { + st_fx->bws_cnt = add(st_fx->bws_cnt,1); + move16(); + } + ELSE IF( st_fx->bws_cnt > 0 ) + { + IF( GT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt1 = shr(sub(N_WS2N_FRAMES, st_fx->bws_cnt), 1); + move16(); + } + ELSE + { + st_fx->bws_cnt1 = 0; + move16(); + } + + IF( GT_16(st_fx->bwidth, st_fx->last_bwidth)) + { + st_fx->bws_cnt = 0; + move16(); + } + ELSE + { + IF( EQ_16(st_fx->bwidth, WB)) + { + st_fx->bws_cnt = add(st_fx->bws_cnt,1); + move16(); + } + ELSE + { + st_fx->bws_cnt = 0; + move16(); + } + } + } + + return; +} +#endif /*---------------------------------------------------------------------* diff --git a/lib_dec/core_switching_dec_fx.c b/lib_dec/core_switching_dec_fx.c index 0c3851a33..e5e716a3b 100644 --- a/lib_dec/core_switching_dec_fx.c +++ b/lib_dec/core_switching_dec_fx.c @@ -20,6 +20,12 @@ static void core_switch_lb_upsamp(Decoder_State* st, float* output); static void smoothTransitionDtxToTcx(float synth[], const int16_t output_frame, const int16_t delay_comp); #endif + +#ifdef IVAS_FLOAT_FIXED +static void smoothTransitionDtxToTcx_fx(Word16 synth[], const Word16 output_frame, const Word16 delay_comp); +static void core_switch_lb_upsamp_fx(Decoder_State* st, Word32* output); +#endif + void bandwidth_switching_detect_fx( Decoder_State *st_fx /* i/o: encoder state structure */ ) @@ -1489,6 +1495,590 @@ ivas_error core_switching_post_dec_fx( return error; } +#ifdef IVAS_FLOAT_FIXED +ivas_error core_switching_post_dec_ivas_fx( + Decoder_State *st_fx, /* i/o: decoder state structure */ + Word16 *synth, /* i/o: output synthesis Qsynth */ + Word32 *output_fx, /* i/o: LB synth/upsampled LB synth */ + Word16 output_mem_fx[], /* i : OLA memory from last TCX/HQ frame */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const Word16 use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const Word16 output_frame, /* i : frame length */ + const Word16 core_switching_flag, /* i : ACELP->HQ switching flag */ + const Word16 sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + const Word16 nchan_out, /* i : number of output channels */ + const Word16 last_element_mode, /* i : element mode of previous frame */ + Word16 *Qsynth /* i/o: Scaling of ACELP exit (Q_syn2-1) or HQ exit (Qsynth); changes after this function */ +) +{ + Word16 i, delay_comp, delta, alpha; + Word16 tmpF, tmp, Fs_kHz, shift, *ptmp1, *ptmp2, tmpV, nzeroes; + Word32 L_tmp; + Word16 synth_subfr_out[SWITCH_MAX_GAP], synth_subfr_bwe[SWITCH_MAX_GAP]; + Word16 mem_synth[NS2SA( 16000, DELAY_CLDFB_NS ) + 2]; + Word16 Qtmp; + Word16 Qsubfr; + TD_BWE_DEC_HANDLE hBWE_TD; + FD_BWE_DEC_HANDLE hBWE_FD; + HQ_DEC_HANDLE hHQ_core; + ivas_error error; + int16_t offset; + + L_tmp = 0; + + + hBWE_TD = st_fx->hBWE_TD; + hBWE_FD = st_fx->hBWE_FD; + hHQ_core = st_fx->hHQ_core; + error = IVAS_ERR_OK; + + // PMT("core_switching_post_dec_fx : Only handles has been converted, code needs to be entirely reviewed ") + + /* Rescale synthesis in Q0 to avoid multiple rescaling after */ + tmp = Find_Max_Norm16( synth, output_frame ); + Scale_sig( synth, output_frame, tmp ); + *Qsynth = add( *Qsynth, tmp ); + + test(); + test(); + test(); + IF( EQ_16( st_fx->core, ACELP_CORE ) && st_fx->bfi && hHQ_core != NULL && !st_fx->con_tcx ) + { + /*needed to be converted to fixed curretnly using evs implementation not in line*/ + if ( ( error = acelp_core_switch_dec_bfi_fx( st_fx, hHQ_core->fer_samples_fx, st_fx->coder_type ) ) != IVAS_ERR_OK ) + { + return error; + } /*the output at Q0*/ + } + + /* set multiplication factor according to the sampling rate */ + tmp = extract_l( L_shr( st_fx->output_Fs, 13 ) ); + Fs_kHz = shl( add( tmp, 1 ), 3 ); + + delta = 1; + move16(); + if ( GE_16( output_frame, L_FRAME16k ) ) + { + delta = shr( Fs_kHz, 3 ); + } + + /* set delay compensation between HQ synthesis and ACELP synthesis */ + delay_comp = i_mult2( delta, HQ_DELAY_COMP ); + /*needed to add more condition in if*/ + IF( ( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) || use_cldfb_for_dft ) && ( !sba_dirac_stereo_flag || ( sba_dirac_stereo_flag && EQ_32( st_fx->core_brate, SID_2k40 ) && EQ_16( st_fx->cng_type, FD_CNG ) ) ) ) + { + IF( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) || ( EQ_16( st_fx->core, ACELP_CORE ) && EQ_16( st_fx->bfi, 1 ) && EQ_16( st_fx->con_tcx, 1 ) ) ) + { + st_fx->use_acelp_preq = 0; + move16(); + /* rescaling to the min exp of the 2 */ + /* Qtmp=s_min(*Qsynth,st_fx->Q_old_postdec); + Scale_sig(synth, output_frame, sub(Qtmp,*Qsynth)); + Scale_sig(st_fx->delay_buf_out_fx, delay_comp, sub(Qtmp,st_fx->Q_old_postdec));*/ + IF( st_fx->hBWE_FD != NULL ) + { + hBWE_FD->mem_deemph_old_syn_fx = 0; + } + move16(); + + test(); + test(); + test(); + IF( EQ_16( st_fx->element_mode, EVS_MONO ) && EQ_16( st_fx->core, HQ_CORE ) ) + { + IF( core_switching_flag && EQ_16( st_fx->last_L_frame, st_fx->last_L_frame_ori ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) + { + IF( ( error = acelp_core_switch_dec_fx( st_fx, synth_subfr_out, synth_subfr_bwe, output_frame, core_switching_flag, mem_synth, &Qsubfr ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + test(); + test(); + IF( core_switching_flag && EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->prev_bfi ) + { + Copy( st_fx->delay_buf_out_fx, synth_subfr_out, delay_comp ); + Qsubfr = hHQ_core->Q_old_postdec; + } + } + /* delay HQ synthesis to synchronize with ACELP synthesis */ + /* rescaling to the min exp of the 2 */ + Qtmp = s_min( *Qsynth, hHQ_core->Q_old_postdec ); + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); + *Qsynth = Qtmp; + move16(); + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, sub( Qtmp, hHQ_core->Q_old_postdec ) ); + hHQ_core->Q_old_postdec = Qtmp; + move16(); + Word16 temp_buffer[L_FRAME48k]; + + Copy( st_fx->delay_buf_out_fx, temp_buffer, delay_comp ); + Copy( synth + output_frame - delay_comp, st_fx->delay_buf_out_fx, delay_comp ); + Copy( synth, synth + delay_comp, output_frame - delay_comp ); + Copy( temp_buffer, synth, delay_comp ); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( EQ_16( st_fx->element_mode, EVS_MONO ) && EQ_16( st_fx->core, HQ_CORE ) ) + { + + IF( core_switching_flag && EQ_16( st_fx->last_L_frame, st_fx->last_L_frame_ori ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) + { + /* mem_over_hp_fx : Qsubfr */ + core_switching_OLA_fx( mem_synth, st_fx->last_L_frame, st_fx->output_Fs, synth, synth_subfr_out, synth_subfr_bwe, output_frame, st_fx->bwidth, Qsynth, &Qsubfr ); + } + ELSE IF( core_switching_flag && EQ_16( st_fx->last_core, HQ_CORE ) && st_fx->prev_bfi ) /* HQ | ACELP | TRANSITION with ACELP frame lost */ + { + /* Overlapp between old->out (stocked in st_fx->fer_samples)and good HQ frame on L/2 */ + ptmp1 = &synth[delay_comp]; + shift = i_mult2( Fs_kHz, 10 ); + tmp = i_mult2( delta, shr( N16_CORE_SW, 1 ) ); + + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + ptmp2 = &hHQ_core->fer_samples_fx[tmp]; + tmp = div_s( 1, shift ); /*Q15*/ + tmpF = 0; + move16(); + + FOR( i = 0; i < shift; i++ ) + { + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ +#ifdef BASOP_NOGLOB + *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ +#else + *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ +#endif + ptmp1++; + ptmp2++; + tmpF = add( tmpF, tmp ); + } + } + ELSE IF( ( !core_switching_flag && EQ_16( st_fx->core, HQ_CORE ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* ACELP | TRANSITION | HQ with TRANSITION lost */ + || ( core_switching_flag && st_fx->prev_bfi && NE_16( st_fx->last_L_frame, st_fx->last_L_frame_ori ) ) ) + { + /* Overlapp between CELP estimation (BFI) and good HQ frame on L/2 */ + shift = i_mult2( Fs_kHz, 10 ); + tmp = div_s( 1, shift ); /*Q15*/ + tmpF = 0; + move16(); + ptmp1 = synth; + Scale_sig( hHQ_core->fer_samples_fx, output_frame, *Qsynth ); + ptmp2 = hHQ_core->fer_samples_fx; + FOR( i = 0; i < shift; i++ ) + { + L_tmp = L_mult( ( *ptmp1 ), tmpF ); /*Qsynth + 16*/ +#ifdef BASOP_NOGLOB + *ptmp1 = round_fx_sat( L_mac_sat( L_tmp, add_sat( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ +#else + *ptmp1 = round_fx( L_mac( L_tmp, add( sub( 24576, tmpF ), 8192 ), ( *ptmp2 ) ) ); /*Qsynth*/ +#endif + tmpF = add( tmpF, tmp ); + ptmp1++; + ptmp2++; + } + } + } + ELSE IF( ( ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core_bfi, ACELP_CORE ) ) && !( EQ_16( st_fx->prev_bfi, 1 ) && EQ_16( st_fx->last_con_tcx, 1 ) ) ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) + { + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( NE_32( st_fx->last_core_brate, SID_2k40 ) && NE_32( st_fx->last_core_brate, FRAME_NO_DATA ) ) || ( NE_16( st_fx->element_mode, IVAS_CPE_DFT ) && NE_16( st_fx->element_mode, IVAS_CPE_TD ) ) || EQ_16( nchan_out, 1 ) ) && !( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( st_fx->idchan, 1 ) && ( EQ_16( nchan_out, 1 ) || EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) ) + { + Scale_sig32( output_fx, L_FRAME48k, 10 - 4 ); + core_switch_lb_upsamp_fx( st_fx, output_fx ); + } + + Copy_Scale_sig( st_fx->previoussynth_fx, synth, delay_comp, *Qsynth ); + + /* Overlap between TCX-LB and TCX-FB*/ + Word16 tmpDelta = NS2SA( st_fx->output_Fs, DELAY_BWE_TOTAL_NS ); + Word32 L_tmp2; + FOR( i = 0; i < tmpDelta; i++ ) + { + L_tmp = 0; + L_tmp2 = 0; + tmp = st_fx->previoussynth_fx[i + delay_comp]; + L_tmp = L_mac0( L_tmp, div_s( i, tmpDelta ), synth[i + delay_comp] ); + L_tmp = L_shl( L_tmp, 1 ); + L_tmp2 = L_mac0( L_tmp2, div_s( sub( tmpDelta, i ), tmpDelta ), tmp ); + L_tmp2 = L_shl( L_tmp2, 1 ); + synth[i + delay_comp] = round_fx( L_add( L_tmp, L_tmp2 ) ); + } + test(); + test(); + test(); + IF( ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( ivas_format, ISM_FORMAT ) && EQ_16( st_fx->core, TCX_20_CORE ) /* <- means TCX in general, TCX10 is forbidden after ACELP */ ) ) && LE_32( st_fx->last_core_brate, SID_2k40 ) && GT_32( st_fx->core_brate, SID_2k40 ) ) + { + /* smooth transitions to avoid pops in car noise items */ + smoothTransitionDtxToTcx_fx( synth, output_frame, delay_comp ); + } + /* Reset memories of CLDFBs */ + IF( st_fx->cldfbAna_fx != NULL ) + { + IF( NE_16( i_mult( st_fx->cldfbAna->no_channels, st_fx->cldfbAna->no_col ), st_fx->L_frame ) ) + { + configureCldfb_ivas_fx( st_fx->cldfbAna, st_fx->L_frame * FRAMES_PER_SEC ); + configureCldfb_ivas_fx( st_fx->cldfbBPF, L_min( 16000, st_fx->L_frame * FRAMES_PER_SEC ) ); + } + + cldfb_reset_memory_fx( st_fx->cldfbAna ); + cldfb_reset_memory_fx( st_fx->cldfbBPF ); + } + cldfb_reset_memory_fx( st_fx->cldfbSyn ); + + /* Update memories for CLDFB ana for eventual next ACELP frame */ + IF( st_fx->cldfbAna != NULL ) + { + delta = st_fx->cldfbAna->no_channels; + offset = sub( st_fx->cldfbAna->p_filter_length, st_fx->cldfbAna->no_channels ); + tmp = div_s( 1, delta ); + alpha = tmp; + FOR( i = 0; i < delta; i++ ) + { + st_fx->cldfbAna->cldfb_state_fx[offset - delta + i] = + Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], 10 - 4 ), alpha ); + IF( alpha < sub( 32767, tmp ) ) + { + alpha = add( alpha, tmp ); + } + ELSE + { + alpha = 32767; + move16(); + } + } + } + } + ELSE IF( NE_16( st_fx->element_mode, EVS_MONO ) ) + { + /*needed to be filled with ivas specific code*/ + /* Reset memories of CLDFBs */ + IF( st_fx->cldfbAna != NULL ) + { + IF( NE_16( i_mult( st_fx->cldfbAna->no_channels, st_fx->cldfbAna->no_col ), st_fx->L_frame ) ) + { + configureCldfb_ivas_fx( st_fx->cldfbAna, st_fx->L_frame * FRAMES_PER_SEC ); + configureCldfb_ivas_fx( st_fx->cldfbBPF, L_min( 16000, st_fx->L_frame * FRAMES_PER_SEC ) ); + } + + cldfb_reset_memory_fx( st_fx->cldfbAna ); + cldfb_reset_memory_fx( st_fx->cldfbBPF ); + } + + IF( st_fx->cldfbSyn_fx != NULL ) + { + cldfb_reset_memory_fx( st_fx->cldfbSyn ); + } + + /* Update memories for CLDFB ana for eventual next ACELP frame */ + /* Analysis CLDF memory is fed with ramped signal for last slot */ + IF( st_fx->cldfbAna != NULL ) + { + delta = st_fx->cldfbAna->no_channels; + offset = sub( st_fx->cldfbAna->p_filter_length, st_fx->cldfbAna->no_channels ); + tmp = div_s( 1, delta ); + alpha = tmp; + FOR( i = 0; i < delta; i++ ) + { + st_fx->cldfbAna->cldfb_state_fx[offset - delta + i] = + Mpy_32_16_1( L_shl( output_fx[st_fx->L_frame - delta + i], 10 - 4 ), alpha ); + IF( alpha < sub( 32767, tmp ) ) + { + alpha = add( alpha, tmp ); + } + ELSE + { + alpha = 32767; + move16(); + } + } + } + } + IF( st_fx->hBWE_TD != NULL ) + { + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + } + IF( st_fx->hHQ_core != NULL && !( EQ_16( inner_frame_tbl[st_fx->bwidth], L_FRAME16k ) && EQ_32( st_fx->core_brate, HQ_32k ) ) ) + { + set32_fx( hHQ_core->prev_env_fx, 0, SFM_N_WB ); + set32_fx( hHQ_core->prev_normq_fx, 0, SFM_N_WB ); + } + Copy_Scale_sig( synth, st_fx->previoussynth_fx, output_frame, negate( *Qsynth ) ); /*scaling of st_fx->previoussynth_fx set at Q0*/ + + /*Set post-filtering flag to zero*/ + IF( st_fx->hBPF != NULL ) + { + st_fx->hPFstat->on = 0; + } + move16(); + } + ELSE + { + IF( EQ_16( st_fx->last_core, HQ_CORE ) || st_fx->last_core == TCX_20_CORE || st_fx->last_core == TCX_10_CORE ) /* MDCT to ACELP transition */ + { + Qtmp = s_min( *Qsynth, 0 ); + IF( hHQ_core != NULL ) + { + Qtmp = s_min( s_min( *Qsynth, hHQ_core->Q_old_postdec ), hHQ_core->Q_old_wtda ); + } + + Scale_sig( synth, output_frame, sub( Qtmp, *Qsynth ) ); + Scale_sig( st_fx->delay_buf_out_fx, delay_comp, Qtmp ); /*delay buff_out_fx is Q0*/ + IF( hHQ_core != NULL ) + { + Scale_sig( hHQ_core->old_out_fx, L_FRAME48k, sub( Qtmp, hHQ_core->Q_old_wtda ) ); + hHQ_core->Q_old_postdec = Qtmp; + move16(); + hHQ_core->Q_old_wtda = Qtmp; + move16(); + } + Scale_sig( output_mem_fx, NS2SA( st_fx->output_Fs, STEREO_DFT32MS_OVL_NS ), Qtmp ); + *Qsynth = Qtmp; + move16(); + + Copy( st_fx->delay_buf_out_fx, synth, delay_comp ); /* copy the HQ/ACELP delay synchroniation buffer at the beginning of ACELP frame */ + + nzeroes = i_mult2( delta, N_ZERO_8 ); + shift = i_mult2( Fs_kHz, 3 ); + test(); + IF( st_fx->prev_bfi && hHQ_core->HqVoicing_fx && st_fx->hHQ_core != NULL && st_fx->last_core == HQ_CORE ) + { + Copy_Scale_sig( hHQ_core->fer_samples_fx, &hHQ_core->old_out_fx[nzeroes], shift, *Qsynth ); + } + + tmp = div_s( 1, shift ); + tmpF = 0; + move16(); + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) && st_fx->hHQ_core == NULL ) + { + ptmp2 = output_mem_fx; + ptmp1 = &synth[delay_comp]; + FOR( i = 0; i < NS2SA( st_fx->output_Fs, 3000000 ); i++ ) + { + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); + ptmp1++; + ptmp2++; + tmpF = add( tmpF, tmp ); + } + } + ELSE IF( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && LE_32( st_fx->core_brate, SID_2k40 ) && st_fx->prev_bfi ) + { + ptmp2 = &hHQ_core->old_out_fx[nzeroes]; + ptmp1 = &synth[delay_comp]; + FOR( i = 0; i < NS2SA( st_fx->output_Fs, 3000000 ); i++ ) + { + L_tmp = L_mult0( st_fx->hTcxDec->conceal_eof_gain, *ptmp2 ); + L_tmp = L_shl( L_tmp, 1 ); + tmpV = round_fx( L_tmp ); + + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), tmpV ) ); + ptmp1++; + ptmp2++; + } + } + ELSE + { + ptmp2 = &hHQ_core->old_out_fx[nzeroes]; + ptmp1 = &synth[delay_comp]; + FOR( i = 0; i < shift; i++ ) + { + *ptmp1 = add( mult_r( tmpF, *ptmp1 ), mult_r( sub( 32767, tmpF ), *ptmp2 ) ); + ptmp1++; + ptmp2++; + tmpF = add( tmpF, tmp ); + } + } + } + + set16_fx( st_fx->delay_buf_out_fx, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); + IF( hHQ_core != NULL ) + { + hHQ_core->oldHqVoicing = 0; + } + move16(); + } + } + ELSE + { + /* memory update needed for DFT stereo -> TD stereo switching, scaling synth to Q0 */ + Copy_Scale_sig( synth + output_frame - delay_comp, st_fx->delay_buf_out_fx, delay_comp, negate( *Qsynth ) ); + } + + /* reset SWB BWE buffers */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( st_fx->bws_cnt == 0 || ( st_fx->bws_cnt > 0 && NE_16( st_fx->coder_type, INACTIVE ) && NE_16( st_fx->coder_type, AUDIO ) ) ) + { + st_fx->attenu_fx = 3277; + move16(); + } + + IF( ( NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || ( NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) || + ( ( EQ_16( st_fx->last_core, HQ_CORE ) || EQ_16( st_fx->last_extl, SWB_TBE ) ) && st_fx->extl < 0 && NE_16( st_fx->core, HQ_CORE ) ) || ( EQ_16( st_fx->last_core, ACELP_CORE ) && EQ_16( st_fx->core, ACELP_CORE ) && ( ( NE_16( st_fx->prev_coder_type, INACTIVE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) || ( NE_16( st_fx->prev_coder_type, AUDIO ) && EQ_16( st_fx->coder_type, AUDIO ) ) ) && st_fx->bws_cnt > 0 ) ) + { + set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); + hBWE_FD->old_wtda_swb_fx_exp = 0; + move16(); + IF( NE_16( st_fx->last_extl, WB_BWE ) ) + { + hBWE_FD->prev_mode_fx = NORMAL; + move16(); + } + + hBWE_FD->prev_Energy_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm_fx = 8; + move16(); + hBWE_FD->prev_frica_flag = 0; + move16(); + set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_td_energy_fx = 0; + move16(); + hBWE_FD->prev_weight_fx = 6554; + move16(); /*0.2 in Q15*/ + st_fx->prev_fb_ener_adjust_fx = 0; + move16(); + } + + /* reset WB BWE buffers */ + test(); + IF( NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && st_fx->hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); + + test(); + IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + } + hBWE_FD->prev_Energy_wb_fx = 0; + move16(); + hBWE_FD->prev_L_swb_norm = 8; + move16(); + set16_fx( hBWE_FD->mem_imdct_fx, 0, L_FRAME48k ); + hBWE_FD->prev_flag = 0; + move16(); + } + + /* reset TBE buffers */ + if ( hBWE_TD != NULL ) + { + /* reset SWB TBE buffers */ + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) || EQ_16( st_fx->extl, SWB_CNG ) ) && + ( NE_16( st_fx->L_frame, st_fx->last_L_frame ) || ( NE_16( st_fx->last_extl, SWB_TBE ) && NE_16( st_fx->last_extl, FB_TBE ) ) || EQ_16( st_fx->last_core, HQ_CORE ) ) ) || + ( LT_16( st_fx->bwidth, st_fx->last_bwidth ) && NE_16( st_fx->last_extl, SWB_TBE ) ) || st_fx->old_ppp_mode_fx || ( ( EQ_16( st_fx->prev_coder_type, AUDIO ) || EQ_16( st_fx->prev_coder_type, INACTIVE ) ) && st_fx->bws_cnt > 0 ) || ( st_fx->bws_cnt == 0 && EQ_16( st_fx->prev_bws_cnt, N_WS2N_FRAMES ) ) ) + { + swb_tbe_reset_fx( hBWE_TD->mem_csfilt_fx, hBWE_TD->mem_genSHBexc_filt_down_shb_fx, hBWE_TD->state_lpc_syn_fx, + hBWE_TD->syn_overlap_fx, hBWE_TD->state_syn_shbexc_fx, &( hBWE_TD->tbe_demph_fx ), &( hBWE_TD->tbe_premph_fx ), hBWE_TD->mem_stp_swb_fx, &( hBWE_TD->gain_prec_swb_fx ) ); + + set16_fx( st_fx->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + swb_tbe_reset_synth_fx( hBWE_TD->genSHBsynth_Hilbert_Mem_fx, hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx ); + + st_fx->hBWE_TD->prev_pow_exc16kWhtnd_fx = 32767; /*Q15 1.f*/ + st_fx->hBWE_TD->prev_mix_factor_fx = 32767; /*Q15 1.f*/ + + IF( EQ_16( output_frame, L_FRAME16k ) ) + { + /* reset in case that SWB TBE layer is transmitted, but the output x`x`is 16kHz sampled */ + set16_fx( hBWE_TD->mem_resamp_HB_32k_fx, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); + } + set16_fx( hBWE_TD->int_3_over_2_tbemem_dec_fx, 0, INTERP_3_2_MEM_LEN ); + } + ELSE IF( ( EQ_16( st_fx->extl, SWB_TBE ) || EQ_16( st_fx->extl, FB_TBE ) ) && + ( NE_32( st_fx->last_total_brate, st_fx->total_brate ) || NE_16( st_fx->last_bwidth, st_fx->bwidth ) || + NE_16( st_fx->last_codec_mode, MODE1 ) || NE_16( st_fx->rf_flag, st_fx->rf_flag_last ) ) ) + { + set16_fx( hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->gain_prec_swb_fx = 16384; + move16(); /*Q14 = 1 */ + } + ELSE IF( st_fx->hBWE_TD != NULL && ( st_fx->last_core == TCX_20_CORE || st_fx->last_core == TCX_10_CORE ) ) + { + TBEreset_dec_ivas_fx( st_fx ); + } + + /* reset FB TBE buffers */ + test(); + test(); + IF( EQ_16( st_fx->extl, FB_TBE ) && ( NE_16( st_fx->last_extl, FB_TBE ) || NE_16( st_fx->L_frame, st_fx->last_L_frame ) ) ) + { + set16_fx( hBWE_TD->fb_state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + hBWE_TD->fb_tbe_demph_fx = 0; + fb_tbe_reset_synth_fx( hBWE_TD->fbbwe_hpf_mem_fx, hBWE_TD->fbbwe_hpf_mem_fx_Q, &hBWE_TD->prev_fbbwe_ratio_fx ); + } + + /* reset WB TBE buffers */ + test(); + IF( NE_16( st_fx->last_extl, WB_TBE ) && EQ_16( st_fx->extl, WB_TBE ) ) + { + wb_tbe_extras_reset_fx( hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, hBWE_TD->mem_genSHBexc_filt_down_wb3_fx ); + wb_tbe_extras_reset_synth_fx( hBWE_TD->state_lsyn_filt_shb_fx, hBWE_TD->state_lsyn_filt_dwn_shb_fx, hBWE_TD->state_32and48k_WB_upsample_fx, hBWE_TD->mem_resamp_HB_fx ); + + set16_fx( hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD / 4 ); + set16_fx( hBWE_TD->syn_overlap_fx, 0, L_SHB_LAHEAD ); + set32_fx( hBWE_TD->mem_csfilt_fx, 0, 2 ); + } + } + + /* Interp_3_2 CNG buffers reset */ + test(); + test(); + test(); + IF( EQ_32( st_fx->output_Fs, 48000 ) && ( ( GT_32( st_fx->last_core_brate, SID_2k40 ) ) && ( EQ_32( st_fx->core_brate, FRAME_NO_DATA ) || EQ_32( st_fx->core_brate, SID_2k40 ) ) ) ) + { + set16_fx( st_fx->interpol_3_2_cng_dec_fx, 0, INTERP_3_2_MEM_LEN ); + } + + return error; +} +#endif + /*---------------------------------------------------------------------* * core_switching_hq_prepare_dec() * @@ -1566,3 +2156,154 @@ void core_switching_hq_prepare_dec_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +static void core_switch_lb_upsamp_fx( + Decoder_State *st, /* i/o: Decoder state */ + Word32 *output /* i/o: LB synth/upsampled LB synth */ +) +{ + Word16 i, no_col; + Word32 *realBuffer_fx[CLDFB_OVRLP_MIN_SLOTS], *imagBuffer_fx[CLDFB_OVRLP_MIN_SLOTS]; + Word32 realBufferTmp_fx[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; + Word32 imagBufferTmp_fx[CLDFB_OVRLP_MIN_SLOTS][CLDFB_NO_CHANNELS_MAX]; + + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + FOR( i = 0; i < CLDFB_OVRLP_MIN_SLOTS; i++ ) + { + set32_fx( realBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + set32_fx( imagBufferTmp_fx[i], 0, CLDFB_NO_CHANNELS_MAX ); + realBuffer_fx[i] = realBufferTmp_fx[i]; + imagBuffer_fx[i] = imagBufferTmp_fx[i]; + } + + /* check if the CLDFB works on the right sample rate */ + IF( NE_16( ( st->cldfbAna->no_channels * st->cldfbAna->no_col ), st->L_frame ) ) + { + resampleCldfb_ivas_fx( st->cldfbAna, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + + IF( st->cldfbBPF != NULL && LE_16( st->L_frame, L_FRAME16k ) ) + { + resampleCldfb_ivas_fx( st->cldfbBPF, L_mult0( st->L_frame, FRAMES_PER_SEC ) ); + } + + IF( GT_16( st->ini_frame, 0 ) ) + { + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + move16(); + } + } + /* analysis of the synthesis at internal sampling rate */ + cldfbAnalysis_ivas_fx( output, realBuffer_fx, imagBuffer_fx, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbAna->no_channels ), st->cldfbAna ); + + /* analysis and add the BPF error signal */ + IF( st->p_bpf_noise_buf_32 ) + { + addBassPostFilter_fx( st->p_bpf_noise_buf_32, st->bpf_off ? 0 : i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbBPF->no_channels ), realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + } + + /* set output mask for upsampling */ + IF( EQ_16( st->bwidth, NB ) ) + { + /* set NB mask for upsampling */ + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, 10 ); + } + ELSE IF( NE_16( st->cldfbSyn->bandsToZero, sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ) ) ) + { + /* in case of BW switching, re-init to default */ + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->cldfbAna->no_channels ); + move16(); + } + + /* synthesis of the combined signal */ + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, output, i_mult( CLDFB_OVRLP_MIN_SLOTS, st->cldfbSyn->no_channels ), st->cldfbSyn ); + + /*rescaling whole buffer to a common Q*/ + no_col = st->cldfbSyn->no_col; + + IF( CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels > -1 ) + { + no_col = s_min( no_col, ( CLDFB_OVRLP_MIN_SLOTS * st->cldfbSyn->no_channels + st->cldfbSyn->no_channels - 1 ) / st->cldfbSyn->no_channels ); + } + + Scale_sig32( output + no_col * st->cldfbSyn->no_channels, L_FRAME48k - no_col * st->cldfbSyn->no_channels, 4 - 10 ); + + /* save synthesis - needed in case of core switching */ + IF( st->hTcxDec != NULL ) + { + Copy_Scale_sig_32_16( output, st->previoussynth_fx, st->hTcxDec->L_frameTCX, -4 ); + } + + return; +} + +#define TRANSITION_SMOOTHING_LEN_16k 15 +#define TRANSITION_SMOOTHING_LEN_32k 31 +#define TRANSITION_SMOOTHING_LEN_48k 47 + +static void smoothTransitionDtxToTcx_fx( + Word16 synth[], /* i/o: synthesis */ + const Word16 output_frame, /* i : output frame length */ + const Word16 delay_comp /* i : delay compensation in samples */ +) +{ + Word16 i, filter_len; + Word16 w, step, fade_in; + Word32 mem; + Word16 smoothing_input_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; + Word16 smoothing_out_buffer[2 * NS2SA( 48000, DELAY_CLDFB_NS ) + TRANSITION_SMOOTHING_LEN_48k]; + + filter_len = TRANSITION_SMOOTHING_LEN_16k; + IF( EQ_16( output_frame, L_FRAME32k ) ) + { + filter_len = TRANSITION_SMOOTHING_LEN_32k; + } + ELSE IF( EQ_16( output_frame, L_FRAME48k ) ) + { + filter_len = TRANSITION_SMOOTHING_LEN_48k; + } + + /* prepare buffer */ + FOR( i = 0; i < filter_len / 2; i++ ) + { + smoothing_input_buffer[i] = synth[0]; + } + Copy( synth, smoothing_input_buffer + filter_len / 2, add( shl( delay_comp, 1 ), shr( filter_len, 1 ) ) ); + + /* apply Mean filter */ + w = div_s( 1, filter_len ); + mem = 0; + FOR (i = 0; i < filter_len; i++) + { + mem = L_add(mem, L_deposit_l(smoothing_input_buffer[i])); + } + //mem = sum32_fx( smoothing_input_buffer, filter_len ); + FOR( i = 0; i < 2 * delay_comp; i++ ) + { + smoothing_out_buffer[i] = extract_l(Mpy_32_16_1( mem, w )); + move16(); + mem = L_add( mem, L_sub(L_deposit_l(smoothing_input_buffer[i + filter_len]), L_deposit_l(smoothing_input_buffer[i]) )); + } + + /* apply fades around transition */ + step = div_s( 1, delay_comp ); + step = shr( step, 2 ); + fade_in = extract_l( 0 ); + FOR( i = 0; i < delay_comp; i++ ) + { + synth[i] = add( mult_r( smoothing_out_buffer[i], fade_in ), mult_r( synth[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); + move16(); + fade_in = add( fade_in, step ); + } + + fade_in = 0; + FOR( ; i < 2 * delay_comp; i++ ) + { + synth[i] = add( mult_r( synth[i], fade_in ), mult_r( smoothing_out_buffer[i], sub( ONE_IN_Q15 - 1, fade_in ) ) ); + move16(); + fade_in = add( fade_in, step ); + } + + return; +} +#endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 20e29db41..da29a4795 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -156,8 +156,9 @@ ivas_error ivas_core_dec( int16_t nchan_out; float *save_hb_synth; ivas_error error; - Word16 tmp1, tmp2; - Word32 L_tmp; + Word16 tmp1, tmp2; + Word32 L_tmp; + Word16 Q_synth; #ifdef IVAS_FLOAT_FIXED Word16 hb_synth_fx[6][L_FRAME48k]; /*not sure about number of channels so kept it as 6 will change it later*/ @@ -839,7 +840,8 @@ ivas_error ivas_core_dec( #ifdef IVAS_FLOAT_FIXED Word16 synth_fx[L_FRAME48k]; Word16 output_fx[L_FRAME48k]; - Word16 Q_synth = 0, Q_output = 0; + Q_synth = 0; + Word16 Q_output = 0; HQ_DEC_HANDLE hHQ_core; Word16 tmp_size = NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ); @@ -1396,10 +1398,367 @@ ivas_error ivas_core_dec( mvr2r( synth[n], hSCE->save_synth, output_frame ); } + +#ifdef IVAS_FLOAT_FIXED + + IF( EQ_16( st->core, ACELP_CORE ) && st->bfi && st->hHQ_core != NULL && !st->con_tcx ) + { + if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) + { + return error; + } + } + ELSE + { + +#ifndef IVAS_CODE_TO_BE_REMOVED + /*cldfb struct*/ + + /*------------------fix-to-fix-start---------------------*/ + /*core_switching_post_dec*/ + Q_synth = 0; + if (st->hHQ_core != NULL) + { + st->hHQ_core->Q_old_postdec = 0; + st->hHQ_core->Q_old_wtda = 0; + } + st->bws_cnt = st->bws_cnt; + st->coder_type = st->coder_type; + st->prev_coder_type = st->prev_coder_type; + st->prev_bws_cnt = st->prev_bws_cnt; + st->old_ppp_mode_fx = st->old_ppp_mode; + + /*------------------fix-to-fix-end-----------------------*/ + + Word16 *synth_fx16; + Word16 *output_mem_fx; + Word32 *output_fx32; + + synth_fx16 = (Word16 *) malloc( L_FRAME48k * sizeof( Word16 ) ); + output_fx32 = (Word32 *) malloc( L_FRAME48k * sizeof( Word32 ) ); + output_mem_fx = (Word16 *) malloc( NS2SA( st->output_Fs, 3125000 ) * sizeof( Word16 ) ); + + IF ( p_output_mem != NULL ) + { + floatToFixed_arr( p_output_mem, output_mem_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); + } + ELSE + { + set16_fx( output_mem_fx, 0, NS2SA( st->output_Fs, 3125000 ) ); + } + + floatToFixed_arr( synth[n], synth_fx16, Q_synth, L_FRAME48k ); + floatToFixed_arrL( output[n], output_fx32, 4, L_FRAME48k ); + + tmp = extract_l( L_shr( st->output_Fs, 13 ) ); + Word16 Fs_kHz = shl( add( tmp, 1 ), 3 ); + + Word16 delta = 1; + move16(); + IF ( GE_16( output_frame, L_FRAME16k ) ) + { + delta = shr( Fs_kHz, 3 ); + } + + Word16 delay_comp = i_mult2( delta, HQ_DELAY_COMP ); + + if ( st->hBWE_FD != NULL ) + { + st->hBWE_FD->mem_deemph_old_syn_fx = floatToFixed( st->hBWE_FD->mem_deemph_old_syn, 0 ); + } + IF( st->hHQ_core != NULL ) + { + floatToFixed_arr( st->hHQ_core->old_out, st->hHQ_core->old_out_fx, 0, L_FRAME48k ); + floatToFixed_arr( st->hHQ_core->fer_samples, st->hHQ_core->fer_samples_fx, 0, NS2SA( st->output_Fs, 3000000 ) ); + FOR( i = 0; i < SFM_N_WB; ++i ) + { + st->hHQ_core->prev_env_fx[i] = floatToFixed( st->hHQ_core->prev_env[i], st->hHQ_core->prev_env_Q[i] ); + } + floatToFixed_arrL( st->hHQ_core->prev_normq, st->hHQ_core->prev_normq_fx, 14, SFM_N_WB ); + } + floatToFixed_arr( st->previoussynth, st->previoussynth_fx, 0, L_FRAME48k ); + floatToFixed_arr( st->delay_buf_out, st->delay_buf_out_fx, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); + + if ( st->hTcxDec != NULL ) + { + st->hTcxDec->conceal_eof_gain = floatToFixed( st->hTcxDec->conceal_eof_gain_float, 14); + } + + /*size of synth is choosen as delay comp to start with*/ + // synth //Q0 -> Qsynth + // output_fx //Q ? + // delay_buf_buf //Q0 -> Q_old_postdec + // fer_samples //Q0 -> Q? + /*-------------------cldfb-start-------------------------*/ + + Word16 cldfb_size = (Word16) ( st->L_frame / 16 + 0.5 ); + + floatToFixed_arrL( st->bpf_noise_buf_float, st->bpf_noise_buf_32, 11, L_FRAME_16k ); + if ( st->cldfbAna != NULL ) + { + floatToFixed_arrL( st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, 10, st->cldfbAna->cldfb_size ); + } + if ( st->cldfbSyn != NULL ) + { + floatToFixed_arrL( st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, 4, st->cldfbSyn->p_filter_length ); + } + if ( st->cldfbBPF != NULL ) + { + floatToFixed_arrL( st->cldfbBPF->cldfb_state, st->cldfbBPF->cldfb_state_fx, 11, st->cldfbBPF->cldfb_size ); + } + + /*-------------------cldfb-end---------------------------*/ +#endif + if ( ( error = core_switching_post_dec_ivas_fx( st, synth_fx16, output_fx32, output_mem_fx, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE, &Q_synth ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifndef IVAS_CODE_TO_BE_REMOVED + + /*-------------------cldfb-start-------------------------*/ + + /*note : cldfb_size here signifies the original size which was assigned to cldfb_state_fx buffer not its current size*/ + + if ( st->cldfbAna != NULL ) + { + fixedToFloat_arrL( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, 10, st->cldfbAna->cldfb_state_length ); + } + if ( st->cldfbSyn != NULL ) + { + fixedToFloat_arrL( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, 4, st->cldfbSyn->p_filter_length ); + } + if ( st->cldfbBPF != NULL ) + { + fixedToFloat_arrL( st->cldfbBPF->cldfb_state_fx, st->cldfbBPF->cldfb_state, 11, st->cldfbBPF->cldfb_state_length ); + } + + /*-------------------cldfb-end---------------------------*/ + + fixedToFloat_arr( synth_fx16, synth[n], Q_synth, L_FRAME48k ); + fixedToFloat_arrL( output_fx32, output[n], 4, L_FRAME48k ); + fixedToFloat_arr( st->delay_buf_out_fx, st->delay_buf_out, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); + IF ( st->hHQ_core != NULL ) + { + fixedToFloat_arr( st->hHQ_core->old_out_fx, st->hHQ_core->old_out, 0, L_FRAME48k ); + fixedToFloat_arr( st->hHQ_core->fer_samples_fx, st->hHQ_core->fer_samples, 0, NS2SA( st->output_Fs, 3000000 ) ); + FOR( i = 0; i < SFM_N_WB; ++i ) + { + st->hHQ_core->prev_env[i] = fixedToFloat( st->hHQ_core->prev_env_fx[i], st->hHQ_core->prev_env_Q[i] ); + } + fixedToFloat_arrL( st->hHQ_core->prev_normq_fx, st->hHQ_core->prev_normq, 14, SFM_N_WB ); + } + fixedToFloat_arr( st->previoussynth_fx, st->previoussynth, 0, L_FRAME48k ); + + + + /*------------------reset-code-start---------------------*/ + + /*reset function flags*/ + Word8 reset_wb_tbe_extras = 0; + Word8 reset_wb_tbe_synth = 0; + Word8 reset_swb_tbe = 0; + Word8 reset_swb_tbe_synth = 0; + Word8 reset_fb_tbe_synth = 0; + + if ( st->hBWE_FD != NULL ) + { + st->hBWE_FD->mem_deemph_old_syn = fixedToFloat( st->hBWE_FD->mem_deemph_old_syn_fx, 0 ); + } + + IF( st->bws_cnt == 0 || ( st->bws_cnt > 0 && NE_16( st->coder_type, INACTIVE ) && NE_16( st->coder_type, AUDIO ) ) ) + { + st->attenu1 = fixedToFloat( st->attenu_fx, 15 ); + } + IF( ( NE_16( st->last_extl, SWB_BWE ) && EQ_16( st->extl, SWB_BWE ) ) || ( NE_16( st->last_extl, FB_BWE ) && EQ_16( st->extl, FB_BWE ) ) || + ( ( EQ_16( st->last_core, HQ_CORE ) || EQ_16( st->last_extl, SWB_TBE ) ) && st->extl < 0 && NE_16( st->core, HQ_CORE ) ) || ( EQ_16( st->last_core, ACELP_CORE ) && EQ_16( st->core, ACELP_CORE ) && ( ( NE_16( st->prev_coder_type, INACTIVE ) && EQ_16( st->coder_type, INACTIVE ) ) || ( NE_16( st->prev_coder_type, AUDIO ) && EQ_16( st->coder_type, AUDIO ) ) ) && st->bws_cnt > 0 ) ) + { + fixedToFloat_arrL( st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame ); + + IF( NE_16( st->last_extl, WB_BWE ) ) + { + st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode_fx; + } + + st->hBWE_FD->prev_Energy = fixedToFloat( st->hBWE_FD->prev_Energy_fx, 0 ); // setting to zero + st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm_fx; // fixed + st->hBWE_FD->prev_frica_flag = st->hBWE_FD->prev_frica_flag; // fixed + st->hBWE_FD->prev_td_energy = st->hBWE_FD->prev_td_energy_fx; // setting to zero + st->hBWE_FD->prev_weight = fixedToFloat( st->hBWE_FD->prev_weight_fx, 15 ); // 6554; /*0.2 in Q15*/ + st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat( st->prev_fb_ener_adjust_fx, 0 ); // setting to zero + fixedToFloat_arr( st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); // setting to zero + } + + /* reset WB BWE buffers */ + + IF( NE_16( st->last_extl, WB_BWE ) && EQ_16( st->extl, WB_BWE ) && st->hBWE_FD != NULL) + { + // set16_fx( st->hBWE_FD->L_old_wtda_swb_fx, 0, output_frame ); + fixedToFloat_arrL( st->hBWE_FD->L_old_wtda_swb_fx, st->hBWE_FD->old_wtda_swb, 0, output_frame ); + + IF( NE_16( st->last_extl, SWB_BWE ) && NE_16( st->last_extl, FB_BWE ) ) + { + st->hBWE_FD->prev_mode = st->hBWE_FD->prev_mode; + } + st->hBWE_FD->prev_Energy_wb = st->hBWE_FD->prev_Energy_wb_fx; + st->hBWE_FD->prev_L_swb_norm = st->hBWE_FD->prev_L_swb_norm; + st->hBWE_FD->prev_flag = st->hBWE_FD->prev_flag; + fixedToFloat_arr( st->hBWE_FD->mem_imdct_fx, st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); // setting to zero + } + + /* reset TBE buffers */ + if ( st->hBWE_TD != NULL ) + { + IF( ( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) || EQ_16( st->extl, SWB_CNG ) ) && + ( NE_16( st->L_frame, st->last_L_frame ) || ( NE_16( st->last_extl, SWB_TBE ) && NE_16( st->last_extl, FB_TBE ) ) || EQ_16( st->last_core, HQ_CORE ) ) ) || + ( LT_16( st->bwidth, st->last_bwidth ) && NE_16( st->last_extl, SWB_TBE ) ) || st->old_ppp_mode || ( ( EQ_16( st->prev_coder_type, AUDIO ) || EQ_16( st->prev_coder_type, INACTIVE ) ) && st->bws_cnt > 0 ) || ( st->bws_cnt == 0 && EQ_16( st->prev_bws_cnt, N_WS2N_FRAMES ) ) ) + { + + reset_swb_tbe = 1; + reset_swb_tbe_synth = 1; + + fixedToFloat_arr( st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + + IF( EQ_16( output_frame, L_FRAME16k ) ) + { + /* reset in case that SWB TBE layer is transmitted, but the output x`x`is 16kHz sampled */ + fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); + } + fixedToFloat_arr( st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN ); + st->hBWE_TD->prev_pow_exc16kWhtnd = (float)st->hBWE_TD->prev_pow_exc16kWhtnd_fx / 32767; + st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; + } + ELSE IF( ( EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) ) && + ( NE_32( st->last_total_brate, st->total_brate ) || NE_16( st->last_bwidth, st->bwidth ) || + NE_16( st->last_codec_mode, MODE1 ) || NE_16( st->rf_flag, st->rf_flag_last ) ) ) + { + fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_zero_swb_fx, st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER ); // setting to zero + st->hBWE_TD->gain_prec_swb = fixedToFloat( st->hBWE_TD->gain_prec_swb_fx, 14 ); /* Q14 = 1 */ + } + ELSE IF( st->hBWE_TD != NULL && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) + { + /*------------TBEreset_dec_ivas_fx-start------------------*/ + IF( NE_16( st->last_core, ACELP_CORE ) ) + { + fixedToFloat_arr( st->hBWE_TD->old_bwe_exc_fx, st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); // setting to zero + st->hBWE_TD->bwe_non_lin_prev_scale = fixedToFloat( st->hBWE_TD->bwe_non_lin_prev_scale_fx, 0 ); // setting to zero + } + IF( EQ_16( st->bwidth, WB ) ) + { + reset_wb_tbe_extras = 1; + reset_wb_tbe_synth = 1; + + fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, 7 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, 10 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4 ); + fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); + fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); + } + ELSE IF( EQ_16( st->bwidth, SWB ) || EQ_16( st->bwidth, FB ) ) + { + reset_swb_tbe = 1; + reset_swb_tbe_synth = 1; + fixedToFloat_arr( st->GainShape_Delay, st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->int_3_over_2_tbemem_dec_fx, st->hBWE_TD->int_3_over_2_tbemem_dec, 0, INTERP_3_2_MEM_LEN ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_32k_fx, st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero + st->hBWE_TD->prev_pow_exc16kWhtnd = (float) st->hBWE_TD->prev_pow_exc16kWhtnd_fx/32767; /*Q15 1.f*/ + st->hBWE_TD->prev_mix_factor = (float)st->hBWE_TD->prev_mix_factor_fx / 32767; /*Q15 1.f */ + + IF( EQ_16( st->bwidth, FB ) ) + { + IF( st->hBWE_FD != NULL ) + { + st->hBWE_FD->prev_fb_ener_adjust = fixedToFloat( st->prev_fb_ener_adjust_fx, 0 ); + } + fixedToFloat_arr( st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); + st->hBWE_TD->fb_tbe_demph = fixedToFloat( st->hBWE_TD->fb_tbe_demph_fx, 0 ); // setting to zero + reset_fb_tbe_synth = 1; + } + } + /*------------TBEreset_dec_ivas_fx-end--------------------*/ + } + + IF( EQ_16( st->extl, FB_TBE ) && ( NE_16( st->last_extl, FB_TBE ) || NE_16( st->L_frame, st->last_L_frame ) ) ) + { + fixedToFloat_arr( st->hBWE_TD->fb_state_lpc_syn_fx, st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); + st->hBWE_TD->fb_tbe_demph = fixedToFloat( st->hBWE_TD->fb_tbe_demph_fx, 0 ); // setting to zero + reset_fb_tbe_synth = 1; + } + + + IF( NE_16( st->last_extl, WB_TBE ) && EQ_16( st->extl, WB_TBE ) ) + { + reset_wb_tbe_extras = 1; + reset_wb_tbe_synth = 1; + fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); // setting to zero + fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); // setting to zero + } + + IF( reset_swb_tbe ) + { + fixedToFloat_arrL( st->hBWE_TD->mem_csfilt_fx, st->hBWE_TD->mem_csfilt, 0, 2 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_shb_fx, st->hBWE_TD->mem_genSHBexc_filt_down_shb, 0, ( 2 * ALLPASSSECTIONS_STEEP + 1 ) ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_lpc_syn_fx, st->hBWE_TD->state_lpc_syn, 0, LPC_SHB_ORDER ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->syn_overlap_fx, st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_syn_shbexc_fx, st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_stp_swb_fx, st->hBWE_TD->mem_stp_swb, 0, LPC_SHB_ORDER ); // setting to zero + + st->hBWE_TD->tbe_demph = fixedToFloat( st->hBWE_TD->tbe_demph_fx, 0 ); // setting to zero + st->hBWE_TD->tbe_premph = fixedToFloat( st->hBWE_TD->tbe_premph_fx, 0 ); // setting to zero + st->hBWE_TD->gain_prec_swb = fixedToFloat( st->hBWE_TD->gain_prec_swb_fx, 14 ); // setting to zero + } + IF( reset_swb_tbe_synth ) + { + fixedToFloat_arrL( st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, st->hBWE_TD->genSHBsynth_Hilbert_Mem, 0, HILBERT_MEM_SIZE ); // setting to zero // setting to zero + fixedToFloat_arr( st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero + } + IF( reset_wb_tbe_extras ) + { + fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_wb2_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb2, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->mem_genSHBexc_filt_down_wb3_fx, st->hBWE_TD->mem_genSHBexc_filt_down_wb3, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); // setting to zero + } + IF( reset_wb_tbe_synth ) + { + fixedToFloat_arr( st->hBWE_TD->state_lsyn_filt_shb_fx, st->hBWE_TD->state_lsyn_filt_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero + fixedToFloat_arr( st->hBWE_TD->state_lsyn_filt_dwn_shb_fx, st->hBWE_TD->state_lsyn_filt_dwn_shb, 0, 2 * ALLPASSSECTIONS_STEEP ); // setting to zero + // fixedToFloat(st->hBWE_TD->state_32and48k_WB_upsample_fx, st->hBWE_TD->state_32and48k_WB_upsample,0, 2 * ALLPASSSECTIONS_STEEP); buffer not there in float code* + fixedToFloat_arr( st->hBWE_TD->mem_resamp_HB_fx, st->hBWE_TD->mem_resamp_HB, 0, INTERP_3_1_MEM_LEN ); // setting to zero + } + IF( reset_fb_tbe_synth ) + { + fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[0], st->hBWE_TD->fbbwe_hpf_mem[0], 0, 4 ); // setting to zero + fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[1], st->hBWE_TD->fbbwe_hpf_mem[1], 0, 4 ); // setting to zero + fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[2], st->hBWE_TD->fbbwe_hpf_mem[2], 0, 4 ); // setting to zero + fixedToFloat_arrL( st->hBWE_TD->fbbwe_hpf_mem_fx[3], st->hBWE_TD->fbbwe_hpf_mem[3], 0, 4 ); // setting to zero + st->hBWE_TD->prev_fbbwe_ratio = fixedToFloat( st->hBWE_TD->prev_fbbwe_ratio_fx, 0 ); // scaling unknown setting to 1 + } + } + /* Interp_3_2 CNG buffers reset */ + IF(st->hTdCngDec != NULL && EQ_32( st->output_Fs, 48000 ) && ( ( GT_32( st->last_core_brate, SID_2k40 ) ) && ( EQ_32( st->core_brate, FRAME_NO_DATA ) || EQ_32( st->core_brate, SID_2k40 ) ) ) ) + { + fixedToFloat_arr( st->interpol_3_2_cng_dec_fx, st->hTdCngDec->interpol_3_2_cng_dec, 0, INTERP_3_2_MEM_LEN ); + } + + /*------------------reset-code-end-----------------------*/ + + free( synth_fx16 ); + free( output_fx32 ); + free( output_mem_fx ); +#endif + } + //dbgwrite2_txt(output[n],L_FRAME48k,"../output_n.txt"); + //dbgwrite2_txt(synth[n],L_FRAME48k,"../synth_n.txt"); +#else if ( ( error = core_switching_post_dec( st, synth[n], output[n], p_output_mem, ( st_ivas != NULL ) ? st_ivas->ivas_format : UNDEFINED_FORMAT, use_cldfb_for_dft, output_frame, 0 /*core_switching_flag*/, sba_dirac_stereo_flag, nchan_out, ( hCPE != NULL ) ? hCPE->last_element_mode : IVAS_SCE ) ) != IVAS_ERR_OK ) { return error; } + dbgwrite2_txt(output[n],L_FRAME48k,"../output_n_flt.txt"); + dbgwrite2_txt(synth[n],L_FRAME48k,"../synth_n_flt.txt"); +#endif /* for FD-CNG we need the delay compensation in the synth, so do this afterwards */ if ( sba_dirac_stereo_flag && hSCE && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) @@ -1741,9 +2100,11 @@ ivas_error ivas_core_dec( st->prev_Q_bwe_syn2 = 0; floatToFixed_arr16(st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local_fx, 0, 6); floatToFixed_arrL(st->hBWE_TD->genSHBsynth_Hilbert_Mem, st->hBWE_TD->genSHBsynth_Hilbert_Mem_fx, 0, 21); + st->hTdCngDec->burst_cnt_fx = st->hTdCngDec->burst_cnt; swb_CNG_dec_ivas_fx( st, synth_fx, hb_synth_fx, sid_bw[n], q ); + st->hTdCngDec->burst_cnt = st->hTdCngDec->burst_cnt_fx; fixedToFloat_arr(synth_fx, synth[n], q, 960); fixedToFloat_arr(hb_synth_fx, hb_synth[n], q, 960); st->hTdCngDec->shb_cng_gain = fix_to_float(st->hTdCngDec->shb_cng_gain_fx_32, Q11); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 939afbe52..5cb110891 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -60,6 +60,10 @@ static void ivas_jbm_dec_copy_tc( Decoder_Struct *st_ivas, const int16_t nSample static void ivas_jbm_dec_tc_buffer_playout( Decoder_Struct *st_ivas, const uint16_t nSamplesAsked, uint16_t *nSamplesRendered, float *output[] ); +#ifdef IVAS_FLOAT_FIXED +static void ivas_jbm_dec_tc_buffer_playout_fx( Decoder_Struct *st_ivas, const UWord16 nSamplesAsked, UWord16 *nSamplesRendered, Word32 *output_fx[]); +#endif + static void ivas_jbm_dec_copy_masa_meta_to_buffer( Decoder_Struct *st_ivas ); #ifdef IVAS_FLOAT_FIXED @@ -2785,7 +2789,22 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->hTcBuffer->tc_buffer_mode == TC_BUFFER_MODE_BUFFER ) { +#ifdef IVAS_FLOAT_FIXED + FOR(Word16 ind = 0; ind < st_ivas->hTcBuffer->nchan_transport_jbm; ind++) { + floatToFixed_arrL(st_ivas->hTcBuffer->tc[ind] + st_ivas->hTcBuffer->n_samples_rendered, st_ivas->hTcBuffer->tc_fx[ind] + st_ivas->hTcBuffer->n_samples_rendered, Q11, s_max(*nSamplesRendered, nSamplesAskedLocal)); + p_output_fx[ind] = malloc(sizeof(Word32) * 960); + floatToFixed_arrL(p_output[ind], p_output_fx[ind], Q11, s_max(*nSamplesRendered, nSamplesAskedLocal)); + } + + ivas_jbm_dec_tc_buffer_playout_fx( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output_fx ); + + FOR(Word16 ind = 0; ind < st_ivas->hTcBuffer->nchan_transport_jbm; ind++) { + fixedToFloat_arrL(p_output_fx[ind], p_output[ind], Q11, s_max(*nSamplesRendered, nSamplesAskedLocal)); + free(p_output_fx[ind]); + } +#else ivas_jbm_dec_tc_buffer_playout( st_ivas, nSamplesAskedLocal, nSamplesRendered, p_output ); +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -3638,8 +3657,22 @@ ivas_error ivas_jbm_dec_render( #endif } } +#ifdef IVAS_FLOAT_FIXED + Word16 q_p_output = Q11; + FOR(Word16 i = 0; i < nchan_out; i++) { + p_output_fx[i] = malloc(sizeof(Word32) * (*nSamplesRendered)); + floatToFixed_arrL(p_output[i], p_output_fx[i], q_p_output, *nSamplesRendered); + } + + ivas_syn_output_fx( p_output_fx, q_p_output, *nSamplesRendered, nchan_out, data ); + + FOR(Word16 i = 0; i < nchan_out; i++) { + free(p_output_fx[i]); + } +#else ivas_syn_output( p_output, *nSamplesRendered, nchan_out, data ); +#endif *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; @@ -5615,6 +5648,43 @@ static void ivas_jbm_dec_tc_buffer_playout( return; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_jbm_dec_tc_buffer_playout_fx( + Decoder_Struct *st_ivas, + const UWord16 nSamplesAsked, + UWord16 *nSamplesRendered, + Word32 *output_fx[] ) +{ + Word16 ch_idx, slot_size, slots_to_render, first_sf, last_sf, tmp, e; + + slot_size = st_ivas->hTcBuffer->n_samples_granularity; + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + tmp = BASOP_Util_Divide1616_Scale(nSamplesAsked, slot_size, &e); + tmp = shr(tmp, sub(15, e)); + slots_to_render = s_min( sub( st_ivas->hTcBuffer->num_slots, st_ivas->hTcBuffer->slots_rendered), tmp ); + st_ivas->hTcBuffer->slots_rendered = add(st_ivas->hTcBuffer->slots_rendered, slots_to_render); + *nSamplesRendered = (UWord16) L_mult0(slots_to_render, slot_size); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + + WHILE ( GT_16(slots_to_render, 0) ) + { + slots_to_render = sub(slots_to_render, st_ivas->hTcBuffer->subframe_nbslots[last_sf]); + last_sf = add(last_sf, 1); + } + + FOR ( ch_idx = 0; ch_idx < st_ivas->hTcBuffer->nchan_transport_jbm; ch_idx++ ) + { + mvl2l( st_ivas->hTcBuffer->tc_fx[ch_idx] + st_ivas->hTcBuffer->n_samples_rendered, output_fx[ch_idx], *nSamplesRendered ); + } + + st_ivas->hTcBuffer->subframes_rendered = last_sf; + + return; +} +#endif + /*--------------------------------------------------------------------------* * ivas_jbm_dec_tc_buffer_close() -- GitLab