diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index dff4997f02f71537d9cf6cf51ad63f1d2553b309..2cf76473c1b3a33bcbf31ce6135ac049b1766374 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3008,7 +3008,7 @@ void encod_gen_2sbfr( Word16 *bwe_exc, /* o : excitation for SWB TBE */ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel */ - Word16 *Q_new ); + Word16 Q_new ); void acelp_fast_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ @@ -4439,7 +4439,7 @@ void tdm_low_rate_enc( /* i : current frame ISF vector */ // x2.56 Word16 *tmp_noise, /* o : long-term noise energy */ // Q8 - Word16 *Q_new ); + Word16 Q_new ); void tdm_low_rate_dec_fx( Decoder_State *st, /* i/o: decoder static memory */ diff --git a/lib_com/swb_tbe_com_fx.c b/lib_com/swb_tbe_com_fx.c index e9b9530f338fd855e4ebb3f66d018b5fceaa5361..aa4a1e2bee1e70734ce8fcbfc62afab984c89e6d 100644 --- a/lib_com/swb_tbe_com_fx.c +++ b/lib_com/swb_tbe_com_fx.c @@ -6486,7 +6486,7 @@ void prep_tbe_exc_ivas_fx( #ifdef BASOP_NOGLOB pitch = shl_o( add( shl_o( T0, 2, &Overflow ), T0_frac ), 5, &Overflow ); /* Q7 */ #else /* BASOP_NOGLOB */ - pitch = shl( add( shl( T0, 2 ), T0_frac ), 5 ); /* Q7 */ + pitch = shl( add( shl( T0, 2 ), T0_frac ), 5 ); /* Q7 */ #endif /* BASOP_NOGLOB */ test(); @@ -6518,20 +6518,21 @@ void prep_tbe_exc_ivas_fx( #ifdef BASOP_NOGLOB gain_code16 = round_fx_o( L_shl_o( gain_code_fx, Q_exc, &Overflow ), &Overflow ); /*Q_exc */ #else - gain_code16 = round_fx( L_shl( gain_code_fx, Q_exc ) ); /*Q_exc */ + gain_code16 = round_fx( L_shl( gain_code_fx, Q_exc ) ); /*Q_exc */ #endif FOR( i = 0; i < L_subfr * HIBND_ACB_L_FAC; i++ ) { - L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ - L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ - L_tmp = L_mac( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ + L_tmp = L_mult( gain_code16, tmp_code_fx[i] ); /* Q9 + Q_exc + 1*/ + L_tmp = L_shl( L_tmp, 5 ); /* Q9 + Q_exc + Q6*/ #ifdef BASOP_NOGLOB - L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ -#else /* BASOP_NOGLOB */ - L_tmp = L_shl( L_tmp, 1 ); /*16+Q_exc */ /* saturation can occur here */ - bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx( L_tmp ); /*Q_exc */ -#endif /* BASOP_NOGLOB */ + L_tmp = L_mac_o( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC], &Overflow ); /*Q15+Q_exc */ + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx_o( L_tmp, &Overflow ); /*Q_exc */ +#else /* BASOP_NOGLOB */ + L_tmp = L_mac( L_tmp, gain_pit_fx, bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] ); /*Q15+Q_exc */ + L_tmp = L_shl( L_tmp, 1 ); /*16+Q_exc */ /* saturation can occur here */ + bwe_exc_fx[i + i_subfr_fx * HIBND_ACB_L_FAC] = round_fx( L_tmp ); /*Q_exc */ +#endif /* BASOP_NOGLOB */ move16(); } } @@ -6558,8 +6559,8 @@ void prep_tbe_exc_ivas_fx( tmp_code_preInt_fx[i] = round_fx_o( L_add_o( Ltemp1, Ltemp2, &Overflow ), &Overflow ); /* Q_exc */ #else /* BASOP_NOGLOB */ - Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ - Ltemp2 = L_shl( Ltemp2, Q_exc + 4 /*Q_exc+16-13*/ ); /*Q_exc+16 */ + Ltemp1 = L_shl( Ltemp1, Q_exc + 6 /*Q_exc+16-19*/ ); /*Q_exc+16 */ + Ltemp2 = L_shl( Ltemp2, Q_exc + 4 /*Q_exc+16-13*/ ); /*Q_exc+16 */ tmp_code_preInt_fx[i] = round_fx( L_add( Ltemp1, Ltemp2 ) ); /* Q_exc */ #endif /* BASOP_NOGLOB */ diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 47ccebb5615f79bc699773a88441cb4ecc4b1aaf..e5d162502f3e31eec3397f206b700dba1e7fe169 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -95,10 +95,10 @@ ivas_error acelp_core_enc( float Aq[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ float syn[L_FRAME16k]; /* synthesis signal buffer */ float res[L_FRAME16k]; /* Residual signal for FER protection */ -#endif // IVAS_FLOAT_FIXED_CONVERSIONS - float exc2[L_FRAME16k]; /* enhanced excitation */ - float Es_pred; /* predicited scaled innovation energy */ - float tmp_noise; /* NB post-filter long-term noise energy*/ +#endif // IVAS_FLOAT_FIXED_CONVERSIONS + float exc2[L_FRAME16k]; /* enhanced excitation */ + float Es_pred; /* predicited scaled innovation energy */ + // float tmp_noise; /* NB post-filter long-term noise energy*/ Word16 tc_subfr; /* TC sub-frame indication */ float old_bwe_exc[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ float *bwe_exc; /* excitation for SWB TBE */ @@ -108,7 +108,7 @@ ivas_error acelp_core_enc( /* SC-VBR - back-up memories for LSF quantizer and synthesis filter */ Word16 pstreaklen; - float mem_MA[M], mem_AR[M], Bin_E[L_FFT], Bin_E_old[L_FFT / 2], lsp_new_bck[M], lsp_mid_bck[M], mem_syn_bck[M]; + float /* mem_MA[M], mem_AR[M], Bin_E[L_FFT], Bin_E_old[L_FFT / 2],*/ lsp_new_bck[M], lsp_mid_bck[M], mem_syn_bck[M]; float q_env[NUM_ENV_CNG]; Word16 sid_bw = -1; @@ -121,12 +121,12 @@ ivas_error acelp_core_enc( // float tmpF; Word16 ppp_mode, nelp_mode; Word16 tdm_lp_reuse_flag, tdm_low_rate_mode, tdm_Pitch_reuse_flag; - float *tdm_Pri_pitch_buf; + // float *tdm_Pri_pitch_buf; /* bitstream */ BSTR_ENC_HANDLE hBstr = st->hBstr; #if 1 - Word16 Q_exc = 0; + // Word16 Q_exc = 0; move16(); Word16 A_fx[85], Aw_fx[85]; Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ @@ -140,7 +140,7 @@ ivas_error acelp_core_enc( // Word16 tc_subfr_fx; /* TC sub-frame indication */ Word16 old_bwe_exc_fx[( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2]; /* excitation buffer */ - Word16 Q_old_bwe_exc; + // Word16 Q_old_bwe_exc; Word16 *bwe_exc_fx; /* excitation for SWB TBE */ // Word16 allow_cn_step_fx; // Word16 int_fs_fx; @@ -183,8 +183,8 @@ ivas_error acelp_core_enc( Word16 tmpF_fx; #endif #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 pitch_buf_fx[NB_SUBFR16k]; /* To be removed once this is taken as input arg of function */ - Word16 voice_factors_fx[NB_SUBFR16k]; /* To be removed once this is taken as input arg of function */ + Word16 pitch_buf_fx[NB_SUBFR16k] = { 0 }; /* To be removed once this is taken as input arg of function */ + Word16 voice_factors_fx[NB_SUBFR16k] = { 0 }; /* To be removed once this is taken as input arg of function */ Word16 tmp; set_zero( old_bwe_exc, 1380 ); for ( i = 0; i < NB_SUBFR16k; i++ ) @@ -194,34 +194,42 @@ ivas_error acelp_core_enc( f2me_buf_16( &A[i * ( M + 1 )], &A_fx[i * ( M + 1 )], &tmp, ( M + 1 ) ); f2me_buf_16( &Aw[i * ( M + 1 )], &Aw_fx[i * ( M + 1 )], &tmp, ( M + 1 ) ); } - IF( st->hLPDmem ) - f2me_buf_16( &st->hLPDmem->old_exc_flt[-M - 1], &st->hLPDmem->old_exc[-M - 1], &st->hLPDmem->e_old_exc, L_EXC_MEM + M + 1 ); - IF( st->hBWE_TD ) - floatToFixed_arr16( st->hBWE_TD->old_bwe_exc, st->hBWE_TD->old_bwe_exc_fx, Q_exc, PIT16k_MAX * 2 ); floatToFixed_arr16( lsp_mid, lsp_mid_fx, 15, M ); floatToFixed_arr16( lsp_new, lsp_new_fx, 15, M ); + Word16 inp_buff[L_FRAME16k + M + 1]; + Word16 *inp_fx; + inp_fx = &inp_buff[M + 1]; + Word16 q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; + q_comm_Bin = min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); + Q_new = Q_factor_arr( &inp[-M - 1], L_FRAME16k + M + 1 ); + Q_new = min( Q_new, q_comm_Bin - ( QSCALE - 2 ) ); + Q_new = min( Q_new, 5 ); + IF( st->hBWE_TD ) + { + Q_new = min( Q_new, Q_factor_arrL( st->hBWE_TD->old_bwe_exc, PIT16k_MAX * 2 ) ); + } IF( st->hLPDmem ) { + Q_new = min( Q_new, Q_factor_arrL( &st->hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ) ); + floatToFixed_arr( &st->hLPDmem->old_exc_flt[-M - 1], &st->hLPDmem->old_exc[-M - 1], Q_new, L_EXC_MEM + M + 1 ); Word16 Q_temp = s_min( Q_factor_arr( st->hLPDmem->mem_syn_flt, 16 ), s_min( Q_factor_arr( st->hLPDmem->mem_syn1_flt, 16 ), s_min( Q_factor_arr( st->hLPDmem->mem_syn2_flt, 16 ), s_min( Q_factor_arr( st->hLPDmem->mem_syn3_flt, 16 ), Q_factor_arr( st->hLPDmem->mem_syn_r_flt, 60 ) ) ) ) ); - st->hLPDmem->e_mem_syn = Q31 - Q_temp; - floatToFixed_arr( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, Q_temp, 16 ); - floatToFixed_arr( st->hLPDmem->mem_syn1_flt, st->hLPDmem->mem_syn1_fx, Q_temp, 16 ); - floatToFixed_arr( st->hLPDmem->mem_syn2_flt, st->hLPDmem->mem_syn2, Q_temp, 16 ); - floatToFixed_arr( st->hLPDmem->mem_syn3_flt, st->hLPDmem->mem_syn3, Q_temp, 16 ); - floatToFixed_arr( st->hLPDmem->mem_syn_r_flt, st->hLPDmem->mem_syn_r, Q_temp, 60 ); + Q_new = min( Q_temp, Q_new ); + // st->hLPDmem->mem_syn_q = Q_new; + floatToFixed_arr( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, Q_new - 1, 16 ); + floatToFixed_arr( st->hLPDmem->mem_syn1_flt, st->hLPDmem->mem_syn1_fx, Q_new - 1, 16 ); + floatToFixed_arr( st->hLPDmem->mem_syn2_flt, st->hLPDmem->mem_syn2, Q_new - 1, 16 ); + floatToFixed_arr( st->hLPDmem->mem_syn3_flt, st->hLPDmem->mem_syn3, Q_new - 1, 16 ); + floatToFixed_arr( st->hLPDmem->mem_syn_r_flt, st->hLPDmem->mem_syn_r, Q_new - 1, 60 ); + } + // Q_new = Q_new - 3; //guard bits + IF( st->hBWE_TD ) + { + floatToFixed_arr( st->hBWE_TD->old_bwe_exc, st->hBWE_TD->old_bwe_exc_fx, Q_new, PIT16k_MAX * 2 ); } - Word16 inp_buff[L_FRAME16k + M + 1]; - Word16 *inp_fx; - inp_fx = &inp_buff[M + 1]; - Word16 q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; - q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); - Q_new = Q_factor_arr( &inp[-M - 1], L_FRAME16k + M + 1 ); - Q_new = s_min( Q_new, q_comm_Bin - ( QSCALE - 2 ) ); - Q_new = s_min( Q_new, 5 ); - floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); + floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new - 1, L_FRAME16k + M + 1 ); floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, Q_new + Q_SCALE - 2, 128 ); floatToFixed_arrL( st->Bin_E, st->Bin_E_fx, Q_new + Q_SCALE - 2, 256 ); #endif @@ -307,7 +315,6 @@ ivas_error acelp_core_enc( move32(); } - tmp_noise = 0; tmp_noise_fx = 0; move16(); tc_subfr = -1; @@ -349,16 +356,12 @@ ivas_error acelp_core_enc( test(); /* TD stereo */ - float tdm_Pri_pitch_buf_flt[NB_SUBFR]; - set_zero( tdm_Pri_pitch_buf_flt, NB_SUBFR ); IF( EQ_16( st->element_mode, IVAS_CPE_TD ) && EQ_16( st->idchan, 1 ) ) { tdm_lp_reuse_flag = hStereoTD->tdm_lp_reuse_flag; tdm_low_rate_mode = hStereoTD->tdm_low_rate_mode; tdm_Pitch_reuse_flag = hStereoTD->tdm_Pitch_reuse_flag; tdm_Pri_pitch_buf_fx = hStereoTD->tdm_Pri_pitch_buf_fx; - fixedToFloat_arr( tdm_Pri_pitch_buf_fx, tdm_Pri_pitch_buf_flt, Q6, NB_SUBFR ); - tdm_Pri_pitch_buf = tdm_Pri_pitch_buf_flt; } ELSE { @@ -371,7 +374,6 @@ ivas_error acelp_core_enc( move16(); } tdm_Pitch_reuse_flag = 0; - tdm_Pri_pitch_buf = NULL; tdm_Pri_pitch_buf_fx = NULL; } move16(); @@ -438,15 +440,16 @@ ivas_error acelp_core_enc( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS IF( st->hLPDmem ) { - Word16 Q_temp = Q31 - st->hLPDmem->e_mem_syn; - fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, Q_temp, 16 ); - fixedToFloat_arr( st->hLPDmem->mem_syn1_fx, st->hLPDmem->mem_syn1_flt, Q_temp, 16 ); - fixedToFloat_arr( st->hLPDmem->mem_syn2, st->hLPDmem->mem_syn2_flt, Q_temp, 16 ); - fixedToFloat_arr( st->hLPDmem->mem_syn3, st->hLPDmem->mem_syn3_flt, Q_temp, 16 ); - fixedToFloat_arr( st->hLPDmem->mem_syn_r, st->hLPDmem->mem_syn_r_flt, Q_temp, 60 ); + fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, Q_new - 1, 16 ); + fixedToFloat_arr( st->hLPDmem->mem_syn1_fx, st->hLPDmem->mem_syn1_flt, Q_new - 1, 16 ); + fixedToFloat_arr( st->hLPDmem->mem_syn2, st->hLPDmem->mem_syn2_flt, Q_new - 1, 16 ); + fixedToFloat_arr( st->hLPDmem->mem_syn3, st->hLPDmem->mem_syn3_flt, Q_new - 1, 16 ); + fixedToFloat_arr( st->hLPDmem->mem_syn_r, st->hLPDmem->mem_syn_r_flt, Q_new - 1, 60 ); } - me2f_buf_16( &st->hLPDmem->old_exc[-M - 1], st->hLPDmem->e_old_exc, &st->hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ); - me2f_buf_16( old_exc_fx, st->hLPDmem->e_old_exc, old_exc_flt, L_EXC_MEM ); + // me2f_buf_16( &st->hLPDmem->old_exc[-M - 1], st->hLPDmem->e_old_exc, &st->hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ); + fixedToFloat_arr( &st->hLPDmem->old_exc[-M - 1], &st->hLPDmem->old_exc_flt[-M - 1], Q_new, L_EXC_MEM + M + 1 ); + // me2f_buf_16( old_exc_fx, st->hLPDmem->e_old_exc, old_exc_flt, L_EXC_MEM ); + fixedToFloat_arr( old_exc_fx, old_exc_flt, Q_new, L_EXC_MEM ); for ( i = 0; i < NB_SUBFR16k; i++ ) { // Array is getting modified in chunks of 17 inside. @@ -483,25 +486,22 @@ ivas_error acelp_core_enc( #endif cng_params_postupd_ivas_fx( st->hTdCngEnc->ho_circ_ptr, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf, st->hTdCngEnc->cng_Qexc_buf, st->hTdCngEnc->cng_brate_buf, st->hTdCngEnc->ho_env_circ_fx, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 q_inp; floatToFixed_arr( Aq, Aq_fx, NB_SUBFR16k * ( M + 1 ), Q12 ); - q_inp = Q_factor_arr( inp, st->L_frame ); - floatToFixed_arr( inp, inp_fx, q_inp, st->L_frame ); floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); - floatToFixed_arr( st->hTdCngEnc->exc_mem2, st->hTdCngEnc->exc_mem2_fx, q_inp, 30 ); + floatToFixed_arr( st->hTdCngEnc->exc_mem2, st->hTdCngEnc->exc_mem2_fx, Q_new - 1, 30 ); for ( i = 0; i < M; i++ ) { lsf_new_fx[i] = (Word16) ( lsf_new[i] * 2.56f ); } #endif /* encode CNG parameters */ - CNG_enc_ivas_fx( st, Aq_fx, inp_fx, /*ener_fx,*/ lsp_mid_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, q_inp, q_env_fx, &sid_bw ); + CNG_enc_ivas_fx( st, Aq_fx, inp_fx, /*ener_fx,*/ lsp_mid_fx, lsp_new_fx, lsf_new_fx, &allow_cn_step, sub( Q_new, 1 ), q_env_fx, &sid_bw ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS fixedToFloat_arr( Aq_fx, Aq, Q12, NB_SUBFR16k * ( M + 1 ) ); fixedToFloat_arr( lsp_new_fx, lsp_new, Q15, M ); fixedToFloat_arrL32( q_env_fx, q_env, Q6, NUM_ENV_CNG ); - fixedToFloat_arr( st->hTdCngEnc->exc_mem2_fx, st->hTdCngEnc->exc_mem2, q_inp, 30 ); + fixedToFloat_arr( st->hTdCngEnc->exc_mem2_fx, st->hTdCngEnc->exc_mem2, Q_new - 1, 30 ); for ( i = 0; i < M; i++ ) { lsf_new[i] = ( (float) lsf_new_fx[i] / 2.56f ); @@ -519,8 +519,8 @@ ivas_error acelp_core_enc( // Word16 Q_exc_l = Q_factor_arr( st->hTdCngEnc->exc_mem, 24 ); // Word16 Q_exc1_l = Q_factor_arr( st->hTdCngEnc->exc_mem1, 30 ); // Q_exc_l = min( Q_exc_l, Q_exc1_l ); - floatToFixed_arr( st->hTdCngEnc->exc_mem, st->hTdCngEnc->exc_mem_fx, Q_new, 24 ); - floatToFixed_arr( st->hTdCngEnc->exc_mem1, st->hTdCngEnc->exc_mem1_fx, Q_new, 30 ); + floatToFixed_arr( st->hTdCngEnc->exc_mem, st->hTdCngEnc->exc_mem_fx, Q_new - 1, 24 ); + floatToFixed_arr( st->hTdCngEnc->exc_mem1, st->hTdCngEnc->exc_mem1_fx, Q_new - 1, 30 ); #endif /* comfort noise generation */ @@ -528,17 +528,17 @@ ivas_error acelp_core_enc( //&st->hTdCngEnc->cng_ener_seed, bwe_exc, allow_cn_step, &st->hTdCngEnc->last_allow_cn_step, st->hTdCngEnc->num_ho, q_env, st->hTdCngEnc->lp_env, st->hTdCngEnc->old_env, // st->hTdCngEnc->exc_mem, st->hTdCngEnc->exc_mem1, &sid_bw, &st->hTdCngEnc->cng_ener_seed1, exc3, st->Opt_AMR_WB, EVS_MONO ); CNG_exc_fx( st->core_brate, st->L_frame, &st->hTdCngEnc->Enew_fx, &st->hTdCngEnc->cng_seed, exc_fx, exc2_fx, &st->hTdCngEnc->lp_ener_fx, st->last_core_brate, - &st->hDtxEnc->first_CNG, &st->hTdCngEnc->cng_ener_seed, bwe_exc_fx, allow_cn_step, &st->hTdCngEnc->last_allow_cn_step, sub( st->prev_Q_new, 1 ), Q_new, st->hTdCngEnc->num_ho, + &st->hDtxEnc->first_CNG, &st->hTdCngEnc->cng_ener_seed, bwe_exc_fx, allow_cn_step, &st->hTdCngEnc->last_allow_cn_step, sub( st->prev_Q_new, 1 ), sub( Q_new, 1 ), st->hTdCngEnc->num_ho, q_env_fx, st->hTdCngEnc->lp_env_fx, st->hTdCngEnc->old_env_fx, st->hTdCngEnc->exc_mem_fx, st->hTdCngEnc->exc_mem1_fx, &sid_bw, &st->hTdCngEnc->cng_ener_seed1, exc3_fx, st->Opt_AMR_WB, EVS_MONO ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS fixedToFloat_arrL( q_env_fx, q_env, Q6, NUM_ENV_CNG ); - fixedToFloat_arr( exc_fx, exc, Q_new, st->L_frame ); - fixedToFloat_arr( exc2_fx, exc2, Q_new, st->L_frame ); - fixedToFloat_arr( exc3_fx, exc3, Q_new, st->L_frame ); - fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_new, st->L_frame ); - fixedToFloat_arr( st->hTdCngEnc->exc_mem_fx, st->hTdCngEnc->exc_mem, Q_new, 24 ); - fixedToFloat_arr( st->hTdCngEnc->exc_mem1_fx, st->hTdCngEnc->exc_mem1, Q_new, 30 ); + fixedToFloat_arr( exc_fx, exc, Q_new - 1, st->L_frame ); + fixedToFloat_arr( exc2_fx, exc2, Q_new - 1, st->L_frame ); + fixedToFloat_arr( exc3_fx, exc3, Q_new - 1, st->L_frame ); + fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_new - 1, st->L_frame ); + fixedToFloat_arr( st->hTdCngEnc->exc_mem_fx, st->hTdCngEnc->exc_mem, Q_new - 1, 24 ); + fixedToFloat_arr( st->hTdCngEnc->exc_mem1_fx, st->hTdCngEnc->exc_mem1, Q_new - 1, 30 ); #endif } else @@ -627,24 +627,23 @@ ivas_error acelp_core_enc( } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 Q_syn_l, Q_exc_l; + Word16 Q_exc_l; Q_exc_l = Q_factor_arr( exc3, st->L_frame ); floatToFixed_arr( exc3, exc3_fx, Q_exc_l, st->L_frame ); - Q_syn_l = Q_factor_arr( hLPDmem->mem_syn3_flt, M ); - floatToFixed_arr( hLPDmem->mem_syn3_flt, hLPDmem->mem_syn3, Q_syn_l, M ); + floatToFixed_arr( hLPDmem->mem_syn3_flt, hLPDmem->mem_syn3, st->Q_syn, M ); floatToFixed_arr( Aq, Aq_fx, Q12, NB_SUBFR16k * ( M + 1 ) ); #endif /* synthesis at 12.8kHz sampling rate */ - syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, Q_exc_l, Q_syn_l ); + syn_12k8_fx( st->L_frame, Aq_fx, exc3_fx, syn1_fx, hLPDmem->mem_syn3, 1, Q_exc_l, st->Q_syn ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS fixedToFloat_arr( Aq_fx, Aq, Q12, NB_SUBFR16k * ( M + 1 ) ); fixedToFloat_arr( exc3_fx, exc, Q_exc_l, st->L_frame ); - fixedToFloat_arr( hLPDmem->mem_syn3, hLPDmem->mem_syn3_flt, Q_syn_l, M ); - fixedToFloat_arr( syn1_fx, syn1, Q_syn_l, st->L_frame ); + fixedToFloat_arr( hLPDmem->mem_syn3, hLPDmem->mem_syn3_flt, st->Q_syn, M ); + fixedToFloat_arr( syn1_fx, syn1, st->Q_syn, st->L_frame ); #endif /* reset the encoder */ @@ -667,44 +666,33 @@ ivas_error acelp_core_enc( { #ifdef IVAS_FLOAT_FIXED_CONVERSIONS Word16 old_syn_12k8_16k_fx[L_FRAME16k]; - Word16 Q_syn1_l = Q_factor_arr( syn1, st->L_frame ); - Word16 Q_old_syn_l = Q_factor_arr( st->hBWE_FD->old_syn_12k8_16k, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - Q_syn1_l = min( Q_syn1_l, Q_old_syn_l ); - Word16 Q_deemph_l = Q_factor( st->hBWE_FD->mem_deemph_old_syn ); - Q_syn1_l = min( Q_syn1_l, Q_deemph_l ); - // Q_syn1_l = sub( Q_syn1_l, 1 ); - st->hBWE_FD->mem_deemph_old_syn_fx = float_to_fix16_thrld( st->hBWE_FD->mem_deemph_old_syn, Q_syn1_l ); - floatToFixed_arr( syn1, syn1_fx, Q_syn1_l, st->L_frame ); - floatToFixed_arr( st->hBWE_FD->old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, Q_syn1_l, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + st->hBWE_FD->mem_deemph_old_syn_fx = float_to_fix16_thrld( st->hBWE_FD->mem_deemph_old_syn, st->Q_syn ); + floatToFixed_arr( syn1, syn1_fx, st->Q_syn, st->L_frame ); + floatToFixed_arr( st->hBWE_FD->old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k_fx, st->Q_syn, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); #endif // save_old_syn( st->L_frame, syn1, old_syn_12k8_16k, st->hBWE_FD->old_syn_12k8_16k, st->preemph_fac_flt, &st->hBWE_FD->mem_deemph_old_syn ); save_old_syn_fx( st->L_frame, syn1_fx, old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k_fx, st->preemph_fac, &st->hBWE_FD->mem_deemph_old_syn_fx ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( syn1_fx, syn1, Q_syn1_l, st->L_frame ); - fixedToFloat_arr( old_syn_12k8_16k_fx, old_syn_12k8_16k, Q_syn1_l, st->L_frame ); - st->hBWE_FD->mem_deemph_old_syn = fix16_to_float( st->hBWE_FD->mem_deemph_old_syn_fx, Q_syn1_l ); - fixedToFloat_arr( st->hBWE_FD->old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k, Q_syn1_l, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + fixedToFloat_arr( syn1_fx, syn1, st->Q_syn, st->L_frame ); + fixedToFloat_arr( old_syn_12k8_16k_fx, old_syn_12k8_16k, st->Q_syn, st->L_frame ); + st->hBWE_FD->mem_deemph_old_syn = fix16_to_float( st->hBWE_FD->mem_deemph_old_syn_fx, st->Q_syn ); + fixedToFloat_arr( st->hBWE_FD->old_syn_12k8_16k_fx, st->hBWE_FD->old_syn_12k8_16k, st->Q_syn, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); st->preemph_fac_flt = fix16_to_float( st->preemph_fac, Q15 ); #endif } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 /* Q_syn_l, */ Q_lpd_syn_l; - Q_syn_l = Q_factor_arr( syn1, st->L_frame ); - Q_lpd_syn_l = Q_factor_arr( hLPDmem->syn_flt, ( M + 1 ) ); - Q_syn_l = min( Q_syn_l, Q_lpd_syn_l ); - - floatToFixed_arr( syn1, syn1_fx, Q_syn_l, st->L_frame ); - floatToFixed_arr( hLPDmem->syn_flt, hLPDmem->syn, Q_syn_l, ( M + 1 ) ); + floatToFixed_arr( syn1, syn1_fx, st->Q_syn, st->L_frame ); + floatToFixed_arr( hLPDmem->syn_flt, hLPDmem->syn, st->Q_syn, ( M + 1 ) ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); #endif /*Update MODE2 core switching memory*/ // deemph( syn1, st->preemph_fac_flt, st->L_frame, &( hLPDmem->syn_flt[M] ) ); deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( syn1_fx, syn1, Q_syn_l, st->L_frame ); - fixedToFloat_arr( hLPDmem->syn, hLPDmem->syn_flt, Q_syn_l, ( M + 1 ) ); + fixedToFloat_arr( syn1_fx, syn1, st->Q_syn, st->L_frame ); + fixedToFloat_arr( hLPDmem->syn, hLPDmem->syn_flt, st->Q_syn, ( M + 1 ) ); #endif mvr2r( syn1 + st->L_frame - M - 1, hLPDmem->syn_flt, M + 1 ); } @@ -729,13 +717,13 @@ ivas_error acelp_core_enc( IF( st->hLPDmem ) { st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); - f2me_buf_16( &st->hLPDmem->mem_syn_flt[-1], &st->hLPDmem->mem_syn[-1], &st->hLPDmem->e_mem_syn, M + 1 ); // -1 to sync the exponent of mem_syn with mem_w0 + floatToFixed_arr( &st->hLPDmem->mem_syn_flt[-1], &st->hLPDmem->mem_syn[-1], Q_new - 1, M + 1 ); // -1 to sync the exponent of mem_syn with mem_w0 } floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); st->clip_var_fx[0] = (Word16) ( st->clip_var[0] * 2.56f ); st->clip_var_fx[1] = float_to_fix16( st->clip_var[1], Q14 ); - st->clip_var_fx[2] = float_to_fix16( st->clip_var[2], Q7 ); + st->clip_var_fx[2] = float_to_fix16( st->clip_var[2], Q8 ); st->clip_var_fx[3] = float_to_fix16( st->clip_var[3], 0 ); st->clip_var_fx[4] = float_to_fix16( st->clip_var[4], Q14 ); st->clip_var_fx[5] = float_to_fix16( st->clip_var[5], Q14 ); @@ -744,14 +732,14 @@ ivas_error acelp_core_enc( IF( tdm_lsfQ_PCh ) tdm_lsfQ_PCh_fx[idx] = (Word16) ( tdm_lsfQ_PCh[idx] * 2.56f ); } - Q_old_bwe_exc = Q_factor_arr( old_bwe_exc, 1380 ); - floatToFixed_arr( old_bwe_exc, old_bwe_exc_fx, Q_old_bwe_exc, 1380 ); - Q_exc = Q_factor_arr( old_exc_flt, st->L_frame ); + // Q_old_bwe_exc = Q_factor_arr( old_bwe_exc, 1380 ); + floatToFixed_arr( old_bwe_exc, old_bwe_exc_fx, Q_new, 1380 ); + /*Q_exc = Q_factor_arr( old_exc_flt, st->L_frame ); hLPDmem->e_old_exc = Q_factor_arr( &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ) - 1; - Q_exc = s_min( Q_exc, hLPDmem->e_old_exc ); - hLPDmem->e_old_exc = Q15 - Q_exc; - floatToFixed_arr( &hLPDmem->old_exc_flt[-M - 1], &hLPDmem->old_exc[-M - 1], Q15 - hLPDmem->e_old_exc, L_EXC_MEM + M + 1 ); - floatToFixed_arr16( old_exc_flt, old_exc_fx, Q_exc, st->L_frame ); + Q_exc = min(s_min( Q_exc, hLPDmem->e_old_exc ), Q_new); + hLPDmem->e_old_exc = Q15 - Q_exc;*/ + floatToFixed_arr( &hLPDmem->old_exc_flt[-M - 1], &hLPDmem->old_exc[-M - 1], Q_new, L_EXC_MEM + M + 1 ); + floatToFixed_arr( old_exc_flt, old_exc_fx, Q_new, st->L_frame ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); @@ -874,8 +862,9 @@ ivas_error acelp_core_enc( /* Prepare ACB memory from last HQ frame */ tmpF_fx = hLPDmem->old_exc[0]; PREEMPH_FX( hLPDmem->old_exc, st->preemph_fac, st->L_frame, &tmpF_fx ); - hLPDmem->e_mem_syn = hLPDmem->e_old_exc; + // hLPDmem->e_mem_syn = hLPDmem->e_old_exc; Copy( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M ); + // Copy_Scale_sig( hLPDmem->old_exc + sub( st->L_frame, M ), hLPDmem->mem_syn, M, sub( Q_new, st->prev_Q_new ) ); Residu3_fx( Aq_fx, hLPDmem->old_exc, old_exc_fx, st->L_frame, 0 ); } @@ -891,7 +880,7 @@ ivas_error acelp_core_enc( { lerp( old_exc_fx, old_bwe_exc_fx, L_EXC_MEM_DEC * 2, L_EXC_MEM_DEC ); } - Q_old_bwe_exc = Q_exc; + // Q_old_bwe_exc = Q_exc; move16(); } @@ -913,7 +902,7 @@ ivas_error acelp_core_enc( IF( EQ_16( st->coder_type, TRANSITION ) ) { - tc_classif_enc_fx( Q_new + 1, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); + tc_classif_enc_fx( Q_new, st->L_frame, &tc_subfr, &position, attack_flag, st->pitch[0], res_fx ); config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 1, NULL, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } @@ -925,214 +914,138 @@ ivas_error acelp_core_enc( IF( nb_bits > 0 ) { - Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new + 1 ); + Es_pred_enc_fx( &Es_pred_fx, &i, st->L_frame, res_fx, st->voicing_fx, nb_bits, uc_two_stage_flag, Q_new ); push_indice( hBstr, IND_ES_PRED, i, nb_bits ); } /*------------------------------------------------------------* * Encode excitation according to coding type *------------------------------------------------------------*/ - Word16 Q_exc2 = add( Q_new, 1 ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 shift; + shift = 0; + move16(); +#endif + test(); + test(); IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ { IF( LE_16( st->coder_type, UNVOICED ) ) { - tdm_low_rate_enc( st, Aq_fx, res_fx, syn_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, &Q_exc2 ); + tdm_low_rate_enc( st, Aq_fx, res_fx, syn_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, 0 /*attack_flag*/, lsf_new_fx, &tmp_noise_fx, Q_new ); } ELSE /* GENERIC */ { - encod_gen_2sbfr( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, &Q_exc2 ); + encod_gen_2sbfr( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new ); } } ELSE IF( nelp_mode ) { /* SC-VBR - NELP frames */ - encod_nelp_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, Q_new, 0 ); - } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); - - st->clip_var[0] = (float) st->clip_var_fx[0] / 2.56f; - st->clip_var[1] = fix16_to_float( st->clip_var_fx[1], Q14 ); - st->clip_var[2] = fix16_to_float( st->clip_var_fx[2], Q7 ); - st->clip_var[3] = fix16_to_float( st->clip_var_fx[3], 0 ); - st->clip_var[4] = fix16_to_float( st->clip_var_fx[4], Q14 ); - st->clip_var[5] = fix16_to_float( st->clip_var_fx[5], Q14 ); - - for ( int ii = 0; ii < M; ii++ ) - { - mem_AR[ii] = (float) mem_AR_fx[ii] / 2.56f; - mem_MA[ii] = (float) mem_MA_fx[ii] / 2.56f; - } - fixedToFloat_arr( lsp_new_bck_fx, lsp_new_bck, Q15, M ); - fixedToFloat_arr( lsp_mid_bck_fx, lsp_mid_bck, Q15, M ); - me2f_buf_16( mem_syn_bck_fx, st->hLPDmem->e_mem_syn, mem_syn_bck, M ); - fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); - fixedToFloat_arr( lsp_mid_fx, lsp_mid, 15, M ); - for ( i = 0; i < M; i++ ) - { - - lsf_new[i] = lsf_new_fx[i] / 2.56f; - } - fixedToFloat_arrL( st->Bin_E_old_fx, st->Bin_E_old, q_comm_Bin, 128 ); - fixedToFloat_arrL( st->Bin_E_fx, st->Bin_E, q_comm_Bin, 256 ); - st->clip_var[0] = st->clip_var_fx[0] / 2.56f; - fixedToFloat_arr( &st->clip_var_fx[1], &st->clip_var[1], Q14, 5 ); - for ( i = 0; i < NB_SUBFR16k; i++ ) - { - // Array is getting modified in chunks of 17 inside. - // So each chunk might have a different Q which is predicted by 1st element. - fixedToFloat_arr( &Aq_fx[i * ( M + 1 )], &Aq[i * ( M + 1 )], 14 - norm_s( Aq_fx[i * ( M + 1 )] ), ( M + 1 ) ); + encod_nelp_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, &tmp_noise_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, Q_new, shift ); } - fixedToFloat_arr( old_exc_fx, old_exc_flt, Q15 - hLPDmem->e_old_exc, st->L_frame ); - me2f_buf_16( &hLPDmem->old_exc[-M - 1], hLPDmem->e_old_exc, &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1 ); - fixedToFloat_arr( old_bwe_exc_fx, old_bwe_exc, Q_old_bwe_exc, 1380 ); - fixedToFloat_arr( res_fx, res, Q_new + 1, st->L_frame ); - Es_pred = fix16_to_float( Es_pred_fx, Q8 ); - - me2f_buf_16( &st->hLPDmem->mem_w0, st->hLPDmem->e_mem_syn, &st->hLPDmem->mem_w0_flt, M + 1 ); - fixedToFloat_arr( exc_fx, exc, Q_exc, L_FRAME ); - fixedToFloat_arr( exc2_fx, exc2, Q_exc, L_FRAME16k ); - if ( st->hBWE_TD ) - fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_exc, L_FRAME32k ); - st->hGSCEnc->Last_frame_ener = fixedToFloat_32( st->hGSCEnc->Last_frame_ener_fx, Q4 ); - me2f_buf_16( st->hGSCEnc->last_exc_dct_in_fx, Q15 - st->hGSCEnc->Q_last_exc_dct_in, st->hGSCEnc->last_exc_dct_in, L_FRAME16k ); - fixedToFloat_arr( syn_fx, syn, Q_exc2, L_FRAME16k ); - fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, NB_SUBFR16k ); - fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR ); - tmp_noise = fix16_to_float( tmp_noise_fx, Q8 ); - IF( st->hLPDmem ) - st->hLPDmem->tilt_code_flt = fix16_to_float( st->hLPDmem->tilt_code, Q15 ); #endif -#endif - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ - { - } - else if ( nelp_mode ) - { - } - else if ( st->coder_type == UNVOICED ) + ELSE IF( EQ_16( st->coder_type, UNVOICED ) ) { /* UNVOICED frames (Gauss. excitation) */ - encod_unvoiced( st, inp, Aw, Aq, Es_pred, uc_two_stage_flag, res, syn, &tmp_noise, exc, pitch_buf, voice_factors, bwe_exc ); + // encod_unvoiced( st, inp, Aw, Aq, Es_pred, uc_two_stage_flag, res, syn, &tmp_noise, exc, pitch_buf, voice_factors, bwe_exc ); + encod_unvoiced_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, Es_pred_fx, uc_two_stage_flag, res_fx, syn_fx, &tmp_noise_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, Q_new, shift ); } - else if ( st->coder_type == TRANSITION ) + ELSE IF( EQ_16( st->coder_type, TRANSITION ) ) { - encod_tran( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tc_subfr, position, unbits ); + // encod_tran( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, tc_subfr, position, unbits ); + encod_tran_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, tc_subfr, position, unbits, shift, Q_new ); } - else if ( ppp_mode ) + ELSE IF( ppp_mode ) { /* SC-VBR - PPP frames */ -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 shift; - shift = 0; - move16(); -#endif IF( ( error = encod_ppp_fx( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, Q_new, shift ) ) != IVAS_ERR_OK ) { return error; } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( i = 0; i < NB_SUBFR16k; i++ ) - { - // Array is getting modified in chunks of 17 inside. - // So each chunk might have a different Q which is predicted by 1st element. - fixedToFloat_arr( &Aq_fx[i * ( M + 1 )], &Aq[i * ( M + 1 )], 14 - norm_s( Aq_fx[i * ( M + 1 )] ), ( M + 1 ) ); - } - fixedToFloat_arr( res_fx, res, Q_new + 1, st->L_frame ); - fixedToFloat_arr( syn_fx, syn, Q_exc2, L_FRAME16k ); - fixedToFloat_arr( exc_fx, exc, Q_exc, L_FRAME ); - fixedToFloat_arr( exc2_fx, exc2, Q_exc, L_FRAME16k ); - fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR ); - fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, NB_SUBFR16k ); - if ( st->hBWE_TD ) - { - fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_exc, L_FRAME32k ); - } -#endif -#else - if ( ( error = encod_ppp( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif - if ( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ + IF( st->hSC_VBR->bump_up ) /* PPP failed, bump up */ { /* restore memories of LSF quantizer and synthesis filter */ -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - floatToFixed_arr( lsp_new_bck, lsp_new_bck_fx, Q15, M ); - floatToFixed_arr( lsp_mid_bck, lsp_mid_bck_fx, Q15, M ); - q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, L_FFT / 2 ), Q_factor_arrL( st->Bin_E, L_FFT ) ); - floatToFixed_arrL( Bin_E, Bin_E_fx, q_comm_Bin, L_FFT ); - floatToFixed_arrL( Bin_E_old, Bin_E_old_fx, q_comm_Bin, L_FFT / 2 ); - Word16 mem_syn = Q_factor_arr( mem_syn_bck, M ); - floatToFixed_arr( mem_syn_bck, mem_syn_bck_fx, mem_syn, M ); - for ( i = 0; i < M; i++ ) - { - mem_AR_fx[i] = (Word16) ( mem_AR[i] * 2.56f ); - mem_MA_fx[i] = (Word16) ( mem_MA[i] * 2.56f ); - } -#endif lsf_syn_mem_restore_ivas_fx( st, tilt_code_bck_fx, gc_threshold_bck_fx, clip_var_bck_fx, next_force_sf_bck, lsp_new_fx, lsp_mid_fx, clip_var_fx, mem_AR_fx, mem_MA_fx, lsp_new_bck_fx, lsp_mid_bck_fx, Bin_E_fx, Bin_E_old_fx, mem_syn_bck_fx, mem_w0_bck_fx, streaklimit_fx, pstreaklen ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st->hLPDmem->tilt_code_flt = fix16_to_float( st->hLPDmem->tilt_code, Q15 ); - st->clip_var[0] = st->clip_var_fx[0] / 2.56f; - st->clip_var[1] = fix16_to_float( st->clip_var_fx[1], Q14 ); - st->clip_var[2] = fix16_to_float( st->clip_var_fx[2], Q7 ); - st->clip_var[3] = fix16_to_float( st->clip_var_fx[3], 0 ); - st->clip_var[4] = fix16_to_float( st->clip_var_fx[4], Q14 ); - st->clip_var[5] = fix16_to_float( st->clip_var_fx[5], Q14 ); - fixedToFloat_arr( lsp_new_fx, lsp_new, Q15, M ); - fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); - fixedToFloat_arrL( st->Bin_E_fx, st->Bin_E, q_comm_Bin, L_FFT ); - fixedToFloat_arrL( st->Bin_E_old_fx, st->Bin_E_old, q_comm_Bin, L_FFT / 2 ); - fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, mem_syn, M ); - st->hLPDmem->mem_w0_flt = me2f( st->hLPDmem->mem_w0, st->hLPDmem->e_mem_syn ); -#endif -#else - lsf_syn_mem_restore( st, tilt_code_bck, gc_threshold_bck, clip_var_bck, next_force_sf_bck, lsp_new, lsp_mid, clip_var, mem_AR, mem_MA, lsp_new_bck, lsp_mid_bck, Bin_E, Bin_E_old, mem_syn_bck, mem_w0_bck, streaklimit, pstreaklen ); -#endif /* Configure ACELP bit allocation */ config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); /* redo LSF quantization */ -#ifdef IVAS_FLOAT_FIXED lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, tdm_low_rate_mode, 0, NULL, Q_new ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( i = 0; i < M; i++ ) - { - - lsf_new[i] = lsf_new_fx[i] / 2.56f; - } - fixedToFloat_arr( Aq_fx, Aq, 12, NB_SUBFR16k * ( M + 1 ) ); - fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); -#endif -#else - lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL ); -#endif /* recalculation of LP residual (filtering through A[z] filter) */ - calc_residu( inp, res, Aq, st->L_frame ); + // calc_residu( inp, res, Aq, st->L_frame ); + calc_residu_fx( st, inp_fx, res_fx, Aq_fx ); st->hTdCngEnc->burst_ho_cnt = 0; /* VOICED frames in SC-VBR */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + // encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + encod_gen_voic_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, shift, Q_new ); } } - else if ( st->coder_type == AUDIO || ( st->coder_type == INACTIVE && st->inactive_coder_type_flag ) ) + ELSE IF( EQ_16( st->coder_type, AUDIO ) || ( EQ_16( st->coder_type, INACTIVE ) && st->inactive_coder_type_flag ) ) { /* AUDIO and INACTIVE frames (coded by GSC technology) */ - encod_audio( st, inp, Aw, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, attack_flag, lsf_new, &tmp_noise, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + // encod_audio( st, inp, Aw, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, attack_flag, lsf_new, &tmp_noise, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + encod_audio_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, res_fx, syn_fx, exc_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, attack_flag, lsf_new_fx, &tmp_noise_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, Q_new, shift ); } - else + ELSE { /* GENERIC, VOICED and INACTIVE frames (coded by AVQ technology) */ - encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + // encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + + encod_gen_voic_ivas_fx( st, inp_fx, Aw_fx, Aq_fx, Es_pred_fx, res_fx, syn_fx, exc_fx, exc2_fx, pitch_buf_fx, voice_factors_fx, bwe_exc_fx, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf_fx, shift, Q_new ); } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); + + st->clip_var[0] = (float) st->clip_var_fx[0] / 2.56f; + st->clip_var[1] = fix16_to_float( st->clip_var_fx[1], Q14 ); + st->clip_var[2] = fix16_to_float( st->clip_var_fx[2], Q8 ); + st->clip_var[3] = fix16_to_float( st->clip_var_fx[3], 0 ); + st->clip_var[4] = fix16_to_float( st->clip_var_fx[4], Q14 ); + st->clip_var[5] = fix16_to_float( st->clip_var_fx[5], Q14 ); + + fixedToFloat_arr( lsp_new_bck_fx, lsp_new_bck, Q15, M ); + fixedToFloat_arr( lsp_mid_bck_fx, lsp_mid_bck, Q15, M ); + fixedToFloat_arr( mem_syn_bck_fx, mem_syn_bck, Q_new, M ); + fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); + fixedToFloat_arr( lsp_mid_fx, lsp_mid, 15, M ); + for ( i = 0; i < M; i++ ) + { + + lsf_new[i] = lsf_new_fx[i] / 2.56f; + } + fixedToFloat_arrL( st->Bin_E_old_fx, st->Bin_E_old, q_comm_Bin, 128 ); + fixedToFloat_arrL( st->Bin_E_fx, st->Bin_E, q_comm_Bin, 256 ); + for ( i = 0; i < NB_SUBFR16k; i++ ) + { + // Array is getting modified in chunks of 17 inside. + // So each chunk might have a different Q which is predicted by 1st element. + fixedToFloat_arr( &Aq_fx[i * ( M + 1 )], &Aq[i * ( M + 1 )], 14 - norm_s( Aq_fx[i * ( M + 1 )] ), ( M + 1 ) ); + } + fixedToFloat_arr( old_exc_fx, old_exc_flt, Q_new, st->L_frame ); + // me2f_buf_16(&hLPDmem->old_exc[-M - 1], hLPDmem->e_old_exc, &hLPDmem->old_exc_flt[-M - 1], L_EXC_MEM + M + 1); + fixedToFloat_arr( &hLPDmem->old_exc[-M - 1], &hLPDmem->old_exc_flt[-M - 1], Q_new, L_EXC_MEM + M + 1 ); + fixedToFloat_arr( old_bwe_exc_fx, old_bwe_exc, Q_new, 1380 ); + fixedToFloat_arr( res_fx, res, Q_new, st->L_frame ); + Es_pred = fix16_to_float( Es_pred_fx, Q8 ); + + fixedToFloat_arr( st->hLPDmem->mem_syn, st->hLPDmem->mem_syn_flt, Q_new - 1, M ); + st->hLPDmem->mem_w0_flt = fixedToFloat( st->hLPDmem->mem_w0, Q_new - 1 ); + fixedToFloat_arr( exc_fx, exc, Q_new, L_FRAME16k + 1 ); + fixedToFloat_arr( exc2_fx, exc2, Q_new, L_FRAME16k ); + if ( st->hBWE_TD ) + fixedToFloat_arr( bwe_exc_fx, bwe_exc, Q_new, L_FRAME32k ); + st->hGSCEnc->Last_frame_ener = fixedToFloat_32( st->hGSCEnc->Last_frame_ener_fx, Q4 ); + me2f_buf_16( st->hGSCEnc->last_exc_dct_in_fx, Q15 - st->hGSCEnc->Q_last_exc_dct_in, st->hGSCEnc->last_exc_dct_in, L_FRAME16k ); + fixedToFloat_arr( syn_fx, syn, Q_new - 1, L_FRAME16k ); + fixedToFloat_arr( voice_factors_fx, voice_factors, Q15, NB_SUBFR16k ); + fixedToFloat_arr( pitch_buf_fx, pitch_buf, Q6, NB_SUBFR16k ); + st->hLPDmem->tilt_code_flt = fix16_to_float( st->hLPDmem->tilt_code, Q15 ); +#endif /* update mem_syn1_flt for ACELP core switching */ mvr2r( hLPDmem->mem_syn_flt, hLPDmem->mem_syn1_flt, M ); @@ -1170,21 +1083,16 @@ ivas_error acelp_core_enc( /*Update MODE2 core switching memory*/ mvr2r( syn, syn1, st->L_frame ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 Q_syn_l, Q_lpd_syn_l; - Q_syn_l = Q_factor_arr( syn1, st->L_frame ); - Q_lpd_syn_l = Q_factor_arr( hLPDmem->syn_flt, ( M + 1 ) ); - Q_syn_l = min( Q_syn_l, Q_lpd_syn_l ); - - floatToFixed_arr( syn1, syn1_fx, Q_syn_l, st->L_frame ); - floatToFixed_arr( hLPDmem->syn_flt, hLPDmem->syn, Q_syn_l, ( M + 1 ) ); + floatToFixed_arr( syn1, syn1_fx, st->Q_syn, st->L_frame ); + floatToFixed_arr( hLPDmem->syn_flt, hLPDmem->syn, st->Q_syn, ( M + 1 ) ); st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); #endif /*Update MODE2 core switching memory*/ deemph_fx( syn1_fx, st->preemph_fac, st->L_frame, &( hLPDmem->syn[M] ) ); // deemph( syn1, st->preemph_fac_flt, st->L_frame, &( hLPDmem->syn_flt[M] ) ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( syn1_fx, syn1, Q_syn_l, st->L_frame ); - fixedToFloat_arr( hLPDmem->syn, hLPDmem->syn_flt, Q_syn_l, ( M + 1 ) ); + fixedToFloat_arr( syn1_fx, syn1, st->Q_syn, st->L_frame ); + fixedToFloat_arr( hLPDmem->syn, hLPDmem->syn_flt, st->Q_syn, ( M + 1 ) ); #endif mvr2r( syn1 + st->L_frame - M - 1, hLPDmem->syn_flt, M + 1 ); @@ -1206,7 +1114,7 @@ ivas_error acelp_core_enc( #else #ifdef IVAS_FLOAT_FIXED_CONVERSIONS // conv params from float to fix - Q_exc2 = Q_factor_arr( exc2, L_FRAME ); + Word16 Q_exc2 = Q_factor_arr( exc2, L_FRAME ); #ifndef MSAN_FIX floatToFixed_arr( exc2, exc2_fx, Q_exc2, L_FRAME16k ); #else @@ -1362,9 +1270,7 @@ ivas_error acelp_core_enc( lsf_new_fx[i] = (Word16) ( lsf_new[i] * 2.56f ); }; - Word16 q_old_exc = Q_factor_arr( old_exc_flt, L_EXC ); - floatToFixed_arr16( old_exc_flt, old_exc_fx, q_old_exc, L_EXC ); - st->hLPDmem->e_old_exc = sub( 15, q_old_exc ); + floatToFixed_arr( old_exc_flt, old_exc_fx, Q_new, L_EXC ); Word16 q_old_bwe_exc = 0; IF( st->hBWE_TD != NULL ) @@ -1383,7 +1289,7 @@ ivas_error acelp_core_enc( updt_enc_fx( st, old_exc_fx, pitch_buf_fx, Es_pred_fx, Aq_fx, lsf_new_fx, lsp_new_fx, old_bwe_exc_fx ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, q_old_exc, L_EXC_MEM ); + fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, Q_new, L_EXC_MEM ); IF( !st->Opt_AMR_WB && st->hBWE_TD != NULL ) { fixedToFloat_arr( st->hBWE_TD->old_bwe_exc_fx, st->hBWE_TD->old_bwe_exc, q_old_bwe_exc, PIT16k_MAX * 2 ); @@ -1468,7 +1374,9 @@ ivas_error acelp_core_enc( #endif } } - +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->prev_Q_new = Q_new; +#endif pop_wmops(); return error; diff --git a/lib_enc/acelp_enc_util_fx.c b/lib_enc/acelp_enc_util_fx.c index ffdf837c4ee090fe1ff596ceb0a61a9e3395b058..f7f1d45b681dcf87fe46e3fd1fd87c214e60220d 100644 --- a/lib_enc/acelp_enc_util_fx.c +++ b/lib_enc/acelp_enc_util_fx.c @@ -197,6 +197,35 @@ void E_ACELP_conv( } } +void E_ACELP_conv_ivas( + const Word16 xn2[], /* i */ + const Word16 h2[], /* i */ + Word16 cn2[] /* o */ +) +{ + Word16 i, k; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + FOR( k = 0; k < L_SUBFR; k++ ) + { + /*cn2[k] = xn2[k]; */ + Word64 L_tmp_64; + L_tmp_64 = W_deposit32_l( L_mult0( xn2[k], 0x800 ) ); + FOR( i = 0; i < k; i++ ) + { + /*cn2[k]-=cn2[i]*h2[k-i];*/ + L_tmp_64 = W_msu0_16_16( L_tmp_64, cn2[i], h2[k - i] ); /*h2 4Q11*/ + } + L_tmp = W_sat_l( L_tmp_64 ); +#ifdef BASOP_NOGLOB + cn2[k] = round_fx_o( L_shl_o( L_tmp, 5, &Overflow ), &Overflow ); +#else + cn2[k] = round_fx( L_shl( L_tmp, 5 ) ); +#endif + } +} void E_ACELP_build_code( Word16 nb_pulse, /* i */ const Word16 codvec[], /* i */ diff --git a/lib_enc/avq_cod_fx.c b/lib_enc/avq_cod_fx.c index ece84e4e95cd46448e961427e032bc582020773f..c303d9ea5dee43cc0b22f622694ce04e6270df7b 100644 --- a/lib_enc/avq_cod_fx.c +++ b/lib_enc/avq_cod_fx.c @@ -16,6 +16,7 @@ * Local prototypes *-------------------------------------------------------------------*/ static void wrte_cv( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits ); +static void wrte_cv_ivas( BSTR_ENC_HANDLE hBstr, const Word16 nq, const Word16 i_ind, const Word16 kv_ind, UWord16 I, Word16 kv[], Word16 *bits ); /*-------------------------------------------------------------------* * Function AVQ_cod() * @@ -408,7 +409,7 @@ void AVQ_encmux_fx( bits = sub( bits, 1 ); } - wrte_cv( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[shl( k, 3 )], &bits ); + wrte_cv( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[k * 8], &bits ); } } /* for */ /* Bit Saving Solution */ @@ -545,7 +546,7 @@ void AVQ_encmux_fx( move16(); /* write codebook indices (rank I and event. Voronoi index kv) */ - wrte_cv( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[shl( i, 3 )], &bits ); + wrte_cv( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[i * 8], &bits ); bits = sub( bits, dummy_bits ); @@ -566,6 +567,437 @@ void AVQ_encmux_fx( return; } +void AVQ_encmux_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 extl, /* i : extension layer */ + Word16 xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed + by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ + Word16 *nb_bits, /* i/o: number of allocated bits */ + const Word16 Nsv, /* i: number of subvectors */ + Word16 nq_out[], /* o : AVQ nq index */ + Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution */ + Word16 trgtSvPos /* i : target SV for AVQ bit savings */ +) +{ + Word16 i, j = 0, bits, pos, pos_max, overflow, pos_tmp, bit_tmp; + Word16 sort_idx[NSV_MAX], nq[NSV_MAX], kv[NSV_MAX * 8]; + Word16 *t; + UWord16 I[NSV_MAX]; + Word16 nq_ind, i_ind, kv_ind; + Word16 nq_est, unused_bits, unused_bits_idx; + Word16 bitsMod, Nsvm1, Nsvm2; + Word16 unusedbitsFlag; + Word16 svOrder[NSV_MAX], k, nullVec, dummy_bits; + Word16 tmp; + + test(); + IF( EQ_16( extl, SWB_BWE_HIGHRATE ) || EQ_16( extl, FB_BWE_HIGHRATE ) ) + { + nq_ind = IND_NQ2; + move16(); + i_ind = IND_I2; + move16(); + kv_ind = IND_KV2; + move16(); + } + ELSE + { + nq_ind = IND_NQ; + move16(); + i_ind = IND_I; + move16(); + kv_ind = IND_KV; + move16(); + } + + FOR( i = 0; i < NSV_MAX; i++ ) + { + I[i] = (UWord16) -1; + move16(); + } + unusedbitsFlag = 0; + bitsMod = 0; + move16(); + move16(); + /*----------------------------------------------------------------- + * Encode subvectors and fix possible overflows in total bit budget, + * i.e. find for each subvector a codebook index nq (nq=0,2,3,4,...,NSV_MAX), + * a base codebook index (I), and a Voronoi index (kv) + *-----------------------------------------------------------------*/ + + /* sort subvectors by estimated bit allocations in decreasing order */ + t = kv; + move16(); /* reuse vector to save memory */ + move16(); /*ptr init*/ + FOR( i = 0; i < Nsv; i++ ) + { + t[i] = xriq[8 * Nsv + i]; + move16(); + } + + FOR( i = 0; i < Nsv; i++ ) + { + bits = t[0]; + move16(); + pos = 0; + move16(); + FOR( j = 1; j < Nsv; j++ ) + { + if ( GT_16( t[j], bits ) ) + { + pos = j; + move16(); + } + bits = s_max( t[j], bits ); + } + sort_idx[i] = pos; + move16(); + t[pos] = -1; + move16(); + } + + /* compute multi-rate indices and avoid bit budget overflow */ + pos_max = 0; + move16(); + bits = 0; + move16(); + FOR( i = 0; i < Nsv; i++ ) + { + /* find vector to quantize (criteria: nb of estimated bits) */ + pos = sort_idx[i]; + move16(); + + /* compute multi-rate index of rounded subvector (nq,I,kv[]) */ + re8_cod_fx( &xriq[pos * 8], &nq[pos], &I[pos], &kv[8 * pos] ); + + IF( nq[pos] > 0 ) + { + j = pos_max; + move16(); + j = s_max( pos, j ); + + /* compute (number of bits -1) to describe Q #nq */ + IF( GE_16( nq[pos], 2 ) ) + { + overflow = sub( i_mult2( nq[pos], 5 ), 1 ); + } + ELSE + { + overflow = 0; + move16(); + } + + /* check for overflow and compute number of bits-1 (n) */ + IF( GT_16( add( bits, add( overflow, j ) ), *nb_bits ) ) + { + /* if budget overflow */ + pos_tmp = add( shl( pos, 3 ), 8 ); /*(pos*8)+8*/ + FOR( j = pos * 8; j < pos_tmp; j++ ) + { + xriq[j] = 0; + move16(); + } + nq[pos] = 0; + move16(); /* force Q0 */ + } + ELSE + { + bits = add( bits, overflow ); + pos_max = j; + move16(); /* update index of the last described subvector */ + } + } + } + nullVec = 0; + Nsvm1 = sub( Nsv, 1 ); + Nsvm2 = sub( Nsvm1, 1 ); + dummy_bits = 0; + svOrder[Nsvm1] = trgtSvPos; + svOrder[0] = 0; + svOrder[1] = 1; + i = 2; + j = i; + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + if ( EQ_16( avq_bit_sFlag, 2 ) ) + { + j = add( i, 1 ); + } + WHILE( LT_16( i, Nsvm1 ) ) + { + svOrder[i] = j; + move16(); + i++; /*ptr*/ + j = add( j, 1 ); + } + /* write indexes to the bitstream */ + /* ============================== */ + + bits = *nb_bits; + move16(); + overflow = 0; + move16(); + FOR( i = 0; i < Nsv; i++ ) + { + k = svOrder[i]; + move16(); + test(); + test(); + test(); + test(); + test(); + tmp = bits; + move16(); + WHILE( GE_16( tmp, 5 ) ) + { + tmp = sub( tmp, 5 ); + } + assert( tmp == bits % 5 ); + IF( EQ_16( avq_bit_sFlag, 2 ) && EQ_16( tmp, 4 ) && GT_16( bits, 8 ) && LT_16( bits, 30 ) && GE_16( k, trgtSvPos ) && LT_16( i, Nsvm1 ) ) + { + ordr_esti( sub( Nsv, i ), &trgtSvPos, &svOrder[i], Nsv ); + k = svOrder[i]; + move16(); + avq_bit_sFlag = 1; + move16(); + } + + test(); + IF( EQ_16( k, trgtSvPos ) && avq_bit_sFlag > 0 ) + { + test(); + test(); + IF( EQ_16( sub( *nb_bits, bits ), 7 ) || LT_16( bits, BIT_SAVING_LOW_THR ) || GE_16( bits, BIT_SAVING_HIGH_THR ) ) + { + avq_bit_sFlag = 0; + move16(); + } + ELSE + { + BREAK; + } + } + + if ( EQ_16( sub( i_mult2( 5, nq[k] ), 1 ), bits ) ) /* check the overflow */ + { + overflow = 1; + move16(); + } + + IF( GT_16( bits, 8 ) ) + { + /* write the unary code for nq[i] */ + j = sub( nq[k], 1 ); + IF( nq[k] > 0 ) + { + /* write the unary code */ + FOR( ; j > 16; j -= 16 ) + { + push_indice( hBstr, nq_ind, 65535, 16 ); + bits = sub( bits, 16 ); + } + + IF( j > 0 ) + { + push_indice( hBstr, nq_ind, extract_l( L_sub( L_shl( 1L, j ), 1L ) ), j ); + bits = sub( bits, j ); + } + } + IF( !overflow ) + { + /* write the stop bit */ + push_indice( hBstr, nq_ind, 0, 1 ); + bits = sub( bits, 1 ); + } + + wrte_cv_ivas( hBstr, nq[k], i_ind, kv_ind, I[k], &kv[k * 8], &bits ); + } + } /* for */ + /* Bit Saving Solution */ + test(); + IF( avq_bit_sFlag > 0 && bits > 8 ) + { + // PMT("code not validated yet") + // bitsMod = bits%5; + bitsMod = bits; + WHILE( GE_16( bitsMod, 5 ) ) + { + bitsMod = sub( bitsMod, 5 ); + } + assert( bitsMod == bits % 5 ); + i = svOrder[Nsvm1]; + move16(); + IF( NE_16( i, Nsvm1 ) ) + { + nullVec = 0; + move16(); + FOR( j = i; j < Nsv - 1; j++ ) + { + if ( nq[svOrder[j]] == 0 ) + { + nullVec = add( nullVec, 1 ); + } + } + /*nq_est = bits / 5;*/ + nq_est = mult( bits, 6554 ); + assert( nq_est == bits / 5 ); + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( bitsMod > 0 || ( EQ_16( nullVec, 4 ) && EQ_16( nq_est, 5 ) ) ) && NE_16( bitsMod, 4 ) && GE_16( add( bits, nullVec ), add( add( shl( nq_est, 2 ), nq_est ), 4 ) ) /*5 * nq_est + 4*/ && nq[svOrder[Nsvm2]] == 0 ) /* detect need for dummy bits */ + { + dummy_bits = sub( 5, bitsMod ); + bits = add( bits, dummy_bits ); /* add dummy bits */ + bitsMod = 0; + move16(); + } + ELSE IF( nq_est > 4 && ( ( bitsMod == 0 && nullVec > 3 && nullVec < 6 ) || ( bitsMod == 4 && nullVec == 5 ) ) && nq[svOrder[Nsvm2]] == 0 ) /* wasted bits 4, 5 for nq 6,7..*/ + { + overflow = 0; + move16(); + tmp = add( bitsMod, nullVec ); + WHILE( GE_16( tmp, 5 ) ) + { + tmp = sub( tmp, 5 ); + } + assert( tmp == add( bitsMod, nullVec ) % 5 ); + if ( tmp != 0 ) + { + overflow = 1; + move16(); + } + dummy_bits = add( nullVec, overflow ); + bits = add( bits, dummy_bits ); /* add dummy bits */ + bitsMod = 0; + move16(); + } + } + + overflow = 1; + move16(); + IF( NE_16( bitsMod, 4 ) ) + { + overflow = 0; + move16(); + bits = sub( bits, bitsMod ); + } + bits = add( bits, overflow ); /*add fake bit */ + unused_bits = sub( bits, add( shl( nq[i], 2 ), nq[i] ) ); + if ( nq[i] == 0 ) /*no bit savings*/ + { + unused_bits = sub( unused_bits, 1 ); /*Stop Bit*/ + } + /*unused_bits_idx = (int16_t)unused_bits / 5;*/ + IF( unused_bits >= 0 ) + { + unused_bits_idx = mult( unused_bits, 6554 ); + } + ELSE + { + unused_bits_idx = negate( mult( negate( unused_bits ), 6554 ) ); + } + assert( unused_bits_idx == unused_bits / 5 ); + unusedbitsFlag = 0; + move16(); + IF( dummy_bits == 0 ) + { + test(); + test(); + IF( EQ_16( unused_bits_idx, 1 ) && GT_16( bits, BIT_SAVING_LOW_THR ) ) + { + unused_bits_idx = 0; + unusedbitsFlag = 1; + move16(); + move16(); + } + ELSE IF( unused_bits_idx == 0 && GT_16( bits, BIT_SAVING_LOW_THR ) ) + { + unused_bits_idx = 1; + unusedbitsFlag = -1; + move16(); + move16(); + } + } + + j = unused_bits_idx; + move16(); + /*Encode Unused Bit Unary Codeword */ + IF( j > 0 ) + { + /* write the unary code */ + push_indice( hBstr, nq_ind, u_extract_l( L_sub( L_shl_sat( 1, j ), 1 ) ), j ); + assert( abs( ( 1 << j ) - 1 ) <= 65536 ); + } + + IF( nq[i] != 0 ) + { + /* write the stop bit */ + push_indice( hBstr, nq_ind, 0, 1 ); + } + + /*Compute AVQ code book number from unused Bits */ + // bit_tmp = add( unusedbitsFlag, unused_bits_idx ); + /*nq_est = (int16_t)ceil(0.2f * (bits - 5 * (unusedbitsFlag + unused_bits_idx)));*/ + // nq_est = mult( 6554, sub( bits, add( shl( bit_tmp, 2 ), bit_tmp ) ) ); + bit_tmp = sub( bits, imult1616( 5, add( unusedbitsFlag, unused_bits_idx ) ) ); + nq_est = 0; + WHILE( bit_tmp > 0 ) + { + nq_est = add( nq_est, 1 ); + bit_tmp = sub( bit_tmp, 5 ); + } + assert( (int16_t) ceil( 0.2f * ( bits - 5 * ( unusedbitsFlag + unused_bits_idx ) ) ) == nq_est ); + + if ( EQ_16( nq_est, 1 ) ) + { + nq_est = 0; + move16(); + } + bits = sub( bits, overflow ); + + bits = sub( bits, j ); + + if ( nq_est != 0 ) + { + bits = sub( bits, 1 ); + } + nq[i] = nq_est; + move16(); + + /* write codebook indices (rank I and event. Voronoi index kv) */ + wrte_cv_ivas( hBstr, nq[i], i_ind, kv_ind, I[i], &kv[i * 8], &bits ); + + bits = sub( bits, dummy_bits ); + + if ( NE_16( bitsMod, 4 ) ) + { + bits = add( bits, bitsMod ); + } + } + *nb_bits = bits; + move16(); + + FOR( i = 0; i < Nsv; i++ ) + { + nq_out[i] = nq[i]; + move16(); + } + + return; +} /*-------------------------------------------------------------------* * Function AVQ_cod_lpc_fx() * @@ -715,3 +1147,63 @@ static void wrte_cv( move16(); return; } + +static void wrte_cv_ivas( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 nq, /* i : AVQ nq index */ + const Word16 i_ind, /* i : Base Bitstream index */ + const Word16 kv_ind, /* i : Vornoi Bitstream index */ + UWord16 I, /* o : rank I code book index */ + Word16 kv[], /* o : Vornoi index kv */ + Word16 *nbits /* i/o: bits */ +) +{ + int16_t pos, j; + int16_t bits, nq4; + + bits = *nbits; + move16(); + + /* write codebook indices (rank I and event. Voronoi index kv) */ + IF( nq == 0 ) /* Q0 */ + { + /* nothing to write */ + } + ELSE IF( LT_16( nq, 5 ) ) /* Q2, Q3, Q4 */ + { + nq4 = shl( nq, 2 ); + push_indice( hBstr, i_ind, I, nq4 ); + bits = sub( bits, nq4 ); + } + ELSE IF( EQ_16( s_and( nq, 1 ), 0 ) ) /* Q4 + Voronoi extensions r=1,2,3,... */ + { + push_indice( hBstr, i_ind, I, 4 * 4 ); + bits = sub( bits, 4 * 4 ); + /*pos = (int16_t)(nq / 2 - 2);*/ /* Voronoi order determination */ + pos = sub( shr( nq, 1 ), 2 ); + FOR( j = 0; j < 8; j++ ) + { + push_indice( hBstr, kv_ind, kv[j], pos ); + } + + bits = sub( bits, shl( pos, 3 ) ); + } + ELSE /* Q3 + Voronoi extensions r=1,2,3,... */ + { + push_indice( hBstr, i_ind, I, 4 * 3 ); + bits = sub( bits, 4 * 3 ); + + /*pos = (int16_t)(nq / 2 - 1);*/ /* Voronoi order determination */ + pos = sub( shr( nq, 1 ), 1 ); + FOR( j = 0; j < 8; j++ ) + { + push_indice( hBstr, kv_ind, kv[j], pos ); + } + + bits = sub( bits, shl( pos, 3 ) ); + } + + *nbits = bits; + move16(); + return; +} diff --git a/lib_enc/cod2t32_fx.c b/lib_enc/cod2t32_fx.c index 06c4d31f0dcacd6f72b95dc16bb8afd8738254f4..04105f232b3c3e7aaddc0fc91fe535f3844e47f9 100644 --- a/lib_enc/cod2t32_fx.c +++ b/lib_enc/cod2t32_fx.c @@ -2,10 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com.h" /* Common constants */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -341,6 +341,318 @@ void acelp_2t32_fx( return; } +void acelp_2t32_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 code[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[] /* o : filtered fixed codebook excitation */ +) +{ + Word16 i, j, k, i0, i1, ix, iy, pos, pos2, sign0, sign1, index; + Word16 ps1, ps2, alpk, alp1, alp2; + Word16 sq, psk; + Word16 pol[L_SUBFR], dn_p[L_SUBFR]; + Word16 ii, jj; + Word16 *p0, *p1, *p2; + const Word16 *ptr_h1, *ptr_h2, *ptr_hf; + + Word32 s, L_cor; + Word32 L_tmp; + Word16 rrixix[NB_TRACK_FCB_2T][NB_POS_FCB_2T]; + Word16 rrixiy[MSIZE]; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + /*----------------------------------------------------------------* + * Compute rrixix[][] needed for the codebook search. + *----------------------------------------------------------------*/ + + /* Init pointers to last position of rrixix[] */ + p0 = &rrixix[0][NB_POS_FCB_2T - 1]; + move16(); + p1 = &rrixix[1][NB_POS_FCB_2T - 1]; + move16(); + + ptr_h1 = h; + move16(); + L_cor = L_deposit_h( 1 ); + FOR( i = 0; i < NB_POS_FCB_2T; i++ ) + { +#ifdef BASOP_NOGLOB + L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); +#else + L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); +#endif + ptr_h1++; + *p1-- = extract_h( L_cor ); + move16(); /*Q9 Q7*/ +#ifdef BASOP_NOGLOB + L_cor = L_mac_o( L_cor, *ptr_h1, *ptr_h1, &Overflow ); +#else + L_cor = L_mac( L_cor, *ptr_h1, *ptr_h1 ); +#endif + ptr_h1++; + *p0-- = extract_h( L_cor ); + move16(); /*Q9 Q7*/ + } + + p0 = rrixix[0]; + move16(); + p1 = rrixix[1]; + move16(); + + FOR( i = 0; i < NB_POS_FCB_2T; i++ ) + { + *p0 = shr( *p0, 1 ); + move16(); + p0++; + *p1 = shr( *p1, 1 ); + move16(); + p1++; + } + + /*------------------------------------------------------------* + * Compute rrixiy[][] needed for the codebook search. + *------------------------------------------------------------*/ + + pos = MSIZE - 1; + move16(); + pos2 = MSIZE - 2; + move16(); + ptr_hf = h + 1; + move16(); + + FOR( k = 0; k < NB_POS_FCB_2T; k++ ) + { + /* Init pointers to last position of diagonals */ + p1 = &rrixiy[pos]; + move16(); + p0 = &rrixiy[pos2]; + move16(); + + ptr_h1 = h; + move16(); + ptr_h2 = ptr_hf; + move16(); + + L_cor = L_mult( *ptr_h1++, *ptr_h2++ ); + FOR( i = k; i < NB_POS_FCB_2T - 1; i++ ) + { +#ifdef BASOP_NOGLOB + *p1 = round_fx_o( L_cor, &Overflow ); + L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); +#else + *p1 = round_fx( L_cor ); + L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); +#endif +#ifdef BASOP_NOGLOB + *p0 = round_fx_o( L_cor, &Overflow ); + L_cor = L_mac_o( L_cor, *ptr_h1++, *ptr_h2++, &Overflow ); +#else + *p0 = round_fx( L_cor ); + L_cor = L_mac( L_cor, *ptr_h1++, *ptr_h2++ ); +#endif + p1 -= ( NB_POS_FCB_2T + 1 ); + move16(); + p0 -= ( NB_POS_FCB_2T + 1 ); + move16(); + } + +#ifdef BASOP_NOGLOB + *p1 = round_fx_o( L_cor, &Overflow ); +#else + *p1 = round_fx( L_cor ); +#endif + pos -= NB_POS_FCB_2T; + move16(); + pos2--; + ptr_hf += STEP; + move16(); + } + + /*----------------------------------------------------------------* + * computing reference vector and pre-selection of polarities + *----------------------------------------------------------------*/ + + L_tmp = L_deposit_h( dn[0] ); + FOR( i = 0; i < L_SUBFR; i++ ) + { + /* FIR high-pass filtering */ + IF( i == 0 ) + { + L_tmp = L_msu( L_tmp, dn[1], 11469 ); + } + ELSE IF( EQ_16( i, L_SUBFR - 1 ) ) + { + L_tmp = L_deposit_h( dn[i] ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); + } + ELSE + { + L_tmp = L_deposit_h( dn[i] ); + L_tmp = L_msu( L_tmp, dn[i - 1], 11469 ); + L_tmp = L_msu( L_tmp, dn[i + 1], 11469 ); + } + + /* pre-selection of polarities */ + IF( L_tmp >= 0 ) + { + pol[i] = 1; + move16(); + dn_p[i] = dn[i]; + move16(); + } + ELSE + { + pol[i] = -1; + move16(); + dn_p[i] = negate( dn[i] ); + move16(); + } + } + + /*----------------------------------------------------------------* + * compute denominator ( multiplied by polarity ) + *----------------------------------------------------------------*/ + + k = 0; + ii = 0; + move16(); + move16(); + FOR( i = 0; i < NB_POS_FCB_2T; i++ ) + { + jj = 1; + move16(); + FOR( j = 0; j < NB_POS_FCB_2T; j++ ) + { + test(); + if ( EQ_16( s_and( pol[ii], pol[jj] ), 1 ) && EQ_16( s_or( pol[ii], pol[jj] ), -1 ) ) + { + rrixiy[k + j] = negate( rrixiy[k + j] ); + move16(); + } + jj = add( jj, 2 ); + } + ii = add( ii, 2 ); + k = add( k, NB_POS_FCB_2T ); + } + + /*----------------------------------------------------------------* + * search 2 pulses + * All combinaisons are tested: + * 32 pos x 32 pos x 2 signs = 2048 tests + *----------------------------------------------------------------*/ + + p0 = rrixix[0]; + move16(); + p1 = rrixix[1]; + move16(); + p2 = rrixiy; + move16(); + psk = -1; + move16(); + alpk = 1; + move16(); + ix = 0; + move16(); + iy = 1; + move16(); + + FOR( i0 = 0; i0 < L_SUBFR; i0 += STEP ) + { + ps1 = dn_p[i0]; + move16(); + alp1 = *p0++; + move16(); + pos = -1; + move16(); + FOR( i1 = 1; i1 < L_SUBFR; i1 += STEP ) + { + ps2 = add( ps1, dn_p[i1] ); +#ifdef BASOP_NOGLOB + alp2 = add_o( alp1, add_o( *p1++, *p2++, &Overflow ), &Overflow ); +#else + alp2 = add( alp1, add( *p1++, *p2++ ) ); +#endif + sq = mult( ps2, ps2 ); +#ifdef BASOP_NOGLOB + s = L_msu_o( L_mult( alpk, sq ), psk, alp2, &Overflow ); +#else + s = L_msu( L_mult( alpk, sq ), psk, alp2 ); +#endif + IF( s > 0 ) + { + psk = sq; + move16(); + alpk = alp2; + move16(); + pos = i1; + move16(); + } + } + p1 -= NB_POS_FCB_2T; + move16(); + + IF( pos >= 0 ) + { + ix = i0; + move16(); + iy = pos; + move16(); + } + } + + i0 = shr( ix, 1 ); + i1 = shr( iy, 1 ); + + sign0 = shl( pol[ix], 9 ); + sign1 = shl( pol[iy], 9 ); + + /*-------------------------------------------------------------------* + * Build the codeword, the filtered codeword and index of codevector. + *-------------------------------------------------------------------*/ + + set16_fx( code, 0, L_SUBFR ); + + code[ix] = sign0; + move16(); + code[iy] = sign1; + move16(); + + index = add( shl( i0, 6 ), i1 ); + + + if ( sign0 < 0 ) + { + index = add( index, 0x800 ); + } + if ( sign1 < 0 ) + { + index = add( index, 0x20 ); /* move16();*/ + } + + set16_fx( y, 0, L_SUBFR ); + /* y_Q9 = sign_Q9<<3 * h_Q12 */ + + sign0 = shl( sign0, 3 ); + sign1 = shl( sign1, 3 ); + + FOR( i = ix; i < L_SUBFR; i++ ) + { + y[i] = mult_r( sign0, h[i - ix] ); + move16(); + } + FOR( i = iy; i < L_SUBFR; i++ ) + { + y[i] = round_fx( L_mac( L_deposit_h( y[i] ), sign1, h[i - iy] ) ); + } + { + /* write index to array of indices */ + push_indice( hBstr, IND_ALG_CDBK_2T32, index, 12 ); + } + return; +} /*---------------------------------------------------------------------------------- * Function acelp_1t64() * @@ -418,3 +730,72 @@ void acelp_1t64_fx( return; } + +void acelp_1t64_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 code[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[], /* o : filtered fixed codebook excitation */ + const Word16 L_subfr /* i : subframe length */ +) +{ + Word16 i, pos, sgn, index; + Word32 L_tmp; + /*-------------------------------------------------------------------* + * Find position and sign of maximum impulse. + *-------------------------------------------------------------------*/ + pos = emaximum_fx( 0, dn, L_subfr, &L_tmp ); + + IF( dn[pos] < 0 ) + { + sgn = -512; + move16(); + } + ELSE + { + sgn = 512; + move16(); + } + + /*-------------------------------------------------------------------* + * Build the codeword, the filtered codeword and index of codevector. + *-------------------------------------------------------------------*/ + + set16_fx( code, 0, L_subfr ); + code[pos] = sgn; + move16(); + + set16_fx( y, 0, L_subfr ); + + FOR( i = pos; i < L_subfr; i++ ) + { + IF( sgn > 0 ) + { + y[i] = shr_r( h[i - pos], 3 ); + move16(); + } + ELSE + { + y[i] = negate( shr_r( h[i - pos], 3 ) ); + move16(); + } + } + + index = pos; + move16(); + if ( sgn > 0 ) + { + index = add( index, L_subfr ); + } + IF( EQ_16( L_subfr, L_SUBFR ) ) + { + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 7 ); + } + ELSE /* L_subfr == 2*L_SUBFR */ + { + push_indice( hBstr, IND_ALG_CDBK_1T64, index, 8 ); + } + + return; +} diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index 85c5d157f5a98925a8736763778adac0ce821374..51cc780c3c0e8a32c8cfa1da90f0549854713337 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -842,6 +842,7 @@ void acelp_fast_fx( Word16 track_order[NB_TRACK_FCB_4T * MAX_NUM_INTER], m0_track[NB_TRACK_FCB_4T]; Word16 ind_stream[NPMAXPT * NB_TRACK_FCB_4T], idx; Word16 G, G1, G2, G3, Gn, Gd; + Word32 Gd32; Word16 y_tmp[L_SUBFR_MAX]; Word32 dn[L_SUBFR_MAX]; Word32 crit_num, crit_den, crit_num_max, crit_den_max, L_tmp1, L_tmp2; @@ -1332,9 +1333,10 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 3 ) ) { - Gn = add( Gn, i_mult( s[1], shr( dn_orig[m[1]], 1 ) ) ); // Q_dn -1 - Gd = add( Gd, add( alp[0], i_mult( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6 - G = Gn; // Q_dn - 1 + Gn = add( Gn, i_mult( s[1], shr( dn_orig[m[1]], 1 ) ) ); // Q_dn -1 + Gd32 = Gd; + Gd32 = L_add( Gd32, L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[1] ), alp[m[0] - m[1]] ) ) ); // Q6 + G = Gn; // Q_dn - 1 move16(); G1 = i_mult( G, s[1] ); // Q_dn-1 G = i_mult( G, s[0] ); // Q_dn-1 @@ -1346,7 +1348,7 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu0( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), 6 ); // Q_dn + dn[i] = L_shr( L_msu( L_msu0( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), 6 ); // Q_dn move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -1362,9 +1364,10 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 4 ) ) { - Gn = add( Gn, i_mult( s[2], shr( dn_orig[m[2]], 1 ) ) ); // Q_dn-1 - Gd = add( Gd, add( add( alp[0], i_mult( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] ) ), i_mult( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] ) ) ); // Q6 - G = Gn; // Q_dn-1 + Gn = add( Gn, i_mult( s[2], shr( dn_orig[m[2]], 1 ) ) ); // Q_dn-1 + Gd32 = Gd; + Gd32 = L_add( Gd32, L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[2] ), alp[m[0] - m[2]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[2] ), alp[m[1] - m[2]] ) ) ); // Q6 + G = Gn; // Q_dn-1 move16(); G1 = i_mult( G, s[1] ); // Q_dn-1 G2 = i_mult( G, s[2] ); // Q_dn-1 @@ -1378,7 +1381,7 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), 6 ); // Q_dn + dn[i] = L_shr( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), 6 ); // Q_dn move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -1400,13 +1403,14 @@ void acelp_fast_fx( IF( GE_16( nb_pulse, 5 ) ) { - Gn = add( Gn, i_mult( s[3], shr( dn_orig[m[3]], 1 ) ) ); // Q_dn-1 - Gd = add( Gd, add( add( add( alp[0], i_mult( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] ) ), i_mult( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] ) ), i_mult( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] ) ) ); // Q6 - G = Gn; // Q_dn-1 - G1 = i_mult( G, s[1] ); // Q_dn-1 - G2 = i_mult( G, s[2] ); // Q_dn-1 - G3 = i_mult( G, s[3] ); // Q_dn-1 - G = i_mult( G, s[0] ); // Q_dn-1 + Gn = add( Gn, i_mult( s[3], shr( dn_orig[m[3]], 1 ) ) ); // Q_dn-1 + Gd32 = Gd; + Gd32 = L_add( Gd32, L_add( L_add( L_add( alp[0], L_mult0( i_mult( shl( s[0], 1 ), s[3] ), alp[m[0] - m[3]] ) ), L_mult0( i_mult( shl( s[1], 1 ), s[3] ), alp[m[1] - m[3]] ) ), L_mult0( i_mult( shl( s[2], 1 ), s[3] ), alp[m[2] - m[3]] ) ) ); // Q6 + G = Gn; // Q_dn-1 + G1 = i_mult( G, s[1] ); // Q_dn-1 + G2 = i_mult( G, s[2] ); // Q_dn-1 + G3 = i_mult( G, s[3] ); // Q_dn-1 + G = i_mult( G, s[0] ); // Q_dn-1 IF( EQ_16( cdk_index, 6 ) ) { @@ -1420,7 +1424,7 @@ void acelp_fast_fx( FOR( i = track; i < L_subfr; i += nb_tracks ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); // Q_dn + dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); // Q_dn move32(); alp_pos0 += nb_tracks; alp_pos1 += nb_tracks; @@ -1440,7 +1444,7 @@ void acelp_fast_fx( FOR( i = 0; i < L_subfr; i++ ) { - dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( L_mult0( Gd, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); /*Q_dn*/ + dn[i] = L_shr( L_msu( L_msu( L_msu( L_msu( imult3216( Gd32, dn_orig[i] ), G, *alp_pos0 ), G1, *alp_pos1 ), G2, *alp_pos2 ), G3, *alp_pos3 ), 6 ); /*Q_dn*/ move16(); alp_pos0++; alp_pos1++; @@ -1570,7 +1574,7 @@ void acelp_fast_fx( set16_fx( code, 0, L_subfr ); FOR( q = 0; q < nb_pulse; q++ ) { - code[m_max[q]] = add( code[m_max[q]], s_max[q] ); // Q0 + code[m_max[q]] = add( code[m_max[q]], shl( s_max[q], Q9 ) ); // Q9 move16(); } test(); diff --git a/lib_enc/cod4t64_fx.c b/lib_enc/cod4t64_fx.c index b20c94daf7d2157509a14463a5470d41ec60f68e..19b195615230f2ac42adf0b1c94ee35265f8c7a1 100644 --- a/lib_enc/cod4t64_fx.c +++ b/lib_enc/cod4t64_fx.c @@ -2,10 +2,10 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* VMR-WB compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_enc.h" /* Encoder static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* VMR-WB compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_enc.h" /* Encoder static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ @@ -471,6 +471,420 @@ Word16 acelp_4t64_fx( } +Word16 acelp_4t64_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 cn[], /* i : residual after long term prediction Q_new*/ + const Word16 H[], /* i : impulse response of weighted synthesis filter Q12*/ + Word16 R[], /* i : autocorrelation values */ + const Word16 acelpautoc, /* i : autocorrealtion flag */ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + Word16 y[], /* o : filtered fixed codebook excitation Q9*/ + Word16 nbbits, /* i : number of bits per codebook */ + const Word16 cmpl_flag, /* i : complexity reduction flag */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + Word16 element_mode ) +{ + + Word16 i, k, index, track; + Word32 L_index; + Word16 ind[NPMAXPT * NB_TRACK_FCB_4T + 32]; /* VE3: why +32 ???*/ + Word16 codvec[NB_PULSE_MAX + 4] = { 0 }; + Word16 saved_bits = 0; + + PulseConfig config; + Word16 indexing_indices[6], wordcnt, bitcnt; + + set16_fx( codvec, 0, NB_PULSE_MAX + 4 ); + SWITCH( nbbits ) + { + + case 20: /* EVS/AMR-WB pulse indexing: 20 bits, 4 pulses, 4 tracks */ + config.nbiter = 4; + move16(); /* 4x12x16=768 loop */ + config.alp = 16384; + move16(); /* 2 in Q13*/ + config.nb_pulse = 4; + move16(); + config.fixedpulses = 0; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 8; + move16(); + BREAK; + + case 28: /* EVS pulse indexing: 28 bits, 6 pulses, 4 tracks */ + config.nbiter = 4; + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; + move16(); /* coeff FOR sign setting */ + config.nb_pulse = 6; + move16(); + config.fixedpulses = 0; + move16(); + config.nbpos[0] = 6; + move16(); + config.nbpos[1] = 6; + move16(); + config.nbpos[2] = 8; + move16(); + BREAK; + + case 36: /* EVS/AMR-WB pulse indexing: 36 bits, 8 pulses, 4 tracks */ + config.nbiter = 4; + move16(); /* 4x20x16=1280 loops */ + config.alp = 8192; + move16(); /* coeff FOR sign setting */ + config.nb_pulse = 8; + move16(); + config.fixedpulses = 2; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 8; + move16(); + config.nbpos[2] = 8; + move16(); + BREAK; + + case 43: /* EVS pulse indexing: 43 bits, 10 pulses, 4 tracks */ + case 44: /* AMR-WB pulse indexing: 44 bits, 10 pulses, 4 tracks */ + config.nbiter = 4; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; + move16(); + config.nb_pulse = 10; + move16(); + config.fixedpulses = 2; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 6; + move16(); + config.nbpos[2] = 8; + move16(); + config.nbpos[3] = 8; + move16(); + BREAK; + + case 50: /* EVS pulse indexing: 50 bits, 12 pulses, 4 tracks */ + case 52: /* AMR-WB pulse indexing: 52 bits, 12 pulses, 4 tracks */ + config.nbiter = 4; + move16(); /* 4x26x16=1664 loops */ + config.alp = 8192; + move16(); + config.nb_pulse = 12; + move16(); + config.fixedpulses = 4; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 6; + move16(); + config.nbpos[2] = 8; + move16(); + config.nbpos[3] = 8; + move16(); + BREAK; + + case 62: /* EVS pulse indexing: 62 bits, 16 pulses, 4 tracks */ + case 64: /* AMR-WB pulse indexing: 64 bits, 16 pulses, 4 tracks */ + config.nbiter = 3; + move16(); /* 3x36x16=1728 loops */ + config.alp = 6554; + move16(); + config.nb_pulse = 16; + move16(); + config.fixedpulses = 4; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 4; + move16(); + config.nbpos[2] = 6; + move16(); + config.nbpos[3] = 6; + move16(); + config.nbpos[4] = 8; + move16(); + config.nbpos[5] = 8; + move16(); + BREAK; + + case 72: /* AMR-WB pulse indexing: 72 bits, 18 pulses, 4 tracks */ + config.nbiter = 3; + move16(); /* 3x35x16=1680 loops */ + config.alp = 6144; + move16(); + config.nb_pulse = 18; + move16(); + config.fixedpulses = 4; + move16(); + config.nbpos[0] = 2; + move16(); + config.nbpos[1] = 3; + move16(); + config.nbpos[2] = 4; + move16(); + config.nbpos[3] = 5; + move16(); + config.nbpos[4] = 6; + move16(); + config.nbpos[5] = 7; + move16(); + config.nbpos[6] = 8; + move16(); + BREAK; + + case 88: /* AMR-WB pulse indexing: 88 bits, 24 pulses, 4 tracks */ + config.nbiter = 2; + move16(); /* 2x53x16=1696 loop */ + config.alp = 4096; + move16(); + config.nb_pulse = 24; + move16(); + config.fixedpulses = 4; + move16(); + config.nbpos[0] = 2; + move16(); + config.nbpos[1] = 2; + move16(); + config.nbpos[2] = 3; + move16(); + config.nbpos[3] = 4; + move16(); + config.nbpos[4] = 5; + move16(); + config.nbpos[5] = 6; + move16(); + config.nbpos[6] = 7; + move16(); + config.nbpos[7] = 8; + move16(); + config.nbpos[8] = 8; + move16(); + config.nbpos[9] = 8; + move16(); + BREAK; + + case 87: /* EVS pulse indexing: 87 bits, 26 pulses, 4 tracks */ + config.nbiter = 1; + move16(); + config.alp = 4096; + move16(); + config.nb_pulse = 26; + move16(); + config.fixedpulses = 4; + move16(); + config.nbpos[0] = 4; + move16(); + config.nbpos[1] = 6; + move16(); + config.nbpos[2] = 6; + move16(); + config.nbpos[3] = 8; + move16(); + config.nbpos[4] = 8; + move16(); + config.nbpos[5] = 8; + move16(); + config.nbpos[6] = 8; + move16(); + config.nbpos[7] = 8; + move16(); + config.nbpos[8] = 8; + move16(); + config.nbpos[9] = 8; + move16(); + config.nbpos[10] = 8; + move16(); + BREAK; + } + + /* reduce the number of iterations as a compromise between the performance and complexity */ + if ( cmpl_flag > 0 ) + { + config.nbiter = cmpl_flag; + move16(); + } + + config.codetrackpos = TRACKPOS_FIXED_FIRST; + move16(); + config.bits = nbbits; + move16(); + + IF( acelpautoc ) + { + E_ACELP_4tsearchx_ivas_fx( dn, cn, R, code, &config, ind, element_mode ); + + /* Generate weighted code */ + E_ACELP_weighted_code( code, H, 12, y ); + } + ELSE + { + E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); + + FOR( i = 0; i < L_SUBFR; i++ ) + { + y[i] = shr( y[i], 3 ); + move16(); /*Q9 */ + } + } + + /*-----------------------------------------------------------------* + * Indexing + *-----------------------------------------------------------------*/ + + IF( !Opt_AMR_WB ) + { + saved_bits = E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, indexing_indices ); + + saved_bits = 0; + move16(); + + wordcnt = shr( nbbits, 4 ); + bitcnt = s_and( nbbits, 15 ); + FOR( i = 0; i < wordcnt; i++ ) + { + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], 16 ); + } + IF( bitcnt ) + { + push_indice( hBstr, IND_ALG_CDBK_4T64, indexing_indices[i], bitcnt ); + } + } + ELSE + { + /* AMR-WB pulse indexing */ + + IF( EQ_16( nbbits, 20 ) ) + { + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + index = quant_1p_N1_fx( ind[k], 4 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 5 ); + } + } + ELSE IF( EQ_16( nbbits, 36 ) ) + { + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + + k = i_mult2( track, NPMAXPT ); /* k = track * NPMAXPT;*/ + index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + } + } + ELSE IF( EQ_16( nbbits, 44 ) ) /* AMR-WB pulse indexing */ + { + FOR( track = 0; track < ( NB_TRACK_FCB_4T - 2 ); track++ ) + { + k = i_mult2( track, NPMAXPT ); + index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + } + + FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + index = quant_2p_2N1_fx( ind[k], ind[k + 1], 4 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 9 ); + } + } + ELSE IF( EQ_16( nbbits, 52 ) ) /* AMR-WB pulse indexing */ + { + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + index = quant_3p_3N1_fx( ind[k], ind[k + 1], ind[k + 2], 4 ); + push_indice( hBstr, IND_ALG_CDBK_4T64, index, 13 ); + } + } + ELSE IF( EQ_16( nbbits, 64 ) ) /* AMR-WB pulse indexing */ + { + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_4p_4N_fx( &ind[k], 4 ); + index = extract_l( L_shr( L_index, 14 ) & 3 ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + } + + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_4p_4N_fx( &ind[k], 4 ); + index = extract_l( L_index & 0x3FFF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + } + } + ELSE IF( EQ_16( nbbits, 72 ) ) + { + FOR( track = 0; track < ( NB_TRACK_FCB_4T - 2 ); track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_5p_5N_fx( &ind[k], 4 ); + index = extract_l( L_shr( L_index, 10 ) & 0x03FF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 10 ); + } + + FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_4p_4N_fx( &ind[k], 4 ); + index = extract_l( L_shr( L_index, 14 ) & 3 ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 2 ); + } + + FOR( track = 0; track < ( NB_TRACK_FCB_4T - 2 ); track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_5p_5N_fx( &ind[k], 4 ); + index = extract_l( L_index & 0x03FF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 10 ); + } + + FOR( track = 2; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_4p_4N_fx( &ind[k], 4 ); + index = extract_l( L_index & 0x3FFF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 14 ); + } + } + ELSE IF( EQ_16( nbbits, 88 ) ) + { + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_6p_6N_2_fx( &ind[k], 4 ); + index = extract_l( L_shr( L_index, 11 ) & 0x07FF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_1, index, 11 ); + } + + FOR( track = 0; track < NB_TRACK_FCB_4T; track++ ) + { + k = i_mult2( track, NPMAXPT ); + L_index = quant_6p_6N_2_fx( &ind[k], 4 ); + index = extract_l( L_index & 0x07FF ); + logic16(); + push_indice( hBstr, IND_ALG_CDBK_4T64_2, index, 11 ); + } + } + } + + return saved_bits; +} + /*---------------------------------------------------------------------* *encode class for 3p 4p 5p 6p/track * *---------------------------------------------------------------------*/ diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index b1fd1d7f256d4d7004ed9ea9a19c5cec199288a5..b4837eecca4323d7d19a6b8b1832f833f1a7fc5b 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -1685,8 +1685,6 @@ static void init_acelp_ivas_fx( Encoder_State *st, Word16 L_frame_old, Word16 sh move16(); set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); move16(); - hLPDmem->e_old_exc = 0; - move16(); /*Resamp others memories*/ /*Size of LPC syn memory*/ /* 1.25/20.0 = 1.0/16.0 -> shift 4 to the right. */ diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index 31d300f31c358e9ae00232b14f2fac6be59dfd1b..0a90b3648dde68a535bbd6465c7a7ce0062f7a86 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -249,7 +249,8 @@ void core_coder_mode_switch_ivas_fx( fixedToFloat_arr( st->lspold_enc_fx, st->lspold_enc, Q15, M ); IF( st->hLPDmem != NULL ) { - me2f_buf_16( st->hLPDmem->old_exc, st->hLPDmem->e_old_exc, st->hLPDmem->old_exc_flt, L_EXC_MEM ); + // me2f_buf_16( st->hLPDmem->old_exc, st->hLPDmem->e_old_exc, st->hLPDmem->old_exc_flt, L_EXC_MEM ); + fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, st->prev_Q_new, L_EXC_MEM ); } #endif } diff --git a/lib_enc/corr_xh_fx.c b/lib_enc/corr_xh_fx.c index a999b893029c93c6cdfdb8018fa91c5a7ff9b5fa..92b3c7ebad9b20dbd5596582691419088ef22780 100644 --- a/lib_enc/corr_xh_fx.c +++ b/lib_enc/corr_xh_fx.c @@ -88,24 +88,147 @@ void corr_xh_ivas_fx( const Word16 L_subfr /* i : length of the subframe */ ) { - Word16 i, j; - Word32 s; - Word32 y32[2 * L_SUBFR]; + Word16 i, j, scale; + Word64 s64; Word16 shift = add( norm_s( h[0] ), 1 ); + scale = sub( sub( 15, shift ), 2 ); FOR( i = 0; i < L_subfr; i++ ) { - s = 0; - move32(); + s64 = 0; + move16(); FOR( j = i; j < L_subfr; j++ ) { - s = L_add( s, shl( mult( x[j], h[j - i] ), shift ) ); // Q_new - 1 + s64 = W_mac0_16_16( s64, x[j], h[j - i] ); // Q_new - 1 + 15 - shift } - y32[i] = s; // Q_new - 1 - move32(); + y[i] = extract_l( W_extract_l( W_shr( s64, scale ) ) ); // Q_new + 1 + move16(); } - Copy_Scale_sig32_16( y32, y, L_subfr, 18 ); // Q_new + 1 return; } + +void corr_hh_ivas_fx( + const Word16 *h, /* i : target signal e(norm_s(h1[0])+1) */ + Word16 *y, /* o : correlation between x[] and h[] Q_new + 1 */ + Word16 *Qy, + const Word16 L_subfr /* i : length of the subframe */ +) +{ + Word16 i, j, k; + Word32 L_tmp, y32[L_SUBFR * 2], L_maxloc, L_tot; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* first keep the result on 32 bits and find absolute maximum */ + L_tot = L_deposit_l( 1 ); + + FOR( k = 0; k < NB_TRACK; k++ ) + { + L_maxloc = L_deposit_l( 0 ); + FOR( i = k; i < L_subfr; i += STEP ) + { + L_tmp = L_mac( 1L, h[i], h[0] ); /* 1 -> to avoid null dn[] */ // 2*(15 - norm_s(h[0])) - 1 + FOR( j = i; j < L_subfr - 1; j++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_o( L_tmp, h[j + 1], h[j + 1 - i], &Overflow ); // 2*(15 - norm_s(h[0])) - 1 +#else + L_tmp = L_mac( L_tmp, x[j + 1], h[j + 1 - i] ); +#endif + } + + y32[i] = L_tmp; + move32(); + L_tmp = L_abs( L_tmp ); + L_maxloc = L_max( L_tmp, L_maxloc ); + } + /* tot += 3*max / 8 */ + L_maxloc = L_shr( L_maxloc, 2 ); +#ifdef BASOP_NOGLOB + L_tot = L_add_o( L_tot, L_maxloc, &Overflow ); /* +max/4 */ + L_tot = L_add_o( L_tot, L_shr( L_maxloc, 1 ), &Overflow ); /* +max/8 */ +#else + L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ + L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ +#endif + } + + /* Find the number of right shifts to do on y32[] so that */ + /* 6.0 x sumation of max of dn[] in each track not saturate. */ + + j = sub( norm_l( L_tot ), 4 ); /* 4 -> 16 x tot */ + + FOR( i = 0; i < L_subfr; i++ ) + { + y[i] = round_fx( L_shl( y32[i], j ) ); // 2*(15 - norm_s(h[0])) - 1 +j - 16 + } + + *Qy = sub( add( shl( sub( 15, norm_s( h[0] ) ), 1 ), j ), 17 ); + return; +} + +void corr_xh_ivas_fx2( + const Word16 x[], /* i : target signal */ + const Word16 Qx, + Word16 dn[], /* o : correlation between x[] and h[] */ + Word16 *Qdn, + const Word16 h[], /* i : impulse response (of weighted synthesis filter) */ + const Word16 L_subfr /* i : length of the subframe */ +) +{ + Word16 i, j, k; + Word32 L_tmp, y32[L_SUBFR * 2], L_maxloc, L_tot; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /* first keep the result on 32 bits and find absolute maximum */ + L_tot = L_deposit_l( 1 ); + + FOR( k = 0; k < NB_TRACK; k++ ) + { + L_maxloc = L_deposit_l( 0 ); + FOR( i = k; i < L_subfr; i += STEP ) + { + L_tmp = L_mac( 1L, x[i], h[0] ); /* 1 -> to avoid null dn[] */ // Qx+(15 - norm_s(h[0])) + FOR( j = i; j < L_subfr - 1; j++ ) + { +#ifdef BASOP_NOGLOB + L_tmp = L_mac_o( L_tmp, x[j + 1], h[j + 1 - i], &Overflow ); // Qx+(15 - norm_s(h[0])) +#else + L_tmp = L_mac( L_tmp, x[j + 1], h[j + 1 - i] ); +#endif + } + + y32[i] = L_tmp; + move32(); + L_tmp = L_abs( L_tmp ); + L_maxloc = L_max( L_tmp, L_maxloc ); + } + /* tot += 3*max / 8 */ + L_maxloc = L_shr( L_maxloc, 2 ); +#ifdef BASOP_NOGLOB + L_tot = L_add_o( L_tot, L_maxloc, &Overflow ); /* +max/4 */ + L_tot = L_add_o( L_tot, L_shr( L_maxloc, 1 ), &Overflow ); /* +max/8 */ +#else + L_tot = L_add( L_tot, L_maxloc ); /* +max/4 */ + L_tot = L_add( L_tot, L_shr( L_maxloc, 1 ) ); /* +max/8 */ +#endif + } + + /* Find the number of right shifts to do on y32[] so that */ + /* 6.0 x sumation of max of dn[] in each track not saturate. */ + + j = sub( norm_l( L_tot ), 4 ); /* 4 -> 16 x tot */ + + FOR( i = 0; i < L_subfr; i++ ) + { + dn[i] = round_fx( L_shl( y32[i], j ) ); // Qx+(15 - norm_s(h[0])) +j - 16 + } + + *Qdn = sub( add( add( Qx, sub( 15, norm_s( h[0] ) ) ), j ), 16 ); + return; +} diff --git a/lib_enc/enc_acelp_fx.c b/lib_enc/enc_acelp_fx.c index a601728279d581792ef508ec6de55c86d601b63e..ee57efffe3b2735dcd2abba7fb1da5d9d236c078 100644 --- a/lib_enc/enc_acelp_fx.c +++ b/lib_enc/enc_acelp_fx.c @@ -355,7 +355,7 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], move16(); sqk[0] = -1; move16(); - if ( mac_r( alp0, cor_x[shr( tracks[0], 2 )], _1_ ) < 0 ) + if ( mac_r_sat( alp0, cor_x[shr( tracks[0], 2 )], _1_ ) < 0 ) { sqk[0] = 1; move16(); @@ -382,7 +382,7 @@ static void E_ACELP_1pulse_search( UWord8 tracks[2], ps1 = add( ps0, dn[x] ); /*alp1 = alp0 + cor_x[x>>2]; SHIFT(1);ADD(1);*/ - alp1 = mac_r( alp0, cor_x[shr( x, 2 )], _1_ ); /*Q6*/ + alp1 = mac_r_sat( alp0, cor_x[shr( x, 2 )], _1_ ); /*Q6*/ alpk[1 - ik] = alp1; move16(); @@ -1569,6 +1569,70 @@ void E_ACELP_4t_fx( return; } +void E_ACELP_4t_ivas_fx( + Word16 dn[], + Word16 cn[] /* Q_xn */, + Word16 H[], + Word16 R[], + Word8 acelpautoc, + Word16 code[], + Word16 cdk_index, + Word16 _index[], + const Word16 L_frame, + const Word16 last_L_frame, + const Word32 total_brate, + const Word16 i_subfr, + const int16_t cmpl_flag, + Word16 element_mode ) +{ + PulseConfig config; + Word16 ind[NPMAXPT * 4]; + Word16 y[L_SUBFR]; + + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + memcpy( &config, &PulseConfTable[cdk_index], sizeof( PulseConfTable[cdk_index] ) ); + + + if ( cmpl_flag > 0 ) + { + config.nbiter = cmpl_flag; + move16(); + } + test(); + test(); + IF( NE_16( L_frame, last_L_frame ) && EQ_32( total_brate, ACELP_24k40 ) && LT_32( i_subfr, 5 * L_SUBFR ) ) + { + config.nbiter = sub( config.nbiter, 1 ); + config.nbiter = s_max( config.nbiter, 1 ); + } + + IF( acelpautoc ) + { + E_ACELP_4tsearchx_ivas_fx( dn, cn, R, code, &config, ind, element_mode ); + } + ELSE + { + E_ACELP_4tsearch_fx( dn, cn, H, code, &config, ind, y ); + } + E_ACELP_indexing_fx( code, &config, NB_TRACK_FCB_4T, _index ); + return; +} + static void E_ACELP_indexing_shift( Word16 wordcnt, /* i: 16-bit word count including the newly shifted-in bits */ Word16 shift_bits, /* i: number of bits to shift in from the lsb */ diff --git a/lib_enc/enc_acelpx_fx.c b/lib_enc/enc_acelpx_fx.c index cac1c81edd1f42f47732c45a6ee66f5c2061200d..43df35a55f4427071b76c8403dc9d413398a80ac 100644 --- a/lib_enc/enc_acelpx_fx.c +++ b/lib_enc/enc_acelpx_fx.c @@ -621,3 +621,273 @@ void E_ACELP_4tsearchx_fx( */ E_ACELP_build_code( nb_pulse, codvec, sign, code, ind ); } + +void E_ACELP_4tsearchx_ivas_fx( + Word16 dn[], + const Word16 cn[], + Word16 Rw[], + Word16 code[], + const PulseConfig *config, + Word16 ind[], + Word16 element_mode ) +{ + Word16 sign[L_SUBFR], vec[L_SUBFR]; + Word16 cor[L_SUBFR]; + Word16 R_buf[2 * L_SUBFR - 1], *R; + Word16 dn2[L_SUBFR]; + Word16 ps2k, ps /* same format as dn[] */, ps2, alpk, alp = 0 /* Q13 and later Q_Rw*Q_signval=Q_cor*Q_signval */; + Word32 s; + Word16 codvec[NB_PULSE_MAX]; + Word16 pos_max[4]; + Word16 dn2_pos[8 * 4]; + UWord8 ipos[NB_PULSE_MAX]; + Word16 i, j, k, st, pos = 0; + Word16 scale; + Word16 sign_val_1, sign_val_2; + Word16 nb_pulse, nb_pulse_m2; + Word16 psk; + Word16 val, index, track; + + psk = ps = 0; /* to avoid compilation warnings */ + + + alp = config->alp; /* Q13 */ + move16(); + nb_pulse = config->nb_pulse; + move16(); + move16(); + nb_pulse_m2 = sub( nb_pulse, 2 ); + + /* Init to avoid crash when the search does not find a solution */ + FOR( k = 0; k < nb_pulse; k++ ) + { + codvec[k] = k; + move16(); + } + + scale = 0; + move16(); + s = L_mult0( Rw[0], Rw[0] ); + FOR( i = 1; i < L_SUBFR; i++ ) + { + s = L_mac0( s, Rw[i], Rw[i] ); + } + if ( s_and( (Word16) GE_16( nb_pulse, 9 ), (Word16) GT_32( s, 0x800000 ) ) ) + { + scale = -1; + move16(); + } + if ( s_and( (Word16) GE_16( nb_pulse, 13 ), (Word16) GT_32( s, 0x4000000 ) ) ) + { + scale = -2; + move16(); + } + IF( GE_16( nb_pulse, 18 ) ) + { + if ( GT_32( s, 0x200000 ) ) + { + scale = -1; + move16(); + } + if ( GT_32( s, 0x400000 ) ) + { + scale = -2; + move16(); + } + if ( GT_32( s, 0x4000000 ) ) + { + scale = -3; + move16(); + } + } + if ( s_and( (Word16) GE_16( nb_pulse, 28 ), (Word16) GT_32( s, 0x800000 ) ) ) + { + scale = -3; + move16(); + } + if ( s_and( (Word16) GE_16( nb_pulse, 36 ), (Word16) GT_32( s, 0x4000000 ) ) ) + { + scale = -4; + move16(); + } + + /* Set up autocorrelation vector */ + R = R_buf + L_SUBFR - 1; + Copy_Scale_sig( Rw, R, L_SUBFR, scale ); + FOR( k = 1; k < L_SUBFR; k++ ) + { + R[-k] = R[k]; + move16(); + } + + /* Sign value */ + sign_val_2 = 0x2000; + move16(); + if ( GE_16( nb_pulse, 24 ) ) + { + sign_val_2 = shr( sign_val_2, 1 ); + } + sign_val_1 = shr( sign_val_2, 1 ); + + /* + * Find sign for each pulse position. + */ + E_ACELP_pulsesign( cn, dn, dn2, sign, vec, alp, sign_val_2, L_SUBFR ); + + /* + * Select the most important 8 position per track according to dn2[]. + */ + E_ACELP_findcandidates( dn2, dn2_pos, pos_max ); + + /* + * Deep first search: + */ + + /* Ensure that in the loop below s > 0 in the first iteration, the actual values do not matter. */ + ps2k = -1; + move16(); + alpk = 1; + move16(); + + /* Number of iterations */ + FOR( k = 0; k < config->nbiter; k++ ) + { + E_ACELP_setup_pulse_search_pos( config, k, ipos ); + + /* index to first non-fixed position */ + pos = config->fixedpulses; + move16(); + + IF( config->fixedpulses == 0 ) /* 1100, 11, 1110, 1111, 2211 */ + { + ps = 0; + move16(); + alp = 0; + move16(); + set16_fx( cor, 0, L_SUBFR ); + } + ELSE + { + assert( config->fixedpulses == 2 || config->fixedpulses == 4 ); + + /* set fixed positions */ + FOR( i = 0; i < pos; ++i ) + { + ind[i] = pos_max[ipos[i]]; + move16(); + } + + /* multiplication of autocorrelation with signed fixed pulses */ + E_ACELP_update_cor( ind, config->fixedpulses, sign, R, NULL, cor ); + + /* normalisation contribution of fixed part */ + s = L_mult0( cor[ind[0]], sign[ind[0]] ); + ps = dn[ind[0]]; + move16(); + FOR( i = 1; i < pos; ++i ) + { + s = L_mac0( s, cor[ind[i]], sign[ind[i]] ); /*Q12+Q9+1=Q6 */ + ps = add( ps, dn[ind[i]] ); + } + alp = round_fx( s ); /*mac0 >>1 sign = 2*/ + } + + /* other stages of 2 pulses */ + st = 0; + move16(); + FOR( j = pos; j < nb_pulse; j += 2 ) + { + IF( GE_16( nb_pulse_m2, j ) ) /* pair-wise search */ + { + /* + * Calculate correlation of all possible positions + * of the next 2 pulses with previous fixed pulses. + * Each pulse can have 16 possible positions. + */ + + E_ACELP_2pulse_searchx( config->nbpos[st], ipos[j], ipos[j + 1], R, &ps, &alp, + &ind[j], &ind[j + 1], dn, dn2_pos, cor, sign, sign_val_2 ); + } + ELSE /* single pulse search */ + { + E_ACELP_1pulse_searchx( &ipos[j], R, &ps, &alp, + &ind[j], dn, cor, sign, sign_val_1 ); + } + + IF( GT_16( alp, ONE_IN_Q14 ) ) + { + alp = shr( alp, 1 ); + Scale_sig( cor, L_SUBFR, -1 ); + Scale_sig( R_buf, 2 * L_SUBFR - 1, -1 ); + Scale_sig( dn, 2 * L_SUBFR, -1 ); + } + + + st = add( st, 1 ); + } + + /* memorise the best codevector */ + /*ps2 = ps * ps; MULT(1);*/ + ps2 = mult( ps, ps ); + + /*s = (alpk * ps2) - (ps2k * alp); MULT(2);ADD(1);*/ + s = L_msu( L_mult( alpk, ps2 ), ps2k, alp ); + + IF( s > 0 ) + { + ps2k = ps2; + move16(); + psk = ps; + move16(); + alpk = alp; + move16(); + Copy( ind, codvec, nb_pulse ); + } + } + + + /* + * Store weighted energy of code, build the codeword and index of codevector. + */ + IF( EQ_16( element_mode, EVS_MONO ) ) + { + E_ACELP_build_code( nb_pulse, codvec, sign, code, ind ); + } + ELSE + { + /* Store weighted energy of code, build the codeword and index of codevector. */ + set16_fx( code, 0, L_SUBFR ); + set16_fx( ind, -1, NPMAXPT * 4 ); + + FOR( k = 0; k < config->nb_pulse; k++ ) + { + i = codvec[k]; /* read pulse position */ + move16(); + val = sign[i]; /* read sign */ + move16(); + + index = shr( i, 2 ); /* pos of pulse (0..15) */ + // track = i % 4; + track = s_and( i, 3 ); + IF( L_mult0( val, psk ) > 0 ) + { + code[i] = add( code[i], ONE_IN_Q9 /*1.0f*/ ); + codvec[k] = add( codvec[k], 2 * L_SUBFR ); + } + ELSE + { + code[i] = sub( code[i], ONE_IN_Q9 /*1.0f*/ ); + index = add( index, 16 ); + } + + i = imult1616( track, NPMAXPT ); + WHILE( ind[i] >= 0 ) + { + i++; + } + + ind[i] = index; + move16(); + } + } +} diff --git a/lib_enc/enc_gen_voic_fx.c b/lib_enc/enc_gen_voic_fx.c index b0a9264ae9aea96d593813e84bc8949fa163beea..4b4a4deacc1fbeac252919e944df5845f7abd4a2 100644 --- a/lib_enc/enc_gen_voic_fx.c +++ b/lib_enc/enc_gen_voic_fx.c @@ -2,9 +2,9 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" /* Function prototypes */ @@ -425,3 +425,382 @@ void encod_gen_voic_fx( } return; } + +void encod_gen_voic_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 speech_fx[], /* i : input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* i/o: core synthesis */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Word16 *unbits_fx, /* i/o: number of unused bits */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 shift, + Word16 Q_new ) +{ + Word16 xn_fx[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2_fx[L_SUBFR]; /* Target vector for codebook search */ + Word16 cn_fx[L_SUBFR]; /* Target vector in residual domain */ + Word16 h1_fx[L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 h2_fx[L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 code_fx[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1_fx[L_SUBFR] = { 0 }; /* Filtered adaptive excitation */ + Word16 y2_fx[L_SUBFR]; /* Filtered algebraic excitation */ + Word16 gain_pit_fx = 0; /* Pitch gain */ + Word16 voice_fac_fx; /* Voicing factor */ + Word32 gain_code_fx = 0; /* Gain of code */ + Word16 gain_inov_fx = 0; /* inovation gain */ + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ + Word16 i, i_subfr_fx; /* tmp variables */ + Word16 T0_fx = 0, T0_frac_fx = 0; /* close loop integer pitch and fractional part */ + Word16 T0_min_fx, T0_max_fx; /* pitch variables */ + Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ + Word16 g_corr_fx[10]; /* ACELP correl, values + gain pitch */ + Word16 clip_gain_fx; /* LSF clip gain */ + const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector*/ + Word16 error_fx = 0; + Word16 gain_preQ_fx = 0; /* Gain of prequantizer excitation */ + Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */ + Word16 unbits_PI_fx = 0; /* number of unused bits for PI */ + Word32 norm_gain_code_fx = 0; + Word16 pitch_limit_flag; + Word16 gcode16; + Word32 Ltmp; + Word32 Ltmp1; + Word32 Lgcode; + Word16 tmp1_fx; + Word16 shift_wsp; + Word16 harm_flag_acelp; + Word16 lp_select, lp_flag, L_frame; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + + gain_pit_fx = 0; + move16(); + gain_code_fx = L_deposit_l( 0 ); + gain_preQ_fx = 0; + move16(); + unbits_PI_fx = 0; + move16(); + error_fx = 0; + move16(); + L_frame = st_fx->L_frame; + move16(); + + + IF( EQ_16( L_frame, L_FRAME ) ) + { + T0_max_fx = PIT_MAX; + move16(); + T0_min_fx = PIT_MIN; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + T0_max_fx = PIT16k_MAX; + move16(); + T0_min_fx = PIT16k_MIN; + move16(); + } + lp_flag = st_fx->acelp_cfg.ltf_mode; + move16(); + + *unbits_fx = 0; + move16(); + + p_Aw_fx = Aw_fx; + p_Aq_fx = Aq_fx; + pt_pitch_fx = pitch_buf_fx; + gain_preQ_fx = 0; + move16(); + set16_fx( code_preQ_fx, 0, L_SUBFR ); + + shift_wsp = add( Q_new, shift ); + + /* set and write harmonicity flag */ + harm_flag_acelp = 0; + move16(); + test(); + test(); + IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && EQ_16( st_fx->coder_type, GENERIC ) ) + { + if ( GT_16( st_fx->last_harm_flag_acelp, 2 ) ) + { + harm_flag_acelp = 1; + move16(); + } + + push_indice( hBstr, IND_HARM_FLAG_ACELP, harm_flag_acelp, 1 ); + } + + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + + FOR( i_subfr_fx = 0; i_subfr_fx < L_frame; i_subfr_fx += L_SUBFR ) + { + + /*----------------------------------------------------------------* + * Find the the excitation search target "xn" and innovation + * target in residual domain "cn" + * Compute impulse response, h1[], of weighted synthesis filter + *----------------------------------------------------------------*/ + + Copy( &res_fx[i_subfr_fx], &exc_fx[i_subfr_fx], L_SUBFR ); + + find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr_fx, &hLPDmem->mem_w0, p_Aq_fx, + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + + Copy_Scale_sig( h1_fx, h2_fx, L_SUBFR, -2 ); + Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + + /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn_fx, L_SUBFR, shift ); + + *pt_pitch_fx = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, st_fx->core_brate, 0, L_frame, st_fx->coder_type, &pitch_limit_flag, i_subfr_fx, exc_fx, + L_SUBFR, st_fx->pitch, &T0_min_fx, &T0_max_fx, &T0_fx, &T0_frac_fx, h1_fx, xn_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + + // tbe_celp_exc(L_frame, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx); + tbe_celp_exc_ivas( st_fx->element_mode, st_fx->idchan, L_frame, L_SUBFR, i_subfr_fx, T0_fx, T0_frac_fx, &error_fx, bwe_exc_fx, st_fx->tdm_LRTD_flag ); + + /*-----------------------------------------------------------------* + * Find adaptive exitation + *-----------------------------------------------------------------*/ + + pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + /*-----------------------------------------------------------------* + * Gain clipping test to avoid unstable synthesis on frame erasure + *-----------------------------------------------------------------*/ + + clip_gain_fx = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr_fx, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + + if ( EQ_16( st_fx->coder_type, INACTIVE ) ) + { + /* in case of AVQ inactive, limit the gain to 0.65 */ + clip_gain_fx = 2; + move16(); + } + + /*-----------------------------------------------------------------* + * LP filtering of the adaptive excitation, codebook target computation + *-----------------------------------------------------------------*/ + + lp_select = lp_filt_exc_enc_fx( MODE1, st_fx->coder_type, i_subfr_fx, exc_fx, h1_fx, + xn_fx, y1_fx, xn2_fx, L_SUBFR, L_frame, g_corr_fx, clip_gain_fx, &gain_pit_fx, &lp_flag ); + + IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) + { + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + } + + /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit_fx;*/ +#ifdef BASOP_NOGLOB + hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ +#else + hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit_fx ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ +#endif + + /*-----------------------------------------------------------------* + * Transform domain contribution encoding - active frames + *-----------------------------------------------------------------*/ + + test(); + IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && NE_16( st_fx->coder_type, INACTIVE ) ) + { + transf_cdbk_enc_ivas_fx( st_fx, harm_flag_acelp, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, + xn2_fx, y1_fx, y2_fx, Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); + } + + /*-----------------------------------------------------------------* + * Innovation encoding + *-----------------------------------------------------------------*/ + + inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, L_frame, st_fx->last_L_frame, + st_fx->coder_type, st_fx->bwidth, st_fx->sharpFlag, i_subfr_fx, -1, p_Aq_fx, + gain_pit_fx, cn_fx, exc_fx, h2_fx, hLPDmem->tilt_code, *pt_pitch_fx, xn2_fx, code_fx, y2_fx, &unbits_PI_fx, L_SUBFR, shift, Q_new ); + + /*-----------------------------------------------------------------* + * Gain encoding + *-----------------------------------------------------------------*/ + + IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) + { + gain_enc_lbr_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->coder_type, i_subfr_fx, xn_fx, y1_fx, sub( shift_wsp, 1 ), y2_fx, code_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, gc_mem, gp_mem, clip_gain_fx, L_SUBFR ); + } + ELSE IF( GT_32( st_fx->core_brate, ACELP_32k ) ) + { + gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr_fx, xn_fx, y1_fx, y2_fx, code_fx, Es_pred_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx, sub( shift_wsp, 1 ) ); + } + ELSE + { + gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame, i_subfr_fx, -1, xn_fx, y1_fx, sub( shift_wsp, 1 ), y2_fx, code_fx, Es_pred_fx, + &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, g_corr_fx, clip_gain_fx ); + } + IF( st_fx->Opt_SC_VBR ) + { + if ( EQ_16( hSC_VBR->last_ppp_mode, 1 ) ) + { + /* SC-VBR - all other st->clip_var values will be updated even in a PPP frame */ + st_fx->clip_var_fx[1] = gain_pit_fx; + move16(); + } + } + gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); + +#ifdef BASOP_NOGLOB + Lgcode = L_shl_o( gain_code_fx, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_o( Lgcode, &Overflow ); +#else + Lgcode = L_shl( gain_code_fx, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx( Lgcode ); +#endif + + hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr_fx], gain_pit_fx, code_fx, Lgcode, &voice_fac_fx, shift ); + + /*-----------------------------------------------------------------* + * Transform domain contribution encoding - inactive frames + *-----------------------------------------------------------------*/ + + test(); + IF( GE_32( st_fx->total_brate, MAX_GSC_INACTIVE_BRATE ) && EQ_16( st_fx->coder_type, INACTIVE ) ) + { + transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr_fx, cn_fx, exc_fx, p_Aq_fx, p_Aw_fx, h1_fx, xn_fx, xn2_fx, y1_fx, y2_fx, + Es_pred_fx, &gain_pit_fx, gain_code_fx, g_corr_fx, clip_gain_fx, &gain_preQ_fx, code_preQ_fx, unbits_fx, Q_new, shift ); + } + + /*-----------------------------------------------------------------* + * Update memory of the weighting filter + *-----------------------------------------------------------------*/ + + /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ + Ltmp = L_mult0( gcode16, y2_fx[L_SUBFR - 1] ); + Ltmp = L_shl( Ltmp, add( 5, shift ) ); // Q_new+14+shift + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn_fx[L_SUBFR - 1], 16384 ); // Q_new-1+15+shift + Ltmp = L_msu( Ltmp, y1_fx[L_SUBFR - 1], gain_pit_fx ); // Q_new-1+15+shift +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); // Q_new+15 + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ +#else + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); + hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ +#endif + IF( gain_preQ_fx != 0 ) + { + tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); + + FOR( i = 0; i < L_SUBFR; i++ ) + { +#ifdef BASOP_NOGLOB + /* Contribution from AVQ layer */ + Ltmp1 = L_mult_o( gain_preQ_fx, code_preQ_fx[i], &Overflow ); /* Q2 + Q6 -> Q9*/ + Ltmp1 = L_shl_o( Ltmp1, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ + + /* Compute exc2 */ + Ltmp = L_shl_o( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1, &Overflow ); + exc2_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); +#else + /* Contribution from AVQ layer */ + Ltmp1 = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q6 -> Q9*/ + Ltmp1 = L_shl( Ltmp1, tmp1_fx ); /* Q16 + Q_exc */ + + /* Compute exc2 */ + Ltmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); + exc2_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); +#endif + + /* code in Q9, gain_pit in Q14 */ + Ltmp = L_mult( gcode16, code_fx[i] ); + Ltmp = L_shl( Ltmp, 5 ); + Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ + exc_fx[i + i_subfr_fx] = round_fx_o( L_add_o( Ltmp, Ltmp1, &Overflow ), &Overflow ); +#else + Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ + + exc_fx[i + i_subfr_fx] = round_fx( L_add( Ltmp, Ltmp1 ) ); +#endif + } + } + ELSE + { + /*-----------------------------------------------------------------* + * Construct adaptive part of the excitation + * Save the non-enhanced excitation for FEC_exc + *-----------------------------------------------------------------*/ + FOR( i = 0; i < L_SUBFR; i++ ) + { + /* code in Q9, gain_pit in Q14 */ + Ltmp = L_mult( gcode16, code_fx[i] ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); + Ltmp = L_mac_o( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx, &Overflow ); + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ + exc_fx[i + i_subfr_fx] = round_fx_o( Ltmp, &Overflow ); +#else + Ltmp = L_shl( Ltmp, 5 ); + Ltmp = L_mac( Ltmp, exc_fx[i + i_subfr_fx], gain_pit_fx ); + Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ + exc_fx[i + i_subfr_fx] = round_fx( Ltmp ); +#endif + } + } + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr_fx, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx, + &voice_factors_fx[i_subfr_fx / L_SUBFR], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_new, + T0_fx, T0_frac_fx, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); + + /*-----------------------------------------------------------------* + * Synthesize speech to update mem_syn[]. + * Update A(z) filters + *-----------------------------------------------------------------*/ + + Syn_filt_s( 1, p_Aq_fx, M, &exc_fx[i_subfr_fx], &syn_fx[i_subfr_fx], L_SUBFR, hLPDmem->mem_syn, 1 ); + + p_Aw_fx += ( M + 1 ); + p_Aq_fx += ( M + 1 ); + pt_pitch_fx++; + } + + /* write reserved bits */ + WHILE( unbits_PI_fx > 0 ) + { + i = s_min( unbits_PI_fx, 16 ); + push_indice( hBstr, IND_UNUSED, 0, i ); + unbits_PI_fx -= i; + } + IF( st_fx->Opt_SC_VBR ) + { + /* SC-VBR */ + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; + move16(); + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + move16(); + } + return; +} diff --git a/lib_enc/enc_higher_acelp_fx.c b/lib_enc/enc_higher_acelp_fx.c index a228b0b6d8e14f86261685f6f2ddf0b4c0aec31e..da58fe7212671e771cf5d8ff01b7761b2866028e 100644 --- a/lib_enc/enc_higher_acelp_fx.c +++ b/lib_enc/enc_higher_acelp_fx.c @@ -2,9 +2,9 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "prot.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ #include "prot_fx.h" @@ -423,6 +423,420 @@ void transf_cdbk_enc_fx( return; } +void transf_cdbk_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ + const Word16 i_subfr, /* i : subframe index */ + Word16 cn[], /* i/o: target vector in residual domain */ + Word16 exc[], /* i/o: pointer to excitation signal frame */ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ + const Word16 Ap[], /* i : weighted LP filter coefficients */ + const Word16 h1[], /* i : weighted filter input response */ + Word16 xn[], /* i/o: target vector */ + Word16 xn2[], /* i/o: target vector for innovation search */ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ + const Word16 y2[], /* i : zero-memory filtered innovative excitation */ + const Word16 Es_pred, /* i : predicited scaled innovation energy */ + Word16 *gain_pit, /* i/o: adaptive excitation gain */ + const Word32 gain_code, /* i : innovative excitation gain */ + Word16 g_corr[], /* o : ACELP correlation values */ + const Word16 clip_gain, /* i : adaptive gain clipping flag */ + Word16 *gain_preQ, /* o : prequantizer excitation gain */ + Word16 code_preQ[], /* o : prequantizer excitation */ + Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 Q_new, /* i : Current frame scaling */ + const Word16 shift /* i : shifting applied to y1, xn,... */ +) +{ + Word16 i, index, nBits, Nsv, Es_pred_loc; + Word16 x_in[L_SUBFR], x_tran[L_SUBFR], gcode16, stmp; + Word16 e_corr, m_corr, e_ener, m_ener, m_den, e_den; + Word16 x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND]; + Word32 L_corr, L_ener, Ltmp, Ltmp1; + Word16 nq[L_SUBFR / WIDTH_BAND]; + Word32 out32[L_SUBFR]; + Word16 Qdct; + Word16 avq_bit_sFlag; + Word16 trgtSvPos; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + avq_bit_sFlag = 0; + move16(); + if ( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + avq_bit_sFlag = 1; + move16(); + } + + /*--------------------------------------------------------------* + * Set bit-allocation + *--------------------------------------------------------------*/ + + Nsv = 8; + move16(); + nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; + move16(); + + /* increase # of AVQ allocated bits by unused bits from the previous subframe */ + nBits = add( nBits, *unbits ); + + /*--------------------------------------------------------------* + * Compute/Update target + * For inactive frame, find target in residual domain + * Deemphasis + *--------------------------------------------------------------*/ + IF( EQ_16( st_fx->coder_type, INACTIVE ) ) + { +#ifdef BASOP_NOGLOB + gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow ); +#else + gcode16 = round_fx( L_shl( gain_code, Q_new ) ); +#endif + FOR( i = 0; i < L_SUBFR; i++ ) + { + /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/ + Ltmp = L_mult( gcode16, y2[i] ); + Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn[i], 16384 ); + Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); + x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */ +#else + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); + x_tran[i] = round_fx( Ltmp ); /*Q_new-1 */ +#endif + } + find_cn_fx( x_tran, Ap, p_Aq, x_in ); + } + ELSE + { + updt_tar_fx( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR ); + } + Deemph2( x_in, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_deemp_preQ_fx ) ); + + /*--------------------------------------------------------------* + * DCT-II + *--------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp ) + { + Copy_Scale_sig( x_in, x_tran, L_SUBFR, -Q_MINUS + 1 ); /*Q_new-1 -> Q_new-4*/ + /*Copy( x_in, x_tran, L_SUBFR );*/ + Qdct = sub( Q_new, Q_MINUS ); + } + ELSE + { + Qdct = 0; + move16(); + edct2_fx( L_SUBFR, -1, x_in, out32, &Qdct, ip_edct2_64, w_edct2_64_fx ); + Qdct = negate( Qdct ); + Copy_Scale_sig_32_16( out32, x_tran, L_SUBFR, sub( Qdct, Q_MINUS - 1 ) ); /* Output in Q_new-4 */ + Qdct = sub( Q_new, Q_MINUS ); + } + + /*--------------------------------------------------------------* + * Split algebraic vector quantizer based on RE8 lattice + *--------------------------------------------------------------*/ + AVQ_cod_fx( x_tran, x_norm, nBits, Nsv, 0 ); + + /*--------------------------------------------------------------* + * Find prequantizer excitation gain + * Quantize the gain + *--------------------------------------------------------------*/ + L_corr = L_deposit_l( 0 ); + L_ener = L_deposit_l( 0 ); + FOR( i = 0; i < Nsv * 8; i++ ) + { + /*fcorr += fx_tran[i]*(float)ix_norm[i];*/ + /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/ +#ifdef BASOP_NOGLOB + stmp = shl_sat( x_norm[i], Q_AVQ_OUT ); + L_corr = L_mac_sat( L_corr, x_tran[i], stmp ); + L_ener = L_mac_sat( L_ener, stmp, stmp ); +#else + stmp = shl( x_norm[i], Q_AVQ_OUT ); + L_corr = L_mac( L_corr, x_tran[i], stmp ); + L_ener = L_mac( L_ener, stmp, stmp ); +#endif + } + L_ener = L_max( L_ener, 1 ); + + /* No negative gains allowed in the quantizer*/ + L_corr = L_max( L_corr, 0 ); + + e_corr = norm_l( L_corr ); + m_corr = extract_h( L_shl( L_corr, e_corr ) ); + e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) ); + e_ener = norm_l( L_ener ); + m_ener = extract_h( L_shl( L_ener, e_ener ) ); + e_ener = sub( 30, e_ener ); + + IF( GT_16( m_corr, m_ener ) ) + { + m_corr = shr( m_corr, 1 ); + e_corr = add( e_corr, 1 ); + } + m_corr = div_s( m_corr, m_ener ); + e_corr = sub( e_corr, e_ener ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ +#else + Ltmp = L_shl( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */ +#endif + IF( EQ_16( st_fx->coder_type, INACTIVE ) ) + { + Ltmp1 = L_max( gain_code, 1 ); + e_den = norm_l( Ltmp1 ); +#ifdef BASOP_NOGLOB + m_den = extract_h( L_shl_sat( Ltmp1, e_den ) ); +#else + m_den = extract_h( L_shl( Ltmp1, e_den ) ); +#endif + /* ensure m_corr < m_den */ + test(); + IF( m_corr > 0 && m_den > 0 ) + { + m_corr = div_s( 16384, m_den ); + e_corr = sub( 14 + 4, e_den ); + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/ +#ifdef BASOP_NOGLOB + stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); +#else + stmp = round_fx( L_shl( Ltmp, 16 ) ); +#endif + } + ELSE + { + stmp = 0; + move16(); + } + IF( GT_32( st_fx->core_brate, 56000 ) ) + { + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + } + ELSE IF( GT_32( st_fx->core_brate, 42000 ) ) + { + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + } + ELSE + { + index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); + } + Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/ +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/ + *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/ +#else + Ltmp = L_shl( Ltmp, 5 ); /* Q13 -> Q18*/ + *gain_preQ = round_fx( Ltmp ); /* Q2*/ +#endif + } + ELSE + { + IF( Es_pred < 0 ) + { + Es_pred_loc = shr( negate( Es_pred ), 2 ); + } + ELSE + { + Es_pred_loc = Es_pred; + move16(); + } + + e_den = norm_s( Es_pred_loc ); + m_den = shl( Es_pred_loc, e_den ); + /* ensure m_corr < m_den */ + test(); + IF( m_corr > 0 && m_den > 0 ) + { + m_corr = div_s( 16384, m_den ); + e_corr = sub( 14 - 8, e_den ); + Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); + } + ELSE + { + Ltmp = L_deposit_l( 0 ); + } + test(); + IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) ) + { + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + } + ELSE + { + index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); + } + Ltmp = L_mult( stmp, Es_pred_loc ); /* Q0*Q8 -> Q9*/ + Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/ + *gain_preQ = round_fx( Ltmp ); /* Q2*/ + } + push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS ); + + /*--------------------------------------------------------------* + * Encode and multiplex subvectors into bit-stream + *--------------------------------------------------------------*/ + trgtSvPos = Nsv - 1; + move16(); + test(); + test(); + test(); + test(); + test(); + IF( avq_bit_sFlag && GT_16( nBits, 85 ) && !harm_flag_acelp && ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, TRANSITION ) || EQ_16( st_fx->coder_type, INACTIVE ) ) ) + { + trgtSvPos = 2; + avq_bit_sFlag = 2; + move16(); + move16(); + } + + AVQ_encmux_ivas_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos ); + + /* save # of AVQ unused bits for next subframe */ + *unbits = nBits; + move16(); + + /* at the last subframe, write AVQ unused bits */ + test(); + test(); + IF( EQ_16( i_subfr, 4 * L_SUBFR ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) ) + { + WHILE( *unbits > 0 ) + { + i = s_min( *unbits, 16 ); + push_indice( st_fx->hBstr, IND_UNUSED, 0, i ); + *unbits -= i; + } + } + + /*--------------------------------------------------------------* + * DCT transform + *--------------------------------------------------------------*/ + + FOR( i = 0; i < Nsv * WIDTH_BAND; i++ ) + { +#ifdef BASOP_NOGLOB + x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow ); +#else + x_tran[i] = shl( x_norm[i], Q_AVQ_OUT_DEC ); +#endif + move16(); + } + set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) ); + + test(); + test(); + test(); + IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp ) + { + Copy( x_tran, code_preQ, L_SUBFR ); + } + ELSE + { + Qdct = 0; + move16(); + edct2_fx( L_SUBFR, 1, x_tran, out32, &Qdct, ip_edct2_64, w_edct2_64_fx ); + /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/ + Qdct = negate( Qdct ); + Copy_Scale_sig_32_16( out32, code_preQ, L_SUBFR, Qdct ); /* Output in Q_AVQ_OUT_DEC */ + /*qdct = Q_AVQ_OUT_DEC;*/ + } + + /*--------------------------------------------------------------* + * Preemphasise + *--------------------------------------------------------------*/ + /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ + test(); + if ( ( nq[7] != 0 ) && ( GT_16( sub( st_fx->last_nq_preQ, nq[0] ), 7 ) ) ) + { + /* *mem_preemp /= 16; */ + st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 ); + move16(); + } + st_fx->last_nq_preQ = nq[7]; + move16(); +#if 1 // def IVAS_CODE + /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */ + test(); + test(); + test(); + test(); + test(); + IF( GT_16( st_fx->element_mode, EVS_MONO ) && NE_16( st_fx->coder_type, INACTIVE ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && !harm_flag_acelp && code_preQ[0] != 0 ) + { + // if ( (float) abs( st->last_code_preq ) > 16.0f * (float) fabs( code_preQ[0] ) ) + if ( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 4 ) ) ) + { + st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 ); + move16(); + } + // else if ( (float) abs( st->last_code_preq ) > 8.0f * (float) fabs( code_preQ[0] ) ) + if ( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 3 ) ) ) + { + st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 3 ); + move16(); + } + } + + // st->last_code_preq = (int16_t) code_preQ[L_SUBFR - 1]; + st_fx->last_code_preq = shr( code_preQ[L_SUBFR - 1], 9 ); // Q0 +#endif + PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) ); + + /*--------------------------------------------------------------* + * For inactive segments + * - Zero-memory filtered pre-filter excitation + * - Update of targets and gain_pit + * For inactive segments + * - Update xn[L_subfr-1] for updating the memory of the weighting filter + *--------------------------------------------------------------*/ + + IF( EQ_16( st_fx->coder_type, INACTIVE ) ) + { + /*ftemp = fcode_preQ[0] *fh1[L_SUBFR-1];*/ + Ltmp = L_mult( code_preQ[0], h1[L_SUBFR - 1] ); /*1+14+shift + Q_AVQ_OUT */ + FOR( i = 1; i < L_SUBFR; i++ ) + { + /*ftemp += fcode_preQ[i] * fh1[L_SUBFR-1-i];*/ + Ltmp = L_mac( Ltmp, code_preQ[i], h1[L_SUBFR - 1 - i] ); + } + /*fxn[L_SUBFR-1] -= *fgain_preQ * ftemp;*/ + Ltmp = L_shr( Mult_32_16( Ltmp, *gain_preQ ), sub( add( Q_AVQ_OUT_DEC, 2 ), Q_new ) ); /* (2 + 1 + 14 +shift+Q_AVQ_OUT)-(Q_AVQ_OUT+2-Q_new) = 15 + Q_new + shift */ + xn[L_SUBFR - 1] = round_fx( L_sub( L_mult( xn[L_SUBFR - 1], 32767 ), Ltmp ) ); /* -> Q_new + shift -1 */ + } + ELSE + { + conv_fx( code_preQ, h1, x_tran, L_SUBFR ); + updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); + + updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR ); +#ifdef BASOP_NOGLOB + *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); +#else + *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0 ); +#endif + /* clip gain if necessary to avoid problems at decoder */ + test(); + if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) + { + *gain_pit = 15565; + move16(); + } + updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR ); + } + + st_fx->use_acelp_preq = 1; + move16(); + + return; +} /*-------------------------------------------------------------------* * Find target in residual domain - cn[] *-------------------------------------------------------------------*/ diff --git a/lib_enc/enc_pit_exc_fx.c b/lib_enc/enc_pit_exc_fx.c index 6385420fe81a161f1a934be3fe2cf9a131ddb0c0..03b02fe96737e5f5701c8600564d519de4240fcf 100644 --- a/lib_enc/enc_pit_exc_fx.c +++ b/lib_enc/enc_pit_exc_fx.c @@ -2,11 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -554,6 +554,522 @@ void enc_pit_exc_fx( } } +#ifdef BASOP_NOGLOB + cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ +#else /* BASOP_NOGLOB */ + cum_gpit = shl( cum_gpit, 1 ); /*Q15*/ +#endif + *gpit = round_fx( L_mac( L_mult( 3277, *gpit ), 29491, cum_gpit ) ); /*Q15*/ +} + +void enc_pit_exc_ivas_fx( + Encoder_State *st_fx, /* i/o: State structure */ + const Word16 *speech, /* i : Input speech */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred, /* i : predicted scaled innov. energy */ + const Word16 *res, /* i : residual signal */ + Word16 *synth, /* i/o: core synthesis */ + Word16 *exc, /* i/o: current non-enhanced excitation */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + Word16 *gpit, /* o : pitch mean gpit */ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new, + Word16 shift ) +{ + Word16 xn[PIT_EXC_L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[PIT_EXC_L_SUBFR]; /* Target vector for codebook search */ + Word16 h1[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 y1[PIT_EXC_L_SUBFR]; /* Filtered adaptive excitation */ + Word16 code[2 * L_SUBFR]; /* Fixed codebook excitation */ + Word16 y2[2 * L_SUBFR]; /* Filtered algebraic excitation */ + Word16 voice_fac; /* Voicing factor */ + Word32 gain_code; /* Gain of code */ + Word16 gain_inov; /* inovation gain */ + Word16 gain_pit; /* Pitch gain */ + Word16 pit_idx, i_subfr; /* tmp variables */ + Word16 T0_min, T0_max; /* pitch variables */ + Word16 g_corr[10]; /* ACELP correlation values + gain pitch */ + Word16 clip_gain, i; /* LSF clip gain and LP flag */ + const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */ + Word16 cn1[PIT_EXC_L_SUBFR], *cn; /* (Used only when L_subfr == L_SUBFR) Target vector in residual domain */ + Word16 *pt_pitch; /* pointer to floating pitch */ + Word16 L_subfr; + Word16 cum_gpit, gpit_tmp; + Word32 Local_BR, Pitch_BR; + Word16 Pitch_CT, unbits_PI = 0; /* saved bits for PI */ + Word32 norm_gain_code; + Word16 pitch_limit_flag; + Word16 h2[PIT_EXC_L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word32 Ltmp; + Word32 Lgcode; + Word16 gcode16; + Word16 shift_wsp; + Word16 lp_select, lp_flag; + Word16 use_fcb; + Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */ + Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes*/ + SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*------------------------------------------------------------------* + * Initialization + *------------------------------------------------------------------*/ + + pitch_limit_flag = 1; + move16(); /* always extended pitch Q range */ + use_fcb = 0; + unbits_PI = 0; + test(); + test(); + Pitch_CT = GENERIC; + move16(); + + IF( st_fx->GSC_IVAS_mode > 0 && ( st_fx->GSC_noisy_speech || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) ) + { + Local_BR = ACELP_8k00; + Pitch_BR = ACELP_8k00; + move32(); + move32(); + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Local_BR = ACELP_14k80; + move32(); + if ( st_fx->GSC_IVAS_mode > 0 ) + { + Local_BR = ACELP_9k60; + move32(); + } + Pitch_BR = st_fx->core_brate; + move32(); + } + } + ELSE IF( st_fx->GSC_noisy_speech ) + { + Local_BR = ACELP_7k20; + move32(); + Pitch_BR = ACELP_7k20; + move32(); + Pitch_CT = GENERIC; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Pitch_BR = st_fx->core_brate; + move32(); + } + } + ELSE + { + + Local_BR = ACELP_7k20; + move32(); + Pitch_BR = st_fx->core_brate; + move32(); + Pitch_CT = AUDIO; + move16(); + + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Local_BR = ACELP_13k20; + move32(); + Pitch_CT = GENERIC; + move16(); + } + } + gain_code = 0; + move16(); + + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + T0_max = PIT16k_MAX; + T0_min = PIT16k_MIN; + } + ELSE + { + T0_max = PIT_MAX; + move16(); + T0_min = PIT_MIN; + move16(); + } + cum_gpit = 0; + move16(); + + L_subfr = mult_r( st_fx->L_frame, div_s( 1, nb_subfr ) ); + + lp_flag = st_fx->acelp_cfg.ltf_mode; + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && + ( ( EQ_16( st_fx->L_frame, L_FRAME ) && GE_32( st_fx->core_brate, ACELP_13k20 ) ) || + ( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, GSC_H_RATE_STG ) ) || st_fx->GSC_IVAS_mode == 0 ) ) ) && + EQ_16( L_subfr, L_SUBFR ) ) ) + { + use_fcb = 1; + move16(); + } + ELSE IF( st_fx->GSC_IVAS_mode > 0 && EQ_16( L_subfr, 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) + { + use_fcb = 2; + st_fx->acelp_cfg.fcb_mode = 1; + move16(); + move16(); + set16_fx( st_fx->acelp_cfg.gains_mode, 6, NB_SUBFR ); + set16_fx( st_fx->acelp_cfg.pitch_bits, 9, NB_SUBFR ); + set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, NB_SUBFR16k ); + } + + *saved_bit_pos = st_fx->next_bit_pos_fx; + move16(); + + /*------------------------------------------------------------------* + * ACELP subframe loop + *------------------------------------------------------------------*/ + cn = NULL; + if ( EQ_16( L_subfr, L_SUBFR ) || EQ_16( L_subfr, L_SUBFR * 2 ) ) + { + cn = cn1; + move16(); + } + p_Aw = Aw; + + p_Aq = Aq; + pt_pitch = pitch_buf; /* pointer to the pitch buffer */ + shift_wsp = add( Q_new, shift ); + FOR( i_subfr = 0; i_subfr < st_fx->L_frame; i_subfr += L_subfr ) + { + + /*----------------------------------------------------------------* + * Bandwidth expansion of A(z) filter coefficients + * Find the the excitation search target "xn" and innovation + * target in residual domain "cn" + * Compute impulse response, h1[], of weighted synthesis filter + *----------------------------------------------------------------*/ + Copy( &res[i_subfr], &exc[i_subfr], L_subfr ); + /* condition on target (compared to float) has been put outside the loop */ +#if 1 // ndef BUG_FIX + find_targets_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, + res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); +#else + find_targets_fx( speech, hGSCEnc->mem_syn_tmp_fx, i_subfr, &hLPDmem->mem_w0, p_Aq, /*_DIFF_FLOAT_FIX_ --> Here I think mem_syn_tmp_fx should be used */ + res, L_subfr, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); +#endif + Copy_Scale_sig( h1, h2, L_subfr, -2 ); + Scale_sig( h1, L_subfr, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + + /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn, L_subfr, shift ); + + /*----------------------------------------------------------------* + * Close-loop pitch search and quantization + * Adaptive exc. construction + *----------------------------------------------------------------*/ + *pt_pitch = pit_encode_ivas_fx( hBstr, st_fx->acelp_cfg.pitch_bits, Pitch_BR, 0, st_fx->L_frame, Pitch_CT, &pitch_limit_flag, i_subfr, exc, + L_subfr, st_fx->pitch, &T0_min, &T0_max, T0, T0_frac, h1, xn, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); + /*-----------------------------------------------------------------* + * Find adaptive exitation + *-----------------------------------------------------------------*/ + + pred_lt4( &exc[i_subfr], &exc[i_subfr], *T0, *T0_frac, L_subfr + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + /*-----------------------------------------------------------------* + * Gain clipping test to avoid unstable synthesis on frame erasure + * or in case of floating point encoder & fixed p. decoder + *-----------------------------------------------------------------*/ + + clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, AUDIO, xn, st_fx->clip_var_fx, sub( shift_wsp, 1 ) ); + + /*-----------------------------------------------------------------* + * Codebook target computation + * (No LP filtering of the adaptive excitation) + *-----------------------------------------------------------------*/ + + lp_select = lp_filt_exc_enc_fx( MODE1, AUDIO, i_subfr, exc, h1, + xn, y1, xn2, L_subfr, st_fx->L_frame, g_corr, clip_gain, &gain_pit, &lp_flag ); + + IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) + { + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + } + + /*st_fx->lowrate_pitchGain = 0.9f * st_fx->lowrate_pitchGain + 0.1f * gain_pit;*/ +#ifdef BASOP_NOGLOB + hSpMusClas->lowrate_pitchGain = round_fx_o( L_mac_o( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit, &Overflow ), &Overflow ); /*Q14*Q16(0.1) + Q15 -> Q15*/ +#else + hSpMusClas->lowrate_pitchGain = round_fx( L_mac( L_mult( 29491, hSpMusClas->lowrate_pitchGain ), 6554, gain_pit ) ); /*Q14*Q16(0.1) + Q15 -> Q15*/ +#endif + + gpit_tmp = gain_pit; + move16(); /*Q14*/ + test(); + IF( use_fcb > 0 ) + { + /* h2 in Q12 for codebook search */ + /* h1 has been scaled with 1 + shift so we need to remove 2 and (1+shift) = -3 - shift*/ + Copy_Scale_sig( h1, h2, L_subfr, sub( -2 - 1, shift ) ); + } + + IF( use_fcb == 0 ) + { + IF( GE_32( st_fx->core_brate, MIN_RATE_FCB ) ) + { + pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 32 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 5 ); + } + ELSE + { + pit_idx = vquant_fx( &gain_pit, mean_gp_fx, &gain_pit, dic_gp_fx, 1, 16 ); + push_indice( hBstr, IND_PIT_IDX, pit_idx, 4 ); + } + } + else if ( use_fcb == 2 ) + { + /*-----------------------------------------------------------------* + * Innovation encoding + *-----------------------------------------------------------------*/ + + inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, st_fx->last_L_frame, GENERIC, st_fx->bwidth, 0, i_subfr, -1, p_Aq, + gain_pit, cn, exc, h2, st_fx->hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, 2 * L_SUBFR, shift, Q_new ); + // PMT("code to be validated") + /*-----------------------------------------------------------------* + * Gain encoding + *-----------------------------------------------------------------*/ + + gain_enc_lbr_ivas_fx( st_fx->hBstr, st_fx->acelp_cfg.gains_mode, GENERIC, i_subfr, xn, y1, sub( shift_wsp, 1 ), y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gc_mem, gp_mem, clip_gain, 2 * L_SUBFR ); + } + ELSE + { + /*-----------------------------------------------------------------* + * Innovation & gain encoding + *-----------------------------------------------------------------*/ + + inov_encode_ivas_fx( st_fx, Local_BR, 0, st_fx->L_frame, st_fx->last_L_frame, LOCAL_CT, WB, 1, i_subfr, -1, p_Aq, + gain_pit, cn, exc, h2, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR, shift, Q_new ); + /*-----------------------------------------------------------------* + * Gain encoding + *-----------------------------------------------------------------*/ + gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_FRAME, i_subfr, -1, xn, y1, sub( shift_wsp, 1 ), y2, code, Es_pred, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain ); + } + gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); + +#ifdef BASOP_NOGLOB + Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_sat( Lgcode ); +#else + Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx( Lgcode ); +#endif + IF( use_fcb != 0 ) + { + hLPDmem->tilt_code = Est_tilt2( &exc[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + move16(); + } + ELSE + { + hLPDmem->tilt_code = 0; + move16(); + } + /*-----------------------------------------------------------------* + * Update memory of the weighting filter + *-----------------------------------------------------------------*/ + IF( use_fcb != 0 ) + { + Ltmp = L_mult0( gcode16, y2[L_subfr - 1] ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_o( Ltmp, add( 5, shift ), &Overflow ); // Q_new+14+shift + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac_o( Ltmp, xn[L_subfr - 1], 16384, &Overflow ); // Q_new-1+15+shift + Ltmp = L_msu_o( Ltmp, y1[L_subfr - 1], gain_pit, &Overflow ); // Q_new-1+15+shift + Ltmp = L_shl_o( Ltmp, sub( 1, shift ), &Overflow ); // Q_new+15 + hLPDmem->mem_w0 = round_fx_o( Ltmp, &Overflow ); /*Q_new-1 */ +#else + Ltmp = L_mult( gcode16, y2[L_subfr - 1] ); + Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn[L_subfr - 1], 16384 ); + Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); + hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ +#endif + } + ELSE + { + Ltmp = L_mult( xn[L_subfr - 1], 16384 ); +#ifdef BASOP_NOGLOB + Ltmp = L_msu_sat( Ltmp, y1[L_subfr - 1], gain_pit ); + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); + hLPDmem->mem_w0 = round_fx_sat( Ltmp ); /*Q_new-1 */ +#else + Ltmp = L_msu( Ltmp, y1[L_subfr - 1], gain_pit ); + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); + hLPDmem->mem_w0 = round_fx( Ltmp ); /*Q_new-1 */ +#endif + } + + /*-----------------------------------------------------------------* + * Construct adaptive part of the excitation + * Save the non-enhanced excitation for FEC_exc + *-----------------------------------------------------------------*/ + IF( use_fcb != 0 ) + { + FOR( i = 0; i < L_subfr; i++ ) + { + /* code in Q9, gain_pit in Q14 */ + Ltmp = L_mult( gcode16, code[i] ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_o( Ltmp, 5, &Overflow ); + Ltmp = L_mac_o( Ltmp, exc[i + i_subfr], gain_pit, &Overflow ); + Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */ + exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow ); +#else + Ltmp = L_mult( gcode16, code[i] ); + Ltmp = L_shl( Ltmp, 5 ); + Ltmp = L_mac( Ltmp, exc[i + i_subfr], gain_pit ); + Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ + exc[i + i_subfr] = round_fx( Ltmp ); +#endif + } + } + ELSE + { + FOR( i = 0; i < L_subfr; i++ ) + { + + Ltmp = L_mult( exc[i + i_subfr], gain_pit ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ + exc[i + i_subfr] = round_fx_sat( Ltmp ); +#else + Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ + exc[i + i_subfr] = round_fx( Ltmp ); +#endif + } + } + + /*-----------------------------------------------------------------* + * Synthesize speech to update mem_syn[]. + * Update A(z) filters + *-----------------------------------------------------------------*/ + + Syn_filt_s( 1, p_Aq, M, &exc[i_subfr], &synth[i_subfr], L_subfr, hGSCEnc->mem_syn_tmp_fx, 1 ); + + IF( EQ_16( L_subfr, 5 * L_SUBFR ) ) + { + cum_gpit = gpit_tmp; + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + + p_Aw += 5 * ( M + 1 ); + p_Aq += 5 * ( M + 1 ); + } + ELSE IF( EQ_16( L_subfr, 5 * L_SUBFR / 2 ) ) + { + IF( i_subfr == 0 ) + { + cum_gpit = mult_r( gpit_tmp, 13107 ); /* .4f*/ + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + p_Aw += 2 * ( M + 1 ); + p_Aq += 2 * ( M + 1 ); + } + ELSE + { + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 19660 ) ); /*0.6*/ + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + p_Aw += 3 * ( M + 1 ); + p_Aq += 3 * ( M + 1 ); + } + } + ELSE IF( EQ_16( L_subfr, 2 * L_SUBFR ) ) + { + IF( i_subfr == 0 ) + { + cum_gpit = mult_r( gpit_tmp, 16384 ); + } + ELSE + { + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 16384 ) ); + } + p_Aw += 2 * ( M + 1 ); + move16(); + p_Aq += 2 * ( M + 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + } + ELSE IF( EQ_16( L_subfr, 4 * L_SUBFR ) ) + { + cum_gpit = gpit_tmp; + move16(); + + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + move16(); + pt_pitch++; + *pt_pitch = *( pt_pitch - 1 ); + pt_pitch++; + p_Aw += 4 * ( M + 1 ); + p_Aq += 4 * ( M + 1 ); + } + ELSE + { + IF( i_subfr == 0 ) + { + + cum_gpit = mult_r( gpit_tmp, 8192 ); + } + ELSE + { + cum_gpit = add( cum_gpit, mult_r( gpit_tmp, 8192 ) ); + } + + pt_pitch++; + p_Aw += ( M + 1 ); + p_Aq += ( M + 1 ); + } + } + #ifdef BASOP_NOGLOB cum_gpit = shl_o( cum_gpit, 1, &Overflow ); /*Q15*/ #else /* BASOP_NOGLOB */ diff --git a/lib_enc/enc_tran_fx.c b/lib_enc/enc_tran_fx.c index d3127ccda1e79619dae577f0381a8fff783ef81b..395a73d20247118c72754af674caf26e510aa595 100644 --- a/lib_enc/enc_tran_fx.c +++ b/lib_enc/enc_tran_fx.c @@ -7,6 +7,7 @@ //#include "prot_fx.h" /* Function prototypes */ #include "rom_com_fx.h" /* Static table prototypes */ #include "rom_com.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -446,3 +447,407 @@ Word16 encod_tran_fx( return tc_subfr; } + +Word16 encod_tran_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 speech_fx[], /* i : input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* i/o: core synthesis */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + Word16 tc_subfr, /* i/o: TC subframe classification */ + Word16 position, /* i : maximum of residual signal index */ + Word16 *unbits, /* i/o: number of unused bits */ + const Word16 shift, /* i : Scaling to get 12 bits */ + const Word16 Q_new /* i : Input scaling */ +) +{ + Word16 xn[L_SUBFR]; /* Target vector for pitch search */ + Word16 xn2[L_SUBFR]; /* Target vector for codebook search */ + Word16 cn[L_SUBFR]; /* Target vector in residual domain */ + Word16 h1[L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 h2_fx[L_SUBFR + ( M + 1 )]; /* Impulse response vector */ + Word16 code[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 y2[L_SUBFR]; /* Filtered algebraic excitation */ + Word16 gain_pit = 0, Gain_pitX2, gcode16; /* Pitch gain */ + Word16 voice_fac; /* Voicing factor */ + Word32 gain_code = 0; /* Gain of code */ + Word32 Lgcode; + Word16 gain_inov = 0; /* inovation gain */ + Word16 i, i_subfr, tmp1_fx, tmp_fx; /* tmp variables */ + Word16 unbits_ACELP; + Word16 T0_min, T0_max; /* pitch and TC variables */ + Word16 T0, T0_frac; /* close loop integer pitch and fractional part */ + Word16 *pt_pitch; /* pointer to floating pitch buffer */ + Word16 g_corr[10]; /* ACELP correlation values and gain pitch */ + Word16 clip_gain; /* LSF clip gain */ + const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */ + Word16 gain_preQ = 0; /* Gain of prequantizer excitation */ + Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */ + Word16 Jopt_flag; /* joint optimization flag */ + Word16 unbits_PI = 0; /* saved bits for PI */ + Word32 norm_gain_code = 0; + Word16 L_frame_fx; + Word16 shift_wsp; + Word32 L_tmp; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + + L_frame_fx = st_fx->L_frame; + move16(); + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + gain_pit = 0; + move16(); + gain_code = L_deposit_l( 0 ); + gain_preQ = 0; + move16(); + unbits_PI = 0; + move16(); + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + T0_max = PIT_MAX; + move16(); + T0_min = PIT_MIN; + move16(); + } + ELSE /* L_frame == L_FRAME16k */ + { + T0_max = PIT16k_MAX; + move16(); + T0_min = PIT16k_MIN; + move16(); + } + + /**unbits = 0;move16();*/ + Jopt_flag = 0; + move16(); + unbits_ACELP = *unbits; + move16(); + *unbits = 0; + move16(); + + p_Aw = Aw_fx; + p_Aq = Aq_fx; + pt_pitch = pitch_buf_fx; + gain_preQ = 0; + move16(); + set16_fx( code_preQ, 0, L_SUBFR ); + shift_wsp = add( Q_new, shift ); + + /*----------------------------------------------------------------* + * ACELP subframe loop + *----------------------------------------------------------------*/ + + FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR ) + { + /*----------------------------------------------------------------* + * Find the the excitation search target "xn" and innovation + * target in residual domain "cn" + * Compute impulse response, h1[], of weighted synthesis filter + *----------------------------------------------------------------*/ + + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + + find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, + res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 ); + + Copy_Scale_sig( h1, h2_fx, L_SUBFR, -2 ); + Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + + /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn, L_SUBFR, shift ); + + /*-----------------------------------------------------------------* + * TC: subframe determination & + * adaptive/glottal part of excitation construction + *-----------------------------------------------------------------*/ + + transition_enc_ivas_fx( st_fx, i_subfr, &tc_subfr, &Jopt_flag, &position, &T0, &T0_frac, &T0_min, &T0_max, exc_fx, y1, + h1, xn, xn2, st_fx->clip_var_fx, &gain_pit, g_corr, &clip_gain, &pt_pitch, bwe_exc_fx, &unbits_ACELP, Q_new, shift ); + + /*-----------------------------------------------------------------* + * Transform domain contribution encoding - active frames + *-----------------------------------------------------------------*/ + + IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) + { + transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr, cn, exc_fx, p_Aq, Aw_fx, h1, xn, xn2, y1, y2, Es_pred_fx, + &gain_pit, gain_code, g_corr, clip_gain, &gain_preQ, code_preQ, unbits, Q_new, shift ); + } + + /*-----------------------------------------------------------------* + * ACELP codebook search + pitch sharpening + *-----------------------------------------------------------------*/ + + inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, st_fx->last_L_frame, st_fx->coder_type, st_fx->bwidth, st_fx->sharpFlag, + i_subfr, tc_subfr, p_Aq, gain_pit, cn, exc_fx, h2_fx, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR, shift, Q_new ); + + test(); + test(); + test(); + if ( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) && ( EQ_16( T0, 2 * L_SUBFR ) ) ) + { + Jopt_flag = 1; + move16(); + } + /*-----------------------------------------------------------------* + * Quantize the gains + * Test quantized gain of pitch for pitch clipping algorithm + * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced) + *-----------------------------------------------------------------*/ + IF( Jopt_flag == 0 ) + { + /* SQ gain_code */ + gain_enc_tc_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, sub( shift_wsp, 1 ) ); + } + ELSE + { + IF( GT_32( st_fx->core_brate, ACELP_32k ) ) + { + /* SQ gain_pit and gain_code */ + gain_enc_SQ_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y1, y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain, sub( shift_wsp, 1 ) ); + } + ELSE + { + /* VQ gain_pit and gain_code */ + gain_enc_mless_ivas_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame_fx, i_subfr, tc_subfr, xn, y1, sub( shift_wsp, 1 ), y2, code, Es_pred_fx, + &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain ); + } + } + gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx ); + +#ifdef BASOP_NOGLOB + Lgcode = L_shl_o( gain_code, Q_new, &Overflow ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx_o( Lgcode, &Overflow ); +#else + Lgcode = L_shl( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/ + gcode16 = round_fx( Lgcode ); +#endif + hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); + /*-----------------------------------------------------------------* + * Update memory of the weighting filter + *-----------------------------------------------------------------*/ + + /*st->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]);*/ + L_tmp = L_mult0( gcode16, y2[L_SUBFR - 1] ); + L_tmp = L_shl( L_tmp, add( 5, shift ) ); // Q_new+14+shift + L_tmp = L_negate( L_tmp ); + L_tmp = L_mac( L_tmp, xn[L_SUBFR - 1], 16384 ); // Q_new-1+15+shift + L_tmp = L_msu( L_tmp, y1[L_SUBFR - 1], gain_pit ); // Q_new-1+15+shift +#ifdef BASOP_NOGLOB + L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); // Q_new+15 + hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/ +#else + L_tmp = L_shl( L_tmp, sub( 1, shift ) ); + hLPDmem->mem_w0 = round_fx( L_tmp ); /*Q_new-1*/ +#endif + /*-----------------------------------------------------------------* + * Construct adaptive part of the excitation + * Save the non-enhanced excitation for FEC_exc + *-----------------------------------------------------------------*/ + + /* Here, all these conditions have one purpose: to use */ + /* the most efficient loop (the one with the least ops) */ + /* This is done by upscaling gain_pit_fx and/or gain_code16 */ + /* when they don't use all 16 bits of precision */ + + /* exc Q_exc, gpit Q14, code Q12, gcode Q0 */ + IF( norm_s( gain_pit ) == 0 ) + { + FOR( i = 0; i < L_SUBFR; i++ ) + { +#ifdef BASOP_NOGLOB + exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); +#else + exc2_fx[i + i_subfr] = round_fx( L_shl( L_mult( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); +#endif + } + } + ELSE + { + Gain_pitX2 = shl( gain_pit, 1 ); + FOR( i = 0; i < L_SUBFR; i++ ) + { + exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); + } + } + + /*-----------------------------------------------------------------* + * Construct adaptive part of the excitation + * Save the non-enhanced excitation for FEC_exc + *-----------------------------------------------------------------*/ + FOR( i = 0; i < L_SUBFR; i++ ) + { + /* code in Q9, gain_pit in Q14 */ + L_tmp = L_mult( gcode16, code[i] ); +#ifdef BASOP_NOGLOB + L_tmp = L_shl_o( L_tmp, 5, &Overflow ); + L_tmp = L_mac_o( L_tmp, exc_fx[i + i_subfr], gain_pit, &Overflow ); + L_tmp = L_shl_o( L_tmp, 1, &Overflow ); /* saturation can occur here */ + exc_fx[i + i_subfr] = round_fx_o( L_tmp, &Overflow ); +#else + L_tmp = L_shl( L_tmp, 5 ); + L_tmp = L_mac( L_tmp, exc_fx[i + i_subfr], gain_pit ); + L_tmp = L_shl( L_tmp, 1 ); /* saturation can occur here */ + exc_fx[i + i_subfr] = round_fx( L_tmp ); +#endif + } + + /*-----------------------------------------------------------------* + * Add the ACELP pre-quantizer contribution + *-----------------------------------------------------------------*/ + + IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) ) + { + tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new ); + FOR( i = 0; i < L_SUBFR; i++ ) + { + L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/ +#ifdef BASOP_NOGLOB + L_tmp = L_shl_o( L_tmp, tmp1_fx, &Overflow ); /* Q16 + Q_exc */ + tmp_fx = round_fx_o( L_tmp, &Overflow ); + + exc2_fx[i + i_subfr] = add_o( exc2_fx[i + i_subfr], tmp_fx, &Overflow ); + move16(); + exc_fx[i + i_subfr] = add_o( exc_fx[i + i_subfr], tmp_fx, &Overflow ); + move16(); +#else + L_tmp = L_shl( L_tmp, tmp1_fx ); /* Q16 + Q_exc */ + tmp_fx = round_fx( L_tmp ); + + exc2_fx[i + i_subfr] = add( exc2_fx[i + i_subfr], tmp_fx ); + move16(); + exc_fx[i + i_subfr] = add( exc_fx[i + i_subfr], tmp_fx ); + move16(); +#endif + } + } + + /*-----------------------------------------------------------------* + * Prepare TBE excitation + *-----------------------------------------------------------------*/ + + prep_tbe_exc_ivas_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], + bwe_exc_fx, gain_preQ, code_preQ, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, + st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag ); + + /*-----------------------------------------------------------------* + * Synthesize speech to update mem_syn[]. + * Update A(z) filters + *-----------------------------------------------------------------*/ + + Syn_filt_s( 1, p_Aq, M, &exc_fx[i_subfr], &syn_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 ); + + p_Aw += ( M + 1 ); + p_Aq += ( M + 1 ); + pt_pitch++; + } + + /* write reserved bits */ + WHILE( unbits_PI > 0 ) + { + i = s_min( unbits_PI, 16 ); + push_indice( hBstr, IND_UNUSED, 0, i ); + unbits_PI -= i; + } + + /* write TC configuration */ + IF( EQ_16( L_frame_fx, L_FRAME ) ) + { + IF( EQ_16( tc_subfr, TC_0_0 ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + ELSE IF( EQ_16( tc_subfr, TC_0_64 ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + ELSE IF( EQ_16( tc_subfr, TC_0_128 ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + } + ELSE IF( EQ_16( tc_subfr, TC_0_192 ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + IF( tc_subfr == 0 ) + { + push_indice( hBstr, IND_TC_SUBFR, 0, 2 ); + } + ELSE IF( EQ_16( tc_subfr, L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 1, 2 ); + } + ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 2, 2 ); + } + ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 0, 1 ); + } + ELSE IF( EQ_16( tc_subfr, 4 * L_SUBFR ) ) + { + push_indice( hBstr, IND_TC_SUBFR, 3, 2 ); + push_indice( hBstr, IND_TC_SUBFR, 1, 1 ); + } + } + + IF( st_fx->Opt_SC_VBR ) + { + /* SC-VBR */ + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; + move16(); + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + move16(); + } + + return tc_subfr; +} diff --git a/lib_enc/enc_uv_fx.c b/lib_enc/enc_uv_fx.c index 981d02a868bfe60a1a220de6e22de478ff260342..f87220008b072e6485429c49e80d5b2bfb78db0e 100644 --- a/lib_enc/enc_uv_fx.c +++ b/lib_enc/enc_uv_fx.c @@ -5,7 +5,7 @@ #include #include "options.h" /* Compilation switches */ #include "cnst.h" /* Common constants */ -//#include "prot_fx.h" /* Function prototypes */ +#include "prot.h" /* Function prototypes */ #include "rom_com.h" #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -262,3 +262,264 @@ void encod_unvoiced_fx( return; } + +void encod_unvoiced_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 *speech_fx, /* i : Input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ + const Word16 Es_pred, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* o : core synthesis */ + Word16 *tmp_noise_fx, /* o : long-term noise energy */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 Q_new, + const Word16 shift ) +{ + Word16 xn_fx[L_SUBFR]; /* Target vector for pitch search */ + Word16 h1_fx[L_SUBFR]; /* Impulse response vector */ + Word16 code_fx[L_SUBFR]; /* Fixed codebook excitation */ + Word16 y2_fx[L_SUBFR]; /* Filtered algebraic excitation */ + Word16 *pt_pitch_fx; /* pointer to floating pitch buffer */ + Word16 gain_pit_fx; /* Pitch gain */ + Word16 voice_fac_fx; /* Voicing factor */ + Word32 L_gain_code_fx; /* gain of code */ + Word16 gain_inov_fx; /* inovative gain */ + Word16 cn_fx[L_SUBFR]; /* Target vector in residual domain */ + Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */ + Word16 code2[L_SUBFR]; /* Gaussian excitation */ + Word16 y22[L_SUBFR]; /* Filtered Gaussian excitation */ + // Word16 prm_t[2 * NPRM_DIV], *prm = prm_t; + const Word16 *p_Aw_fx, *p_Aq_fx; /* pointer to LP filter coeff. vector */ + Word32 norm_gain_code_fx; + ACELP_config *acelp_cfg; + ACELP_CbkCorr g_corr; + Word32 gain_code2; + Word32 gain_code_vect[2], Ltmp, Ltmp2; +#if 0 + Word16 i_subfr, clip_gain, Q_xn, Q_new_p5, tmp2, j, i; + Word16 exc2[L_SUBFR], index, i_subfr_idx; +#else + Word16 i_subfr, Q_xn, Q_new_p5, tmp2, j, i; + Word16 index, i_subfr_idx; + Word16 unbits_PI; +#endif + acelp_cfg = &( st_fx->acelp_cfg ); + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + + /*------------------------------------------------------------------* + * Initializations + *------------------------------------------------------------------*/ + gain_pit_fx = 0; + move16(); + + test(); + test(); + test(); + IF( st_fx->Opt_SC_VBR && st_fx->vad_flag == 0 && ( EQ_16( hSC_VBR->last_ppp_mode, 1 ) || EQ_16( hSC_VBR->last_nelp_mode, 1 ) ) ) + { + /* SC_VBR - reset the encoder, to avoid memory not updated issue for the + case when UNVOICED mode is used to code inactive speech */ + CNG_reset_enc_fx( st_fx, hLPDmem, pitch_buf_fx, voice_factors_fx, 1 ); + } + + p_Aw_fx = Aw_fx; + p_Aq_fx = Aq_fx; + pt_pitch_fx = pitch_buf_fx; + move16(); + Q_xn = add( sub( Q_new, 1 ), shift ); + Q_new_p5 = add( Q_new, 5 ); + + + FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) + { + /*----------------------------------------------------------------* + * Bandwidth expansion of A(z) filter coefficients + * Find the excitation search target "xn" and innovation target in residual domain "cn" + * Compute impulse response, h1[], of weighted synthesis filter + *----------------------------------------------------------------*/ + i_subfr_idx = shr( i_subfr, 6 ); + Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); + + find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq_fx, + res_fx, L_SUBFR, p_Aw_fx, st_fx->preemph_fac, xn_fx, cn_fx, h1_fx ); + + /*Copy_Scale_sig(h1_fx, h2_fx, L_SUBFR, -2);*/ + Scale_sig( h1_fx, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */ + + /* scaling of xn[] to limit dynamic at 12 bits */ + Scale_sig( xn_fx, L_SUBFR, shift ); + /*----------------------------------------------------------------* + * Unvoiced subframe processing + *----------------------------------------------------------------*/ + IF( !uc_two_stage_flag ) + { + *pt_pitch_fx = gaus_encode_ivas_fx( st_fx, i_subfr, h1_fx, xn_fx, exc_fx, &hLPDmem->mem_w0, st_fx->clip_var_fx, + &hLPDmem->tilt_code, code_fx, &L_gain_code_fx, y2_fx, &gain_inov_fx, + &voice_fac_fx, &gain_pit_fx, Q_new, shift, &norm_gain_code_fx ); + } + ELSE + { + /*----------------------------------------------------------------* + * Unvoiced subframe processing in two stages + *----------------------------------------------------------------*/ + // PMT("The code below needs validation, never been tested") + /* No adaptive codebook (UC) */ + set16_fx( y1, 0, L_SUBFR ); + set16_fx( exc_fx + i_subfr, 0, L_SUBFR ); + /*-----------------------------------------------------------------* + * Gain clipping test to avoid unstable synthesis on frame erasure + * or in case of floating point encoder & fixed p. decoder + *-----------------------------------------------------------------*/ +#if 0 + clip_gain = Mode2_gp_clip(st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn); +#else + Mode2_gp_clip( st_fx->voicing_fx, i_subfr, st_fx->coder_type, xn_fx, st_fx->clip_var_fx, L_SUBFR, Q_xn ); +#endif + *pt_pitch_fx = L_SUBFR << 6; + move16(); + /*----------------------------------------------------------------------* + * Encode the algebraic innovation * + *----------------------------------------------------------------------*/ + + // E_ACELP_innovative_codebook_ivas_fx( exc_fx, *pt_pitch_fx, 0, 1, gain_pit_fx, hLPDmem->tilt_code, acelp_cfg, i_subfr, p_Aq_fx, h1_fx, xn_fx, cn_fx, y1, y2_fx, (Word8) st_fx->acelp_autocorr, &prm, code_fx, shift, st_fx->L_frame, st_fx->last_L_frame, st_fx->total_brate, st_fx->element_mode ); + inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, L_FRAME, st_fx->last_L_frame, + UNVOICED, st_fx->bwidth, st_fx->sharpFlag, i_subfr, -1, p_Aq_fx, + gain_pit_fx, cn_fx, exc_fx, h1_fx, hLPDmem->tilt_code, *pt_pitch_fx, xn_fx, code_fx, y2_fx, &unbits_PI, L_SUBFR, shift, Q_new ); + + E_ACELP_xy2_corr( xn_fx, y1, y2_fx, &g_corr, L_SUBFR, Q_xn ); + + g_corr.y2y2_e = sub( g_corr.y2y2_e, 18 ); /* -18 (y2*y2: Q9*Q9) */ + g_corr.xy2_e = sub( g_corr.xy2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (xn: Q_xn y2: Q9) */ + g_corr.y1y2_e = sub( g_corr.y1y2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (y1: Q_xn y2: Q9) */ + g_corr.xx_e = sub( g_corr.xx_e, add( Q_xn, Q_xn ) ); /* -(Q_xn+Q_xn) (xn: Q_xn) */ + + assert( gain_pit_fx == 0 ); + gauss_L2_fx( h1_fx, code2, y2_fx, y22, &gain_code2, &g_corr, gain_pit_fx, hLPDmem->tilt_code, p_Aq_fx, acelp_cfg->formant_enh_num, &( st_fx->seed_acelp ), shift ); + + /*----------------------------------------------------------* + * - Compute the fixed codebook gain * + * - quantize fixed codebook gain * + *----------------------------------------------------------*/ + + index = gain_enc_uv_fx( code_fx, code2, L_SUBFR, &gain_pit_fx, &L_gain_code_fx, &gain_code2, + st_fx->flag_noisy_speech_snr_fx, &g_corr, Es_pred, &norm_gain_code_fx, &gain_inov_fx, FUNC_GAIN_ENC_GACELP_UV ); + +#ifdef DEBUGGING + assert( st_fx->acelp_cfg.gains_mode[i_subfr_idx] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); +#endif + push_indice( st_fx->hBstr, IND_GAIN, index, st_fx->acelp_cfg.gains_mode[i_subfr_idx] ); + + gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit_fx, st_fx->clip_var_fx ); + + gain_code_vect[0] = L_gain_code_fx; + move32(); + gain_code_vect[1] = L_gain_code_fx; + move32(); + + /*----------------------------------------------------------* + * - voice factor (for pitch enhancement) * + *----------------------------------------------------------*/ + E_UTIL_voice_factor( exc_fx, i_subfr, code_fx, gain_pit_fx, L_gain_code_fx, &voice_fac_fx, &( hLPDmem->tilt_code ), L_SUBFR, acelp_cfg->voice_tilt, Q_new, shift ); + + IF( st_fx->Opt_RF_ON ) + { + st_fx->hRF->rf_tilt_buf[i_subfr_idx] = hLPDmem->tilt_code; + } + /*-----------------------------------------------------------------* + * Update memory of the weighting filter + *-----------------------------------------------------------------*/ + /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */ + Ltmp = Mpy_32_16_1( L_gain_code_fx, y2_fx[L_SUBFR - 1] ); + Ltmp = L_shl( Ltmp, add( 5, Q_xn ) ); // Qxn+15 + Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit_fx ); + /* Add Gaussian contribution*/ + Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] ); + Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) ); // Q_xn+15 + Ltmp = L_add( Ltmp, Ltmp2 ); + hLPDmem->mem_w0 = sub( xn_fx[L_SUBFR - 1], round_fx( Ltmp ) ); // Q_xn-1 + move16(); + BASOP_SATURATE_WARNING_OFF_EVS; +#ifdef BASOP_NOGLOB + hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); /*Qnew-1*/ +#else + hLPDmem->mem_w0 = shr( hLPDmem->mem_w0, shift ); /*Qnew-1*/ +#endif + BASOP_SATURATE_WARNING_ON_EVS; + + /*-------------------------------------------------------* + * - Find the total excitation. * + *-------------------------------------------------------*/ + + tmp2 = shr( L_SUBFR, 1 ); + FOR( j = 0; j < 2; j++ ) + { + FOR( i = sub( tmp2, shr( L_SUBFR, 1 ) ); i < tmp2; i++ ) + { + /* code in Q9, gain_pit in Q14; exc Q_new */ + Ltmp = Mpy_32_16_1( gain_code2, code2[i] ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, Q_new_p5 ); + Ltmp = L_mac_sat( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); +#else + Ltmp = L_shl( Ltmp, Q_new_p5 ); + Ltmp = L_mac( Ltmp, gain_pit_fx, exc_fx[i + i_subfr] ); +#endif +#if 0 + BASOP_SATURATE_WARNING_OFF_EVS + exc2[i] = round_fx(L_shl(Ltmp, 1)); + BASOP_SATURATE_WARNING_ON_EVS +#endif + Ltmp2 = Mpy_32_16_1( gain_code_vect[j], code_fx[i] ); +#ifdef BASOP_NOGLOB + Ltmp2 = L_shl_sat( Ltmp2, Q_new_p5 ); + Ltmp = L_add_sat( Ltmp, Ltmp2 ); + Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */ + exc_fx[i + i_subfr] = round_fx_sat( Ltmp ); +#else + BASOP_SATURATE_WARNING_OFF_EVS + Ltmp2 = L_shl( Ltmp2, Q_new_p5 ); + Ltmp = L_add( Ltmp, Ltmp2 ); + Ltmp = L_shl( Ltmp, 1 ); /* saturation can occur here */ + BASOP_SATURATE_WARNING_ON_EVS + exc_fx[i + i_subfr] = round_fx( Ltmp ); +#endif + } + tmp2 = L_SUBFR; + move16(); + } + } + + *tmp_noise_fx = extract_h( norm_gain_code_fx ); + voice_factors_fx[i_subfr / L_SUBFR] = 0; + move16(); + + interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); + + /*-----------------------------------------------------------------* + * Synthesize speech to update mem_syn[]. + * Update A(z) filters + *-----------------------------------------------------------------*/ + Syn_filt_s( 1, p_Aq_fx, M, &exc_fx[i_subfr], &syn_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 ); + + p_Aw_fx += ( M + 1 ); + p_Aq_fx += ( M + 1 ); + pt_pitch_fx++; + } + + /* SC-VBR */ + IF( hSC_VBR ) + { + hSC_VBR->prev_ppp_gain_pit_fx = gain_pit_fx; + move16(); + hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; + move16(); + } + + return; +} diff --git a/lib_enc/eval_pit_contr_fx.c b/lib_enc/eval_pit_contr_fx.c index f1cc5460619b07d9c50026ef6388f2a21bcbb1a1..f295e1736813a9199ec213cc37145fc3d76cb237 100644 --- a/lib_enc/eval_pit_contr_fx.c +++ b/lib_enc/eval_pit_contr_fx.c @@ -2,11 +2,11 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -430,3 +430,386 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit return last_pit_bin; } + + +Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin where pitch contribution is significant */ + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 *dct_res, /* i : DCT of residual */ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ + Word16 *pitch_buf, /* i/o: Pitch per subframe */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + Word16 *hangover, /* i : hangover for the time contribution switching */ + Word16 Qnew ) +{ + + Word16 corr_dct_pit[MBANDS_LOC]; + Word32 corr_tmp, L_tmp; + Word16 av_corr, min_corr, ftmp, tmp_ex, tmp_res; + Word16 freq, i, j; + Word16 last_pit_band, pit_contr_idx, last_pit_bin; + Word32 ener_res; + Word32 ener_pit; + Word16 low_pit, F1st_harm, F8th_harm; + Word16 corr_dct_pit_tmp[MBANDS_LOC]; + Word16 time_flg = 0; + Word16 Len, max_len; + Word16 tmp_dec; + Word16 Mbands_loc = MBANDS_LOC - 2; + Word16 exp1, tmp, exp2; + Word32 L_tmp1, ener_init; + Word16 exp_norm; + Word16 norm; + Word16 val_thrs; + SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; + + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Mbands_loc = MBANDS_LOC; + move16(); + } + + minimum_fx( pitch_buf, nb_subfr, &low_pit ); + exp1 = norm_s( low_pit ); + tmp = shl( low_pit, exp1 ); + tmp_dec = 12800; + move16(); + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + tmp_dec = 16000; + move16(); + } + /*F1st_harm = (12800.0f|160000.f)/low_pit;*/ + tmp = div_s( tmp_dec, tmp ); /*15-6-exp1(->9-exp1)*/ + F1st_harm = shr_r( tmp, sub( 5, exp1 ) ); /*Q4*/ + + /*F8th_harm = 8.0f*F1st_harm;*/ + F8th_harm = extract_l( L_shr_r( L_mult0( F1st_harm, 8 ), 2 ) ); /*Q2*/ + + freq = 0; + move16(); + ener_init = L_shl( 3, 2 * Qnew - 5 ); /*(0.1->3 in Q5) 2*Qnew*/ + FOR( i = 0; i < Mbands_loc; i++ ) /* up to maximum allowed voiced critical band */ + { + corr_tmp = L_deposit_l( 0 ); + ener_res = L_add( ener_init, 0 ); + ener_pit = L_add( ener_init, 0 ); + + FOR( j = 0; j < mfreq_bindiv_loc[i]; j++ ) /* up to maximum allowed voiced critical band */ + { + tmp_ex = mult_r( dct_pitex[j + freq], 8192 ); + tmp_res = mult_r( dct_res[j + freq], 8192 ); + corr_tmp = L_mac0( corr_tmp, tmp_res, tmp_ex ); /*2*Qnew*/ + ener_res = L_mac0( ener_res, tmp_res, tmp_res ); /*2*Qnew*/ + ener_pit = L_mac0( ener_pit, tmp_ex, tmp_ex ); /*2*Qnew*/ + } + + L_tmp1 = Mult_32_32( ener_res, ener_pit ); + exp2 = norm_l( L_tmp1 ); + L_tmp1 = L_shl( L_tmp1, exp2 ); + exp_norm = sub( 30, exp2 ); + L_tmp1 = Isqrt_lc( L_tmp1, &exp_norm ); + norm = extract_h( L_tmp1 ); /*15-exp_norm*/ + L_tmp1 = L_shl( Mult_32_16( corr_tmp, norm ), exp_norm ); + corr_dct_pit[i] = round_fx( L_shl( L_tmp1, 14 ) ); /*Q14*/ + + freq = add( freq, mfreq_bindiv_loc[i] ); + } + + val_thrs = 8192; + move16(); /* 0.5 in Q14*/ + /* Smooth the inter-correlation value and skip the last band for the average (since last band is almost always 0)*/ + tmp = mac_r( L_mult( ALPA_FX, corr_dct_pit[0] ), ALPAM1_FX, corr_dct_pit[1] ); /*Qnew*/ + tmp = s_max( tmp, val_thrs ); + + corr_dct_pit_tmp[0] = shl( sub( tmp, val_thrs ), 1 ); + move16(); + + FOR( i = 1; i < Mbands_loc - 1; i++ ) /* up to maximum allowed voiced critical band */ + { + L_tmp = L_mult( BETA_FX, corr_dct_pit[i - 1] ); + L_tmp = L_mac( L_tmp, BETA_FX, corr_dct_pit[i + 1] ); + + tmp = mac_r( L_tmp, ALPA_FX, corr_dct_pit[i] ); + tmp = s_max( tmp, val_thrs ); + + corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); + move16(); + } + tmp = mac_r( L_mult( ALPA_FX, corr_dct_pit[i] ), ALPAM1_FX, corr_dct_pit[i - 1] ); /*Qnew*/ + tmp = s_max( tmp, val_thrs ); + corr_dct_pit_tmp[i] = shl( sub( tmp, val_thrs ), 1 ); + move16(); + + Copy( corr_dct_pit_tmp, corr_dct_pit, Mbands_loc ); + + L_tmp1 = L_mult( DIV_NB_VOIC_FX, corr_dct_pit[0] ); /*Qnew*/ + FOR( i = 1; i < NB_VOIC_FX; i++ ) /* up to maximum allowed voiced critical band */ + { + L_tmp1 = L_mac( L_tmp1, DIV_NB_VOIC_FX, corr_dct_pit[i] ); + } + av_corr = round_fx( L_tmp1 ); /*Qnew*/ + + /* Find the cut-off freq similarly to HSX */ + last_pit_band = 0; + move16(); + av_corr = round_fx( L_shl( L_mult0( av_corr, 6400 ), 16 - 12 ) ); /*Q14*Q0-12=Q2*/ + + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + /*av_corr *= 1.25f;*/ + av_corr = add( av_corr, shr( av_corr, 2 ) ); + } + test(); + if ( GE_16( st_fx->GSC_IVAS_mode, 1 ) || LT_32( st_fx->core_brate, ACELP_9k60 ) ) + { + av_corr = shl_sat( av_corr, 1 ); /*Q2 Correlation really poor at low rate, time domain still valide*/ + } + min_corr = abs_s( sub( mfreq_loc_Q2fx[0], av_corr ) ); /*Q2*/ + + FOR( i = 1; i < Mbands_loc; i++ ) /* up to maximum allowed voiced critical band */ + { + ftmp = abs_s( sub( mfreq_loc_Q2fx[i], av_corr ) ); /*Q2*/ + + IF( LT_16( ftmp, min_corr ) ) + { + last_pit_band = i; + move16(); + min_corr = ftmp; + move16(); + } + } + + IF( GT_16( F8th_harm, mfreq_loc_Q2fx[last_pit_band] ) ) + { + DO + { + last_pit_band = add( last_pit_band, 1 ); + } + WHILE( GE_16( F8th_harm, mfreq_loc_Q2fx[last_pit_band] ) ); + } + if ( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) + { + last_pit_band = s_max( last_pit_band, 7 ); + } + test(); + test(); + test(); + IF( GT_16( last_pit_band, 7 + BAND1k2 ) && ( LT_32( st_fx->core_brate, CFREQ_BITRATE ) || EQ_16( st_fx->bwidth, NB ) ) ) /*Added for 9.1*/ + { + last_pit_band = 7 + BAND1k2; + move16(); + } + ELSE IF( GT_16( last_pit_band, 10 + BAND1k2 ) && GE_32( st_fx->core_brate, CFREQ_BITRATE ) ) + { + last_pit_band = add( 10, BAND1k2 ); + } + + time_flg = 0; + move16(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( hGSCEnc->mem_last_pit_band > 0 && GT_16( st_fx->old_corr_fx, 16384 ) && GT_16( hSpMusClas->mold_corr_fx, 16384 ) && GE_16( hGSCEnc->lt_gpitch_fx, 19661 ) /*1.5f*GPIT_THR*/ ) || ( GT_16( last_pit_band, 6 ) ) || ( GE_16( last_pit_band, 4 ) && GE_16( hGSCEnc->lt_gpitch_fx, 19661 ) /*1.5f*GPIT_THR*/ && GT_16( st_fx->old_corr_fx, 22938 ) ) || ( GT_16( last_pit_band, BAND1k2 ) && GT_16( hSpMusClas->mold_corr_fx, 26214 ) && GE_16( hGSCEnc->lt_gpitch_fx, 13107 ) /*GPIT_THR*/ ) ) + { + tmp_dec = 1; + move16(); + } + ELSE + { + tmp_dec = 0; + move16(); + } + + /* Different past and current decision */ + test(); + test(); + test(); + IF( ( hGSCEnc->mem_last_pit_band == 0 && EQ_16( tmp_dec, 1 ) ) || ( hGSCEnc->mem_last_pit_band > 0 && tmp_dec == 0 ) ) + { + IF( *hangover == 0 ) + { + time_flg = tmp_dec; + move16(); + *hangover = HANGOVER_DELAY; + move16(); + } + ELSE + { + time_flg = 0; + move16(); + if ( hGSCEnc->mem_last_pit_band > 0 ) + { + time_flg = 1; + move16(); + } + + ( *hangover ) = sub( ( *hangover ), 1 ); + if ( *hangover < 0 ) + { + *hangover = 0; + move16(); + } + } + } + ELSE + { + time_flg = tmp_dec; + move16(); + *hangover = HANGOVER_DELAY; + move16(); + } + + /* Decicison on final length of time contribution */ + pit_contr_idx = 0; + move16(); + test(); + test(); + IF( EQ_16( time_flg, 1 ) || NE_16( st_fx->coder_type, INACTIVE ) || st_fx->GSC_noisy_speech ) + { + test(); + test(); + /*if(st_fx->core_brate core_brate, ACELP_9k60 ) && LT_16( low_pit, 4096 ) ) + { + last_pit_band = add( 9, BAND1k2 ); + if ( EQ_16( st_fx->bwidth, NB ) ) + { + last_pit_band = add( 7, BAND1k2 ); + } + } + ELSE IF( LT_32( st_fx->core_brate, ACELP_9k60 ) && LT_16( low_pit, 8192 ) ) + { + last_pit_band = add( 5, BAND1k2 ); + } + ELSE IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) + { + last_pit_band = add( 3, BAND1k2 ); + } + ELSE IF( LT_16( last_pit_band, add( BAND1k2, 1 ) ) ) + { + last_pit_band = add( BAND1k2, 1 ); + } + last_pit_bin = mfreq_loc_div_25[last_pit_band]; + move16(); + + st_fx->bpf_off = 0; + move16(); + + max_len = sub( st_fx->L_frame, last_pit_bin ); + + if ( EQ_16( st_fx->bwidth, NB ) ) + { + max_len = sub( 160, last_pit_bin ); + } + + Len = 80; + move16(); + if ( LT_16( max_len, 80 ) ) + { + Len = max_len; + move16(); + } + test(); + IF( ( EQ_32( st_fx->core_brate, ACELP_8k00 ) ) && ( NE_16( st_fx->bwidth, NB ) ) ) + { + move16(); /*ptr init*/ + FOR( i = 0; i < max_len; i++ ) + { + dct_pitex[i + last_pit_bin] = 0; + move16(); + } + } + ELSE + { + + FOR( i = 0; i < Len; i++ ) + { + dct_pitex[i + last_pit_bin] = mult_r( dct_pitex[i + last_pit_bin], sm_table_fx[i] ); + } + FOR( ; i < max_len; i++ ) + { + dct_pitex[i + last_pit_bin] = 0; + move16(); + } + } + hGSCEnc->mem_last_pit_band = last_pit_band; + move16(); + pit_contr_idx = sub( last_pit_band, BAND1k2 ); + } + ELSE + { + set16_fx( dct_pitex, 0, st_fx->L_frame ); + st_fx->bpf_off = 1; + move16(); + last_pit_bin = 0; + move16(); + last_pit_band = 0; + move16(); + pit_contr_idx = 0; + move16(); + hGSCEnc->mem_last_pit_band = 0; + move16(); + + set16_fx( pitch_buf, shl( L_SUBFR, 6 ), NB_SUBFR16k ); + /* pitch contribution useless - delete all previously written indices belonging to pitch contribution */ + FOR( i = TAG_ACELP_SUBFR_LOOP_START; i < TAG_ACELP_SUBFR_LOOP_END; i++ ) + { +#if 0 // ndef IVAS_CODE_BITSTREAM + IF( hBstr->ind_list[i].nb_bits != -1 ) + { + hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[i].nb_bits ); + hBstr->ind_list[i].nb_bits = -1; + move16(); + } +#else + delete_indice( hBstr, i ); +#endif + } + +#if 0 // ndef IVAS_CODE_BITSTREAM + IF( hBstr->ind_list[IND_ES_PRED].nb_bits != -1 ) + { + hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, hBstr->ind_list[IND_ES_PRED].nb_bits ); + hBstr->ind_list[IND_ES_PRED].nb_bits = -1; + move16(); + } +#else + delete_indice( hBstr, i ); +#endif + } + IF( LT_32( st_fx->core_brate, CFREQ_BITRATE ) ) + { + IF( LT_32( st_fx->core_brate, ACELP_9k60 ) ) + { + if ( pit_contr_idx > 0 ) + { + pit_contr_idx = 1; + move16(); + } + + IF( EQ_16( st_fx->coder_type, INACTIVE ) ) + { + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 1 ); + } + } + ELSE + { + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 3 ); + } + } + ELSE + { + push_indice( hBstr, IND_PIT_CONTR_IDX, pit_contr_idx, 4 ); + } + + return last_pit_bin; +} diff --git a/lib_enc/gain_enc_fx.c b/lib_enc/gain_enc_fx.c index 2e53060b5f5dc16dd086f0aa3ee16b23ea1e92ce..630dd5aeb0b53090c60009112720f47d11b4cde4 100644 --- a/lib_enc/gain_enc_fx.c +++ b/lib_enc/gain_enc_fx.c @@ -811,8 +811,8 @@ void gain_enc_mless_ivas_fx( qua_table = gain_qua_mless_6b_fx; if ( GT_16( element_mode, EVS_MONO ) ) { -#ifdef IVAS_CODE - qua_table = gain_qua_mless_6b_stereo; +#if 1 // def IVAS_CODE + qua_table = gain_qua_mless_6b_stereo_fx; #else // PMTE() #endif @@ -1174,6 +1174,297 @@ void gain_enc_SQ_fx( return; } +void gain_enc_SQ_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *xn, /* i : target vector Q_xn */ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ + const Word16 *code, /* i : algebraic excitation Q9 */ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ + Word16 *gain_pit, /* o : quantized pitch gain Q14 */ + Word32 *gain_code, /* o : quantized codebook gain Q16 */ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ + const Word16 Q_xn /* i : xn and y1 scaling */ +) +{ + Word16 index, nBits_pitch, nBits_code; + Word16 gcode0, Ei, gain_code16; + Word16 coeff[5], exp_coeff[5]; + Word16 exp, exp_code, exp_inov, exp_gcode0, frac, tmp; + + Word32 L_tmp, L_tmp1, L_tmp2; + Word16 tmp1, expg; + Word16 exp1, exp2; + Word16 exp_num, exp_den, exp_div, frac_den; + Word32 L_frac_num, L_frac_den, L_div; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*-----------------------------------------------------------------* + * calculate the rest of the correlation coefficients + * c2 = , c3 = -2, c4 = 2 + *-----------------------------------------------------------------*/ + /*g_corr[1] *= -0.5;*/ + /*g_corr[2] = dotp( y2, y2, L_SUBFR ) + 0.01f;*/ + /*g_corr[3] = dotp( xn, y2, L_SUBFR ) - 0.02f;*/ + /*g_corr[4] = dotp( yy1, y2, L_SUBFR ) + 0.02f;*/ + + coeff[0] = g_corr[0]; + move16(); + exp_coeff[0] = g_corr[1]; + move16(); + coeff[1] = g_corr[2]; + move16(); /* coeff[1] = xn yy1 */ + exp_coeff[1] = g_corr[3]; + move16(); + + /* Compute scalar product */ + coeff[2] = extract_h( Dot_product12( y2, y2, L_SUBFR, &exp ) ); + exp_coeff[2] = add( sub( exp, 18 ), shl( Q_xn, 1 ) ); + move16(); /* -18 (y2 Q9) */ + + /* Compute scalar product */ + coeff[3] = extract_h( Dot_product12( xn, y2, L_SUBFR, &exp ) ); + exp_coeff[3] = add( sub( exp, 9 ), Q_xn ); + move16(); /* -9 (y2 Q9), (xn y2) */ + + /* Compute scalar product */ + coeff[4] = extract_h( Dot_product12( yy1, y2, L_SUBFR, &exp ) ); + exp_coeff[4] = add( sub( exp, 9 ), Q_xn ); + move16(); /* -9 (y2 Q9), (y1 y2) */ + + /*-----------------------------------------------------------------* + * calculate the unscaled innovation energy + * calculate the predicted gain code + * calculate optimal gains + *-----------------------------------------------------------------*/ + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR;*/ + /**gain_inov = 1.0f / (float)sqrt( Ecode );*/ + + L_tmp = Dot_product12( code, code, L_SUBFR, &exp_code ); + exp_inov = sub( exp_code, 18 + 6 ); + exp_code = sub( exp_code, 30 ); + + /*Ei = 10 * log10((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + /*----------------------------------------------------------------* + * calculate the predicted gain code + *----------------------------------------------------------------*/ + tmp = norm_l( L_tmp ); + frac = Log2_norm_lc( L_shl( L_tmp, tmp ) ); + tmp = add( 30 - 18 - 6 - 1, sub( exp_code, tmp ) ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + L_tmp1 = Mpy_32_16( tmp, frac, 12330 ); /* Q13 */ + Ei = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + + /* predicted codebook gain */ + gcode0 = sub( Es_pred, Ei ); /* Q8 */ + + /*---------------------------------------------------------------* + * Decode codebook gain and the adaptive excitation low-pass + * filtering factor (Finalize computation ) + *---------------------------------------------------------------*/ + /* gain_inov = 1.0f / sqrt((dot_product(code, code, L_SUBFR) + 0.01) / L_SUBFR) */ + L_tmp = Isqrt_lc( L_tmp, &exp_inov ); + *gain_inov = extract_h( L_shl( L_tmp, sub( exp_inov, 3 ) ) ); /* gain_inov in Q12 */ + + /* gcode0 = pow(10, 0.05 * (Es_pred - Ei)) */ + /*----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *----------------------------------------------------------------*/ + + L_tmp = L_mult( gcode0, 21771 ); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + + gcode0 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + /* output of Pow2() will be: */ + /* 16384 < Pow2() <= 32767 */ + exp_gcode0 = sub( exp_gcode0, 14 ); + + + /*tmp1 = (g_corr[0]*g_corr[2]) - (g_corr[4]*g_corr[4]); + tmp2 = g_corr[1]/tmp1; + tmp1 = g_corr[3]/tmp1; + + *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp1); + *gain_code = (g_corr[0]*tmp1) - (g_corr[4]*tmp2);*/ + + /* *gain_pit = (g_corr[2]*tmp2) - (g_corr[4]*tmp3); + = ((g_corr[1]*g_corr[2]) - (g_corr[3]*g_corr[4]))/tmp1;*/ + + /* *gain_code = (g_corr[0]*tmp3) - (g_corr[4]*tmp2); + = ((g_corr[3]*g_corr[0]) - (g_corr[1]*g_corr[4]))/tmp1;*/ + + L_tmp1 = L_mult( coeff[0], coeff[2] ); /*Q31*/ + exp1 = add( exp_coeff[0], exp_coeff[2] ); + +#ifdef BASOP_NOGLOB + L_tmp2 = L_mult_o( coeff[4], coeff[4], &Overflow ); /*Q31*/ +#else + L_tmp2 = L_mult( coeff[4], coeff[4] ); /*Q31*/ +#endif + exp2 = add( exp_coeff[4], exp_coeff[4] ); + + IF( GT_16( exp1, exp2 ) ) + { + L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ + exp_den = exp1; + move16(); + } + ELSE + { + L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ + exp_den = exp2; + move16(); + } + L_frac_den = L_sub( L_tmp1, L_tmp2 ); /*Q31*/ + + frac_den = extract_h( L_frac_den ); + frac_den = s_max( frac_den, 1 ); + L_frac_den = L_max( L_frac_den, 1 ); + exp = norm_l( L_frac_den ); + tmp = div_s( shl( 1, sub( 14, exp ) ), frac_den ); /*Q(14-exp)*/ + + + L_tmp1 = L_mult( coeff[3], coeff[4] ); /*Q31*/ + exp1 = add( exp_coeff[3], exp_coeff[4] ); + + L_tmp2 = L_mult( coeff[1], coeff[2] ); /*Q31*/ + exp2 = add( exp_coeff[1], exp_coeff[2] ); + + IF( GT_16( exp1, exp2 ) ) + { + L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ + exp_num = exp1; + move16(); + } + ELSE + { + L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ + exp_num = exp2; + move16(); + } +#ifdef BASOP_NOGLOB + L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ +#else /* BASOP_NOGLOB */ + L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ +#endif /* BASOP_NOGLOB */ + + L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ + exp_div = sub( exp_num, exp_den ); + +#ifdef BASOP_NOGLOB + *gain_pit = round_fx_o( L_shl_o( L_div, add( exp, exp_div ), &Overflow ), &Overflow ); /*Q14*/ +#else /* BASOP_NOGLOB */ + *gain_pit = round_fx( L_shl( L_div, add( exp, exp_div ) ) ); /*Q14*/ +#endif /* BASOP_NOGLOB */ + + L_tmp1 = L_mult( coeff[1], coeff[4] ); /*Q31*/ + exp1 = add( exp_coeff[1], exp_coeff[4] ); + + L_tmp2 = L_mult( coeff[0], coeff[3] ); /*Q31*/ + exp2 = add( exp_coeff[0], exp_coeff[3] ); + + IF( GT_16( exp1, exp2 ) ) + { + L_tmp2 = L_shr( L_tmp2, sub( exp1, exp2 ) ); /*Q31*/ + exp_num = exp1; + } + ELSE + { + L_tmp1 = L_shr( L_tmp1, sub( exp2, exp1 ) ); /*Q31*/ + exp_num = exp2; + } +#ifdef BASOP_NOGLOB + L_frac_num = L_sub_o( L_tmp2, L_tmp1, &Overflow ); /*Q31*/ +#else /* BASOP_NOGLOB */ + L_frac_num = L_sub( L_tmp2, L_tmp1 ); /*Q31*/ +#endif /* BASOP_NOGLOB */ + + L_div = Mult_32_16( L_frac_num, tmp ); /*Q(30-exp)*/ + exp_div = sub( exp_num, exp_den ); + +#ifdef BASOP_NOGLOB + *gain_code = L_shl_sat( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); +#else + *gain_code = L_shl( L_div, s_max( -31, sub( add( exp, exp_div ), 14 ) ) ); +#endif + move32(); /*Q16*/ + + *gain_pit = s_max( G_PITCH_MIN_Q14, s_min( *gain_pit, G_PITCH_MAX_Q14 ) ); + + /*-----------------------------------------------------------------* + * limit the pitch gain searching range (if indicated by clip_gain) + *-----------------------------------------------------------------*/ + + test(); + test(); + IF( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) ) + { + *gain_pit = 15565; + move16(); + } + ELSE IF( EQ_16( clip_gain, 2 ) && GT_16( *gain_pit, 10650 ) ) + { + *gain_pit = 10650; + move16(); + } + + /*-----------------------------------------------------------------* + * search for the best quantized values + *-----------------------------------------------------------------*/ + + nBits_pitch = gains_mode[shr( i_subfr, 6 )]; + + /* set number of bits for two SQs */ + nBits_code = shr( add( nBits_pitch, 1 ), 1 ); + nBits_pitch = shr( nBits_pitch, 1 ); + + /* gain_pit Q */ + /*tmp1 = (G_PITCH_MAX - G_PITCH_MIN) / ((1 << nBits_pitch) - 1);*/ /* set quantization step */ + tmp1 = mult_r( G_PITCH_MAX_Q13, div_s( 1, sub( shl( 1, nBits_pitch ), 1 ) ) ); /*Q13*/ /* set quantization step */ + + index = usquant_fx( *gain_pit, gain_pit, G_PITCH_MIN_Q14, tmp1, shl( 1, nBits_pitch ) ); + move16(); + push_indice( hBstr, IND_GAIN_PIT, index, nBits_pitch ); + + /* gain_code Q */ + /* *gain_code /= gcode0; */ + IF( gcode0 != 0 ) + { + tmp = div_s( 16384, gcode0 ); /*Q15*/ + L_tmp = Mult_32_16( *gain_code, tmp ); /*Q16*/ + *gain_code = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + } + + index = gain_quant_fx( gain_code, &gain_code16, LG10_G_CODE_MIN_Q14, LG10_G_CODE_MAX_Q13, nBits_code, &expg ); + push_indice( hBstr, IND_GAIN_CODE, index, nBits_code ); + L_tmp = L_mult( gain_code16, gcode0 ); /*Q0*Q0 -> Q1*/ +#ifdef BASOP_NOGLOB + *gain_code = L_shl_sat( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); +#else + *gain_code = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); +#endif + move32(); /*Q16*/ + + /* *norm_gain_code = *gain_code / *gain_inov; */ + exp = sub( norm_s( *gain_inov ), 1 ); + exp = s_max( exp, 0 ); + + tmp = div_s( shr( 8192, exp ), *gain_inov ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + move32(); + + return; +} + /*-------------------------------------------------------------------* * gain_enc_gaus() * @@ -1426,6 +1717,192 @@ void gain_enc_tc_fx( move32(); return; } + +void gain_enc_tc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 xn_fx[], /* i : target vector */ + const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation */ + const Word16 code_fx[], /* i : algebraic excitation */ + const Word16 Es_pred_fx, /* i : predicted scaled innovation energy */ + Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain */ + Word32 *gain_code_fx, /* o : quantized codebook gain */ + Word16 *gain_inov_fx, /* o : innovation gain */ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation */ + const Word16 Q_xn /* i : xn and y1 scaling Q0 */ +) +{ + Word16 i, index = 0, nBits, num, den, exp_num, exp_den; + Word16 Ei_fx, g_code_fx, gcode0_fx; + Word16 expg, expg2, e_tmp, f_tmp, exp_gcode0, tmp_fx, frac, tmp16; + Word32 L_tmp, L_tmp1; + Word16 wgain_code = 0, gain_code16; + *gain_pit_fx = 0; + move16(); + /*----------------------------------------------------------------* + * get number of bits for gain quantization + *----------------------------------------------------------------*/ + nBits = gains_mode[shr( i_subfr, 6 )]; + + /*----------------------------------------------------------------* + * find the code pitch (for current subframe) + *----------------------------------------------------------------*/ + + /**gain_code = dotp( xn, y2, L_SUBFR )/( dotp( y2, y2, L_SUBFR ) + 0.01f );*/ + /* Compute scalar product */ + L_tmp = Dot_product( y2_fx, y2_fx, L_SUBFR ); /* -18 (y2 Q9) */ + exp_den = norm_l( L_tmp ); + den = extract_h( L_shl( L_tmp, exp_den ) ); + exp_den = sub( add( exp_den, 18 ), shl( Q_xn, 1 ) ); + + /* Compute scalar product */ + L_tmp1 = Dot_product( xn_fx, y2_fx, L_SUBFR ); /* -9 (y2 Q9) */ + exp_num = sub( norm_l( L_tmp1 ), 1 ); + num = extract_h( L_shl( L_tmp1, exp_num ) ); + exp_num = sub( add( exp_num, 8 ), Q_xn ); + + tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */ + num = abs_s( num ); + + /*----------------------------------------------------------------* + * compute gain = xy/yy + *----------------------------------------------------------------*/ + g_code_fx = div_s( num, den ); + + i = sub( exp_num, exp_den ); /* Gain_trans in Q7 */ + g_code_fx = i_mult2( g_code_fx, tmp16 ); /* apply sign */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shr_sat( L_deposit_l( g_code_fx ), i ); +#else + *gain_code_fx = L_shr( L_deposit_l( g_code_fx ), i ); +#endif + move32(); + + /*----------------------------------------------------------------* + * calculate the predicted gain code + * decode codebook gain + *----------------------------------------------------------------*/ + + *gain_pit_fx = 0; + move16(); + + /*Ecode = (dotp( code, code, L_SUBFR) + 0.01f) / L_SUBFR; + *gain_inov = 1.0f / (float)sqrt( Ecode );*/ + + L_tmp = Dot_product12( code_fx, code_fx, L_SUBFR, &expg ); + expg = sub( expg, 18 + 6 ); /* exp: -18 (code in Q9), -6 (/L_SUBFR) */ + expg2 = expg; + move16(); + L_tmp1 = L_tmp; /* sets to 'L_tmp' in 1 clock */ + move32(); + L_tmp = Isqrt_lc( L_tmp, &expg ); + + *gain_inov_fx = extract_h( L_shl( L_tmp, sub( expg, 3 ) ) ); + move16(); /* gain_inov in Q12 */ + + /*Ei = 10 * (float)log10( Ecode );*/ + e_tmp = norm_l( L_tmp1 ); + f_tmp = Log2_norm_lc( L_shl( L_tmp1, e_tmp ) ); + e_tmp = sub( expg2, add( 1, e_tmp ) ); + L_tmp1 = Mpy_32_16( e_tmp, f_tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/ + Ei_fx = round_fx( L_shl( L_tmp1, 11 ) ); /* Q8 */ + /*gcode0 = (float) pow(10, 0.05 * (Es_pred - Ei));*/ + gcode0_fx = sub( Es_pred_fx, Ei_fx ); /* Q8 */ + /*-----------------------------------------------------------------* + * gcode0 = pow(10.0, gcode0/20) + * = pow(2, 3.321928*gcode0/20) + * = pow(2, 0.166096*gcode0) + *-----------------------------------------------------------------*/ + L_tmp = L_mult( gcode0_fx, 21771 ); /* *0.166096 in Q17 -> Q26 */ + L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */ + frac = L_Extract_lc( L_tmp, &exp_gcode0 ); /* Extract exponent of gcode0 */ + gcode0_fx = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */ + exp_gcode0 = sub( exp_gcode0, 14 ); + IF( GT_16( nBits, 3 ) ) + { + /*g_code = *gain_code / gcode0;*/ + IF( gcode0_fx != 0 ) + { + tmp16 = div_s( 16384, gcode0_fx ); /*Q15*/ + L_tmp = Mult_32_16( *gain_code_fx, tmp16 ); /*Q16*/ + *gain_code_fx = L_shr( L_tmp, add( 14, exp_gcode0 ) ); /*Q16*/ + } + ELSE + { + *gain_code_fx = MAX_32; + move32(); + } + + /*index = gain_quant( &g_code, G_CODE_MIN, G_CODE_MAX, nBits );*/ + index = gain_quant_fx( gain_code_fx, &gain_code16, LG10_G_CODE_MIN_TC_Q14, LG10_G_CODE_MAX_TC_Q13, nBits, &expg ); + + /**gain_code = g_code * gcode0;*/ + L_tmp = L_mult( gain_code16, gcode0_fx ); /*Q0*Q0 -> Q1*/ + *gain_code_fx = L_shl( L_tmp, add( add( expg, exp_gcode0 ), 15 ) ); /*Q16*/ + move32(); + + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); + } + ELSE + { + index = N_GAIN_CODE_TC - 1; + move16(); + FOR( i = 0; i < N_GAIN_CODE_TC - 1; i++ ) + { + L_tmp = L_mult( tbl_gain_code_tc_quant_mean[i], gcode0_fx ); /* Q13*Q0 -> Q14 */ + L_tmp = L_shl( L_tmp, add( exp_gcode0, 2 ) ); /* Q14 -> Q16 */ + + IF( LT_32( *gain_code_fx, L_tmp ) ) + { + index = i; + move16(); + BREAK; + } + } + /*----------------------------------------------------------------* + * 3-bit -> 2-bit encoding + *----------------------------------------------------------------*/ + IF( EQ_16( nBits, 2 ) ) + { + /* 2-bit -> 3-bit decoding */ + index = shr( index, 1 ); + wgain_code = tbl_gain_code_tc_fx[shl( index, 1 )]; + move16(); + /**gain_code *= gcode0;*/ + L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); + move32(); /* Q14 -> Q16 */ + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); + } + ELSE /* nBits == 3 */ + { + wgain_code = tbl_gain_code_tc_fx[index]; + move16(); + /**gain_code *= gcode0;*/ + L_tmp = L_mult( wgain_code, gcode0_fx ); /* Q13*Q0 -> Q14 */ +#ifdef BASOP_NOGLOB + *gain_code_fx = L_shl_sat( L_tmp, add( exp_gcode0, 2 ) ); +#else + *gain_code_fx = L_shl( L_tmp, add( exp_gcode0, 2 ) ); +#endif + move32(); /* Q14 -> Q16 */ + push_indice( hBstr, IND_GAIN_CODE, index, nBits ); + } + } + + /*-----------------------------------------------------------------* + * decode normalized codebook gain + *-----------------------------------------------------------------*/ + /**norm_gain_code = *gain_code / *gain_inov;*/ + expg = sub( norm_s( *gain_inov_fx ), 1 ); + expg = s_max( expg, 0 ); + + tmp_fx = div_s( shr( 8192, expg ), *gain_inov_fx ); + *norm_gain_code_fx = L_shr( Mult_32_16( *gain_code_fx, tmp_fx ), sub( 1, expg ) ); + move32(); + return; +} /*-----------------------------------------------------------------* * Find_Opt_gainQ_fx() * diff --git a/lib_enc/gaus_enc_fx.c b/lib_enc/gaus_enc_fx.c index 57a336ec25f80eb161e363fbd6b232fe4ef512f7..5bded26033aa7ef4f289a73a679e18d74a0197e1 100644 --- a/lib_enc/gaus_enc_fx.c +++ b/lib_enc/gaus_enc_fx.c @@ -2,12 +2,12 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -#include "rom_enc.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "rom_enc.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ //#include "basop_mpy.h" @@ -141,6 +141,109 @@ Word16 gaus_encode_fx( return ( L_SUBFR << 6 ); } +Word16 gaus_encode_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *h1, /* i : weighted filter input response */ + const Word16 *xn, /* i : target vector */ + Word16 *exc, /* o : pointer to excitation signal frame */ + Word16 *mem_w0, /* o : weighting filter denominator memory */ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ + Word16 *code, /* o : algebraic excitation Q9 */ + Word32 *gain_code, /* o : Code gain. Q16 */ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ + Word16 *gain_inov, /* o : innovation gain Q12 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ +) +{ + Word16 nb_bits, idx; + Word16 i = 0; + Word32 Ltmp; + Word16 dn[L_SUBFR], exp_code, gcode; /* Correlation between xn and h1 */ + Word16 exp, tmp, tmp_idx; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + + /*----------------------------------------------------------------* + * Encode gaussian excitation + *----------------------------------------------------------------*/ + + /* Correlation between target xn2[] and impulse response h1[] */ + corr_xh_fx( xn, dn, h1 ); + + tmp_idx = shr( i_subfr, 6 ); + nb_bits = st_fx->acelp_cfg.fixed_cdk_index[tmp_idx]; + move16(); + + gauss2v_fx( st_fx->hBstr, h1, xn, dn, code, y2, gain_code, L_SUBFR, shift, Q_new, shr( nb_bits, 1 ) ); + + /*----------------------------------------------------------------* + * Encode gaussian gain + *----------------------------------------------------------------*/ + + /* codeword energy computation */ + Ltmp = Dot_product12( code, code, L_SUBFR, &exp_code ); + + exp_code = sub( exp_code, 18 + 6 ); /* exp: -18 (code in Q9), -6 (L_subfr = 64) */ + Ltmp = Isqrt_lc( Ltmp, &exp_code ); + *gain_inov = extract_h( L_shl( Ltmp, sub( exp_code, 3 ) ) ); /* g_code_inov in Q12 */ + + nb_bits = st_fx->acelp_cfg.gains_mode[tmp_idx]; + move16(); + /* low bound = -30; stepSize = 1.71875; inv_stepSize = 0.5818181 */ + idx = gain_enc_gaus_fx( gain_code, nb_bits, -7680, 28160, 19065 ); + push_indice( st_fx->hBstr, IND_GAIN, idx, nb_bits ); + + /*----------------------------------------------------------------* + * Total excitation for Unvoiced coders + *----------------------------------------------------------------*/ +#ifdef BASOP_NOGLOB + gcode = round_fx_o( L_shl_o( *gain_code, Q_new, &Overflow ), &Overflow ); /* scaled gain_code with Qnew */ +#else /* BASOP_NOGLOB */ + gcode = round_fx( L_shl( *gain_code, Q_new ) ); /* scaled gain_code with Qnew */ +#endif /* BASOP_NOGLOB */ + FOR( i = 0; i < L_SUBFR; i++ ) + { + exc[i + i_subfr] = round_fx( L_shl( L_mult( gcode, code[i] ), 15 - 9 ) ); + } + + /*----------------------------------------------------------------* + * Updates: last value of new target is stored in mem_w0 + *----------------------------------------------------------------*/ + + Ltmp = L_mult( gcode, y2[L_SUBFR - 1] ); + Ltmp = L_shl( Ltmp, add( 5, shift ) ); + Ltmp = L_negate( Ltmp ); + Ltmp = L_mac( Ltmp, xn[L_SUBFR - 1], 16384 ); +#ifdef BASOP_NOGLOB + Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); + *mem_w0 = round_fx_sat( Ltmp ); +#else + Ltmp = L_shl( Ltmp, sub( 1, shift ) ); + *mem_w0 = round_fx( Ltmp ); +#endif + init_gp_clip_fx( clip_gain ); /* reset pitch clipping parameters */ + + *gain_pit = 0; + *tilt_code = 0; + move16(); /* purely unvoiced */ + *voice_fac = -32768; + move16(); /* purely unvoiced */ + exp = sub( norm_s( *gain_inov ), 1 ); + exp = s_max( exp, 0 ); + + tmp = div_s( shr( 8192, exp ), *gain_inov ); + *norm_gain_code = L_shr( Mult_32_16( *gain_code, tmp ), sub( 1, exp ) ); + move16(); + + return ( L_SUBFR << 6 ); +} /*-------------------------------------------------------------------* * gauss2v() * diff --git a/lib_enc/gp_clip_fx.c b/lib_enc/gp_clip_fx.c index 6a98b1d4717d051ae5d77572ab209279fd098aef..d99636a1bea23aa7d3a70a4c266d3decae24e6ab 100644 --- a/lib_enc/gp_clip_fx.c +++ b/lib_enc/gp_clip_fx.c @@ -160,7 +160,14 @@ Word16 gp_clip_fx( e_ener = norm_l( ener ); f_ener = Log2_norm_lc( L_shl( ener, e_ener ) ); e_ener = sub( 30, e_ener ); - e_ener = sub( e_ener, Q_new ); + IF( GT_16( element_mode, EVS_MONO ) ) + { + e_ener = sub( e_ener, Q_new * 2 + 1 ); + } + ELSE + { + e_ener = sub( e_ener, Q_new ); + } ener = Mpy_32_16( e_ener, f_ener, LG10 ); wener = round_fx( L_shl( ener, 10 ) ); diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index 95557d238f21bdf285278953622cf26a0cd75d91..e1cd71e0a1a82b83a0fbf69656dd758c0bcacf9d 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -372,6 +372,358 @@ void encod_audio_fx( return; } +void encod_audio_ivas_fx( + Encoder_State *st_fx, /* i/o: State structure */ + const Word16 speech[], /* i : input speech Q_new */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 *res, /* i : residual signal Q_new */ + Word16 *synth, /* i/o: core synthesis Q-1 */ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new */ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6 */ + Word16 *voice_factors, /* o : voicing factors Q15 */ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q0 */ + const Word16 attack_flag, /* i : Flag that point to an attack coded with AC mode (GSC) */ + Word16 *lsf_new, /* i : current frame ISF vector */ + Word16 *tmp_noise, /* o : noise energy */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new, + Word16 shift ) +{ + const Word16 *p_Aq; + Word16 i, i_subfr, nb_subfr, last_pit_bin; + Word16 T0_tmp, T0_frac_tmp, nb_subfr_flag; + Word16 tmp_nb_bits_tot = 0; + Word16 Es_pred; + Word16 dct_res[L_FRAME16k], dct_epit[L_FRAME16k]; + Word16 m_mean = 0; + Word16 saved_bit_pos; + Word16 exc_wo_nf[L_FRAME16k]; + Word32 Lm_mean; + Word16 nb_bits; + Word16 indice; + SP_MUS_CLAS_HANDLE hSpMusClas = st_fx->hSpMusClas; + GSC_ENC_HANDLE hGSCEnc = st_fx->hGSCEnc; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + + m_mean = 0; + move16(); + tmp_nb_bits_tot = 0; + move16(); + + T0_tmp = 64; + move16(); + T0_frac_tmp = 0; + move16(); + Copy( hLPDmem->mem_syn, hGSCEnc->mem_syn_tmp_fx, M ); + hGSCEnc->mem_w0_tmp_fx = hLPDmem->mem_w0; + move16(); + Es_pred = 0; + move16(); + + /*---------------------------------------------------------------* + * Encode GSC IVAS mode + * Encode GSC attack flag (used to reduce possible pre-echo) + * Encode GSC SWB speech flag + *---------------------------------------------------------------*/ +#if 1 // def GSC_IVAS // TVB -->>>>>> + test(); + if ( GT_16( st_fx->element_mode, EVS_MONO ) && st_fx->idchan == 0 ) + { + push_indice( hBstr, IND_GSC_IVAS_SP, st_fx->GSC_IVAS_mode, 2 ); + } +#endif + IF( attack_flag > 0 ) + { + push_indice( hBstr, IND_GSC_ATTACK, 1, 1 ); + } + ELSE + { + push_indice( hBstr, IND_GSC_ATTACK, 0, 1 ); + } + + + test(); + test(); + test(); + test(); + test(); + test(); + IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( NE_16( st_fx->coder_type, INACTIVE ) && ( ( EQ_16( st_fx->element_mode, EVS_MONO ) && GE_32( st_fx->total_brate, ACELP_13k20 ) ) || + ( GT_16( st_fx->element_mode, EVS_MONO ) && GT_32( st_fx->total_brate, MIN_BRATE_GSC_NOISY_FLAG ) && GE_16( st_fx->bwidth, SWB ) && !st_fx->flag_ACELP16k ) ) ) ) + { + push_indice( hBstr, IND_GSC_SWB_SPEECH, st_fx->GSC_noisy_speech, 1 ); + } + /*---------------------------------------------------------------* + * Find and encode the number of subframes + *---------------------------------------------------------------*/ + test(); + IF( GE_32( st_fx->core_brate, ACELP_9k60 ) && LE_32( st_fx->core_brate, ACELP_13k20 ) ) + { + FOR( i = 0; i < 5; i++ ) + { + test(); + if ( GT_16( abs_s( hSpMusClas->gsc_lt_diff_etot_fx[MAX_LT - i - 1] ), 1536 ) && EQ_16( hGSCEnc->cor_strong_limit, 1 ) ) + { + hGSCEnc->cor_strong_limit = 0; + move16(); + } + } + } + test(); + IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) || ( st_fx->GSC_noisy_speech && st_fx->GSC_IVAS_mode == 0 ) ) + { + nb_subfr = NB_SUBFR; + move16(); + test(); + test(); + if ( st_fx->GSC_IVAS_mode > 0 && LT_16( st_fx->GSC_IVAS_mode, 3 ) && LT_32( st_fx->core_brate, GSC_L_RATE_STG ) ) + { + nb_subfr = 2; + move16(); + } + hGSCEnc->cor_strong_limit = 0; + move16(); + nb_subfr_flag = 1; + move16(); + } + ELSE IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( LE_32( st_fx->core_brate, ACELP_13k20 ) || EQ_16( st_fx->coder_type, INACTIVE ) ) ) + { + hGSCEnc->cor_strong_limit = 0; + nb_subfr = SWNB_SUBFR; + nb_subfr_flag = 1; + move16(); + move16(); + move16(); + } + ELSE + { + test(); + test(); + IF( ( hGSCEnc->cor_strong_limit == 0 || EQ_16( st_fx->coder_type, INACTIVE ) ) && GE_32( st_fx->core_brate, ACELP_9k60 ) ) + { + nb_subfr = 2; + move16(); + nb_subfr_flag = 0; + move16(); + hGSCEnc->cor_strong_limit = 0; + move16(); + } + ELSE + { + nb_subfr = SWNB_SUBFR; + move16(); + nb_subfr_flag = 1; + move16(); + } + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && ( GT_16( hSpMusClas->mold_corr_fx, 26214 ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) && NE_16( st_fx->coder_type, INACTIVE ) ) ) + { + nb_subfr = shl( nb_subfr, 1 ); + nb_subfr_flag |= 0x2; + logic16(); + } + + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, MIN_RATE_4SBFR ) ) + { + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 2 ); + } + ELSE IF( GE_32( st_fx->core_brate, ACELP_9k60 ) ) + { + /* nb_subfr_flag can only have the value 0 or 1 */ + push_indice( hBstr, IND_HF_NOISE, nb_subfr_flag, 1 ); + } + } + test(); + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && EQ_16( nb_subfr, NB_SUBFR ) ) + { + nb_subfr = NB_SUBFR16k; + move16(); + } + + /*---------------------------------------------------------------* + * Compute adaptive (pitch) excitation contribution + *---------------------------------------------------------------*/ + + test(); + IF( !( st_fx->GSC_IVAS_mode > 0 && EQ_16( st_fx->L_frame, i_mult( nb_subfr, 2 * L_SUBFR ) ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) ) && + ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || st_fx->GSC_noisy_speech ) && + ( ( EQ_16( nb_subfr, NB_SUBFR ) && EQ_16( st_fx->L_frame, L_FRAME ) ) || ( EQ_16( nb_subfr, NB_SUBFR16k ) && EQ_16( st_fx->L_frame, L_FRAME16k ) ) ) ) ) + { + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + nb_bits = 5; + } + ELSE + { + nb_bits = Es_pred_bits_tbl[BIT_ALLOC_IDX_fx( st_fx->core_brate, GENERIC, -1, -1 )]; + move16(); + } + Es_pred_enc_fx( &Es_pred, &indice, st_fx->L_frame, res, st_fx->voicing_fx, nb_bits, 0, Q_new ); + push_indice( hBstr, IND_ES_PRED, indice, nb_bits ); + } + + enc_pit_exc_ivas_fx( st_fx, speech, Aw, Aq, Es_pred, res, synth, exc, &T0_tmp, + &T0_frac_tmp, pitch_buf, nb_subfr, &hGSCEnc->lt_gpitch_fx, &saved_bit_pos, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf, Q_new, shift ); + + /*---------------------------------------------------------------* + * DCT transform + *---------------------------------------------------------------*/ + edct_16fx( exc, dct_epit, st_fx->L_frame, 7, st_fx->element_mode ); + edct_16fx( res, dct_res, st_fx->L_frame, 7, st_fx->element_mode ); + /*---------------------------------------------------------------* + * Calculate energy dynamics + *---------------------------------------------------------------*/ + Lm_mean = L_deposit_l( 0 ); + FOR( i = 7; i < 15; i++ ) + { + /*m_mean = add(m_mean,edyn_fx( dct_res+i*16, 16, Q_new )); */ + Lm_mean = L_mac( Lm_mean, edyn_fx( dct_res + i * 16, 16, Q_new ), 4096 ); /*Q7*/ + } + m_mean = round_fx( Lm_mean ); /*Q7*/ + + IF( GT_16( m_mean, hGSCEnc->mid_dyn_fx ) ) + { + /*st_fx->mid_dyn_fx = 0.2f * st_fx->mid_dyn_fx + 0.8f * m_mean;*/ + hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 26214, m_mean ), 6554, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + } + ELSE + { + /*st_fx->mid_dyn_fx = 0.6f * st_fx->mid_dyn_fx + 0.4f * m_mean;*/ + hGSCEnc->mid_dyn_fx = round_fx( L_mac( L_mult( 13107, m_mean ), 19661, hGSCEnc->mid_dyn_fx ) ); /*Q7*/ + } + IF( NE_16( st_fx->coder_type, INACTIVE ) ) + { + hGSCEnc->noise_lev = sub( ( NOISE_LEVEL_SP3 + 1 ), usquant_fx( hGSCEnc->mid_dyn_fx, &m_mean, MIN_DYNAMIC_FX, shr( GSF_NF_DELTA_FX, 1 ), GSC_NF_STEPS ) ); + + hGSCEnc->noise_lev = s_min( hGSCEnc->noise_lev, NOISE_LEVEL_SP3 ); + } + + hGSCEnc->past_dyn_dec = hGSCEnc->noise_lev; + move16(); + IF( GE_16( st_fx->GSC_IVAS_mode, 1 ) ) + { + hGSCEnc->noise_lev = NOISE_LEVEL_SP2; + IF( EQ_16( st_fx->GSC_IVAS_mode, 3 ) ) /* Music like */ + { + hGSCEnc->noise_lev = NOISE_LEVEL_SP0; + move16(); + } + ELSE IF( st_fx->GSC_noisy_speech == 0 ) + { + hGSCEnc->noise_lev = NOISE_LEVEL_SP3; + move16(); + } + } + ELSE IF( LE_32( st_fx->core_brate, ACELP_8k00 ) ) + { + hGSCEnc->noise_lev = s_max( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ); + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP2 ), 2 ); + } + ELSE IF( st_fx->GSC_noisy_speech ) + { + hGSCEnc->noise_lev = NOISE_LEVEL_SP3; + move16(); + } + ELSE + { + push_indice( hBstr, IND_NOISE_LEVEL, sub( hGSCEnc->noise_lev, NOISE_LEVEL_SP0 ), 3 ); + } + + /*---------------------------------------------------------------* + * Find and encode the last band where the adaptive (pitch) contribution is significant + *---------------------------------------------------------------*/ + + last_pit_bin = Pit_exc_contribution_len_ivas_fx( st_fx, dct_res, dct_epit, pitch_buf, nb_subfr, &hGSCEnc->pit_exc_hangover, Q_new ); + + IF( last_pit_bin == 0 ) + { + hLPDmem->tilt_code = 0; + move16(); + } + ELSE + { + /*last_pit_bin++;*/ + last_pit_bin = add( last_pit_bin, 1 ); + } + + /*--------------------------------------------------------------------------------------* + * GSC encoder + *--------------------------------------------------------------------------------------*/ + + /* Find the current total number of bits used */ + tmp_nb_bits_tot = hBstr->nb_bits_tot; + move16(); + + + if ( st_fx->extl_brate > 0 ) + { + /* subtract 1 bit for TBE/BWE BWE flag (bit counted in extl_brate) */ + tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); + } + test(); + test(); + if ( EQ_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, ACELP_9k60 ) && st_fx->idchan == 0 ) + { + /* add 5 bits for noisiness */ + tmp_nb_bits_tot = add( tmp_nb_bits_tot, 5 ); + } + + Word16 Q_exc = Q_new; + move16(); + gsc_enc_ivas_fx( st_fx, dct_res, dct_epit, last_pit_bin, tmp_nb_bits_tot, nb_subfr, lsf_new, exc_wo_nf, tmp_noise, &Q_exc ); + + /*--------------------------------------------------------------------------------------* + * iDCT transform + *--------------------------------------------------------------------------------------*/ + + edct_16fx( dct_epit, exc, st_fx->L_frame, 7, st_fx->element_mode ); + edct_16fx( exc_wo_nf, exc_wo_nf, st_fx->L_frame, 7, st_fx->element_mode ); + /*--------------------------------------------------------------------------------------* + * Remove potential pre-echo in case an onset has been detected + *--------------------------------------------------------------------------------------*/ + + pre_echo_att_fx( &hGSCEnc->Last_frame_ener_fx, exc, attack_flag, Q_exc, st_fx->last_coder_type, st_fx->L_frame ); + + /*--------------------------------------------------------------------------------------* + * Update BWE excitation + *--------------------------------------------------------------------------------------*/ + IF( st_fx->hBWE_TD != NULL ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + set16_fx( voice_factors, 0, NB_SUBFR16k ); + interp_code_4over2_fx( exc, bwe_exc, L_FRAME16k ); + } + ELSE + { + set16_fx( voice_factors, 0, NB_SUBFR ); + interp_code_5over2_fx( exc, bwe_exc, L_FRAME ); + } + } + /*--------------------------------------------------------------------------------------* + * Synthesis + *--------------------------------------------------------------------------------------*/ + + p_Aq = Aq; + FOR( i_subfr = 0; i_subfr < st_fx->L_frame; i_subfr += L_SUBFR ) + { + Syn_filt_s( 1, p_Aq, M, &exc_wo_nf[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 ); + p_Aq += ( M + 1 ); + } + + /*--------------------------------------------------------------------------------------* + * Updates + *--------------------------------------------------------------------------------------*/ + + hLPDmem->mem_w0 = hGSCEnc->mem_w0_tmp_fx; /*_DIFF_FLOAT_FIX_ The way it is written in the original fix point is that at this point mem_w0 falls back to its original value (before enc_pit_exc, seems not the case in float */ + move16(); + Copy( exc_wo_nf, exc, st_fx->L_frame ); + + return; +} + /*================================================================================*/ /* FUNCTION : void gsc_enc_fx () */ /*--------------------------------------------------------------------------------*/ @@ -737,7 +1089,7 @@ void gsc_enc_ivas_fx( } move16(); - Ener_per_band_comp_ivas_fx_2( exc_diff_fx, Ener_per_bd_iQ_fx, *Q_exc, MBANDS_GN, 1, st->L_frame ); + Ener_per_band_comp_ivas_fx( exc_diff_fx, Ener_per_bd_iQ_fx, *Q_exc, MBANDS_GN, 1, st->L_frame ); /*--------------------------------------------------------------------------------------* * Gain quantizaion diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index e1002faaa9628c6df3c9d35515f28b4f1ee73edc..56bd1dbb1c4e81b3ad9fa30190dc7a58d0d44f58 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -405,7 +405,8 @@ void hq_core_enc_ivas_fx( { /* Store LB synthesis in case of switch to ACELP */ Copy( output_fx, st->hLPDmem->old_exc, L_FRAME16k ); - st->hLPDmem->e_old_exc = 15; + // st->hLPDmem->e_old_exc = 15; + st->prev_Q_new = 0; move16(); } pop_wmops(); diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index c754fe4bbe59c25a57a8941a9468e36043450667..0573450d44d80eb9d6cc1601812386876d12c188 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -2305,7 +2305,8 @@ ivas_error init_encoder_ivas_fx( fixedToFloat_arr( st->lspold_enc_fx, st->lspold_enc, Q15, M ); IF( st->hLPDmem != NULL ) { - me2f_buf_16( st->hLPDmem->old_exc, st->hLPDmem->e_old_exc, st->hLPDmem->old_exc_flt, L_EXC_MEM ); + // me2f_buf_16( st->hLPDmem->old_exc, st->hLPDmem->e_old_exc, st->hLPDmem->old_exc_flt, L_EXC_MEM ); + fixedToFloat_arr( st->hLPDmem->old_exc, st->hLPDmem->old_exc_flt, st->prev_Q_new, L_EXC_MEM ); } #endif /*-----------------------------------------------------------------* diff --git a/lib_enc/inov_enc_fx.c b/lib_enc/inov_enc_fx.c index 448c95ab6e0d768aaea8ca1a5526c199fc01e974..5c9e1a7de6e6fca28f6da6eea9089c57ed496edc 100644 --- a/lib_enc/inov_enc_fx.c +++ b/lib_enc/inov_enc_fx.c @@ -449,7 +449,7 @@ Word16 inov_encode_ivas_fx( Word16 shift, Word16 Q_new ) { - Word16 dn[2 * L_SUBFR]; + Word16 dn[2 * L_SUBFR], Qdn; Word16 nBits, cmpl_flag; Word16 stack_pulses; Word16 g1, g2; @@ -493,12 +493,17 @@ Word16 inov_encode_ivas_fx( cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_SUBFR ); /* h2: Q11, Rw: (Rw_e)Q */ - /* Rw_e = */ E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); + // Word16 Rw_e = E_ACELP_hh_corr( h2, Rw, L_SUBFR, 3 ); + Word16 Rw_q; + corr_hh_ivas_fx( h2, Rw, &Rw_q, L_subfr ); // Q(Rw) = Q11-2 - E_ACELP_conv( xn2, h2, cn ); + E_ACELP_conv_ivas( xn2, h2, cn ); // Qcn = Qxn2 /* dn_e -> Rw_e*Q_xn */ - /*dn_e = */ E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); + // Scale_sig(Rw, L_SUBFR, sub(5, Rw_e)); //Q9 + Word16 j = E_ACELP_toeplitz_mul_fx( Rw, cn, dn, L_SUBFR, 1 ); + Qdn = add( add( Q_new - 1 + shift, Rw_q ), j + 1 ); + // Scale_sig(Rw, L_subfr, -3); //Q9->Q6 } ELSE { @@ -509,7 +514,7 @@ Word16 inov_encode_ivas_fx( Scale_sig( cn, L_subfr, shift ); cb_shape_fx( 1, 1, 0, sharpFlag, 0, g1, g2, p_Aq, h2, tilt_code, shr( add( pt_pitch, 26 ), 6 ), 0, L_subfr ); - corr_xh_ivas_fx( xn2, dn, h2, L_subfr ); // Q(dn) = Q_new+1 + corr_xh_ivas_fx2( xn2, Q_new - 1 + shift, dn, &Qdn, h2, L_subfr ); // Q(dn) = Q_new+1 } /*-----------------------------------------------------------------* @@ -528,106 +533,109 @@ Word16 inov_encode_ivas_fx( move16(); } } - ELSE IF( EQ_16( L_frame, L_FRAME ) && EQ_16( coder_type, TRANSITION ) ) - { - test(); - test(); - if ( EQ_32( core_brate, ACELP_8k00 ) && i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) - { - cmpl_flag = 3; - move16(); - } - test(); - test(); - test(); - test(); - test(); - if ( EQ_32( core_brate, ACELP_11k60 ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || EQ_16( tc_subfr, TC_0_0 ) || ( EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( tc_subfr, TC_0_64 ) ) ) ) - { - cmpl_flag = 3; - move16(); - } - test(); - test(); - test(); - test(); - if ( ( EQ_32( core_brate, ACELP_13k20 ) || EQ_32( core_brate, ACELP_12k15 ) ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || LE_16( tc_subfr, TC_0_64 ) ) ) - { - cmpl_flag = 3; - move16(); - } - } - - IF( EQ_16( L_frame, L_FRAME16k ) ) + ELSE { - IF( LE_32( core_brate, ACELP_32k ) ) + IF( EQ_16( L_frame, L_FRAME ) && EQ_16( coder_type, TRANSITION ) ) { - cmpl_flag = 4; - move16(); - test(); - IF( EQ_16( coder_type, TRANSITION ) && GT_16( bwidth, WB ) ) + test(); + if ( EQ_32( core_brate, ACELP_8k00 ) && i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) { - IF( LE_16( i_subfr, L_SUBFR ) ) - { - cmpl_flag = sub( cmpl_flag, 1 ); - } - ELSE - { - cmpl_flag = sub( cmpl_flag, 2 ); - } + cmpl_flag = 3; + move16(); } - } - ELSE IF( LE_32( core_brate, ACELP_48k ) ) - { - cmpl_flag = 3; - move16(); - - IF( EQ_16( coder_type, TRANSITION ) ) + test(); + test(); + test(); + test(); + test(); + if ( EQ_32( core_brate, ACELP_11k60 ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || EQ_16( tc_subfr, TC_0_0 ) || ( EQ_16( i_subfr, 3 * L_SUBFR ) && EQ_16( tc_subfr, TC_0_64 ) ) ) ) { - IF( LE_16( i_subfr, L_SUBFR ) ) - { - cmpl_flag = sub( cmpl_flag, 1 ); - } - ELSE - { - cmpl_flag = sub( cmpl_flag, 2 ); - } + cmpl_flag = 3; + move16(); + } + test(); + test(); + test(); + test(); + if ( ( EQ_32( core_brate, ACELP_13k20 ) || EQ_32( core_brate, ACELP_12k15 ) ) && ( ( i_subfr == 0 && LT_16( tc_subfr, L_SUBFR ) ) || LE_16( tc_subfr, TC_0_64 ) ) ) + { + cmpl_flag = 3; + move16(); } } - ELSE - { - cmpl_flag = 4; - move16(); - IF( EQ_16( coder_type, TRANSITION ) ) + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + IF( LE_32( core_brate, ACELP_32k ) ) { - IF( LE_16( i_subfr, L_SUBFR ) ) + cmpl_flag = 4; + move16(); + + test(); + IF( EQ_16( coder_type, TRANSITION ) && GT_16( bwidth, WB ) ) { - cmpl_flag = sub( cmpl_flag, 1 ); + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } } - ELSE + } + ELSE IF( LE_32( core_brate, ACELP_48k ) ) + { + cmpl_flag = 3; + move16(); + + IF( EQ_16( coder_type, TRANSITION ) ) { - cmpl_flag = sub( cmpl_flag, 2 ); + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } } } - - if ( EQ_16( coder_type, INACTIVE ) ) + ELSE { cmpl_flag = 4; move16(); + + IF( EQ_16( coder_type, TRANSITION ) ) + { + IF( LE_16( i_subfr, L_SUBFR ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } + ELSE + { + cmpl_flag = sub( cmpl_flag, 2 ); + } + } + + if ( EQ_16( coder_type, INACTIVE ) ) + { + cmpl_flag = 4; + move16(); + } } } - } - test(); - test(); - test(); - IF( NE_16( L_frame, st_fx->last_L_frame ) && GT_32( core_brate, ACELP_13k20 ) && ( LT_32( core_brate, ACELP_32k ) || EQ_16( bwidth, WB ) ) ) - { - if ( GT_16( cmpl_flag, 1 ) ) + test(); + test(); + test(); + IF( NE_16( L_frame, st_fx->last_L_frame ) && GT_32( core_brate, ACELP_13k20 ) && ( LT_32( core_brate, ACELP_32k ) || EQ_16( bwidth, WB ) ) ) { - cmpl_flag = sub( cmpl_flag, 1 ); + if ( GT_16( cmpl_flag, 1 ) ) + { + cmpl_flag = sub( cmpl_flag, 1 ); + } } } @@ -670,27 +678,27 @@ Word16 inov_encode_ivas_fx( IF( EQ_16( nBits, 8 ) ) { - acelp_1t64_fx( hBstr, dn, h2, code, y2, L_subfr ); + acelp_1t64_ivas_fx( hBstr, dn, h2, code, y2, L_subfr ); } ELSE { - acelp_fast_fx( hBstr, nBits, dn, add( Q_new, 1 ), cn, h2, code, y2, L_subfr ); + acelp_fast_fx( hBstr, nBits, dn, Qdn, cn, h2, code, y2, L_subfr ); } } ELSE IF( ( EQ_16( st_fx->idchan, 1 ) && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 7 ) ) || ( st_fx->idchan == 0 && LE_16( st_fx->acelp_cfg.fixed_cdk_index[idx2], 3 ) ) ) { IF( st_fx->acelp_cfg.fixed_cdk_index[i_subfr / L_SUBFR] == 0 ) { - acelp_1t64_fx( hBstr, dn, h2, code, y2, L_subfr ); + acelp_1t64_ivas_fx( hBstr, dn, h2, code, y2, L_subfr ); } ELSE { - acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, add( Q_new, 1 ), cn, h2, code, y2, L_SUBFR ); + acelp_fast_fx( hBstr, st_fx->acelp_cfg.fixed_cdk_index[idx2], dn, Qdn, cn, h2, code, y2, L_SUBFR ); } } ELSE { - E_ACELP_4t_fx( dn, cn, h2, Rw, (Word8) acelpautoc, code, st_fx->acelp_cfg.fixed_cdk_index[idx2], prm, L_frame, last_L_frame, st_fx->total_brate, i_subfr, cmpl_flag ); + E_ACELP_4t_ivas_fx( dn, cn, h2, Rw, (Word8) acelpautoc, code, st_fx->acelp_cfg.fixed_cdk_index[idx2], prm, L_frame, last_L_frame, st_fx->total_brate, i_subfr, cmpl_flag, st_fx->element_mode ); wordcnt = shr( ACELP_FIXED_CDK_BITS( st_fx->acelp_cfg.fixed_cdk_index[idx2] ), 4 ); move16(); @@ -708,6 +716,7 @@ Word16 inov_encode_ivas_fx( /* Generate weighted code */ set16_fx( y2, 0, L_SUBFR ); + Word16 sh = add( norm_s( h2[0] ), 1 ); FOR( i = 0; i < L_SUBFR; i++ ) { /* Code is sparse, so check which samples are non-zero */ @@ -715,7 +724,7 @@ Word16 inov_encode_ivas_fx( { FOR( k = 0; k < L_SUBFR - i; k++ ) { - y2[i + k] += code[i] * h2[k]; + y2[i + k] = add( y2[i + k], mult_r( code[i], shl_sat( h2[k], sh ) ) ); } } } @@ -743,15 +752,15 @@ Word16 inov_encode_ivas_fx( IF( EQ_16( nBits, 7 ) ) { - acelp_1t64_fx( hBstr, dn, h2, code, y2, L_SUBFR ); + acelp_1t64_ivas_fx( hBstr, dn, h2, code, y2, L_SUBFR ); } ELSE IF( EQ_16( nBits, 12 ) ) { - acelp_2t32_fx( hBstr, dn, h2, code, y2 ); + acelp_2t32_ivas_fx( hBstr, dn, h2, code, y2 ); } ELSE { - *unbits = add( *unbits, acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, nBits, cmpl_flag, Opt_AMR_WB ) ); + *unbits = add( *unbits, acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, nBits, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ) ); move16(); } } @@ -760,39 +769,39 @@ Word16 inov_encode_ivas_fx( { IF( EQ_32( core_brate, ACELP_6k60 ) ) { - acelp_2t32_fx( hBstr, dn, h2, code, y2 ); + acelp_2t32_ivas_fx( hBstr, dn, h2, code, y2 ); } ELSE IF( ( EQ_32( core_brate, ACELP_8k85 ) ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 20, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 20, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_12k65 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 36, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 36, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_14k25 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 44, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 44, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_15k85 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 52, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 52, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_18k25 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 64, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 64, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_19k85 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 72, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 72, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_23k05 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, cmpl_flag, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, cmpl_flag, Opt_AMR_WB, st_fx->element_mode ); } ELSE IF( EQ_32( core_brate, ACELP_23k85 ) ) { - acelp_4t64_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, 1, Opt_AMR_WB ); + acelp_4t64_ivas_fx( hBstr, dn, cn, h2, Rw, acelpautoc, code, y2, 88, 1, Opt_AMR_WB, st_fx->element_mode ); } } diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index cea581a9480e9a8cc8b407a5f14d3b72e81b5474..26a1d1ffb84dc6f2035afc029681ac3ed42a0097 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -507,7 +507,7 @@ void stereo_tcx_core_enc( Word16 exp_exc; f2me_buf_16( st->hLPDmem->old_exc_flt, st->hLPDmem->old_exc, &exp_exc, L_EXC_MEM ); Q_exc = 15 - exp_exc; - st->hLPDmem->e_old_exc = exp_exc; + st->prev_Q_new = Q_exc; if ( st->hTdCngEnc != NULL ) { floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index 42cea4ce66215b04b1c5915984b9683151e8b727..22e3fcc2ec5cd39e65f85616c54d67a4664fefe9 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -173,7 +173,7 @@ void tdm_low_rate_enc( const Word16 attack_flag, /* i : GSC attack flag */ const Word16 *lsf_new, /* i : current frame ISF vector */ Word16 *tmp_noise, /* o : long-term noise energy */ - Word16 *Q_new ) + Word16 Q_new ) { const Word16 *p_Aq; Word16 i_subfr, nb_subfr, last_pit_bin; @@ -207,7 +207,7 @@ void tdm_low_rate_enc( * DCT transform of the residual and create a subsample residual *---------------------------------------------------------------*/ - edct_16fx( res, dct_res_fx, L_FRAME, st->element_mode, *Q_new ); + edct_16fx( res, dct_res_fx, L_FRAME, 7, st->element_mode ); /*--------------------------------------------------------------------------------------* * GSC encoder @@ -223,7 +223,7 @@ void tdm_low_rate_enc( tmp_nb_bits_tot = sub( tmp_nb_bits_tot, 1 ); } - Word16 Q_exc = *Q_new; + Word16 Q_exc = Q_new; move16(); gsc_enc_ivas_fx( st, dct_res_fx, dct_epit_fx, last_pit_bin, tmp_nb_bits_tot, nb_subfr, lsf_new, exc_wo_nf_fx, tmp_noise, &Q_exc ); @@ -231,9 +231,9 @@ void tdm_low_rate_enc( * iDCT transform *--------------------------------------------------------------------------------------*/ - edct_16fx( dct_epit_fx, exc_fx, L_FRAME, st->element_mode, Q_exc ); + edct_16fx( dct_epit_fx, exc_fx, L_FRAME, 7, st->element_mode ); - edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, st->element_mode, Q_exc ); + edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, 7, st->element_mode ); /*--------------------------------------------------------------------------------------* * Remove potential pre-echo in case an onset has been detected @@ -275,9 +275,6 @@ void tdm_low_rate_enc( *--------------------------------------------------------------------------------------*/ Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); - *Q_new = Q_exc; - move16(); - return; } #endif @@ -489,7 +486,7 @@ void encod_gen_2sbfr( Word16 *bwe_exc, /* o : excitation for SWB TBE Q_new */ const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ const Word16 tdm_Pri_pitch_buf[], /* i : pitch values for primary channel Q4 */ - Word16 *Q_new ) + Word16 Q_new ) { Word16 xn[2 * L_SUBFR]; /* Target vector for pitch search */ Word16 xn2[2 * L_SUBFR]; /* Target vector for codebook search */ @@ -563,8 +560,8 @@ void encod_gen_2sbfr( Copy( &res[i_subfr], &exc[i_subfr], 2 * L_SUBFR ); // Q_new // Scaling mem_syn buffer to Q_new - 1 from e_mem_syn - Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent - hLPDmem->e_mem_syn = sub( Q16, *Q_new ); + // Scale_sig( &hLPDmem->mem_w0, M + 1, sub( add( *Q_new, hLPDmem->e_mem_syn ), Q16 ) ); // M + 1 to sync mem_syn exponent with mem_w0 exponent + // hLPDmem->e_mem_syn = sub( Q16, *Q_new ); find_targets_ivas_fx( speech, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq, res, 2 * L_SUBFR, p_Aw, st->preemph_fac, xn, cn, h1 ); @@ -587,7 +584,7 @@ void encod_gen_2sbfr( * Gain clipping test to avoid unstable synthesis on frame erasure *-----------------------------------------------------------------*/ - clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, *Q_new ); // Q0 + clip_gain = gp_clip_fx( st->element_mode, st->core_brate, st->voicing_fx, i_subfr, coder_type, xn, st->clip_var_fx, Q_new ); // Q0 /*-----------------------------------------------------------------* * LP filtering of the adaptive excitation, codebook target computation @@ -603,13 +600,13 @@ void encod_gen_2sbfr( * Innovation encoding *-----------------------------------------------------------------*/ - inov_encode_ivas_fx( st, st->core_brate, 0, L_frame, st->last_L_frame, coder_type, st->bwidth, st->sharpFlag, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR, 0, *Q_new ); + inov_encode_ivas_fx( st, st->core_brate, 0, L_frame, st->last_L_frame, coder_type, st->bwidth, st->sharpFlag, i_subfr, -1, p_Aq, gain_pit, cn, exc, h1, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &i, 2 * L_SUBFR, 0, Q_new ); /*-----------------------------------------------------------------* * Gain encoding *-----------------------------------------------------------------*/ - gain_enc_lbr_ivas_fx( st->hBstr, st->acelp_cfg.gains_mode, coder_type, i_subfr, xn, y1, add( sub( *Q_new, 1 ), shift ), y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gc_mem, gp_mem, clip_gain, 2 * L_SUBFR ); + gain_enc_lbr_ivas_fx( st->hBstr, st->acelp_cfg.gains_mode, coder_type, i_subfr, xn, y1, add( sub( Q_new, 1 ), shift ), y2, code, &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, gc_mem, gp_mem, clip_gain, 2 * L_SUBFR ); IF( st->Opt_SC_VBR ) { @@ -627,7 +624,7 @@ void encod_gen_2sbfr( gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx ); - hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, *Q_new, 2 * L_SUBFR, 0 ); + hLPDmem->tilt_code = est_tilt_ivas_fx( exc + i_subfr, gain_pit, code, gain_code, &voice_fac, Q_new, 2 * L_SUBFR, 0 ); move16(); /*-----------------------------------------------------------------* @@ -654,7 +651,7 @@ void encod_gen_2sbfr( * Prepare TBE excitation *-----------------------------------------------------------------*/ - prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, *Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); + prep_tbe_exc_ivas_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR], bwe_exc, 0, NULL, Q_new, T0, T0_frac, coder_type, st->core_brate, st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag ); voice_factors[i_subfr / L_SUBFR + 1] = voice_factors[i_subfr / L_SUBFR]; move16(); diff --git a/lib_enc/pit_enc_fx.c b/lib_enc/pit_enc_fx.c index b49e52fad2cb086226cf9b610aece67c1389e60d..609e243434b4da59cc2d4a7c2089c7c547d5aa4a 100644 --- a/lib_enc/pit_enc_fx.c +++ b/lib_enc/pit_enc_fx.c @@ -500,7 +500,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional Word16 pit_flag, delta, mult_Top, nBits; Word16 L_sufr_sft; Word16 T_op[2]; /* values for two half-frames */ -#ifdef REMOVE_IVAS_UNUSED_PARAMETERS_WARNING +#if 0 // def REMOVE_IVAS_UNUSED_PARAMETERS_WARNING (void) tdm_Pitch_reuse_flag; #endif @@ -645,7 +645,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional /* search and encode the closed loop pitch period */ *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_MAX, PIT_MAX, L_FRAME, L_subfr ); - pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE IF( EQ_16( coder_type, VOICED ) ) { @@ -681,7 +681,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional move16(); } - pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } #if 1 //#ifdef ADD_LRTD @@ -725,7 +725,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional *T0_frac = 0; move16(); } - pit_Q_enc_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + pit_Q_enc_ivas_fx( hBstr, 0, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } ELSE { @@ -890,7 +890,7 @@ Word16 pit_encode_ivas_fx( /* o : Fractional *T0 = pitch_fr4_fx( &exc[i_subfr], xn, h1, *T0_min, *T0_max, T0_frac, pit_flag, *limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); } - pit_Q_enc_fx( hBstr, 1, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); + pit_Q_enc_ivas_fx( hBstr, 1, nBits, delta, pit_flag, *limit_flag, *T0, *T0_frac, T0_min, T0_max ); } /*-------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 8b2669996078852c00d383baffd4f880f0608781..27c9e404e44919290479a6bad6323b65254b44f0 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -127,6 +127,18 @@ void AVQ_encmux_fx( Word16 trgtSvPos /* i : target SV for AVQ bit savings */ ); +void AVQ_encmux_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + const Word16 extl, /* i : extension layer */ + Word16 xriq[], /* i/o: rounded subvectors [0..8*Nsv-1] followed + by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] */ + Word16 *nb_bits, /* i/o: number of allocated bits */ + const Word16 Nsv, /* i: number of subvectors */ + Word16 nq_out[], /* o : AVQ nq index */ + Word16 avq_bit_sFlag, /* i : flag for AVQ bit saving solution */ + Word16 trgtSvPos /* i : target SV for AVQ bit savings */ +); + void bw_detect_fx( Encoder_State *st, /* i/o: Encoder State */ const Word16 signal_in[], /* i : i signal */ @@ -1509,6 +1521,22 @@ void E_ACELP_4t_fx( const Word16 i_subfr, const Word16 cmpl_flag ); +void E_ACELP_4t_ivas_fx( + Word16 dn[], + Word16 cn[] /* Q_xn */, + Word16 H[], + Word16 R[], + Word8 acelpautoc, + Word16 code[], + Word16 cdk_index, + Word16 _index[], + const Word16 L_frame, + const Word16 last_L_frame, + const Word32 total_brate, + const Word16 i_subfr, + const int16_t cmpl_flag, + Word16 element_mode ); + void E_ACELP_innovative_codebook_fx( Word16 *exc, /* i : pointer to the excitation frame Q_new */ Word16 T0, /* i : integer pitch lag Q0 */ @@ -1833,6 +1861,26 @@ Word16 encod_tran_fx( const Word16 Q_new /* i : Input scaling */ ); +Word16 encod_tran_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 speech_fx[], /* i : input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* i/o: core synthesis */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ + Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + Word16 tc_subfr, /* i/o: TC subframe classification */ + Word16 position, /* i : maximum of residual signal index */ + Word16 *unbits, /* i/o: number of unused bits */ + const Word16 shift, /* i : Scaling to get 12 bits */ + const Word16 Q_new /* i : Input scaling */ +); + /* Delete the instance of type FD_CNG */ void deleteFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc ); @@ -1917,6 +1965,23 @@ void encod_unvoiced_fx( const Word16 Q_new, const Word16 shift ); +void encod_unvoiced_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 *speech_fx, /* i : Input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 *Aq_fx, /* i : 12k8 Lp coefficient */ + const Word16 Es_pred, /* i : predicted scaled innov. energy */ + const Word16 uc_two_stage_flag, /* i : flag indicating two-stage UC */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* o : core synthesis */ + Word16 *tmp_noise_fx, /* o : long-term noise energy */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */ + const Word16 Q_new, + const Word16 shift ); + void enc_acelp_tcx_main_fx( const Word16 new_samples[], /* i : new samples */ Encoder_State *st, /* i/o: encoder state structure */ @@ -1962,6 +2027,25 @@ void encod_gen_voic_fx( Word16 shift, Word16 Q_new ); +void encod_gen_voic_ivas_fx( + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 speech_fx[], /* i : input speech */ + const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq_fx[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */ + const Word16 *res_fx, /* i : residual signal */ + Word16 *syn_fx, /* i/o: core synthesis */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *exc2_fx, /* i/o: current enhanced excitation */ + Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe */ + Word16 *voice_factors_fx, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + Word16 *unbits_fx, /* i/o: number of unused bits */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 shift, + Word16 Q_new ); + void encod_audio_fx( Encoder_State *st_fx, /* i/o: State structure */ const Word16 speech[], /* i : i speech Q_new */ @@ -1980,6 +2064,26 @@ void encod_audio_fx( const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ Word16 Q_new, Word16 shift ); + +void encod_audio_ivas_fx( + Encoder_State *st_fx, /* i/o: State structure */ + const Word16 speech[], /* i : input speech Q_new */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 *res, /* i : residual signal Q_new */ + Word16 *synth, /* i/o: core synthesis Q-1 */ + Word16 *exc, /* i/o: current non-enhanced excitation Q_new */ + Word16 *pitch_buf, /* i/o: floating pitch values for each subframe Q6 */ + Word16 *voice_factors, /* o : voicing factors Q15 */ + Word16 *bwe_exc, /* o : excitation for SWB TBE Q0 */ + const Word16 attack_flag, /* i : Flag that point to an attack coded with AC mode (GSC) */ + Word16 *lsf_new, /* i : current frame ISF vector */ + Word16 *tmp_noise, /* o : noise energy */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new, + Word16 shift ); + void stat_noise_uv_enc_fx( Encoder_State *st_fx, /* i/o: state structure */ const Word32 *LepsP, /* i : LP prediction errors */ @@ -2077,6 +2181,15 @@ void tcx_hm_analyse_fx( ); void E_ACELP_4tsearchx_fx( Word16 dn[], const Word16 cn[], Word16 Rw[], Word16 code[], const PulseConfig *config, Word16 ind[] ); +void E_ACELP_4tsearchx_ivas_fx( + Word16 dn[], + const Word16 cn[], + Word16 Rw[], + Word16 code[], + const PulseConfig *config, + Word16 ind[], + Word16 element_mode ); + void E_ACELP_weighted_code( const Word16 code[], /* i: code */ const Word16 H[], /* i: impulse response */ @@ -2539,6 +2652,12 @@ void E_ACELP_conv( Word16 cn2[] /* o */ ); +void E_ACELP_conv_ivas( + const Word16 xn2[], /* i */ + const Word16 h2[], /* i */ + Word16 cn2[] /* o */ +); + void gPLC_encInfo_fx( PLC_ENC_EVS_HANDLE self, const Word32 modeBitrate, @@ -2740,6 +2859,22 @@ void corr_xh_ivas_fx( const Word16 L_subfr /* i : length of the subframe */ ); +void corr_hh_ivas_fx( + const Word16 *h, /* i : target signal e(norm_s(h1[0])+1) */ + Word16 *y, /* o : correlation between x[] and h[] Q_new + 1 */ + Word16 *Qy, + const Word16 L_subfr /* i : length of the subframe */ +); + +void corr_xh_ivas_fx2( + const Word16 x[], /* i : target signal */ + const Word16 Qx, + Word16 dn[], /* o : correlation between x[] and h[] */ + Word16 *Qdn, + const Word16 h[], /* i : impulse response (of weighted synthesis filter) */ + const Word16 L_subfr /* i : length of the subframe */ +); + void qlpc_avq_fx( const Word16 *lsf, /* i : Input LSF vectors (14Q1*1.28) */ const Word16 *lsfmid, /* i : Input LSF vectors (14Q1*1.28) */ @@ -3412,6 +3547,31 @@ void transf_cdbk_enc_fx( const Word16 shift /* i : shifting applied to y1, xn,... */ ); +void transf_cdbk_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ + const Word16 i_subfr, /* i : subframe index */ + Word16 cn[], /* i/o: target vector in residual domain */ + Word16 exc[], /* i/o: pointer to excitation signal frame */ + const Word16 *p_Aq, /* i : 12k8 Lp coefficient */ + const Word16 Ap[], /* i : weighted LP filter coefficients */ + const Word16 h1[], /* i : weighted filter input response */ + Word16 xn[], /* i/o: target vector */ + Word16 xn2[], /* i/o: target vector for innovation search */ + Word16 y1[], /* i/o: zero-memory filtered adaptive excitation */ + const Word16 y2[], /* i : zero-memory filtered innovative excitation */ + const Word16 Es_pred, /* i : predicited scaled innovation energy */ + Word16 *gain_pit, /* i/o: adaptive excitation gain */ + const Word32 gain_code, /* i : innovative excitation gain */ + Word16 g_corr[], /* o : ACELP correlation values */ + const Word16 clip_gain, /* i : adaptive gain clipping flag */ + Word16 *gain_preQ, /* o : prequantizer excitation gain */ + Word16 code_preQ[], /* o : prequantizer excitation */ + Word16 *unbits, /* o : number of AVQ unused bits */ + const Word16 Q_new, /* i : Current frame scaling */ + const Word16 shift /* i : shifting applied to y1, xn,... */ +); + void gain_enc_lbr_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 gains_mode[], /* i : gain bits */ @@ -3472,6 +3632,24 @@ void gain_enc_SQ_fx( const Word16 Q_xn /* i : xn and y1 scaling */ ); +void gain_enc_SQ_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *xn, /* i : target vector Q_xn */ + const Word16 *yy1, /* i : zero-memory filtered adaptive excitation Q_xn */ + const Word16 *y2, /* i : zero-memory filtered algebraic codebook excitation Q9 */ + const Word16 *code, /* i : algebraic excitation Q9 */ + const Word16 Es_pred, /* i : predicted scaled innovation energy Q8 */ + Word16 *gain_pit, /* o : quantized pitch gain Q14 */ + Word32 *gain_code, /* o : quantized codebook gain Q16 */ + Word16 *gain_inov, /* o : gain of the innovation (used for normalization) Q12 */ + Word32 *norm_gain_code, /* o : norm. gain of the codebook excitation Q16 */ + Word16 *g_corr, /* i/o: correlations , ,, -2 and 2 */ + const Word16 clip_gain, /* i : gain pitch clipping flag (1 = clipping) */ + const Word16 Q_xn /* i : xn and y1 scaling */ +); + void updt_tar_fx( const Word16 *x, /* i : old target (for pitch search) */ Word16 *x2, /* o : new target (for codebook search) */ @@ -3545,6 +3723,33 @@ void transition_enc_fx( ); +void transition_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *tc_subfr, /* i/o: TC subframe index */ + Word16 *Jopt_flag, /* i : joint optimization flag */ + Word16 *position, /* i/o: maximum of residual signal index */ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch Q0*/ + Word16 *T0_min, /* i/o: lower limit for close-loop search Q0*/ + Word16 *T0_max, /* i/o: higher limit for close-loop search Q0*/ + Word16 *exc_fx, /* i/o: pointer to excitation signal frame Q_new*/ + Word16 *y1_fx, /* o : zero-memory filtered adaptive excitation Q_new-1+shift*/ + const Word16 *h1_fx, /* i : weighted filter input response Q(14+shift)*/ + const Word16 *xn_fx, /* i : target vector Q_new-1+shift*/ + Word16 *xn2_fx, /* o : target vector for innovation search Q_new-1+shift*/ + Word16 *gp_cl_fx, /* i/o: memory of gain of pitch clipping algorithm */ + Word16 *gain_pit_fx, /* o : adaptive excitation gain Q14*/ + Word16 *g_corr_fx, /* o : ACELP correlation values */ + Word16 *clip_gain, /* i/o: adaptive gain clipping flag */ + Word16 **pt_pitch_fx, /* o : floating pitch values */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/ + Word16 *unbits_ACELP, /* i/o: unused bits */ + Word16 Q_new, /* i : Current scaling */ + Word16 shift /* i : downscaling needs for 12 bits convolutions */ + +); + void transf_cdbk_enc_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP */ @@ -3584,6 +3789,21 @@ void gain_enc_tc_fx( const Word16 Q_xn /* i : xn and y1 scaling Q0 */ ); +void gain_enc_tc_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 gains_mode[], /* i : gain bits */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 xn_fx[], /* i : target vector */ + const Word16 y2_fx[], /* i : zero-memory filtered algebraic codebook excitation */ + const Word16 code_fx[], /* i : algebraic excitation */ + const Word16 Es_pred_fx, /* i : predicted scaled innovation energy */ + Word16 *gain_pit_fx, /* o : Pitch gain / Quantized pitch gain */ + Word32 *gain_code_fx, /* o : quantized codebook gain */ + Word16 *gain_inov_fx, /* o : innovation gain */ + Word32 *norm_gain_code_fx, /* o : norm. gain of the codebook excitation */ + const Word16 Q_xn /* i : xn and y1 scaling Q0 */ +); + Word16 gaus_encode_fx( Encoder_State *st_fx, /* i/o: encoder state structure */ const Word16 i_subfr, /* i : subframe index */ @@ -3603,6 +3823,27 @@ Word16 gaus_encode_fx( const Word16 shift, /* i : scaling factor */ Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ ); + +Word16 gaus_encode_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 i_subfr, /* i : subframe index */ + const Word16 *h1, /* i : weighted filter input response */ + const Word16 *xn, /* i : target vector */ + Word16 *exc, /* o : pointer to excitation signal frame */ + Word16 *mem_w0, /* o : weighting filter denominator memory */ + Word16 *clip_gain, /* o : memory of gain of pitch clipping algorithm */ + Word16 *tilt_code, /* o : synthesis excitation spectrum tilt */ + Word16 *code, /* o : algebraic excitation Q9 */ + Word32 *gain_code, /* o : Code gain. Q16 */ + Word16 *y2, /* o : zero-memory filtered adaptive excitation Q9 */ + Word16 *gain_inov, /* o : innovation gain Q12 */ + Word16 *voice_fac, /* o : voicing factor Q15 */ + Word16 *gain_pit, /* o : adaptive excitation gain Q14 */ + const Word16 Q_new, /* i : scaling factor */ + const Word16 shift, /* i : scaling factor */ + Word32 *norm_gain_code /* o : normalized innovative cb. gain Q16 */ +); + void pre_proc_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 input_frame, /* i : frame length */ @@ -3669,6 +3910,27 @@ void enc_pit_exc_fx( const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ Word16 Q_new, Word16 shift ); + +void enc_pit_exc_ivas_fx( + Encoder_State *st_fx, /* i/o: State structure */ + const Word16 *speech, /* i : Input speech */ + const Word16 Aw[], /* i : weighted A(z) unquantized for subframes */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 Es_pred, /* i : predicted scaled innov. energy */ + const Word16 *res, /* i : residual signal */ + Word16 *synth, /* i/o: core synthesis */ + Word16 *exc, /* i/o: current non-enhanced excitation */ + Word16 *T0, /* i/o: close loop integer pitch */ + Word16 *T0_frac, /* i/o: close-loop pitch period - fractional part */ + Word16 *pitch_buf, /* i/o: Fractionnal per subframe pitch */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + Word16 *gpit, /* o : pitch mean gpit */ + Word16 *saved_bit_pos, /* o : saved position in the bitstream before pitch contribution */ + const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */ + const Word16 tdm_Pri_pitch_buf[], /* i : primary channel pitch buffer */ + Word16 Q_new, + Word16 shift ); + Word16 Pit_exc_contribution_len_fx( /* o : bin where pitch contribution is significant */ Encoder_State *st_fx, /* i/o: state structure */ const Word16 *dct_res, /* i : DCT of residual */ @@ -3678,6 +3940,15 @@ Word16 Pit_exc_contribution_len_fx( /* o : bin where pit Word16 *hangover, /* i : hangover for the time contribution switching */ Word16 Qnew ); +Word16 Pit_exc_contribution_len_ivas_fx( /* o : bin where pitch contribution is significant */ + Encoder_State *st_fx, /* i/o: state structure */ + const Word16 *dct_res, /* i : DCT of residual */ + Word16 *dct_pitex, /* i/o: DCT of pitch contribution */ + Word16 *pitch_buf, /* i/o: Pitch per subframe */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + Word16 *hangover, /* i : hangover for the time contribution switching */ + Word16 Qnew ); + Word16 pvq_core_enc_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 coefs_norm[], /* i/o: normalized coefficients to encode */ @@ -4011,6 +4282,15 @@ void acelp_1t64_fx( const Word16 L_subfr /* i : subframe length */ ); +void acelp_1t64_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 code[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[], /* o : filtered fixed codebook excitation */ + const Word16 L_subfr /* i : subframe length */ +); + void acelp_2t32_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const Word16 dn[], /* i : corr. between target and h[]. */ @@ -4019,6 +4299,14 @@ void acelp_2t32_fx( Word16 y[] /* o : filtered fixed codebook excitation */ ); +void acelp_2t32_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 h[], /* i : impulse response of weighted synthesis filter */ + Word16 code[], /* o : algebraic (fixed) codebook excitation */ + Word16 y[] /* o : filtered fixed codebook excitation */ +); + Word16 acelp_4t64_fx( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ Word16 dn[], /* i : corr. between target and h[]. */ @@ -4033,6 +4321,20 @@ Word16 acelp_4t64_fx( const Word16 Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ ); +Word16 acelp_4t64_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + Word16 dn[], /* i : corr. between target and h[]. */ + const Word16 cn[], /* i : residual after long term prediction Q_new*/ + const Word16 H[], /* i : impulse response of weighted synthesis filter Q12*/ + Word16 R[], /* i : autocorrelation values */ + const Word16 acelpautoc, /* i : autocorrealtion flag */ + Word16 code[], /* o : algebraic (fixed) codebook excitation Q9*/ + Word16 y[], /* o : filtered fixed codebook excitation Q9*/ + Word16 nbbits, /* i : number of bits per codebook */ + const Word16 cmpl_flag, /* i : complexity reduction flag */ + const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */ + Word16 element_mode ); + ivas_error evs_enc_fx( Encoder_State *st, /* i/o: encoder state structure */ const Word16 *data, /* i : i signal */ diff --git a/lib_enc/set_impulse_fx.c b/lib_enc/set_impulse_fx.c index f9efcacca33312130d2350aa325c9be8ab158818..ebdfe868973b39312baa154696c596ea89192f0c 100644 --- a/lib_enc/set_impulse_fx.c +++ b/lib_enc/set_impulse_fx.c @@ -190,7 +190,11 @@ void set_impulse_fx( FOR( j = 1; j <= L_IMPULSE2; j++ ) { /*rr[L_SUBFR-1] += gh[j]*gh[j];*/ +#ifdef BASOP_NOGLOB + Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); +#else Lrr = L_mac( Lrr, gh_fx[j], gh_fx[j] ); +#endif } rr_fx[L_SUBFR - 1] = Lrr; move32(); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 8f0dd5c8a30ad8b42768a295e8607f90f5dc2517..51cbc7a7e6a0b73b2fdab7959fa6359779ea1f59 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1075,7 +1075,6 @@ typedef struct lpd_state_structure Word16 syn[1 + M]; /* Synthesis memory (non-pe) */ Word16 old_exc[L_EXC_MEM]; /* ACELP exc memory (Aq) */ - Word16 e_old_exc; float mem_w0_flt; float mem_syn_flt[M]; /* ACELP synthesis memory (pe) before post-proc */ @@ -1090,7 +1089,6 @@ typedef struct lpd_state_structure Word16 mem_syn2[M]; /* ACELP synthesis memory (pe) after post-proc */ Word16 mem_syn_r[L_SYN_MEM]; /* ACELP synthesis memory for 1.25ms */ Word16 mem_syn3[M]; - Word16 e_mem_syn; float tilt_code_flt; Word16 tilt_code; /* Q15 */ diff --git a/lib_enc/transition_enc_fx.c b/lib_enc/transition_enc_fx.c index 3a9fabba0a0884684d229fee08b50f2e690f41d6..513ea4098f52e70eda4a8039eac7f4274b9d7101 100644 --- a/lib_enc/transition_enc_fx.c +++ b/lib_enc/transition_enc_fx.c @@ -3,11 +3,11 @@ ====================================================================================*/ #include -#include "options.h" /* Compilation switches */ -#include "cnst.h" /* Common constants */ -#include "rom_com_fx.h" /* Static table prototypes */ -#include "rom_com.h" /* Static table prototypes */ -//#include "prot_fx.h" /* Function prototypes */ +#include "options.h" /* Compilation switches */ +#include "cnst.h" /* Common constants */ +#include "rom_com_fx.h" /* Static table prototypes */ +#include "rom_com.h" /* Static table prototypes */ +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -18,6 +18,7 @@ static void gain_trans_enc_fx( Word32 gain_trans32, Word16 exc[], Word16 *quant_index, Word16 *quant_sign, Word16 Q_new ); static void tc_enc_fx( Encoder_State *st_fx, const Word16 i_subfr, Word16 *tc_subfr, Word16 *position, const Word16 *h1_fx, const Word16 *xn_fx, Word16 *exc_fx, Word16 *yy1_fx, Word16 *T0_min, Word16 *T0_max, Word16 *T0, Word16 *T0_frac, Word16 *gain_pit_fx, Word16 g_corr_fx[], Word16 *bwe_exc_fx, Word16 Q_new ); +static void tc_enc_ivas_fx( Encoder_State *st_fx, const Word16 i_subfr, Word16 *tc_subfr, Word16 *position, const Word16 *h1_fx, const Word16 *xn_fx, Word16 *exc_fx, Word16 *yy1_fx, Word16 *T0_min, Word16 *T0_max, Word16 *T0, Word16 *T0_frac, Word16 *gain_pit_fx, Word16 g_corr_fx[], Word16 *bwe_exc_fx, Word16 Q_new ); /*==========================================================================*/ @@ -852,6 +853,801 @@ void transition_enc_fx( return; } +void transition_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 i_subfr, /* i : subframe index */ + Word16 *tc_subfr, /* i/o: TC subframe index */ + Word16 *Jopt_flag, /* i : joint optimization flag */ + Word16 *position, /* i/o: maximum of residual signal index */ + Word16 *T0, /* i/o: close loop integer pitch Q0*/ + Word16 *T0_frac, /* i/o: close loop fractional part of the pitch Q0*/ + Word16 *T0_min, /* i/o: lower limit for close-loop search Q0*/ + Word16 *T0_max, /* i/o: higher limit for close-loop search Q0*/ + Word16 *exc_fx, /* i/o: pointer to excitation signal frame Q_new*/ + Word16 *y1_fx, /* o : zero-memory filtered adaptive excitation Q_new-1+shift*/ + const Word16 *h1_fx, /* i : weighted filter input response Q(14+shift)*/ + const Word16 *xn_fx, /* i : target vector Q_new-1+shift*/ + Word16 *xn2_fx, /* o : target vector for innovation search Q_new-1+shift*/ + Word16 *gp_cl_fx, /* i/o: memory of gain of pitch clipping algorithm */ + Word16 *gain_pit_fx, /* o : adaptive excitation gain Q14*/ + Word16 *g_corr_fx, /* o : ACELP correlation values */ + Word16 *clip_gain, /* i/o: adaptive gain clipping flag */ + Word16 **pt_pitch_fx, /* o : floating pitch values */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE Q_new*/ + Word16 *unbits_ACELP, /* i/o: unused bits */ + Word16 Q_new, /* i : Current scaling */ + Word16 shift /* i : downscaling needs for 12 bits convolutions */ + +) +{ + Word16 pit_flag, pit_start, pit_limit, index, nBits; + Word16 tmp, tmp1, i; + Word32 offset; + Word16 shift_wsp; + Word16 limit_flag, mult_Top, lp_select, lp_flag; + Word16 T_op[2]; /* values for two half-frames */ + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; + + /* set limit_flag to 0 for restrained limits, and 1 for extended limits */ + limit_flag = 0; + move16(); + + pit_start = PIT_MIN; + move16(); + + /*----------------------------------------------------------------* + * convert pitch values to 16kHz domain + *----------------------------------------------------------------*/ + + IF( EQ_16( st_fx->L_frame, L_FRAME ) /*|| (tdm_Pri_pitch_buf != NULL && tdm_Pri_pitch_buf[0] < 0)*/ ) + { + Copy( st_fx->pitch, T_op, 2 ); + } + ELSE /* L_frame == L_FRAME16k */ + { + /*T_op[0] = (int16_t)(pitch[0] * 1.25f + 0.5f); + T_op[1] = (int16_t)(pitch[1] * 1.25f + 0.5f);*/ + T_op[0] = add( st_fx->pitch[0], mult_r( st_fx->pitch[0], 8192 /*0.25f Q15*/ ) ); + T_op[1] = add( st_fx->pitch[1], mult_r( st_fx->pitch[1], 8192 /*0.25f Q15*/ ) ); + } + shift_wsp = add( Q_new, shift ); + + lp_flag = st_fx->acelp_cfg.ltf_mode; + move16(); + /*-----------------------------------------------------------------* + * TC: subrame determination for glottal shape search + * ------------------------------------------------------- + * tc_subfr == 0 - TC in 1st subframe + * tc_subfr == TC_0_0 - TC in 1st subframe + information about T0 + * tc_subfr == L_SUBFR - TC in 2nd subframe + * tc_subfr == 2*L_SUBFR - TC in 3rd subframe + * tc_subfr == 3*L_SUBFR - TC in 4th subframe + *-----------------------------------------------------------------*/ + + IF( i_subfr == 0 ) + { + mult_Top = 1; + IF( limit_flag == 0 ) + { + test(); + IF( EQ_16( st_fx->L_frame, L_FRAME ) && LT_16( T_op[1], PIT_MIN ) ) + { + mult_Top = 2; + move16(); + } + test(); + if ( EQ_16( st_fx->L_frame, L_FRAME16k ) && LT_16( T_op[1], PIT16k_MIN ) ) + { + mult_Top = 2; + move16(); + } + } + + limit_T0_fx( st_fx->L_frame, 8, 0, limit_flag, mult_Top * T_op[1], 0, T0_min, T0_max ); + } + /*-----------------------------------------------------------------* + * zero adaptive excitation signal construction + *-----------------------------------------------------------------*/ + IF( GT_16( *tc_subfr, i_subfr ) ) + { + *gain_pit_fx = 0; + move16(); + *clip_gain = 0; + move16(); + g_corr_fx[0] = 16384; + move16(); + g_corr_fx[1] = add( shl( sub( shift_wsp, 1 ), 1 ), 1 ); + move16(); + g_corr_fx[2] = -16384; + move16(); + g_corr_fx[3] = shl( sub( shift_wsp, 1 ), 1 ); + + set16_fx( &exc_fx[i_subfr], 0, L_SUBFR ); /* set excitation for current subrame to 0 */ + + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + set16_fx( &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], 0, (Word16) ( L_SUBFR * HIBND_ACB_L_FAC ) ); /* set past excitation buffer to 0 */ + } + ELSE + { + set16_fx( &bwe_exc_fx[i_subfr * 2], 0, L_SUBFR * 2 ); /* set past excitation buffer to 0 */ + } + + set16_fx( y1_fx, 0, L_SUBFR ); /* set filtered adaptive excitation to 0 */ + Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + + **pt_pitch_fx = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + move16(); /* save subframe pitch values Q6 */ + } + + /*-----------------------------------------------------------------* + * glottal codebook contribution construction + *-----------------------------------------------------------------*/ + ELSE IF( EQ_16( *tc_subfr, i_subfr ) ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + set16_fx( bwe_exc_fx - PIT_MAX * HIBND_ACB_L_FAC, 0, PIT_MAX * HIBND_ACB_L_FAC ); /* set past excitation buffer to 0 */ + } + ELSE + { + set16_fx( bwe_exc_fx - PIT16k_MAX * 2, 0, PIT16k_MAX * 2 ); /* set past excitation buffer to 0 */ + } + + tc_enc_ivas_fx( st_fx, i_subfr, tc_subfr, position, h1_fx, xn_fx, exc_fx, + y1_fx, T0_min, T0_max, T0, T0_frac, gain_pit_fx, g_corr_fx, bwe_exc_fx, Q_new ); + + IF( EQ_16( *tc_subfr, TC_0_0 ) ) + { + /* this is called only to compute unused bits */ + config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + L_FRAME, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, TC_0_0, 3, NULL, unbits_ACELP, + st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ + ); + } + *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, sub( shift_wsp, 1 ) ); + updt_tar_fx( xn_fx, xn2_fx, y1_fx, *gain_pit_fx, L_SUBFR ); + + **pt_pitch_fx = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + move16(); + *Jopt_flag = 1; + move16(); + } + + /*--------------------------------------------------------------* + * other subframes -> GENERIC encoding type, + * standard adaptive excitation contribution + * - exemption only in case when first glottal impulse is + * in the 1st subframe and the second one in 2nd subframe + * and later + *--------------------------------------------------------------*/ + ELSE IF( LT_16( *tc_subfr, i_subfr ) ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + *Jopt_flag = 1; + move16(); + /* pit_flag for T0 bits number coding determination */ + test(); + IF( ( EQ_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) || ( EQ_16( sub( i_subfr, *tc_subfr ), L_SUBFR - TC_0_0 ) ) ) + { + pit_flag = 0; + move16(); + } + ELSE + { + pit_flag = L_SUBFR; + move16(); + } + + IF( EQ_16( *tc_subfr, TC_0_0 ) ) + { + IF( EQ_16( i_subfr, L_SUBFR ) ) + { + limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); + } + pit_flag = 1; + move16(); + } + + /*----------------------------------------------------------* + * if tc_subfr==0, change tc_subfr corresponding to the + * second glot. impulse position + *----------------------------------------------------------*/ + test(); + IF( ( *tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) + { + IF( GT_16( PIT_MIN, ( *position ) ) ) + { + pit_start = sub( L_SUBFR, ( *position ) ); + } + ELSE + { + pit_start = PIT_MIN; + move16(); + } + pit_start = s_max( pit_start, PIT_MIN ); + + pit_limit = add( shl( pit_start, 1 ), *position ); + + /* Find the closed loop pitch period */ + + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, pit_limit, L_FRAME, L_SUBFR ); + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + } + + + test(); + IF( GT_16( ( *T0 ), sub( 2 * L_SUBFR, ( *position ) ) ) ) + { + IF( GE_16( add( ( *T0 ), ( *position ) ), 3 * L_SUBFR ) ) + { + /* second glottal impulse is in the 4th subframe */ + *tc_subfr = TC_0_192; + move16(); + } + ELSE + { + /* second glottal impulse is in the 3rd subframe */ + *tc_subfr = TC_0_128; + move16(); + } + } + ELSE IF( ( *tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) + { + /* second glottal impulse is in the 2nd subframe */ + *tc_subfr = TC_0_64; + move16(); + } + } + + IF( LE_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) + { + config_acelp1( ENC, st_fx->total_brate, st_fx->core_brate, st_fx->core, st_fx->extl, st_fx->extl_brate, + st_fx->L_frame, -1, &( st_fx->acelp_cfg ), hBstr->nb_bits_tot, TRANSITION, *tc_subfr, 2, NULL, + unbits_ACELP, st_fx->element_mode, &i /*dummy*/, 0 /*tdm_lp_reuse_flag*/, 0 /*tdm_low_rate_mode*/, st_fx->idchan, st_fx->active_fr_cnt_fx, 0 /*tdm_Pitch_reuse_flag*/, st_fx->tdm_LRTD_flag, 0 /*GSC_IVAS_mode*/ ); + } + /*-----------------------------------------------------------------* + * get number of bits for pitch encoding + *-----------------------------------------------------------------*/ + + nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; + move16(); + + /*-----------------------------------------------------------------* + * Find adaptive part of excitation, encode pitch period + *-----------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + test(); + /* first glottal impulse is in the 1st subrame */ + IF( ( EQ_16( i_subfr, L_SUBFR ) ) && ( GE_16( *tc_subfr, TC_0_128 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 3rd or 4th subframe + * - build exc[] in 2nd subframe + *--------------------------------------------------------*/ + *T0 = 2 * L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + *Jopt_flag = 0; + move16(); + set16_fx( &exc_fx[i_subfr], 0, (Word16) ( L_SUBFR + 1 ) ); + set16_fx( &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], 0, (Word16) ( L_SUBFR * HIBND_ACB_L_FAC ) ); + } + ELSE IF( ( EQ_16( i_subfr, L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_64 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 2nd subframe, + * - build exc[] in 2nd subframe + + *--------------------------------------------------------*/ + IF( LT_16( add( *T0, *position ), L_SUBFR ) ) + { + /* impulse must be in the 2nd subframe (not in 1st) */ + *T0 = sub( L_SUBFR, ( *position ) ); + move16(); + *T0_frac = 0; + move16(); + } + IF( GE_16( add( *T0, *position ), 2 * L_SUBFR ) ) + { + /* impulse must be in the 2nd subframe (not in 3rd) */ + *T0 = sub( 2 * L_SUBFR - 1, ( *position ) ); + move16(); + *T0_frac = 2; + move16(); + } + + limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max for delta search */ + + /* 7bit ENCODER */ + /* index = (*T0-pit_start)*2 + *T0_frac/2;*/ + index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); + push_indice( hBstr, IND_PITCH, index, nBits ); + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + } + } + ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_128 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 3rd subframe + * - build exc[] in 3rd subframe + *--------------------------------------------------------*/ + + pit_start = sub( 2 * L_SUBFR, ( *position ) ); + pit_flag = 0; + move16(); + + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, pit_start, 3 * L_SUBFR, L_FRAME, L_SUBFR ); + + IF( LT_16( add( ( *T0 ), ( *position ) ), 2 * L_SUBFR ) ) + { + /* impulse must be in the 3rd subframe (not in 2nd) */ + *T0 = sub( 2 * L_SUBFR, ( *position ) ); + move16(); + *T0_frac = 0; + move16(); + } + + IF( GE_16( add( ( *T0 ), ( *position ) ), 3 * L_SUBFR ) ) + { + /* impulse must be in the 3rd subframe (not in 4th) */ + *T0 = sub( 3 * L_SUBFR - 1, ( *position ) ); + move16(); + *T0_frac = 2; + move16(); + } + + limit_T0_fx( L_FRAME, 8, pit_flag, limit_flag, *T0, 0, T0_min, T0_max ); /* find T0_min and T0_max for delta search */ + + index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); + push_indice( hBstr, IND_PITCH, index, nBits ); + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + } + } + ELSE IF( ( EQ_16( i_subfr, 2 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_192 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 4th subframe + * - build exc[] in 3rd subframe + *--------------------------------------------------------*/ + *T0 = 4 * L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + *Jopt_flag = 0; + move16(); + set16_fx( &exc_fx[i_subfr], 0, (Word16) ( L_SUBFR + 1 ) ); + set16_fx( &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], 0, (Word16) ( L_SUBFR * HIBND_ACB_L_FAC ) ); + } + ELSE IF( ( EQ_16( i_subfr, 3 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_192 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse is in the 4th subframe + * - build exc[] in 4th subframe + *--------------------------------------------------------*/ + /* always T0_frac = 0 */ + pit_flag = 0; + move16(); + + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + + IF( LT_16( add( *T0, *position ), 3 * L_SUBFR ) ) + { + /* impulse must be in the 4th subframe (not in 3rd) */ + *T0 = sub( 3 * L_SUBFR, ( *position ) ); + move16(); + *T0_frac = 0; + move16(); + } + + pit_start = sub( 3 * L_SUBFR, ( *position ) ); + pit_limit = sub( 2 * L_FRAME - PIT_MAX - 2, shl( *position, 1 ) ); + + IF( LT_16( ( *T0 ), pit_limit ) ) + { + index = add( shl( sub( *T0, pit_start ), 1 ), shr( *T0_frac, 1 ) ); + } + ELSE + { + index = add( sub( *T0, pit_limit ), shl( sub( pit_limit, pit_start ), 1 ) ); + *T0_frac = 0; + move16(); + } + push_indice( hBstr, IND_PITCH, index, nBits ); + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + move16(); + } + } + ELSE IF( ( EQ_16( i_subfr, 3 * L_SUBFR ) ) && ( EQ_16( *tc_subfr, TC_0_128 ) ) ) + { + /*--------------------------------------------------------* + * second glottal impulse in the 3rd subframe + * build exc[] in 4th subframe + *--------------------------------------------------------*/ + pit_flag = L_SUBFR; + move16(); + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + index = delta_pit_enc_fx( 2, *T0, *T0_frac, *T0_min ); + push_indice( hBstr, IND_PITCH, index, nBits ); + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + } + } + + /*------------------------------------------------------------* + * first glottal impulse is NOT in the 1st subframe, + * or two impulses are in the 1st subframe + *------------------------------------------------------------*/ + ELSE + { + test(); + IF( EQ_16( nBits, 8 ) || EQ_16( nBits, 5 ) ) + { + test(); + IF( !( ( *tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) ) ) + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_MIN, PIT_FR1_8b, L_FRAME, L_SUBFR ); + } + } + ELSE + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, pit_flag, limit_flag, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + } + pit_Q_enc_ivas_fx( hBstr, 0, nBits, 8, pit_flag, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + + offset = tbe_celp_exc_offset( *T0, *T0_frac, st_fx->L_frame ); + + FOR( i = 0; i < L_SUBFR * HIBND_ACB_L_FAC; i++ ) + { + bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC] = bwe_exc_fx[i + i_subfr * HIBND_ACB_L_FAC - offset]; + } + } + + /*-----------------------------------------------------------------* + * - gain clipping test to avoid unstable synthesis + * - LP filtering of the adaptive excitation (if non-zero) + * - codebook target computation + *-----------------------------------------------------------------*/ + IF( *Jopt_flag == 0 ) + { + /* adaptive/TC excitation is zero */ + Copy( xn_fx, xn2_fx, L_SUBFR ); + g_corr_fx[0] = 0; + move16(); + g_corr_fx[1] = 0; + move16(); + g_corr_fx[2] = 0; + move16(); + g_corr_fx[3] = 0; + move16(); + *clip_gain = 0; + move16(); + } + ELSE + { + *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, ( Q_new + shift - 1 ) ); + + lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, + xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); + + IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) + { + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + } + } + + **pt_pitch_fx = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + move16(); + /*---------------------------------------------------------------------* + * fill the pitch buffer - needed for post-processing + *---------------------------------------------------------------------*/ + test(); + test(); + test(); + test(); + test(); + IF( ( *tc_subfr >= 2 * L_SUBFR ) && ( i_subfr == 3 * L_SUBFR ) ) + { + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + ( *pt_pitch_fx ) -= 3; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + } + ELSE IF( ( *tc_subfr == L_SUBFR ) && ( i_subfr == 2 * L_SUBFR ) ) + { + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + ( *pt_pitch_fx ) -= 2; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + } + ELSE IF( ( *tc_subfr == TC_0_64 ) && ( i_subfr == L_SUBFR ) ) + { + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + ( *pt_pitch_fx ) -= 1; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + } + ELSE IF( ( *tc_subfr == TC_0_128 ) && ( i_subfr == 2 * L_SUBFR ) ) + { + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + ( *pt_pitch_fx ) -= 2; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + } + ELSE IF( ( *tc_subfr == TC_0_192 ) && ( i_subfr == 3 * L_SUBFR ) ) + { + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + ( *pt_pitch_fx ) -= 3; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + move16(); + } + } + ELSE /* L_frame == L_FRAME16k */ + { + if ( GE_16( i_subfr, 2 * L_SUBFR ) ) + { + limit_flag = 1; + move16(); + } + IF( LE_16( i_subfr, 2 * L_SUBFR ) ) + { + IF( LT_16( i_subfr, 2 * L_SUBFR ) ) + { + mult_Top = 1; + move16(); + if ( LT_16( T_op[0], PIT16k_MIN ) ) + { + mult_Top = 2; + move16(); + } + + limit_T0_fx( L_FRAME16k, 8, 0, limit_flag, mult_Top * T_op[0], 0, T0_min, T0_max ); /* TC0 second subfr. */ + } + ELSE + { + limit_T0_fx( L_FRAME16k, 8, 0, limit_flag, T_op[1], 0, T0_min, T0_max ); /* TC0 third subfr., or TC64 third subfr. */ + } + } + + /*-----------------------------------------------------------------* + * get number of bits for pitch encoding + *-----------------------------------------------------------------*/ + + nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; + move16(); + + /*-----------------------------------------------------------------* + * Find adaptive part of excitation, encode pitch period + *-----------------------------------------------------------------*/ + + IF( EQ_16( nBits, 10 ) ) + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, st_fx->L_frame, L_SUBFR ); + pit16k_Q_enc_ivas_fx( hBstr, nBits, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + ELSE IF( EQ_16( nBits, 8 ) ) /* tc_subfr==0 && i_subfr==L_SUBFR */ + { + /*-----------------------------------------------------------------------------* + * The pitch range is encoded absolutely with 8 bits and is divided as follows: + * PIT16k_MIN to PIT16k_FR2_TC0_2SUBFR-1 resolution 1/4 (frac = 0,1,2 or 3) + * PIT16k_FR2_TC0_2SUBFR to 2*L_SUBFR resolution 1/2 (frac = 0 or 2) + *-----------------------------------------------------------------------------*/ + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, limit_flag, PIT16k_FR2_TC0_2SUBFR, 2 * L_SUBFR, st_fx->L_frame, L_SUBFR ); + + IF( GT_16( *T0_max, 2 * L_SUBFR ) ) + { + *T0 = 2 * L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + } + + IF( LT_16( *T0, PIT16k_FR2_TC0_2SUBFR ) ) + { + /*index = (*T0)*4 + (*T0_frac) - (PIT16k_MIN*4);*/ + index = add( shl( *T0, 2 ), sub( *T0_frac, PIT16k_MIN * 4 ) ); + } + ELSE + { + /*index = (*T0)*2 + ((*T0_frac)>>1) - (PIT16k_FR2_TC0_2SUBFR*2) + ((PIT16k_FR2_TC0_2SUBFR-PIT16k_MIN)*4);*/ + index = add( sub( add( shl( *T0, 1 ), shr( *T0_frac, 1 ) ), ( PIT16k_FR2_TC0_2SUBFR * 2 ) ), ( PIT16k_FR2_TC0_2SUBFR - PIT16k_MIN ) * 4 ); + } + push_indice( hBstr, IND_PITCH, index, nBits ); + } + ELSE IF( EQ_16( nBits, 6 ) ) + { + /* delta search */ + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, L_SUBFR, limit_flag, PIT16k_FR2_EXTEND_9b, PIT16k_FR1_EXTEND_9b, st_fx->L_frame, L_SUBFR ); + + index = delta_pit_enc_fx( 4, *T0, *T0_frac, *T0_min ); + push_indice( hBstr, IND_PITCH, index, nBits ); + } + IF( EQ_16( nBits, 6 ) ) + { + limit_T0_fx( L_FRAME16k, 8, L_SUBFR, limit_flag, *T0, *T0_frac, T0_min, T0_max ); + } + + /*-----------------------------------------------------------------* + * - gain clipping test to avoid unstable synthesis + * - LP filtering of the adaptive excitation + * - codebook target computation + *-----------------------------------------------------------------*/ + test(); + IF( ( EQ_16( i_subfr, L_SUBFR ) ) && ( EQ_16( *T0, 2 * L_SUBFR ) ) ) + { + *gain_pit_fx = 0; + move16(); + *clip_gain = 0; + move16(); + g_corr_fx[0] = 0; + move16(); + g_corr_fx[1] = 0; + move16(); + *Jopt_flag = 0; + move16(); + + set16_fx( &exc_fx[i_subfr], 0, L_SUBFR + 1 ); /* set excitation for current subrame to 0 */ + push_indice( hBstr, IND_LP_FILT_SELECT, 0, 1 ); /* this bit is actually not needed */ + + Copy( xn_fx, xn2_fx, L_SUBFR ); /* target vector for codebook search */ + set16_fx( y1_fx, 0, L_SUBFR ); /* set filtered adaptive excitation to 0 */ + set16_fx( &bwe_exc_fx[i_subfr * 2], 0, L_SUBFR * 2 ); + } + ELSE + { + /* Find the adaptive codebook vector - ACELP long-term prediction */ + pred_lt4( &exc_fx[i_subfr], &exc_fx[i_subfr], *T0, *T0_frac, L_SUBFR + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP ); + offset = L_deposit_l( 0 ); + + tmp = extract_l( L_mult( *T0_frac, 32 ) ); /*Q8, 0.25 in Q7*/ + tmp = add( 512, tmp ); /*Q8; 2 in Q8*/ + tmp = mult_r( tmp, 256 ); /*Q16->Q0; 2 in Q7*/ + + tmp1 = sub( *T0, 2 ); /*Q0*/ + tmp1 = shl( tmp1, 1 ); /*Q0 */ + + offset = add( tmp, tmp1 ); /*Q0*/ + FOR( i = 0; i < L_SUBFR * 2; i++ ) + { + /* bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - *T0 * 2 - (int) ((float) *T0_frac * 0.5f + 4 + 0.5f) + 4];move16();*/ + bwe_exc_fx[i + i_subfr * 2] = bwe_exc_fx[i + i_subfr * 2 - offset + 4]; + } + + *clip_gain = gp_clip_fx( st_fx->element_mode, st_fx->core_brate, st_fx->voicing_fx, i_subfr, TRANSITION, xn_fx, gp_cl_fx, Q_new ); + + lp_select = lp_filt_exc_enc_fx( MODE1, TRANSITION, i_subfr, exc_fx, h1_fx, + xn_fx, y1_fx, xn2_fx, L_SUBFR, st_fx->L_frame, g_corr_fx, *clip_gain, gain_pit_fx, &lp_flag ); + + IF( EQ_16( lp_flag, NORMAL_OPERATION ) ) + { + push_indice( hBstr, IND_LP_FILT_SELECT, lp_select, 1 ); + } + + *Jopt_flag = 1; + move16(); + } + + /***pt_pitch = (float)(*T0) + (float)(*T0_frac)/4.0f;*/ /* save subframe pitch value */ + /***pt_pitch_fx = shl(add(*T0,shr(*T0_frac,2)),4); move16();*/ + tmp = shl( add( shl( *T0, 2 ), *T0_frac ), 4 ); + **pt_pitch_fx = tmp; + move16(); + + /*---------------------------------------------------------------------* + * fill the pitch buffer - needed for post-processing + *---------------------------------------------------------------------*/ + test(); + test(); + IF( ( EQ_16( sub( i_subfr, *tc_subfr ), L_SUBFR ) ) || ( *tc_subfr == 0 && EQ_16( i_subfr, 2 * L_SUBFR ) ) ) + { + index = shr( i_subfr, 6 ); + ( *pt_pitch_fx ) -= index; + move16(); + + FOR( i = 0; i < index; i++ ) + { + **pt_pitch_fx = tmp; + move16(); + ( *pt_pitch_fx )++; + } + } + } + } + + return; +} + /*-------------------------------------------------------------------------------------------* * tc_enc() * @@ -1084,6 +1880,222 @@ static void tc_enc_fx( return; } +static void tc_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 i_subfr, /* i : subrame index */ + Word16 *tc_subfr, /* i/o: TC subframe index */ + Word16 *position, /* i/o: index of the residual signal maximum */ + const Word16 *h1_fx, /* i : weighted filter input response Q(14+shift)*/ + const Word16 *xn_fx, /* i : target signal Q_new-1+shift*/ + Word16 *exc_fx, /* o : glottal codebook contribution Q_new*/ + Word16 *yy1_fx, /* o : filtered glottal codebook contribution */ + Word16 *T0_min, /* o : lower pitch limit Q0*/ + Word16 *T0_max, /* o : higher pitch limit Q0*/ + Word16 *T0, /* o : close loop integer pitch Q0*/ + Word16 *T0_frac, /* o : close loop fractional part of the pitch Q0*/ + Word16 *gain_pit_fx, /* o : pitch gain (0..GAIN_PIT_MAX) Q14*/ + Word16 g_corr_fx[], /* o : correlations and -2 */ + Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q_new*/ + Word16 Q_new /* i : input scaling */ +) +{ + Word16 i, imp_shape, imp_pos, index, nBits, h1_tmp_fx[L_SUBFR]; + Word16 pitch_index, pitch_sign_fx; + Word32 gain_trans32; + BSTR_ENC_HANDLE hBstr = st_fx->hBstr; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; +#endif + imp_pos = sub( *position, i_subfr ); + FOR( i = 0; i < L_SUBFR; i++ ) + { + h1_tmp_fx[i] = h1_fx[i]; + move16(); + } + /*-----------------------------------------------------------------* + * get number of bits for pitch encoding + *-----------------------------------------------------------------*/ + + nBits = st_fx->acelp_cfg.pitch_bits[shr( i_subfr, 6 )]; + + /*--------------------------------------------------------------* + * Closed loop pitch search + *--------------------------------------------------------------*/ + + *T0_frac = 0; + move16(); + + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + test(); + IF( ( LE_16( *T0_min, L_SUBFR ) ) || ( EQ_16( *tc_subfr, 3 * L_SUBFR ) ) ) + { + IF( EQ_16( nBits, 9 ) ) + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_FR2_9b, PIT_FR1_9b, L_FRAME, L_SUBFR ); + } + ELSE IF( EQ_16( nBits, 6 ) ) + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MIN, L_SUBFR, L_FRAME, L_SUBFR ); + } + ELSE + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT_MAX, PIT_MIN, L_FRAME, L_SUBFR ); + } + } + ELSE + { + *T0 = L_SUBFR; + move16(); + } + test(); + if ( EQ_16( *tc_subfr, L_SUBFR ) && LT_16( *T0, L_SUBFR ) ) + { + *T0 = L_SUBFR; + move16(); + } + } + ELSE /* st_fx->L_frame == L_FRAME16k */ + { + IF( EQ_16( nBits, 10 ) ) + { + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 1, PIT16k_FR2_EXTEND_10b, PIT16k_MAX, L_FRAME16k, L_SUBFR ); + } + ELSE IF( EQ_16( nBits, 6 ) ) + { + /* T0_frac with 1/2 sample resolution */ + *T0 = pitch_fr4_fx( &exc_fx[i_subfr], xn_fx, h1_fx, *T0_min, *T0_max, T0_frac, 0, 0, PIT16k_MIN, L_SUBFR, L_FRAME16k, L_SUBFR ); + IF( *T0 > L_SUBFR ) + { + *T0 = L_SUBFR; + move16(); + *T0_frac = 0; + move16(); + } + } + } + + + /* set tc_subfr to TC_0_0 */ + test(); + test(); + test(); + if ( i_subfr == 0 && EQ_16( st_fx->L_frame, L_FRAME ) && ( LT_16( *T0, L_SUBFR ) || EQ_16( *tc_subfr, 3 * L_SUBFR ) ) ) + { + *tc_subfr = TC_0_0; + move16(); + } + + /*--------------------------------------------------------------* + * Builds glottal codebook contribution + *--------------------------------------------------------------*/ + + set_impulse_fx( xn_fx, h1_tmp_fx, &exc_fx[i_subfr], yy1_fx, &imp_shape, &imp_pos, &gain_trans32, Q_new ); /*chk h1_tmp_fx*/ + + /*--------------------------------------------------------------* + * quantize gain_trans and scale glottal codebook contribution + *--------------------------------------------------------------*/ + + gain_trans_enc_fx( gain_trans32, &exc_fx[i_subfr], &pitch_index, &pitch_sign_fx, Q_new ); + + /* set past excitation buffer to zeros */ + set16_fx( exc_fx - L_EXC_MEM, 0, L_EXC_MEM ); + /*--------------------------------------------------------------* + * adapt. search of the second impulse in the same subframe + * (when appears) + *--------------------------------------------------------------*/ + + pred_lt4_tc_fx( exc_fx, *T0, *T0_frac, inter4_2_fx, imp_pos, i_subfr ); + IF( st_fx->hBWE_TD != NULL ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + interp_code_5over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * HIBND_ACB_L_FAC], L_SUBFR ); + } + ELSE + { + interp_code_4over2_fx( &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * 2], L_SUBFR ); + } + } + /*--------------------------------------------------------------* + * compute glottal-shape codebook excitation + *--------------------------------------------------------------*/ + + /* create filtered glottal codebook contribution */ + conv_fx( &exc_fx[i_subfr], h1_fx, yy1_fx, L_SUBFR ); + + /* gain_pit computation */ +#ifdef BASOP_NOGLOB + *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0, &Overflow ); +#else + *gain_pit_fx = corr_xy1_fx( xn_fx, yy1_fx, g_corr_fx, L_SUBFR, 0 ); +#endif + /*--------------------------------------------------------------* + * Encode parameters and write indices + *--------------------------------------------------------------*/ + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + test(); + test(); + IF( ( ( i_subfr != 0 ) || ( EQ_16( *tc_subfr, TC_0_0 ) ) ) && ( NE_16( *tc_subfr, L_SUBFR ) ) ) + { + test(); + /* write pitch index */ + IF( ( GE_16( *T0, L_SUBFR ) ) && ( NE_16( *tc_subfr, 3 * L_SUBFR ) ) ) + { + push_indice( hBstr, IND_PITCH, 0, nBits ); + } + ELSE IF( EQ_16( *tc_subfr, 3 * L_SUBFR ) ) + { + IF( EQ_16( nBits, 9 ) ) + { + index = abs_pit_enc_fx( 4, 0, *T0, *T0_frac ); + } + ELSE + { + index = abs_pit_enc_fx( 2, 0, *T0, *T0_frac ); + } + push_indice( hBstr, IND_PITCH, index, nBits ); + + limit_T0_fx( L_FRAME, 8, 0, 0, *T0, 0, T0_min, T0_max ); + } + ELSE + { + IF( EQ_16( nBits, 6 ) ) + { + index = delta_pit_enc_fx( 2, *T0, *T0_frac, PIT_MIN - 1 ); + push_indice( hBstr, IND_PITCH, index, nBits ); + } + ELSE + { + index = delta_pit_enc_fx( 0, *T0, *T0_frac, PIT_MIN - 1 ); + push_indice( hBstr, IND_PITCH, index, nBits ); + } + } + } + } + ELSE /* st_fx->L_frame == L_FRAME16k */ + { + IF( EQ_16( nBits, 10 ) ) + { + pit16k_Q_enc_ivas_fx( hBstr, nBits, 1, *T0, *T0_frac, T0_min, T0_max ); + } + ELSE IF( EQ_16( nBits, 6 ) ) + { + index = add( shl( sub( *T0, PIT16k_MIN ), 1 ), shr( *T0_frac, 1 ) ); + push_indice( hBstr, IND_PITCH, index, nBits ); + } + } + push_indice( hBstr, IND_TC_IMP_SHAPE, imp_shape, 3 ); + push_indice( hBstr, IND_TC_IMP_POS, imp_pos, 6 ); + push_indice( hBstr, IND_TC_IMP_SIGN, pitch_sign_fx, 1 ); + push_indice( hBstr, IND_TC_IMP_GAIN, pitch_index, 3 ); + + *position = add( imp_pos, i_subfr ); + move16(); + return; +} + /*-----------------------------------------------------------------* * gain_trans_enc()