From e59852952f5aa0c7534c6191d71ac627a9a614a7 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Fri, 8 Mar 2024 16:27:12 +0530 Subject: [PATCH] Updates for acelp_core_dec nb_post_filt_ivas, deemph [disabled re-scaling required], AGC_dec [disabled re-scaling required], Copy_Scale_sig, formant_post_filt, Residu3, E_UTIL_synthesis, scale_st, blend_subfr2 functions integarted to acelp call stack. --- lib_com/prot.h | 10 ++ lib_com/prot_fx2.h | 23 +++ lib_com/tools_fx.c | 20 +++ lib_dec/acelp_core_dec.c | 280 ++++++++++++++++++++++++++++-- lib_dec/dec_post_fx.c | 365 +++++++++++++++++++++++++++++++++++++++ lib_dec/evs_dec.c | 3 + lib_dec/init_dec.c | 14 +- lib_dec/ivas_core_dec.c | 8 + 8 files changed, 711 insertions(+), 12 deletions(-) diff --git a/lib_com/prot.h b/lib_com/prot.h index 683a2b07d..7f92257c5 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2481,6 +2481,16 @@ 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_com/prot_fx2.h b/lib_com/prot_fx2.h index 30be7a81c..00e6cfe18 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -71,6 +71,8 @@ Word16 float_to_fix16( float number, Word16 Q ); // Word16 to Float float fix16_to_float( Word16 number, Word16 Q ); +Word16 float_to_fix16_thrld(float number, Word16 Q); + void floatToFixed_arrL( float * f, Word32* i, Word16 Q, Word16 l); void floatToFixed_arr( float * f, Word16* i, Word16 Q, Word16 l); void fixedToFloat_arrL( Word32 *i, float * f, Word16 Q, Word16 l); @@ -5927,6 +5929,18 @@ void TonalMDCTConceal_Apply( const Word16 off_flag /* i : off flag */ ); +#ifdef IVAS_FLOAT_FIXED + void formant_post_filt_fx( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *synth_in, /* i : 12k8 synthesis */ + Word16 *Aq, /* i : LP filter coefficient */ + Word16 *synth_out, /* i/o: i signal */ + Word16 L_frame, + Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + Word32 rate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ + ); +#endif void Filt_mu( Word16 * sig_in, /* i : signal (beginning at sample -1) */ Word16 * sig_out, /* o : signal with tilt */ @@ -5934,6 +5948,15 @@ void TonalMDCTConceal_Apply( Word16 L_subfr /* i : the length of subframe */ ); +#ifdef IVAS_FLOAT_FIXED + void Filt_mu_fx( + Word16 * sig_in, /* i : signal (beginning at sample -1) */ + Word16 * sig_out, /* o : signal with tilt */ + Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ + Word16 L_subfr, /* i : the length of subframe */ + const Word16 extl + ); +#endif void scale_st( const Word16 * sig_in, /* i : postfilter i signal */ Word16 * sig_out, /* i/o: postfilter o signal */ diff --git a/lib_com/tools_fx.c b/lib_com/tools_fx.c index 0f629a176..77ccfa4ab 100644 --- a/lib_com/tools_fx.c +++ b/lib_com/tools_fx.c @@ -83,6 +83,26 @@ Word16 float_to_fix16( float number, Word16 Q ) return ret; } +#ifdef IVAS_FLOAT_FIXED +Word16 float_to_fix16_thrld(float number, Word16 Q) +{ + assert(Q >= 0); + if (number == 1.0f && Q == Q15) + return MAX16B; + float limit = (float)pow(2, 15 - Q); + /*Add threshold*/ + if (number > MAX16B_FLT) { + number = MAX16B_FLT; + } + else if (number < MIN16B_FLT) { + number = MIN16B_FLT; + } + assert(number <= limit && number >= -limit); + Word16 ret = (Word16)(number * ((UWord16)1 << Q)); + return ret; +} +#endif + float fix16_to_float( Word16 number, Word16 Q ) { assert( Q >= 0 ); diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 86f3132e6..127357e72 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -36,11 +36,13 @@ #include #include +#include #include "options.h" #include "cnst.h" #include "rom_com.h" #include "prot.h" #include "prot_fx2.h" +#include "prot_fx1.h" #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_rom_com.h" @@ -91,6 +93,7 @@ ivas_error acelp_core_dec( float mem_tmp[M]; /* temporary synthesis filter memory */ float enr_q; /* E information for FER protection */ float tmp_noise; /* Long term temporary noise energy */ + float Es_pred; /* predicted scaled innov. energy */ float FEC_pitch; /* FEC pitch */ float old_bwe_exc[( ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 )]; /* excitation buffer */ @@ -128,6 +131,14 @@ ivas_error acelp_core_dec( float *p_tdm_Pri_pitch_buf; int16_t local_element_mode; ivas_error error; +#ifdef IVAS_FLOAT_FIXED + Word16 syn_tmp_fx[L_FRAME16k + L_SUBFR], *syn_fx; + set_zero(Aq, NB_SUBFR16k * (M + 1)); + Word16 Aq_fx[NB_SUBFR16k * (M + 1)]; + set16_fx(Aq_fx, 0, NB_SUBFR16k * (M + 1)); + Word16 tmp_noise_fx; + set_zero(temp_buf, L_FRAME16k + L_SYN_MEM); +#endif error = IVAS_ERR_OK; @@ -252,6 +263,11 @@ ivas_error acelp_core_dec( LSF_Q_prediction = -1; set_f( syn_tmp, 0, L_SUBFR ); syn = syn_tmp + L_SUBFR; +#ifdef IVAS_FLOAT_FIXED + set_f(syn_tmp, 0, L_FRAME16k + L_SUBFR); + set16_fx(syn_tmp_fx, 0, L_SUBFR); + syn_fx = syn_tmp_fx + L_SUBFR; +#endif syn1_tmp[0] = 0; syn1_tmp[1] = 0; syn1 = syn1_tmp + 2; @@ -576,11 +592,15 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp_flt[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst_flt[i]; } #ifdef IVAS_FLOAT_FIXED - Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; + //Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; st->Q_syn = 0; - for ( int p = 0; p < L_FRAME16k; p++ ) + /*for ( int p = 0; p < L_FRAME16k; p++ ) { syn_fx[L_SUBFR + p] = (Word16) ( syn[p] * ( 1u << st->Q_syn ) ); + }*/ + for (int p = 0; p < L_FRAME16k; p++) + { + syn_fx[p] = (Word16)(syn[p] * (1u << st->Q_syn)); } for ( int p = 0; p < ( st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand ); p++ ) { @@ -593,7 +613,8 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->sidNoiseEst[p] = (Word32) ( st->hFdCngDec->hFdCngCom->sidNoiseEst_flt[p] * ( 1u << ( 31 - st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ) ); } - ApplyFdCng_fx( syn_fx + L_SUBFR, st->Q_syn, NULL, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + //ApplyFdCng_fx( syn_fx + L_SUBFR, st->Q_syn, NULL, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx(syn_fx, st->Q_syn, NULL, realBuffer_fx, imagBuffer_fx, NULL, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); for ( int p = 0; p < ( st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand ); p++ ) { @@ -1116,6 +1137,21 @@ ivas_error acelp_core_dec( } } +#ifdef IVAS_FLOAT_FIXED + floatToFixed_arr( Aq, Aq_fx, Q12, NB_SUBFR16k * ( M + 1 ) ); + IF( st->hBWE_TD != NULL ) + { + IF( EQ_16( st->L_frame, L_FRAME ) ) + { + Copy( Aq_fx + 2 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); + } + ELSE + { + Copy( Aq_fx + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) ); + } + fixedToFloat_arr( st->hBWE_TD->cur_sub_Aq_fx, st->hBWE_TD->cur_sub_Aq, Q12, M + 1 ); + } +#else if ( st->hBWE_TD != NULL ) { if ( st->L_frame == L_FRAME ) @@ -1127,11 +1163,86 @@ ivas_error acelp_core_dec( mvr2r( Aq + 3 * ( M + 1 ), st->hBWE_TD->cur_sub_Aq, ( M + 1 ) ); } } +#endif /*--------------------------------------------------------* * Apply NB postfilter in case of 8kHz output *--------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + Word16 pitch_buf_tmp[NB_SUBFR16k]; + /*----ftf conversions---*/ + st->Q_syn = 0; + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + tmp_noise_fx = (Word16) floatToFixed( tmp_noise, 0 ); + if ( st->last_bwidth == NB && st->hPFstat != NULL ) + { + floatToFixed_arr( pitch_buf, pitch_buf_tmp, Q6, NB_SUBFR16k ); + st->psf_lp_noise_fx = (Word16) floatToFixed( st->psf_lp_noise, Q8 ); + } + st->lp_noise = floatToFixed( st->lp_noise_float, Q23 ); + /*---------------------*/ + test(); + IF( EQ_16( st->last_bwidth, NB ) && st->hPFstat != NULL ) + { + IF( EQ_16( st->bwidth, NB ) ) + { + st->hPFstat->on = 1; +#ifdef IVAS_FLOAT_FIXED + Word16 prev_reset = st->hPFstat->reset; + move16(); + nb_post_filt( st->L_frame, st->hPFstat, &st->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, st->coder_type_fx, st->BER_detect, 0 ); + /*----ftf conversions---*/ + if ( !st->BER_detect ) + { + if ( st->coder_type_fx == INACTIVE ) + { + st->psf_lp_noise = fixedToFloat( st->psf_lp_noise_fx, Q8 ); + } + } + + if ( prev_reset == 1 ) + { + st->hPFstat->gain_prec_flt = fixedToFloat( st->hPFstat->gain_prec, Q14 ); + fixedToFloat_arr( st->hPFstat->mem_pf_in, st->hPFstat->mem_pf_in_flt, st->Q_syn, L_SYN_MEM ); + fixedToFloat_arr( st->hPFstat->mem_stp, st->hPFstat->mem_stp_flt, st->Q_syn, L_SYN_MEM ); + } + /*---------------------*/ +#else + nb_post_filt_ivas( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, st->coder_type, st->BER_detect, 0 ); +#endif + } + ELSE + { + st->hPFstat->on = 0; +#ifdef IVAS_FLOAT_FIXED + Word16 prev_reset = st->hPFstat->reset; + nb_post_filt( st->L_frame, st->hPFstat, &st->psf_lp_noise_fx, tmp_noise_fx, syn_fx, Aq_fx, pitch_buf_tmp, AUDIO, st->BER_detect, 0 ); + /*----ftf conversions---*/ + if ( prev_reset == 1 ) + { + st->hPFstat->gain_prec_flt = fixedToFloat( st->hPFstat->gain_prec, Q14 ); + fixedToFloat_arr( st->hPFstat->mem_pf_in, st->hPFstat->mem_pf_in_flt, st->Q_syn, L_SYN_MEM ); + fixedToFloat_arr( st->hPFstat->mem_stp, st->hPFstat->mem_stp_flt, st->Q_syn, L_SYN_MEM ); + } + /*---------------------*/ +#else + nb_post_filt_ivas( st->L_frame, L_SUBFR, st->hPFstat, &st->psf_lp_noise, tmp_noise, syn, Aq, pitch_buf, AUDIO, st->BER_detect, 0 ); +#endif + } + } + else + { +#ifdef IVAS_FLOAT_FIXED + st->psf_lp_noise_fx = round_fx( L_shl( st->lp_noise, 1 ) ); + /*----ftf conversions---*/ + st->psf_lp_noise = fix16_to_float( st->psf_lp_noise_fx, Q8 ); + /*---------------------*/ +#else + st->psf_lp_noise = st->lp_noise_float; +#endif + } +#else if ( st->last_bwidth == NB && st->hPFstat != NULL ) { if ( st->bwidth == NB ) @@ -1149,27 +1260,171 @@ ivas_error acelp_core_dec( { st->psf_lp_noise = st->lp_noise_float; } +#endif /*------------------------------------------------------------------* * Perform fixed deemphasis through 1/(1 - g*z^-1) *-----------------------------------------------------------------*/ /* update old synthesis buffer - needed for ACELP internal sampling rate switching */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + Copy( syn_fx + st->L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM ); + fixedToFloat_arr( st->mem_syn_r, st->mem_syn_r_float, st->Q_syn, L_SYN_MEM ); +#else mvr2r( syn + st->L_frame - L_SYN_MEM, st->mem_syn_r_float, L_SYN_MEM ); +#endif + +#ifdef IVAS_FLOAT_FIXED_S + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + st->mem_deemph_fx = float_to_fix16_thrld( st->mem_deemph, st->Q_syn ); + st->preemph_fac = float_to_fix16( st->preemph_fac_float, Q15 ); + + deemph_fx( syn_fx, st->preemph_fac, st->L_frame, &( st->mem_deemph_fx ) ); + + st->mem_deemph = fix16_to_float( st->mem_deemph_fx, st->Q_syn ); + fixedToFloat_arr( syn_fx, syn, st->Q_syn, st->L_frame ); +#else deemph( syn, st->preemph_fac_float, st->L_frame, &( st->mem_deemph ) ); +#endif +#ifdef IVAS_FLOAT_FIXED_S + Word16 syn_fx_tmp2[L_FRAME_16k]; + unscale_AGC( syn_fx, st->Q_syn, syn_fx_tmp2, st->agc_mem_fx, st->L_frame ); // re-check : removed right shift inside + Copy( syn_fx_tmp2, syn_fx, st->L_frame ); + for ( i = 0; i < st->L_frame; i++ ) + { + syn[i] = fix16_to_float( syn_fx[i], st->Q_syn ); + } + st->agc_mem2[0] = me2f_16( st->agc_mem_fx[0], st->Q_syn - 1 ); + st->agc_mem2[1] = me2f_16( st->agc_mem_fx[1], st->Q_syn - 1 ); +#else AGC_dec( syn, st->agc_mem2, st->L_frame ); +#endif + +#ifdef IVAS_FLOAT_FIXED + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_FRAME16k ); + IF( st->hTcxDec != NULL ) + { + Copy_Scale_sig( syn_fx + st->L_frame / 2, st->hTcxDec->old_syn_Overl, st->L_frame / 2, sub( -1, st->Q_syn ) ); /*Q-1*/ + fixedToFloat_arr( st->hTcxDec->old_syn_Overl, st->hTcxDec->old_syn_Overl_float, st->Q_syn - 1, st->L_frame / 2 ); + } + Copy_Scale_sig( syn_fx + st->L_frame - M - 1, st->syn, M + 1, sub( 0, st->Q_syn ) ); /*Q0*/ + fixedToFloat_arr( st->syn, st->syn_float, st->Q_syn, M + 1 ); +#else if ( st->hTcxDec != NULL ) { mvr2r( syn + st->L_frame / 2, st->hTcxDec->old_syn_Overl_float, st->L_frame / 2 ); } mvr2r( syn + st->L_frame - M - 1, st->syn_float, M + 1 ); +#endif +#else + mvr2r(syn + st->L_frame - L_SYN_MEM, st->mem_syn_r_float, L_SYN_MEM); + deemph(syn, st->preemph_fac_float, st->L_frame, &(st->mem_deemph)); + + AGC_dec(syn, st->agc_mem2, st->L_frame); + + if (st->hTcxDec != NULL) + { + mvr2r(syn + st->L_frame / 2, st->hTcxDec->old_syn_Overl_float, st->L_frame / 2); + } + mvr2r(syn + st->L_frame - M - 1, st->syn_float, M + 1); +#endif /*------------------------------------------------------------------* * Formant post-filter *-----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED + Word16 temp_buf_fx[L_FRAME16k + L_SYN_MEM]; + test(); + test(); + test(); + IF( st->hPFstat != NULL && GE_16( st->last_bwidth, WB ) && ( GT_32( st->core_brate, ACELP_24k40 ) || GT_16( st->element_mode, EVS_MONO ) ) && LE_32( st->core_brate, ACELP_32k ) ) + { + st->hPFstat->on = 1; +#ifdef IVAS_FLOAT_FIXED + /*----ftf conversions---*/ + floatToFixed_arr( syn, syn_fx, st->Q_syn, st->L_frame ); + Copy( syn_fx, temp_buf_fx + L_SYN_MEM, L_FRAME16k ); + + for ( i = 0; i < L_SYN_MEM; i++ ) + { + temp_buf_fx[i] = float_to_fix16_thrld( temp_buf[i], st->Q_syn ); + } + set16_fx( st->hPFstat->mem_zero, 0, M ); + if ( st->hPFstat ) + { + floatToFixed_arr( st->hPFstat->mem_pf_in_flt, st->hPFstat->mem_pf_in, st->Q_syn, L_SUBFR ); + floatToFixed_arr( st->hPFstat->mem_stp_flt, st->hPFstat->mem_stp, st->Q_syn, L_SUBFR ); + floatToFixed_arr( st->hPFstat->mem_res2_flt, st->hPFstat->mem_res2, st->Q_syn, DECMEM_RES2 ); + floatToFixed_arr( st->hPFstat->mem_res2_flt, st->hPFstat->mem_res2, st->Q_syn, M ); + st->hPFstat->gain_prec = float_to_fix16( st->hPFstat->gain_prec_flt, Q14 ); + } + /*---------------------*/ + + formant_post_filt_fx( st->hPFstat, temp_buf_fx + L_SYN_MEM, Aq_fx, syn_fx, st->L_frame, st->lp_noise, st->total_brate, 0 ); + + /*----ftf conversions---*/ + if ( st->hPFstat ) + { + fixedToFloat_arr( st->hPFstat->mem_pf_in, st->hPFstat->mem_pf_in_flt, st->Q_syn, L_SUBFR ); + fixedToFloat_arr( st->hPFstat->mem_stp, st->hPFstat->mem_stp_flt, st->Q_syn, L_SUBFR ); + fixedToFloat_arr( st->hPFstat->mem_res2, st->hPFstat->mem_res2_flt, st->Q_syn, DECMEM_RES2 ); + fixedToFloat_arr( st->hPFstat->mem_res2, st->hPFstat->mem_res2_flt, st->Q_syn, M ); + st->hPFstat->gain_prec_flt = fixedToFloat( st->hPFstat->gain_prec, Q14 ); + } + fixedToFloat_arr( syn_fx, syn, st->Q_syn, st->L_frame ); + /*---------------------*/ +#else + mvr2r( syn, temp_buf + L_SYN_MEM, L_FRAME16k ); + formant_post_filt_ivas( st->hPFstat, temp_buf + L_SYN_MEM, Aq, syn, st->L_frame, L_SUBFR, st->lp_noise_float, st->total_brate, 0 ); +#endif + } + ELSE IF( st->hPFstat != NULL && GE_16( st->last_bwidth, WB ) ) + { + IF( st->hPFstat->on ) + { +#ifdef IVAS_FLOAT_FIXED + /*----ftf conversions---*/ + floatToFixed_arr( st->hPFstat->mem_pf_in_flt, st->hPFstat->mem_pf_in, st->Q_syn, L_SUBFR ); + floatToFixed_arr( syn, syn_fx, st->Q_syn, L_SUBFR ); + floatToFixed_arr( Aq, Aq_fx, Q12, NB_SUBFR16k * ( M + 1 ) ); + /*---------------------*/ + + Copy( st->hPFstat->mem_pf_in + L_SYN_MEM - M, temp_buf_fx, M ); + Copy( syn_fx, temp_buf_fx + M, L_SUBFR ); + Residu3_fx( Aq_fx, temp_buf_fx + M, temp_buf_fx + M + L_SUBFR, L_SUBFR, 1 ); + E_UTIL_synthesis( 1, Aq_fx, temp_buf_fx + M + L_SUBFR, temp_buf_fx, L_SUBFR, st->hPFstat->mem_stp + L_SYN_MEM - M, 0, M ); + scale_st( syn_fx, temp_buf_fx, &st->hPFstat->gain_prec, L_SUBFR ); + Copy( temp_buf_fx, syn_fx, L_SUBFR / 2 ); + blend_subfr2( temp_buf_fx + L_SUBFR / 2, syn_fx + L_SUBFR / 2, syn_fx + L_SUBFR / 2 ); + + /*----ftf conversions---*/ + if ( st->hPFstat ) + { + fixedToFloat_arr( st->hPFstat->mem_stp, st->hPFstat->mem_stp_flt, st->Q_syn, L_SUBFR ); + st->hPFstat->gain_prec_flt = fixedToFloat( st->hPFstat->gain_prec, Q14 ); + } + + fixedToFloat_arr( temp_buf_fx, temp_buf, st->Q_syn, L_FRAME16k + L_SYN_MEM ); + fixedToFloat_arr( syn_fx, syn, st->Q_syn, L_SUBFR ); + /*---------------------*/ +#else + mvr2r( st->hPFstat->mem_pf_in_flt + L_SYN_MEM - M, temp_buf, M ); + mvr2r( syn, temp_buf + M, L_SUBFR ); + residu( Aq, M, temp_buf + M, temp_buf + M + L_SUBFR, L_SUBFR ); + syn_filt( Aq, M, temp_buf + M + L_SUBFR, temp_buf, L_SUBFR, st->hPFstat->mem_stp_flt + L_SYN_MEM - M, 0 ); + scale_st_ivas( syn, temp_buf, &st->hPFstat->gain_prec_flt, L_SUBFR, -1 ); + mvr2r( temp_buf, syn, L_SUBFR / 2 ); + blend_subfr2_flt( temp_buf + L_SUBFR / 2, syn + L_SUBFR / 2, syn + L_SUBFR / 2 ); +#endif + } + st->hPFstat->on = 0; + } +#else if ( st->hPFstat != NULL && st->last_bwidth >= WB && ( st->core_brate > ACELP_24k40 || st->element_mode > EVS_MONO ) && st->core_brate <= ACELP_32k ) { mvr2r( syn, temp_buf + L_SYN_MEM, L_FRAME16k ); @@ -1191,7 +1446,7 @@ ivas_error acelp_core_dec( } st->hPFstat->on = 0; } - +#endif /*----------------------------------------------------------------* * Comfort noise addition *----------------------------------------------------------------*/ @@ -1224,11 +1479,15 @@ ivas_error acelp_core_dec( { /*Noise estimate*/ #ifdef IVAS_FLOAT_FIXED - Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; + //Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; st->Q_syn = 0; - for ( int p = 0; p < L_FRAME16k; p++ ) + /*for ( int p = 0; p < L_FRAME16k; p++ ) { syn_fx[L_SUBFR + p] = (Word16) ( syn[p] * ( 1u << st->Q_syn ) ); + }*/ + for (int p = 0; p < L_FRAME16k; p++) + { + syn_fx[p] = (Word16)(syn[p] * (1u << st->Q_syn)); } for ( int p = 0; p < st->L_frame; p++ ) { @@ -1253,7 +1512,8 @@ ivas_error acelp_core_dec( } /*==========================================================*/ - ApplyFdCng_fx( syn_fx + L_SUBFR, st->Q_syn, NULL, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + //ApplyFdCng_fx( syn_fx + L_SUBFR, st->Q_syn, NULL, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx(syn_fx, st->Q_syn, NULL, realBuffer_fx, imagBuffer_fx, NULL, st, 0, (st->coder_type == AUDIO && !st->GSC_noisy_speech)); /*==========================================================*/ if ( ( ( st->m_frame_type == ACTIVE_FRAME ) && ( ( st->bfi == 0 && @@ -1447,11 +1707,11 @@ ivas_error acelp_core_dec( if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) { #ifdef IVAS_FLOAT_FIXED - Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; + //Word16 syn_fx[L_FRAME16k + L_SUBFR] = { 0 }; st->Q_syn = 0; for ( int p = 0; p < L_FRAME16k; p++ ) { - syn_fx[L_SUBFR + p] = (Word16) ( syn[p] * ( 1u << st->Q_syn ) ); + syn_fx[p] = (Word16) ( syn[p] * ( 1u << st->Q_syn ) ); } for ( int p = 0; p < st->L_frame; p++ ) { @@ -1475,7 +1735,7 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->cngNoiseLevel[p] = (Word32) ( st->hFdCngDec->hFdCngCom->cngNoiseLevel_flt[p] * ( 1u << ( 31 - st->hFdCngDec->hFdCngCom->cngNoiseLevelExp ) ) ); } - ApplyFdCng_fx( syn_fx + L_SUBFR, st->Q_syn, NULL, realBuffer, imagBuffer, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); + ApplyFdCng_fx( syn_fx, st->Q_syn, NULL, realBuffer_fx, imagBuffer_fx, NULL, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); if ( ( ( st->m_frame_type == ACTIVE_FRAME ) && ( ( st->bfi == 0 && ( syn_fx == NULL || diff --git a/lib_dec/dec_post_fx.c b/lib_dec/dec_post_fx.c index aaf334c68..80385bcfb 100644 --- a/lib_dec/dec_post_fx.c +++ b/lib_dec/dec_post_fx.c @@ -39,6 +39,12 @@ static void modify_pst_param( const Word16 lp_noise, Word16 *g1, Word16 *g2, con static void Dec_formant_postfilt( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); +#ifdef IVAS_FLOAT_FIXED +static void Dec_formant_postfilt_fx( PFSTAT_HANDLE hPFstat, Word16 *signal_ptr, Word16 *coeff, Word16 *sig_out, Word16 gamma1, Word16 gamma2 ); + +static void calc_st_filt_fx( Word16 *apond2, Word16 *apond1, Word16 *parcor0, Word16 *sig_ltp_ptr, Word16 *mem_zero, const Word16 extl ); +#endif + /*-------------------------------------------------------------------------- * Init_post_filter @@ -381,6 +387,132 @@ void formant_post_filt( } +#ifdef IVAS_FLOAT_FIXED +void formant_post_filt_fx( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *synth_in, /* i : 12k8 synthesis */ + Word16 *Aq, /* i : LP filter coefficient */ + Word16 *synth_out, /* i/o: input signal */ + Word16 L_frame, + Word32 lp_noise, /* (i) : background noise energy (15Q16) */ + Word32 brate, /* (i) : bit-rate */ + const Word16 off_flag /* i : off flag */ +) +{ + Word16 i_subfr; + Word16 *p_Aq; + Word16 post_G1, post_G2; + + + /*default parameter for noisy speech and high bit-rates*/ + IF( EQ_16( L_frame, L_FRAME ) ) + { + post_G2 = 22938 /*0.7f Q15*/; + move16(); + IF( LT_32( lp_noise, LP_NOISE_THRESH ) ) + { + /*Clean speech*/ + IF( LT_32( brate, ACELP_13k20 ) ) + { + /*Low rates*/ + + post_G1 = 26214 /*0.8f Q15*/; + move16(); + } + ELSE IF( LT_32( brate, ACELP_24k40 ) ) + { + /*Low rates*/ + + post_G1 = 24576 /*0.75f Q15*/; + move16(); + } + ELSE + { + post_G1 = 23593 /*0.72f Q15*/; + move16(); + } + } + ELSE /*Noisy speech*/ + { + post_G1 = 22938 /*0.7f Q15*/; + move16(); + if ( LT_32( brate, ACELP_15k85 ) ) + { + /*Low rates*/ + post_G1 = 24576 /*0.75f Q15*/; + move16(); + } + } + } + ELSE + { + post_G2 = 24904 /*0.76f Q15*/; + move16(); + test(); + IF( GE_32( lp_noise, LP_NOISE_THRESH ) ) + { + post_G1 = 24904 /*0.76f Q15*/; + } + ELSE IF( EQ_32( brate, ACELP_13k20 ) ) + { + post_G1 = 26870 /*0.82f Q15*/; + move16(); + } + ELSE IF( EQ_32( brate, ACELP_16k40 ) ) + { + post_G1 = 26214 /*0.80f Q15*/; + move16(); + } + ELSE IF( EQ_32( brate, ACELP_24k40 ) || EQ_32( brate, ACELP_32k ) ) + { + post_G1 = 25559 /*0.78f Q15*/; + move16(); + } + ELSE + { + post_G1 = 24904 /*0.76f Q15*/; + move16(); + } + } + + /* Switch off post-filter */ + if ( off_flag != 0 ) + { + post_G1 = post_G2; + move16(); + } + + /* Reset post filter */ + if ( hPFstat->reset != 0 ) + { + post_G1 = MAX16B; + move16(); + post_G2 = MAX16B; + move16(); + hPFstat->reset = 0; + move16(); + Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); + Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_stp, L_SYN_MEM ); + hPFstat->gain_prec = 16384; + move16(); + Copy( synth_in, synth_out, L_frame ); + + return; + } + + /* input memory*/ + Copy( hPFstat->mem_pf_in, synth_in - L_SYN_MEM, L_SYN_MEM ); + Copy( &synth_in[L_frame - L_SYN_MEM], hPFstat->mem_pf_in, L_SYN_MEM ); + + move16(); + p_Aq = Aq; + FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR ) + { + Dec_formant_postfilt_fx( hPFstat, &synth_in[i_subfr], p_Aq, &synth_out[i_subfr], post_G1, post_G2 ); + p_Aq += ( M + 1 ); + } +} +#endif /*---------------------------------------------------------------------------- * Dec_postfilt * @@ -475,7 +607,87 @@ static void Dec_formant_postfilt( return; } +#ifdef IVAS_FLOAT_FIXED +static void Dec_formant_postfilt_fx( + PFSTAT_HANDLE hPFstat, /* i : core decoder parameters */ + Word16 *signal_ptr, /* i : input signal (pointer to current subframe */ + Word16 *coeff, /* i : LPC coefficients for current subframe */ + Word16 *sig_out, /* o : postfiltered output */ + Word16 gamma1, /* i : short term postfilt. den. weighting factor*/ + Word16 gamma2 /* i : short term postfilt. num. weighting factor*/ +) +{ + /* Local variables and arrays */ + Word16 apond1[M + 1]; /* s.t. denominator coeff. */ + Word16 apond2[LONG_H_ST]; + Word16 res2[L_SUBFR]; + Word16 resynth[L_SUBFR + 1]; + Word16 parcor0; + Word16 i, max; + Word16 scale_down; + + /* Compute weighted LPC coefficients */ + weight_a_fx(coeff, apond1, gamma1, M); + weight_a_fx(coeff, apond2, gamma2, M); + set16_fx(&apond2[M + 1], 0, LONG_H_ST - (M + 1)); + + max = abs_s(signal_ptr[0]); + FOR(i = 1; i < L_SUBFR; i++) + { + max = s_max(max, abs_s(signal_ptr[i])); + } + scale_down = 0; + move16(); + if (GT_16(max, 16384)) + { + scale_down = 1; + move16(); + } + + /* Compute A(gamma2) residual */ + IF(!scale_down) + { + Residu3_fx(apond2, signal_ptr, res2, L_SUBFR, 1); + } + ELSE + { + Residu3_fx(apond2, signal_ptr, res2, L_SUBFR, 0); + Scale_sig(hPFstat->mem_stp, L_SYN_MEM, -1); + } + /* Controls short term pst filter gain and compute parcor0 */ + calc_st_filt_fx(apond2, apond1, &parcor0, res2, hPFstat->mem_zero , -1 ); + + /* 1/A(gamma1) filtering, mem_stp is updated */ + resynth[0] = *(hPFstat->mem_stp + sub(L_SYN_MEM, 1)); + move16(); + + E_UTIL_synthesis(1, apond1, res2, &(resynth[1]), L_SUBFR, hPFstat->mem_stp + L_SYN_MEM - M, 0, M); + + IF(!scale_down) + { + Copy(&(resynth[1]) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM); + } + ELSE + { + Copy_Scale_sig(&(resynth[1]) + L_SUBFR - L_SYN_MEM, hPFstat->mem_stp, L_SYN_MEM, 1); + } + + /* Tilt filtering */ + Filt_mu_fx(resynth, sig_out, parcor0, L_SUBFR , -1); + IF(scale_down) + { + Scale_sig(sig_out, L_SUBFR, 1); + } + + /* Gain control */ + scale_st(signal_ptr, sig_out, &hPFstat->gain_prec, L_SUBFR); + + + return; +} + +#endif /*------------------------------------------------------------------------------------ * modify_pst_param() * @@ -1387,6 +1599,61 @@ static void calc_st_filt( return; } +#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 Word16 extl /* i : extension layer info */ +) +{ + Word32 L_g0; + + Word16 h[LONG_H_ST]; + + Word16 g0, temp; + Word16 i; + + + temp = sub(2, norm_s(apond2[0])); + + /* compute i.r. of composed filter apond2 / apond1 */ + if (extl == SWB_TBE) + { + E_UTIL_synthesis(temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, LPC_SHB_ORDER); + } + else { + E_UTIL_synthesis(temp, apond1, apond2, h, LONG_H_ST, mem_zero, 0, M); + } + + /* compute 1st parcor */ + Calc_rc0_h(h, parcor0); + + /* compute g0 */ + L_g0 = L_mult0(1, abs_s(h[0])); + FOR(i = 1; i < LONG_H_ST; i++) + { + L_g0 = L_mac0(L_g0, 1, abs_s(h[i])); + } + g0 = extract_h(L_shl(L_g0, 14)); + + /* Scale signal i of 1/A(gamma1) */ + IF(GT_16(g0, 1024)) + { + temp = div_s(1024, g0); /* temp = 2**15 / gain0 */ + FOR(i = 0; i < L_SUBFR; i++) + { + sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp); + move16(); + } + } + + + return; +} +#endif /*---------------------------------------------------------------------------- * filt_mu * @@ -1465,7 +1732,105 @@ void Filt_mu( return; } +#ifdef IVAS_FLOAT_FIXED +void Filt_mu_fx( + Word16 * sig_in, /* i : signal (beginning at sample -1) */ + Word16 * sig_out, /* o : signal with tilt */ + Word16 parcor0, /* i : parcor0 (mu = parcor0 * gamma3) */ + Word16 L_subfr, /* i : the length of subframe */ + const Word16 extl +) +{ + Word32 L_acc, L_temp, L_fact; + + Word16 *ptrs; + + Word16 n; + Word16 mu, mu2, ga, temp; + Word16 fact, sh_fact; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + IF( extl == SWB_TBE ) + { + IF( parcor0 > 0 ) + { + mu = mult_r( parcor0, GAMMA3_PLUS_WB_FX ); + /* GAMMA3_PLUS_FX < 0.5 */ + sh_fact = 14; + move16(); /* sh_fact */ + fact = (Word16) 0x4000; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l( 0x2000 ); /* fact >> 1 */ + } + ELSE + { + mu = mult_r( parcor0, GAMMA3_MINUS_WB_FX ); + /* GAMMA3_MINUS_FX < 0.9375 */ + sh_fact = 11; + move16(); /* sh_fact */ + fact = (Word16) 0x0800; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l( 0x0400 ); /* fact >> 1 */ + } + } + ELSE + { + IF( parcor0 > 0 ) + { + mu = mult_r( parcor0, GAMMA3_PLUS_FX ); + /* GAMMA3_PLUS_FX < 0.5 */ + sh_fact = 14; + move16(); /* sh_fact */ + fact = (Word16) 0x4000; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l( 0x2000 ); /* fact >> 1 */ + } + ELSE + { + mu = mult_r( parcor0, GAMMA3_MINUS_FX ); + /* GAMMA3_MINUS_FX < 0.9375 */ + sh_fact = 11; + move16(); /* sh_fact */ + fact = (Word16) 0x0800; + move16(); /* 2**sh_fact */ + L_fact = (Word32) L_deposit_l( 0x0400 ); /* fact >> 1 */ + } + } + + temp = sub(1, abs_s(mu)); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + mu2 = add_o(32767, temp, &Overflow); /* 2**15 (1 - |mu|) */ +#else + mu2 = add(32767, temp); /* 2**15 (1 - |mu|) */ +#endif + BASOP_SATURATE_WARNING_ON_EVS; + ga = div_s(fact, mu2); /* 2**sh_fact / (1 - |mu|) */ + + ptrs = sig_in; /* points on sig_in(-1) */ + + sh_fact = sub(sh_fact, 16); /* to remove the saturate(), should shl by 16 before rounding */ + + FOR(n = 0; n < L_subfr; n++) + { + L_acc = L_mult0(mu, *ptrs++); + L_temp = L_mac(L_acc, 16384, *ptrs); /* sig_in(n) * 2**15 */ + + L_temp = Madd_32_16(L_fact, L_temp, ga); + L_temp = L_shr(L_temp, sh_fact); /* mult. temp x ga */ + + BASOP_SATURATE_WARNING_OFF_EVS; + /*sig_out[n] = saturate(L_temp); move16();*/ + sig_out[n] = round_fx(L_temp); + BASOP_SATURATE_WARNING_ON_EVS; + } + + return; +} +#endif /*---------------------------------------------------------------------------- * scale_st() * diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index b29c72e5c..48d35293e 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -71,6 +71,9 @@ ivas_error evs_dec_flt( float old_syn_12k8_16k[L_FRAME16k]; float tmp, tmpF; float pitch_buf[NB_SUBFR16k]; +#ifdef IVAS_FLOAT_FIXED + set_zero(pitch_buf, NB_SUBFR16k); +#endif int16_t unbits; int16_t hq_core_type; int16_t sid_bw; diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 4906fe5e0..c86292341 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -132,6 +132,9 @@ ivas_error init_decoder( st->stab_fac = 0.0f; st->stab_fac_smooth = 0.0f; set_f( st->agc_mem2, 0, 2 ); +#ifdef IVAS_FLOAT_FIXED + set16_fx(st->agc_mem_fx, 0, 2); +#endif set_f( st->mem_syn3, 0, M ); st->stab_fac_smooth_lt = 0.0f; st->log_energy_diff_lt = 0.0f; @@ -242,9 +245,16 @@ ivas_error init_decoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for NB/formant postflter\n" ) ); } - +#ifdef IVAS_FLOAT_FIXED + Init_post_filter(st->hPFstat);//fixed + st->psf_lp_noise_fx = 0; + /*to be cleaned up*/ + Init_post_filter_ivas(st->hPFstat); + st->psf_lp_noise = 0.0f; +#else Init_post_filter_ivas( st->hPFstat ); st->psf_lp_noise = 0.0f; +#endif } else { @@ -621,7 +631,7 @@ ivas_error init_decoder( st->hTcxDec->old_synthFB = st->hTcxDec->synth_history + NS2SA( st->output_Fs, PH_ECU_MEM_NS ); st->hTcxDec->prev_good_synth = st->hTcxDec->old_synthFB + NS2SA( st->output_Fs, PH_ECU_LOOKAHEAD_NS ); #ifdef IVAS_FLOAT_FIXED - set32_fx(st->hTcxDec->FBTCXdelayBuf, 0, 111); + set16_fx(st->hTcxDec->FBTCXdelayBuf, 0, 111); st->hTcxDec->old_synthFB_fx = st->hTcxDec->synth_history_fx + NS2SA( st->output_Fs, PH_ECU_MEM_NS ); st->hTcxDec->prev_good_synth_fx = st->hTcxDec->old_synthFB_fx + NS2SA(st->output_Fs, PH_ECU_LOOKAHEAD_NS); #endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index abc98ad63..f4f4d5d27 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -83,6 +83,14 @@ ivas_error ivas_core_dec( float old_syn_12k8_16k[CPE_CHANNELS][L_FRAME16k]; float tmp; float pitch_buf[CPE_CHANNELS][NB_SUBFR16k]; +#ifdef IVAS_FLOAT_FIXED + for ( i = 0; i < CPE_CHANNELS; i++ ) + { + for (int j = 0; j < NB_SUBFR16k; j++) { + pitch_buf[i][j] = 0.f; + } + } +#endif int16_t unbits[CPE_CHANNELS]; int16_t sid_bw[CPE_CHANNELS]; FRAME_MODE frameMode[CPE_CHANNELS]; -- GitLab