From a67a7c47d968c4b7935be892b833d3a2c2fac15d Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 11 Mar 2024 15:45:00 +0530 Subject: [PATCH] acelp_core_dec sub-functions fixed implementation updated/integrated. --- lib_com/prot.h | 10 - lib_dec/acelp_core_dec.c | 440 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 420 insertions(+), 30 deletions(-) diff --git a/lib_com/prot.h b/lib_com/prot.h index bc711de0c..dbad1b746 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2481,16 +2481,6 @@ void calc_st_filt( const int16_t extl /* i : extension layer info */ ); -#ifdef IVAS_FLOAT_FIXED -static void calc_st_filt_fx( - Word16 * apond2, /* i : coefficients of numerator */ - Word16 * apond1, /* i : coefficients of denominator */ - Word16 * parcor0, /* o : 1st parcor calcul. on composed filter */ - Word16 * sig_ltp_ptr, /* i/o: i of 1/A(gamma1) : scaled by 1/g0 */ - Word16 * mem_zero, /* i : All zero memory */ - const int16_t extl /* i : extension layer info */ -); -#endif void scale_st_ivas( const float *sig_in, /* i : postfilter input signal */ float *sig_out, /* i/o: postfilter output signal */ diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 1876fa035..3009cf2e0 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -34,6 +34,7 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ + #include #include #include @@ -47,10 +48,6 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" -#ifdef IVAS_FLOAT_FIXED -#include "prot_fx2.h" -#endif -#include "math.h" /*-------------------------------------------------------------------* * acelp_core_dec() @@ -138,6 +135,8 @@ ivas_error acelp_core_dec( set16_fx(Aq_fx, 0, NB_SUBFR16k * (M + 1)); Word16 tmp_noise_fx; set_zero(temp_buf, L_FRAME16k + L_SYN_MEM); + Word32 bpf_error_signal_fx[L_FRAME16k]; + Word16 tmp; #endif error = IVAS_ERR_OK; @@ -1960,20 +1959,20 @@ ivas_error acelp_core_dec( ///////////////////////////////////////////////////////////////////////////// test(); - IF ( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) + IF( NE_16( st->L_frame, st->last_L_frame ) && NE_16( st->last_codec_mode, MODE2 ) ) { - IF ( EQ_16( st->L_frame, L_FRAME ) ) + IF( EQ_16( st->L_frame, L_FRAME ) ) { retro_interp5_4_fx( st->hBPF->pst_old_syn_fx ); } - ELSE IF ( EQ_16( st->L_frame, L_FRAME16k ) ) + ELSE IF( EQ_16( st->L_frame, L_FRAME16k ) ) { retro_interp4_5_fx( tmp_syn_fx, st->hBPF->pst_old_syn_fx ); } } // Fixed to float - me2f_buf_16(st->hBPF->pst_old_syn_fx, tmp_syn_exp, st->hBPF->pst_old_syn, NBPSF_PIT_MAX); + me2f_buf_16( st->hBPF->pst_old_syn_fx, tmp_syn_exp, st->hBPF->pst_old_syn, NBPSF_PIT_MAX ); #else if ( st->L_frame != st->last_L_frame && st->last_codec_mode != MODE2 ) { @@ -1988,9 +1987,87 @@ ivas_error acelp_core_dec( } #endif /* bass post-filter */ +#ifdef IVAS_FLOAT_FIXED + Word16 tmp_syn_fx2[L_FRAME16k + L_SUBFR]; + Word16 tmp_Q_syn; + Word16 tmp_pitch_buf_fx[NB_SUBFR16k]; + + // Float to fixed + tmp_Q_syn = -1; // Q0 + one guard bit = Q(-1) + st->stab_fac_fx = float_to_fix16( st->stab_fac, Q15 ); + st->stab_fac_smooth_fx = float_to_fix16( st->stab_fac_smooth, Q15 ); + st->hBPF->pst_mem_deemp_err_fx = (Word16)floatToFixed( st->hBPF->pst_mem_deemp_err, tmp_Q_syn ); + st->hBPF->pst_lp_ener_fx = float_to_fix16( st->hBPF->pst_lp_ener, Q8 ); + st->hBPF->psf_att_fx = float_to_fix16( st->hBPF->psf_att, Q15 ); + for ( i = 0; i < st->L_frame; i++ ) + { + tmp_syn_fx2[i] = (Word16)floatToFixed( syn[i], tmp_Q_syn ); + } + for ( i = 0; i < NBPSF_PIT_MAX; i++ ) + { + st->hBPF->pst_old_syn_fx[i] = (Word16)floatToFixed( st->hBPF->pst_old_syn[i], tmp_Q_syn ); + } + for ( i = 0; i < NB_SUBFR16k; i++ ) + { + tmp_pitch_buf_fx[i] = (Word16)floatToFixed( pitch_buf[i], Q6 ); + } + for ( i = 0; i < L_TRACK_HIST; i++ ) + { + st->hBPF->mem_mean_pit_fx[i] = float_to_fix16( st->hBPF->mem_mean_pit[i], 0 ); + st->hBPF->Track_on_hist_fx[i] = st->hBPF->Track_on_hist[i]; + st->hBPF->vibrato_hist_fx[i] = st->hBPF->vibrato_hist[i]; + } + + Word16 bpf_error_signal_fx_temp[L_FRAME16k]; + for (i = 0; i < L_FRAME16k; i++) + { + bpf_error_signal_fx_temp[i] = extract_h(bpf_error_signal_fx[i]); + } + + bass_psfilter_fx( st->hBPF, + st->Opt_AMR_WB, + tmp_syn_fx2, + st->L_frame, + tmp_pitch_buf_fx, // Q6 + st->bpf_off, + st->stab_fac_fx, // Q15 + &st->stab_fac_smooth_fx, // Q15 + st->coder_type, + tmp_Q_syn, + bpf_error_signal_fx_temp); + + for (i = 0; i < L_FRAME16k; i++) + { + bpf_error_signal_fx[i] = L_deposit_h(bpf_error_signal_fx_temp[i]); + } + + // Fixed to float + st->hBPF->pst_lp_ener = fix16_to_float( st->hBPF->pst_lp_ener_fx, Q8 ); + st->stab_fac_smooth = fix16_to_float( st->stab_fac_smooth_fx, Q15 ); + st->hBPF->mem_mean_pit[0] = fix16_to_float( st->hBPF->mem_mean_pit_fx[0], Q4 ); + st->hBPF->psf_att = fix16_to_float( st->hBPF->psf_att_fx, Q15 ); + for ( i = 0; i < NBPSF_PIT_MAX; i++ ) + { + st->hBPF->pst_old_syn[i] = fixedToFloat( st->hBPF->pst_old_syn_fx[i], tmp_Q_syn ); + } + for ( i = 0; i < L_FRAME16k; i++ ) + { + bpf_error_signal[i] = fixedToFloat( bpf_error_signal_fx[i], tmp_Q_syn + 16 ); + } + for ( i = 0; i < L_TRACK_HIST; i++ ) + { + st->hBPF->Track_on_hist[i] = st->hBPF->Track_on_hist_fx[i]; + st->hBPF->vibrato_hist[i] = st->hBPF->vibrato_hist_fx[i]; + } +#else bass_psfilter( st->hBPF, st->Opt_AMR_WB, syn, st->L_frame, pitch_buf, st->bpf_off, st->stab_fac, &st->stab_fac_smooth, st->coder_type, bpf_error_signal ); +#endif } + Word32 syn_tmp_32_fx[L_FRAME16k + L_SUBFR], *syn_32_fx; + set32_fx(syn_tmp_32_fx, 0, L_FRAME16k + L_SUBFR); + syn_32_fx = syn_tmp_32_fx + L_SUBFR; + if ( st->element_mode != IVAS_CPE_DFT || use_cldfb_for_dft ) { float realBufferSave[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -2001,33 +2078,167 @@ ivas_error acelp_core_dec( pRealSave[i] = realBufferSave[i]; pImagSave[i] = imagBufferSave[i]; } + if ( st->p_bpf_noise_buf_float) { mvr2r( bpf_error_signal, st->p_bpf_noise_buf_float, st->L_frame ); } /* analysis of the synthesis at internal sampling rate */ + +#ifdef IVAS_FLOAT_FIXED + Word32 realBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 imagBufferSave_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + Word32 *pRealSave_fx[CLDFB_NO_COL_MAX], *pImagSave_fx[CLDFB_NO_COL_MAX]; + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + pRealSave_fx[i] = realBufferSave_fx[i]; + pImagSave_fx[i] = imagBufferSave_fx[i]; + } + floatToFixed_arrL( bpf_error_signal, bpf_error_signal_fx, st->Q_syn - 1, st->L_frame ); + IF( st->p_bpf_noise_buf_32 ) + { + Copy32( bpf_error_signal_fx, st->p_bpf_noise_buf_32, st->L_frame ); + } + + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + for ( i = 0; i < L_FRAME16k; i++ ) + { + syn_32_fx[i] = L_shr( L_deposit_h( syn_fx[i] ), 4 ); + } + + Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + floatToFixed_arrL( st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q12, offset ); + + cldfbAnalysis_ivas_fx( syn_32_fx, realBuffer_fx, imagBuffer_fx, -1, st->cldfbAna ); + + fixedToFloat_arrL( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, Q12, offset ); + + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + fixedToFloat_arrL( realBuffer_fx[i], realBuffer[i], Q12 - 5, CLDFB_NO_CHANNELS_MAX ); + fixedToFloat_arrL( imagBuffer_fx[i], imagBuffer[i], Q12 - 5, CLDFB_NO_CHANNELS_MAX ); + } +#else cldfbAnalysis_ivas( syn, realBuffer, imagBuffer, -1, st->cldfbAna ); +#endif /* analysis and add the BPF error signal */ +#ifdef IVAS_FLOAT_FIXED + Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; + Word16 q_bpf_error_signal; + Word16 j; + Word32 cldfb_state_offset = sub(st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels); + + q_bpf_error_signal = Q6; + + // Float to fixed + floatToFixed_arrL(bpf_error_signal, tmp_bpf_error_signal_fx, q_bpf_error_signal, L_FRAME16k); + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + for (j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + realBuffer_fx[i][j] = floatToFixed(realBuffer[i][j], q_bpf_error_signal - 6); + imagBuffer_fx[i][j] = floatToFixed(imagBuffer[i][j], q_bpf_error_signal - 6); + } + } + for (i = 0; i < cldfb_state_offset; i++) + { + st->cldfbBPF->cldfb_state_fx[i] = float_to_fix(st->cldfbBPF->cldfb_state[i], q_bpf_error_signal); + } + + tmp = -1; + move16(); + IF( st->bpf_off ) + { + tmp = 0; + move16(); + } + + addBassPostFilter_fx( tmp_bpf_error_signal_fx, tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + + // Fixed to float + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + for (j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + realBuffer[i][j] = fixedToFloat(realBuffer_fx[i][j], q_bpf_error_signal - 6); + imagBuffer[i][j] = fixedToFloat(imagBuffer_fx[i][j], q_bpf_error_signal - 6); + } + } + for (i = 0; i < cldfb_state_offset; i++) + { + st->cldfbBPF->cldfb_state[i] = fix_to_float(st->cldfbBPF->cldfb_state_fx[i], q_bpf_error_signal); + } +#else addBassPostFilter( bpf_error_signal, st->bpf_off ? 0 : -1, realBuffer, imagBuffer, st->cldfbBPF ); +#endif /* set output mask for upsampling */ - if ( st->bwidth == NB ) +#ifdef IVAS_FLOAT_FIXED + 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 ); + } +#else + if (st->bwidth == NB) { /* set NB mask for upsampling */ st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - 10; } - else if ( st->cldfbSyn->bandsToZero != st->cldfbSyn->no_channels - st->cldfbAna->no_channels ) + else if (st->cldfbSyn->bandsToZero != st->cldfbSyn->no_channels - st->cldfbAna->no_channels) { /* in case of BW switching, re-init to default */ st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->cldfbAna->no_channels; } +#endif + +#ifdef IVAS_FLOAT_FIXED + IF( !st->cng_sba_flag || EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) + { + /*WB/SWB-FD_CNG*/ + IF( ( EQ_32( st->core_brate, FRAME_NO_DATA ) || EQ_32( st->core_brate, SID_2k40 ) ) && ( EQ_16( st->cng_type, FD_CNG ) ) && ( LE_16( st->hFdCngDec->hFdCngCom->numCoreBands, st->cldfbSyn->no_channels ) ) ) + { + /* Float to fixed */ + f2me_buf( st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt, st->hFdCngDec->hFdCngCom->cngNoiseLevel, &st->hFdCngDec->hFdCngCom->cngNoiseLevelExp, FFTCLDFBLEN ); + + // NOTE: this should be removed later. + //st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp; + + Word16 tmpBufferScale = 0; + generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); + + /* Fixed to float */ + FOR( i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++ ) + { + FOR( Word16 j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++ ) + { + realBuffer[i][j] = me2f( realBuffer_fx[i][j], tmpBufferScale + 15 ); + imagBuffer[i][j] = me2f( imagBuffer_fx[i][j], tmpBufferScale + 15 ); + } + } - if ( !st->cng_sba_flag || st->element_mode == IVAS_CPE_MDCT ) + IF( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) + { + st->cldfbSyn->bandsToZero = sub( st->cldfbSyn->no_channels, st->hFdCngDec->hFdCngCom->regularStopBand ); + } + ELSE + { + st->cldfbSyn->bandsToZero = 0; + } + } + } +#else + if (!st->cng_sba_flag || st->element_mode == IVAS_CPE_MDCT) { /*WB/SWB-FD_CNG*/ - if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) ) + if ((st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40) && (st->cng_type == FD_CNG) && (st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels)) { #ifdef IVAS_FLOAT_FIXED /* Float to fixed */ @@ -2037,22 +2248,22 @@ ivas_error acelp_core_dec( //st->hFdCngDec->hFdCngCom->q_cngNoiseLevel = 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp; Word16 tmpBufferScale = 0; - generate_comfort_noise_dec_hf_ivas_fx( realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); - + generate_comfort_noise_dec_hf_ivas_fx(realBuffer_fx, imagBuffer_fx, /*realBuffer, imagBuffer,*/ &tmpBufferScale, st->hFdCngDec->hFdCngCom, st->cng_ism_flag); + /* Fixed to float */ FOR(i = 0; i < st->hFdCngDec->hFdCngCom->numSlots; i++) { - FOR(Word16 j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++) + FOR(j = st->hFdCngDec->hFdCngCom->numCoreBands; j < st->hFdCngDec->hFdCngCom->regularStopBand; j++) { realBuffer[i][j] = me2f(realBuffer_fx[i][j], tmpBufferScale + 15); imagBuffer[i][j] = me2f(imagBuffer_fx[i][j], tmpBufferScale + 15); } } #else - generate_comfort_noise_dec_hf_flt( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); + generate_comfort_noise_dec_hf_flt(realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag); #endif - if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) + if (st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels) { st->cldfbSyn->bandsToZero = st->cldfbSyn->no_channels - st->hFdCngDec->hFdCngCom->regularStopBand; } @@ -2062,10 +2273,70 @@ ivas_error acelp_core_dec( } } } +#endif if ( save_hb_synth != NULL ) { /* save and then zero-out lowband */ +#ifdef IVAS_FLOAT_FIXED + Word32 save_hb_synth_fx[L_FRAME48k]; + Word32 synth_fx[L_FRAME48k]; + + Word16 Q_real = 0, Q_imag = 0; + float max_real = 0.f, max_imag = 0.f; + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + for ( int j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + max_real = (float) max( max_real, fabs( realBuffer[i][j] ) ); + max_imag = (float) max( max_imag, fabs( imagBuffer[i][j] ) ); + } + } + float max_val = max( max_real, max_imag ); + Q_imag = norm_s( (Word16) max_val ); + Q_real = Q_imag; + + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + floatToFixed_arrL( realBuffer[i], realBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX ); + floatToFixed_arrL( imagBuffer[i], imagBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX ); + } + floatToFixed_arrL( st->cldfbSynHB->cldfb_state, st->cldfbSynHB->cldfb_state_fx, Q_real - 1, st->cldfbSynHB->p_filter_length ); + floatToFixed_arrL( save_hb_synth, save_hb_synth_fx, Q_real - 1, L_FRAME48k ); + + FOR( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + realBufferSave_fx[i][j] = realBuffer_fx[i][j]; + imagBufferSave_fx[i][j] = imagBuffer_fx[i][j]; + IF( j < st->hFdCngDec->hFdCngCom->numCoreBands && i < st->hFdCngDec->hFdCngCom->numSlots ) + { + realBuffer_fx[i][j] = 0; + imagBuffer_fx[i][j] = 0; + } + } + } + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, save_hb_synth_fx, -1, st->cldfbSynHB ); + + fixedToFloat_arrL( synth_fx, synth, Q_real - 1, L_FRAME48k ); + fixedToFloat_arrL( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_state, Q_real - 1, st->cldfbSynHB->p_filter_length ); + + /* restore lowband */ + FOR( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + FOR( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + realBuffer_fx[i][j] = realBufferSave_fx[i][j]; + imagBuffer_fx[i][j] = imagBufferSave_fx[i][j]; + } + } + floatToFixed_arrL( st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, Q_real - 1, st->cldfbSyn->p_filter_length ); + cldfbSynthesis_ivas_fx( pRealSave_fx, pImagSave_fx, synth_fx, -1, st->cldfbSyn ); + fixedToFloat_arrL( synth_fx, synth, Q_real - 1, L_FRAME48k ); + fixedToFloat_arrL( st->cldfbSynHB->cldfb_state_fx, st->cldfbSynHB->cldfb_state, Q_real - 1, st->cldfbSynHB->p_filter_length ); +#else for ( int16_t j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) { for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) @@ -2079,7 +2350,6 @@ ivas_error acelp_core_dec( } } } - cldfbSynthesis_ivas( realBuffer, imagBuffer, save_hb_synth, -1, st->cldfbSynHB ); /* restore lowband */ @@ -2093,11 +2363,41 @@ ivas_error acelp_core_dec( } cldfbSynthesis_ivas( pRealSave, pImagSave, synth, -1, st->cldfbSyn ); +#endif } else { /* synthesis of the combined signal */ - cldfbSynthesis_ivas( realBuffer, imagBuffer, synth, -1, st->cldfbSyn ); +#ifdef IVAS_FLOAT_FIXED + Word16 Q_real = 0, Q_imag = 0; + float max_real = 0.f, max_imag = 0.f; + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + for (int j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) { + max_real = (float)max(max_real , fabs(realBuffer[i][j])); + max_imag = (float)max(max_imag, fabs(imagBuffer[i][j])); + } + } + float max_val = max(max_real, max_imag); + Q_imag = norm_s((Word16)max_val); + Q_real = Q_imag; + + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + floatToFixed_arrL(realBuffer[i], realBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX); + floatToFixed_arrL(imagBuffer[i], imagBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX); + } + floatToFixed_arrL(st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, Q_real - 1, st->cldfbSyn->p_filter_length); + Word32 synth_fx[L_FRAME48k]; + floatToFixed_arrL(synth, synth_fx, Q_real - 1, L_FRAME48k); + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx, -1, st->cldfbSyn ); + + fixedToFloat_arrL(synth_fx, synth, Q_real - 1, L_FRAME48k); + fixedToFloat_arrL(st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, Q_real - 1, st->cldfbSyn->p_filter_length); +#else + cldfbSynthesis_ivas(realBuffer, imagBuffer, synth, -1, st->cldfbSyn); +#endif } /* save synthesis - needed in case of core switching */ @@ -2109,13 +2409,113 @@ ivas_error acelp_core_dec( int16_t nSamples = NS2SA( st->L_frame * FRAMES_PER_SEC, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ); /* IVAS-64: optimization is likely possible here (don't resample the whole frame) */ /* analysis of the synthesis at internal sampling rate - needed for DFT stereo -> TD stereo switching */ +#ifdef IVAS_FLOAT_FIXED + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + for ( i = 0; i < L_FRAME16k; i++ ) + { + syn_32_fx[i] = L_shr( L_deposit_h( syn_fx[i] ), 4 ); + } + + Word16 offset = sub( st->cldfbAna->p_filter_length, st->cldfbAna->no_channels ); + floatToFixed_arrL( st->cldfbAna->cldfb_state, st->cldfbAna->cldfb_state_fx, Q12, offset ); + + cldfbAnalysis_ivas_fx( syn_32_fx + st->L_frame - nSamples, realBuffer_fx, imagBuffer_fx, nSamples, st->cldfbAna ); + + fixedToFloat_arrL( st->cldfbAna->cldfb_state_fx, st->cldfbAna->cldfb_state, Q12, offset ); + + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + fixedToFloat_arrL( realBuffer_fx[i], realBuffer[i], Q12 - 5, CLDFB_NO_CHANNELS_MAX ); + fixedToFloat_arrL( imagBuffer_fx[i], imagBuffer[i], Q12 - 5, CLDFB_NO_CHANNELS_MAX ); + } +#else cldfbAnalysis_ivas( syn + st->L_frame - nSamples, realBuffer, imagBuffer, nSamples, st->cldfbAna ); +#endif /* analysis and add the BPF error signal - needed for DFT stereo -> TD stereo switching */ - addBassPostFilter( bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF ); +#ifdef IVAS_FLOAT_FIXED + + Word32 tmp_bpf_error_signal_fx[L_FRAME16k]; + Word16 q_bpf_error_signal; + Word16 j; + Word32 cldfb_state_offset = sub(st->cldfbBPF->p_filter_length, st->cldfbBPF->no_channels); + + // Get Q-factor + q_bpf_error_signal = Q6; + + // Float to fixed + floatToFixed_arrL(bpf_error_signal, tmp_bpf_error_signal_fx, q_bpf_error_signal, L_FRAME16k); + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + for (j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + realBuffer_fx[i][j] = floatToFixed(realBuffer[i][j], q_bpf_error_signal - 6); + imagBuffer_fx[i][j] = floatToFixed(imagBuffer[i][j], q_bpf_error_signal - 6); + } + } + for (i = 0; i < cldfb_state_offset; i++) + { + st->cldfbBPF->cldfb_state_fx[i] = float_to_fix(st->cldfbBPF->cldfb_state[i], q_bpf_error_signal); + } + + tmp = 0; + move16(); + IF(!st->bpf_off) + { + tmp = nSamples; + move16(); + } + addBassPostFilter_fx( tmp_bpf_error_signal_fx + st->L_frame - nSamples, tmp, realBuffer_fx, imagBuffer_fx, st->cldfbBPF ); + // Fixed to float + for (i = 0; i < CLDFB_NO_COL_MAX; i++) + { + for (j = 0; j < CLDFB_NO_CHANNELS_MAX; j++) + { + realBuffer[i][j] = fixedToFloat(realBuffer_fx[i][j], q_bpf_error_signal - 6); + imagBuffer[i][j] = fixedToFloat(imagBuffer_fx[i][j], q_bpf_error_signal - 6); + } + } + for (i = 0; i < cldfb_state_offset; i++) + { + st->cldfbBPF->cldfb_state[i] = fix_to_float(st->cldfbBPF->cldfb_state_fx[i], q_bpf_error_signal); + } +#else + addBassPostFilter( bpf_error_signal + st->L_frame - nSamples, st->bpf_off ? 0 : nSamples, realBuffer, imagBuffer, st->cldfbBPF ); +#endif /* synthesis of the combined signal - needed for DFT stereo -> TD stereo switching */ +#ifdef IVAS_FLOAT_FIXED + Word16 Q_real = 0, Q_imag = 0; + float max_real = 0.f, max_imag = 0.f; + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + for ( int j = 0; j < CLDFB_NO_CHANNELS_MAX; j++ ) + { + max_real = (float) max( max_real, fabs( realBuffer[i][j] ) ); + max_imag = (float) max( max_imag, fabs( imagBuffer[i][j] ) ); + } + } + float max_val = max( max_real, max_imag ); + Q_imag = norm_s( (Word16) max_val ); + Q_real = Q_imag; + + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + floatToFixed_arrL( realBuffer[i], realBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX ); + floatToFixed_arrL( imagBuffer[i], imagBuffer_fx[i], Q_real, CLDFB_NO_CHANNELS_MAX ); + } + floatToFixed_arrL( st->cldfbSyn->cldfb_state, st->cldfbSyn->cldfb_state_fx, Q_real - 1, st->cldfbSyn->p_filter_length ); + Word32 synth_fx[L_FRAME48k]; + floatToFixed_arrL( synth, synth_fx, Q_real - 1, L_FRAME48k ); + + cldfbSynthesis_ivas_fx( realBuffer_fx, imagBuffer_fx, synth_fx /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); + + fixedToFloat_arrL( synth_fx, synth, Q_real - 1, L_FRAME48k ); + fixedToFloat_arrL( st->cldfbSyn->cldfb_state_fx, st->cldfbSyn->cldfb_state, Q_real - 1, st->cldfbSyn->p_filter_length ); + +#else cldfbSynthesis_ivas( realBuffer, imagBuffer, synth /*dummy*/, NS2SA( st->output_Fs, FRAME_SIZE_NS /*DELAY_CLDFB_NS*/ ), st->cldfbSyn ); +#endif if ( st->p_bpf_noise_buf_float) { -- GitLab