diff --git a/lib_com/cng_exc_fx.c b/lib_com/cng_exc_fx.c index b43b174484afef7a20210a21898cd13171605194..b68ac560e557f0207bae321bafa4e67e16a5afae 100644 --- a/lib_com/cng_exc_fx.c +++ b/lib_com/cng_exc_fx.c @@ -776,6 +776,136 @@ void cng_params_postupd_fx( return; } +void cng_params_postupd_ivas_fx( + const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */ + Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */ + const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */ + const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */ + const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */ + Word32 ho_env_circ[], /* i/o: Envelope buffer */ + const Word16 element_mode, /* i : Element mode */ + const Word16 bwidth /* i : Audio bandwidth */ +) +{ + Word16 i, j; + Word16 Q_exc; + const Word16 *exc2; + Word16 fft_io[L_FFT]; + Word32 sp[129]; + Word16 *ptR, *ptI; + Word32 env[NUM_ENV_CNG]; + Word32 L_tmp; + Word16 tmp; + Word16 temp_lo_fx, temp_hi_fx; + Word16 exp_pow; + Word16 exp1; + Word16 CNG_mode; + Word16 ptr; + Word32 last_active_brate; +#ifdef BASOP_NOGLOB_DECLARE_LOCAL + Flag Overflow = 0; + move32(); +#endif + + ptr = add( sub( ho_circ_ptr, *cng_buf_cnt ), 1 ); + if ( ptr < 0 ) + { + ptr = add( ptr, HO_HIST_SIZE ); + } + + FOR( j = 0; j < *cng_buf_cnt; j++ ) + { + exc2 = &cng_exc2_buf[ptr * L_FFT]; + Q_exc = cng_Qexc_buf[ptr]; + move16(); + last_active_brate = cng_brate_buf[ptr]; + move32(); + + /* calculate the spectrum of residual signal */ + Copy( exc2, fft_io, L_FFT ); + + fft_rel_fx( fft_io, L_FFT, LOG2_L_FFT ); + + ptR = &fft_io[1]; + ptI = &fft_io[L_FFT - 1]; + FOR( i = 0; i < NUM_ENV_CNG; i++ ) + { + /* sp[i] = 2.0f*(*ptR * *ptR + *ptI * *ptI)/L_FFT; */ +#ifdef BASOP_NOGLOB + L_tmp = L_mult_o( *ptR, *ptR, &Overflow ); /* 2*Q_exc+1 */ + L_tmp = L_add_o( L_tmp, L_mult_o( *ptI, *ptI, &Overflow ), &Overflow ); /* 2*Q_exc+1 */ + L_tmp = L_add_o( L_tmp, L_tmp, &Overflow ); /* 2*Q_exc+1 */ +#else /* BASOP_NOGLOB */ + L_tmp = L_mult( *ptR, *ptR ); /* 2*Q_exc+1 */ + L_tmp = L_add( L_tmp, L_mult( *ptI, *ptI ) ); /* 2*Q_exc+1 */ + L_tmp = L_add( L_tmp, L_tmp ); /* 2*Q_exc+1 */ +#endif /* BASOP_NOGLOB */ + L_tmp = Mult_32_16( L_tmp, 128 ); /* 2*Q_exc+1 */ + tmp = add( add( Q_exc, Q_exc ), 1 ); + sp[i] = L_shr( L_tmp, sub( tmp, 6 ) ); + move32(); /* Q6 */ + + ptR++; + ptI--; + } + + Copy32( sp, env, NUM_ENV_CNG ); + + test(); + IF( EQ_16( element_mode, IVAS_SCE ) || EQ_16( element_mode, IVAS_CPE_DFT ) ) + { + Word32 att_fx = 0; + move32(); + tmp = 0; + move16(); + apply_scale( &att_fx, bwidth, last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + att_fx = L_shr( Mpy_32_16_1( att_fx, 26214 ), 3 ); /* 26214 = 0.1f in Q18 */ + att_fx = BASOP_Util_fPow( 1342177280 /* 10 in Q27 */, 4, att_fx, 8, &tmp ); + tmp = extract_h( L_shl( att_fx, tmp ) ); + } + ELSE + { + + CNG_mode = get_cng_mode( last_active_brate ); + + /* att = 1/pow(2,ENR_ATT_fx[CNG_mode]); */ + L_tmp = L_shl( L_deposit_l( ENR_ATT_fx[CNG_mode] ), 8 ); /* 16 */ + temp_lo_fx = L_Extract_lc( L_tmp, &temp_hi_fx ); + + exp_pow = sub( 14, temp_hi_fx ); + L_tmp = Pow2( 14, temp_lo_fx ); /* Qexp_pow */ + L_tmp = L_shl( L_tmp, sub( 13, exp_pow ) ); /* Q13 */ + tmp = extract_l( L_tmp ); /* Q13 */ + + exp1 = norm_s( tmp ); + tmp = shl( tmp, exp1 ); /*Q(exp1+13) */ + tmp = div_s( 16384, tmp ); /*Q(15+14-exp1-13) */ + tmp = shr( tmp, sub( 1, exp1 ) ); /* Q15 */ + } + + FOR( i = 0; i < NUM_ENV_CNG; i++ ) + { + env[i] = Mult_32_16( env[i], tmp ); + move32(); + } + + /* update the circular buffer of old residual envelope */ + Copy32( env, &( ho_env_circ[(ptr) *NUM_ENV_CNG] ), NUM_ENV_CNG ); + + ptr = add( ptr, 1 ); + if ( EQ_16( ptr, HO_HIST_SIZE ) ) + { + ptr = 0; + move16(); + } + } + + *cng_buf_cnt = 0; + move16(); + + return; +} + /*-------------------------------------------------------* * cng_params_upd_fx() diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index e2fbbb9f31e2c7550d61c7c46468ea3be5b1259a..9beef9275b62b7d79ccd4b0e88914f25579d03db 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -652,7 +652,7 @@ void tcx5SpectrumInterleaving_fx( } /*-------------------------------------------------------------------* - * tcx5SpectrumDeinterleaving() + * tcx5SpectrumDeinterleaving_fx() * * *-------------------------------------------------------------------*/ diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index 2073ed00213b6eae7e02324df0adffb20fc0b2ca..d7d6b9136c5f6583a216d610903d051e0305cc9d 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -716,18 +716,18 @@ Word32 getCoreSamplerateMode2( test(); test(); test(); - IF( bwidth == NB ) + IF( EQ_16( bwidth, NB ) ) { sr_core = INT_FS_12k8; move32(); } - ELSE IF( element_mode == EVS_MONO && ( L_and( EQ_32( bwidth, WB ), LT_32( total_brate, ACELP_13k20 ) ) || - L_and( EQ_32( bwidth, SWB ), LE_32( total_brate, ACELP_13k20 ) ) || EQ_16( rf_mode, 1 ) ) ) + ELSE IF( EQ_16( element_mode, EVS_MONO ) && ( L_and( EQ_32( bwidth, WB ), LT_32( total_brate, ACELP_13k20 ) ) || + L_and( EQ_32( bwidth, SWB ), LE_32( total_brate, ACELP_13k20 ) ) || EQ_16( rf_mode, 1 ) ) ) { sr_core = INT_FS_12k8; move32(); } - ELSE IF( element_mode > EVS_MONO && flag_ACELP16k == 0 ) + ELSE IF( GT_16( element_mode, EVS_MONO ) && flag_ACELP16k == 0 ) { sr_core = INT_FS_12k8; move32(); @@ -752,7 +752,7 @@ Word32 getCoreSamplerateMode2( sr_core = 25600; move32(); } - ELSE IF( ( element_mode == EVS_MONO && ( bwd_swb_or_fb_flag && LE_32( total_brate, HQ_64k ) ) ) || ( GT_16( element_mode, IVAS_SCE ) && ( ( EQ_16( bwidth, SWB ) && LE_32( total_brate, IVAS_96k ) ) || ( EQ_16( bwidth, FB ) && LE_32( total_brate, IVAS_96k ) ) ) ) ) + ELSE IF( ( EQ_16( element_mode, EVS_MONO ) && ( bwd_swb_or_fb_flag && LE_32( total_brate, HQ_64k ) ) ) || ( GT_16( element_mode, IVAS_SCE ) && ( ( EQ_16( bwidth, SWB ) && LE_32( total_brate, IVAS_96k ) ) || ( EQ_16( bwidth, FB ) && LE_32( total_brate, IVAS_96k ) ) ) ) ) { sr_core = 25600; move32(); diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 9451e9cbfe9c0b828a29725ea89a85131336cd54..b9a6f58751c7489a35b149d10db0782994393d8a 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -40,6 +40,7 @@ #include "cnst.h" #include "rom_com.h" #include "prot.h" +#include "prot_fx.h" #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -263,6 +264,97 @@ static void GSC_gain_DQ( return; } +static void GSC_gain_DQ_fx( + const Word16 element_mode, /* i : element mode */ + const Word16 enc_dec, /* i : encoder/decoder flag */ + const Word16 coder_type, /* i : Coder type */ + const Word16 Mbands_gn, /* i : Number of band */ + const Word32 core_brate, /* i : Core bitrate */ + const Word16 mean_g, /* i : Average gain Q12 */ + const Word16 *Gain_in, /* i : Unquantized gain vector Q12 */ + Word16 *Gain_out /* o : Level adjusted unquantized gain vector Q12 */ +) +{ + Word16 Gain_off; + Word16 i; + + /* Gain adjustment to fit ACELP generic inactive coding gain at low rate */ + Gain_off = 0; + move16(); + + test(); + IF( coder_type == INACTIVE || EQ_16( coder_type, UNVOICED ) ) + { + test(); + IF( LE_32( core_brate, ACELP_5k00 ) && EQ_16( coder_type, UNVOICED ) ) + { + Gain_off = 1843; // 9/20 in Q12 + move16(); + } + ELSE IF( LE_32( core_brate, ACELP_7k20 ) ) + { + Gain_off = 1638; // 8/20 in Q12; /* 0 dB */ + move16(); + } + ELSE IF( LE_32( core_brate, ACELP_8k00 ) ) + { + Gain_off = 1351; // 6.6f/20 in Q12 /* ~-3.3 dB */ + move16(); + } + ELSE IF( LE_32( core_brate, ACELP_9k60 ) ) + { + Gain_off = 983; // 4.8f/20 in Q12 /* ~-2.4 dB */ + move16(); + } + ELSE IF( LE_32( core_brate, ACELP_11k60 ) ) + { + Gain_off = 717; // 3.5f/20 in Q12 /* ~-2.4 dB */ + move16(); + } + ELSE IF( LE_32( core_brate, ACELP_13k20 ) ) + { + Gain_off = 614; // 3.0f/20 in Q12 /* ~-2.4 dB */ + move16(); + } + } + + test(); + IF( coder_type != INACTIVE && NE_16( coder_type, UNVOICED ) ) + { + FOR( i = 0; i < Mbands_gn; i++ ) + { + Gain_out[i] = add( Gain_in[i], mean_g ); // Q12 + move16(); + } + } + ELSE + { + /*mimic ACELP decay of energy for low rates*/ + test(); + IF( element_mode == EVS_MONO && EQ_16( enc_dec, DEC ) ) + { + /* This is to keep EVS mono bit-exact with the standard (there might be a small desynchronization between encoder and decoder but there is no real quality or interop. issue) */ + FOR( i = 0; i < Mbands_gn; i++ ) + { + Gain_out[i] = add( Gain_out[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12 + move16(); + // Gain_out[i] += mean_g - i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ); + } + } + ELSE + { + FOR( i = 0; i < Mbands_gn; i++ ) + { + Gain_out[i] = add( Gain_in[i], sub( mean_g, mult( Gain_off, div_s( i, Mbands_gn ) ) ) ); // Q12 + move16(); + // Gain_out[i] = Gain_in[i] + mean_g - ( i * ( Gain_off / 20.f ) / ( (float) Mbands_gn ) ); + } + } + } + + return; +} + /*-------------------------------------------------------------------* * gsc_gainQ() @@ -495,6 +587,296 @@ float gsc_gainQ( return mean_4g[0]; } +Word16 gsc_gainQ_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t element_mode, /* i : element mode */ + const int16_t idchan, /* i : channel ID */ + const Word16 y_gain4[], + /* i : Energy per band */ // Q12 + Word16 y_gainQ[], + /* o : quantized energy per band */ // Q12 + const int32_t core_brate, /* i : Core rate */ + const int16_t coder_type, /* i : coding type */ + const int16_t bwidth, /* i : input signal bandwidth */ + const int16_t L_frame, /* i : frame length */ + const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const int32_t core_brate_inp /* i : true core bitrate */ +) +{ + Word16 y_gain_tmp[MBANDS_GN16k]; + Word16 y_gain_tmp2[MBANDS_GN16k]; + Word16 i, idx_g = 0; + move16(); + Word16 mean_4g_fx[1], ftmp1_fx; + Word16 Mbands_gn = MBANDS_GN; + Word16 y_gain_tmp3[MBANDS_GN]; + Word32 L_tmp; + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + Mbands_gn = MBANDS_GN16k; + move16(); + } + + mean_4g_fx[0] = 0; + move32(); + + test(); + test(); + IF( ( EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && bwidth == NB ) + { + L_tmp = 0; + move32(); + FOR( i = 0; i < 10; i++ ) + { + L_tmp = L_add( L_tmp, y_gain4[i] ); + } + L_tmp = L_sub( Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ), 2457 /* 0.6f in Q12 */ ); // Q12 + ftmp1_fx = extract_l( L_tmp ); + FOR( i = 0; i < Mbands_gn; i++ ) + { + IF( LT_16( y_gain4[i], ftmp1_fx ) ) + { + y_gain_tmp2[i] = ftmp1_fx; + } + ELSE + { + y_gain_tmp2[i] = y_gain4[i]; + } + move16(); + } + + /* Quantized mean gain without clipping */ + L_tmp = 0; + move32(); + FOR( i = 0; i < 10; i++ ) + { + L_tmp = L_add( L_tmp, y_gain4[i] ); + } + L_tmp = Mpy_32_16_1( L_tmp, 3277 /* (1/10.0f) in Q15 */ ); // Q12 + mean_4g_fx[0] = extract_l( L_tmp ); // Q12 + move16(); + idx_g = vquant_fx( mean_4g_fx, Gain_meanNB_fx, mean_4g_fx, Gain_mean_dicNB_fx, 1, 64 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + + FOR( i = 0; i < Mbands_gn; i++ ) + { + y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12 + move16(); + } + + IF( LT_16( y_gain_tmp[9], -1229 /* -0.3f in Q12 */ ) ) + { + y_gain_tmp[9] = -1229; /* -0.3f in Q12 */ + move16(); + } + + set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 ); + idx_g = vquant_fx( y_gain_tmp, Mean_dic_NB_fx, y_gain_tmp, Gain_dic1_NB_fx, 3, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + IF( LT_32( core_brate, ACELP_9k60 ) ) + { + idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NB_fx, 3, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NB_fx, 4, 16 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + } + ELSE + { + idx_g = vquant_fx( y_gain_tmp + 3, Mean_dic_NB_fx + 3, y_gain_tmp + 3, Gain_dic2_NBHR_fx, 3, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + idx_g = vquant_fx( y_gain_tmp + 6, Mean_dic_NB_fx + 6, y_gain_tmp + 6, Gain_dic3_NBHR_fx, 4, 128 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); + } + + test(); + IF( LE_32( core_brate, ACELP_9k60 ) && coder_type == INACTIVE ) + { + /* Some energy is needed in high band for stat_noise_uv_enc() to be functional in inactive speech */ + y_gain_tmp[10] = mean_fx( y_gain_tmp + 6, 3 ); + move16(); + y_gain_tmp[11] = mean_fx( y_gain_tmp + 7, 3 ); + move16(); + y_gain_tmp[12] = mean_fx( y_gain_tmp + 8, 3 ); + move16(); + y_gain_tmp[13] = mean_fx( y_gain_tmp + 9, 3 ); + move16(); + y_gain_tmp[14] = mean_fx( y_gain_tmp + 10, 3 ); + move16(); + y_gain_tmp[15] = mean_fx( y_gain_tmp + 11, 3 ); + move16(); + } + ELSE + { + set16_fx( y_gain_tmp + 10, 0, MBANDS_GN - 10 ); + } + } + ELSE + { + L_tmp = 0; + move32(); + FOR( i = 0; i < 16; i++ ) + { + L_tmp = L_add( L_tmp, y_gain4[i] ); + } + L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12 + ftmp1_fx = extract_l( L_tmp ); + FOR( i = 0; i < Mbands_gn; i++ ) + { + IF( LT_16( y_gain4[i], sub( ftmp1_fx, 2457 ) ) ) + { + y_gain_tmp2[i] = sub( ftmp1_fx, 2457 ); + } + ELSE IF( GT_16( y_gain4[i], add( ftmp1_fx, 2457 ) ) ) + { + y_gain_tmp2[i] = add( ftmp1_fx, 2457 ); + } + ELSE + { + y_gain_tmp2[i] = y_gain4[i]; + } + move16(); + } + + L_tmp = 0; + move32(); + FOR( i = 0; i < 16; i++ ) + { + L_tmp = L_add( L_tmp, y_gain_tmp2[i] ); + } + L_tmp = Mpy_32_16_1( L_tmp, 2048 /* (1/16.f) in Q15 */ ); // Q12 + mean_4g_fx[0] = extract_l( L_tmp ); // Q12 + move16(); + idx_g = vquant_fx( mean_4g_fx, mean_m_fx, mean_4g_fx, mean_gain_dic_fx, 1, 64 ); + push_indice( hBstr, IND_MEAN_GAIN2, idx_g, 6 ); + + /* Subtraction of the average gain */ + FOR( i = 0; i < Mbands_gn; i++ ) + { + y_gain_tmp[i] = sub( y_gain_tmp2[i], mean_4g_fx[0] ); // Q12 + move16(); + } + + IF( LT_32( core_brate, ACELP_9k60 ) ) + { + /* prediction and quantization of the average gain */ + + /*--------------------------------------------------------------------------------------* + * Quantization of the first 8 bands + * Keep only 4 bands out of the last 8 bands + *--------------------------------------------------------------------------------------*/ + + Copy( y_gain_tmp, y_gain_tmp2, 8 ); + + y_gain_tmp2[8] = y_gain_tmp[8]; + move16(); + y_gain_tmp2[9] = y_gain_tmp[10]; + move16(); + y_gain_tmp2[10] = y_gain_tmp[12]; + move16(); + y_gain_tmp2[11] = y_gain_tmp[14]; + move16(); + + idx_g = 0; + move16(); + idx_g = vquant_fx( y_gain_tmp2, YGain_mean_LR_fx, y_gain_tmp2, YGain_dic1_LR_fx, 3, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + test(); + test(); + test(); + IF( !( coder_type == INACTIVE && tdm_LRTD_flag == 0 && EQ_16( idchan, 1 ) ) || GT_32( core_brate_inp, GSC_LRES_GAINQ_LIMIT ) ) + { + idx_g = vquant_fx( y_gain_tmp2 + 3, YGain_mean_LR_fx + 3, y_gain_tmp2 + 3, YGain_dic2_LR_fx, 4, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + /*----------------------------------------------------------------------* + * Vector quantization of the first 8 bands + quantization of the 4 bands out of the last 8 + * Interpolation of the last 4 bands Q to create bands 8-16 + *----------------------------------------------------------------------*/ + + idx_g = vquant_fx( y_gain_tmp2 + 7, YGain_mean_LR_fx + 7, y_gain_tmp2 + 7, YGain_dic3_LR_fx, 5, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + set16_fx( y_gain_tmp2 + 12, 0, MBANDS_GN - 12 ); + + /* Update to quantized vector */ + Copy( y_gain_tmp2, y_gain_tmp, 8 ); + + Copy( y_gain_tmp2 + 8, y_gain_tmp3, 4 ); + set16_fx( y_gain_tmp + 8, 0, 8 ); + fft_rel_fx( y_gain_tmp2 + 8, 4, 2 ); + + Copy( y_gain_tmp2 + 8, y_gain_tmp + 8, 3 ); + y_gain_tmp[15] = y_gain_tmp2[11]; + move16(); + ifft_rel_fx( y_gain_tmp + 8, 8, 3 ); + + FOR( i = 8; i < 16; i++ ) + { + y_gain_tmp[i] = shl( mult( y_gain_tmp[i], 23101 ), 1 ); + move16(); + } + + y_gain_tmp[8] = y_gain_tmp3[0]; + move16(); + y_gain_tmp[10] = y_gain_tmp3[1]; + move16(); + y_gain_tmp[12] = y_gain_tmp3[2]; + move16(); + y_gain_tmp[14] = y_gain_tmp3[3]; + move16(); + } + ELSE + { + Copy( y_gain_tmp2, y_gain_tmp, 3 ); + set16_fx( y_gain_tmp + 3, 0, MBANDS_GN16k - 3 ); + } + } + ELSE + { + IF( EQ_16( L_frame, L_FRAME ) ) + { + idx_g = vquant_fx( y_gain_tmp, YG_mean16_fx, y_gain_tmp, YG_dicMR_1_fx, 4, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16_fx + 4, y_gain_tmp + 4, YG_dicMR_2_fx, 4, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16_fx + 8, y_gain_tmp + 8, YG_dicMR_3_fx, 4, 32 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 5 ); + + idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16_fx + 12, y_gain_tmp + 12, YG_dicMR_4_fx, 4, 16 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 4 ); + } + ELSE + { + idx_g = vquant_fx( y_gain_tmp, YG_mean16HR_fx, y_gain_tmp, YG_dicHR_1_fx, 4, 128 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 7 ); + + idx_g = vquant_fx( y_gain_tmp + 4, YG_mean16HR_fx + 4, y_gain_tmp + 4, YG_dicHR_2_fx, 4, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + idx_g = vquant_fx( y_gain_tmp + 8, YG_mean16HR_fx + 8, y_gain_tmp + 8, YG_dicHR_3_fx, 4, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + idx_g = vquant_fx( y_gain_tmp + 12, YG_mean16HR_16kHz_fx, y_gain_tmp + 12, YG_dicHR_4_16kHz_fx, 4, 64 ); + push_indice( hBstr, IND_Y_GAIN_TMP, idx_g, 6 ); + + idx_g = vquant_fx( y_gain_tmp + 16, YG_meanL2G_16kHz_fx, y_gain_tmp + 16, YG_dicL2G_16kHz_fx, 2, 8 ); + push_indice( hBstr, IND_Y_GAIN_HF, idx_g, 3 ); + } + } + } + + GSC_gain_DQ_fx( element_mode, ENC, coder_type, Mbands_gn, core_brate, mean_4g_fx[0], y_gain_tmp, y_gainQ ); + + return mean_4g_fx[0]; +} + /*-------------------------------------------------------------------* * gsc_gaindec() * diff --git a/lib_com/gs_gains_fx.c b/lib_com/gs_gains_fx.c index d5e9e2e9ecaae94023c36a19e57420e359c7e1a9..703f0e4efdfee27ff7bb9d895de9594e3df09a15 100644 --- a/lib_com/gs_gains_fx.c +++ b/lib_com/gs_gains_fx.c @@ -387,6 +387,121 @@ void Ener_per_band_comp_ivas_fx( return; } +void Ener_per_band_comp_ivas_fx_2( + const Word16 exc_diff[], /* i : target signal Q_exc */ + Word16 y_gain4[], /* o : Energy per band to quantize Q12 */ + const Word16 Q_exc, + const Word16 Mband, /* i : Max band */ + const Word16 Eflag, /* i : flag of highest band */ + const Word16 L_frame /* i : frame length */ +) +{ + Word32 etmp, L_tmp; + Word16 etmp_e; + const Word16 *pt; + Word16 i, j, tmp; + tmp = add( shl( sub( Q15, Q_exc ), 1 ), 1 ); + + pt = exc_diff; + FOR( j = 0; j < 2; j++ ) + { + y_gain4[j] = 0; + move16(); + etmp = 42949673; /* 0.02 in Q31 */ + move32(); + etmp_e = 0; + move16(); + + pt = exc_diff + shl( j, 3 ); + FOR( i = 0; i < 8; i++ ) + { + etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e ); + pt++; + } + + /* normalized to 16 bins to easy the quantization */ + etmp_e = add( etmp_e, 1 ); + etmp = Sqrt32( etmp, &etmp_e ); + etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25 + y_gain4[j] = extract_h( L_shl( etmp, 3 ) ); // Q12 + move16(); + } + + FOR( j = 1; j < Mband - 2; j++ ) + { + etmp = 21474836; /* 0.01 in Q31 */ + move32(); + etmp_e = 0; + move16(); + + pt = exc_diff + shl( j, 4 ); + FOR( i = 0; i < 16; i++ ) + { + etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e ); + pt++; + } + + etmp = Sqrt32( etmp, &etmp_e ); + etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25 + y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12 + move16(); + } + + IF( EQ_16( Eflag, 1 ) ) + { + etmp = 21474836; /* 0.01 in Q31 */ + move32(); + etmp_e = 0; + move16(); + + pt = exc_diff + shl( j, 4 ); + FOR( i = 0; i < 32; i++ ) + { + etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e ); + pt++; + } + + etmp_e = sub( etmp_e, 1 ); + etmp = Sqrt32( etmp, &etmp_e ); + etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25 + y_gain4[j + 1] = extract_h( L_shl( etmp, 3 ) ); // Q12 + move16(); + } + + IF( EQ_16( L_frame, L_FRAME16k ) ) + { + etmp = 21474836; /* 0.01 in Q31 */ + move32(); + etmp_e = 0; + move16(); + + FOR( i = 0; i < 32; i++ ) + { + etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e ); + pt++; + } + + Word16 tmp2 = sub( etmp_e, 1 ); + L_tmp = Sqrt32( etmp, &tmp2 ); + L_tmp = BASOP_Util_Log10( L_tmp, tmp2 ); // Q25 + y_gain4[j + 2] = extract_h( L_shl( L_tmp, 3 ) ); // Q12 + move16(); + + FOR( i = 0; i < 32; i++ ) + { + etmp = BASOP_Util_Add_Mant32Exp( etmp, etmp_e, L_mult0( *pt, *pt ), tmp, &etmp_e ); + pt++; + } + + etmp_e = sub( etmp_e, 1 ); + etmp = Sqrt32( etmp, &etmp_e ); + etmp = BASOP_Util_Log10( etmp, etmp_e ); // Q25 + y_gain4[j + 3] = extract_h( L_shl( etmp, 3 ) ); // Q12 + move16(); + } + + return; +} /*-------------------------------------------------------------------* * gsc_gainQ() diff --git a/lib_com/gs_preech.c b/lib_com/gs_preech.c index 7508f1e68d63b69a0c15bacac1cfbb987a1a116e..3d1b6f550b4c27e96e631d327597185cc9b97539 100644 --- a/lib_com/gs_preech.c +++ b/lib_com/gs_preech.c @@ -139,6 +139,7 @@ void pre_echo_att( return; } +#ifdef IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED void pre_echo_att_fx( Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ @@ -208,9 +209,9 @@ void pre_echo_att_fx( etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ - /* Find the correction factor and apply it before the attack */ - /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ - /* = isqrt(etmp/(*Last_frame_ener)) */ + /* Find the correction factor and apply it before the attack */ + /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ + /* = isqrt(etmp/(*Last_frame_ener)) */ etmp_fx = L_max( etmp_fx, 1 ); *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); move32(); @@ -264,3 +265,130 @@ void pre_echo_att_fx( return; } #endif + + +void pre_echo_att_ivas_fx( + Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ + Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ + const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) */ + const Word16 Q_new, + const Word16 last_coder_type, /* i : Last coding mode */ + const Word16 L_frame /* i : Frame length*/ +) +{ + Word32 etmp_fx; + Word32 finc_fx[ATT_LENGHT16k] = { 0 }; + move16(); + Word16 ratio_fx; + Word16 attack_pos_fx, i; + Word32 L_tmp, L_tmp1; + Word16 tmp, n1, n2, exp, frac1, frac2; + Word32 etmp1_fx; + Word16 att_len; + + test(); + IF( gsc_attack_flag_fx > 0 && EQ_16( last_coder_type, AUDIO ) ) /*gsc_attack_flag_fx does not get set for all the test cases */ + { + /*-------------------------------------------------------------------------* + * Find where the onset (attack) occurs by computing the energy per section + * The inverse weighting aims to favor the first maxima in case of + * gradual onset + *-------------------------------------------------------------------------*/ + att_len = ATT_LENGHT; + move16(); + if ( EQ_16( L_frame, L_FRAME16k ) ) + { + att_len = ATT_LENGHT16k; + move16(); + } + FOR( i = 0; i < att_len; i++ ) + { + L_tmp = sum2_fx( &exc_fx[shl( i, 2 )], ATT_SEG_LEN ); /*2*Q_new+1, //ATT_SEG_LEN=(L_FRAME/ATT_LENGHT)=4(=shl(x,2))*/ + tmp = div_s( sub( att_len, i ), att_len ); /*Q15 */ + L_tmp = Mult_32_16( L_tmp, tmp ); /*2*Q_new+1 */ + finc_fx[i] = L_tmp; + move32(); /*2*Q_new+1 */ + } + + attack_pos_fx = maximum_32_fx( finc_fx, att_len, &etmp_fx ); + + /* Scaled the maximum energy and allowed 6 dB increase*/ + etmp_fx = L_shr( etmp_fx, add( 2 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_ATT_SEG_LEN=1/4(=shr(x,2)) -> Q4 */ + etmp1_fx = etmp_fx; + move32(); +#ifdef BASOP_NOGLOB + *Last_frame_ener_fx = L_shl_sat( *Last_frame_ener_fx, 2 ); +#else + *Last_frame_ener_fx = L_shl( *Last_frame_ener_fx, 2 ); +#endif + move32(); /*2*Q_new+1 */ + + /* If the maximum normalized energy > last frame energy + 6dB */ + test(); + IF( GT_32( etmp_fx, *Last_frame_ener_fx ) && attack_pos_fx > 0 ) + { + /* Find the average energy before the attack */ + L_tmp = sum32_fx( finc_fx, attack_pos_fx ); /*Q1 */ + L_tmp1 = L_shr( L_mult( attack_pos_fx, attack_pos_fx ), 1 ); /*Q0 */ + tmp = round_fx( Isqrt( L_tmp1 ) ); /*Q15 */ + L_tmp = L_shr( L_tmp, 2 ); /*Q1 ; ATT_SEG_LEN=4 */ + etmp_fx = Mult_32_16( L_tmp, tmp ); /*Q1 */ + + etmp_fx = L_shr( etmp_fx, add( 1 - 4, shl( Q_new, 1 ) ) ); /* makes etmp i nQ4 as *Last_frame_ener_fx */ + /* Find the correction factor and apply it before the attack */ + /* ratio = (float)sqrt(*Last_frame_ener/etmp);*/ + /* = isqrt(etmp/(*Last_frame_ener)) */ + etmp_fx = L_max( etmp_fx, 1 ); + *Last_frame_ener_fx = L_max( *Last_frame_ener_fx, 1 ); + move32(); + n1 = norm_l( etmp_fx ); + n2 = norm_l( *Last_frame_ener_fx ); + + n1 = sub( n1, 1 ); + exp = sub( n1, n2 ); + + frac1 = round_fx( L_shl( etmp_fx, n1 ) ); +#ifdef BASOP_NOGLOB + frac2 = round_fx_sat( L_shl_sat( *Last_frame_ener_fx, n2 ) ); +#else + frac2 = round_fx( L_shl( *Last_frame_ener_fx, n2 ) ); +#endif + L_tmp = L_mult0( 128, div_s( frac1, frac2 ) ); /* s = gain_out / gain_in */ + L_tmp = L_shr( L_tmp, exp ); /* add exponent */ + + L_tmp = Isqrt( L_tmp ); + ratio_fx = round_fx( L_shl( L_tmp, 9 ) ); + + /* Pre-echo atttenuation should never increase the energy */ + ratio_fx = s_min( ratio_fx, 8192 ); + FOR( i = 0; i < attack_pos_fx * ATT_SEG_LEN; i++ ) + { + /*exc_fx[i] *= ratio_fx;*/ + exc_fx[i] = round_fx( L_shl( L_mac( -8192, exc_fx[i], ratio_fx ), 2 ) ); + move16(); + } + } + *Last_frame_ener_fx = etmp1_fx; + move32(); + } + ELSE + { + /*-------------------------------------------------------* + * In normal cases, just compute the energy of the frame + *-------------------------------------------------------*/ + + etmp_fx = sum2_fx( exc_fx, L_frame ); /*2*Q_new+1 */ + + etmp_fx = L_shr( etmp_fx, add( 8 + 1 - 4, shl( Q_new, 1 ) ) ); /*2*Q_new+1 //INV_L_FRAME = 1/256 -> Q4*/ + + if ( EQ_16( L_frame, L_FRAME16k ) ) + { + etmp_fx = Mpy_32_16_1( etmp_fx, 26214 ); + } + *Last_frame_ener_fx = etmp_fx; + move32(); /*2*Q_new+1*/ + } + + return; +} +#endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3f071999f0a10f04d5c7cc147476cd850f2caef3..51a7644727c618f5439f4d63475712ccc155d725 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -2882,6 +2882,7 @@ void gsc_enc( float *tmp_noise /* o : long-term noise energy */ ); +#ifndef IVAS_FLOAT_FIXED void tdm_low_rate_enc( Encoder_State *st, /* i/o: State structure */ const float Aq[], /* i : 12k8 Lp coefficient */ @@ -2895,6 +2896,22 @@ void tdm_low_rate_enc( const float *lsf_new, /* i : current frame ISF vector */ float *tmp_noise /* o : long-term noise energy */ ); +#else +void tdm_low_rate_enc( + Encoder_State *st, /* i/o: State structure */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 *res, /* i : residual signal */ // Q_new + Word16 *synth, /* i/o: core synthesis */ // Q_new + Word16 *exc_fx, /* 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_fx, /* o : excitation for SWB TBE */ // Q_new + const Word16 attack_flag, /* i : attck flag */ + const Word16 *lsf_new, /* i : current frame ISF vector */ // x2.56 + Word16 *tmp_noise, /* o : long-term noise energy */ // Q8 + Word16 *Q_new +); +#endif /*! r: value of the indice */ uint16_t get_indice_st( @@ -3158,6 +3175,15 @@ void stereo_mdct_init_igf_start_band( const int32_t element_brate /* i : element bitrate */ ); +#ifdef IVAS_FLOAT_FIXED +void init_tcx_enc_info_fx( + Encoder_State *st, /* i/o: coder memory state */ + Word16 *L_frame, + Word16 *L_frameTCX, + Word16 *L_spec +); +#endif + void init_tcx_enc_info( Encoder_State *st, /* i : coder memory state */ int16_t *L_frame, diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 7eaeb92e0b3a477092ca7fd6f8a3cc1212a6d97a..866c42a6695b252fc2c623923ea0f321a90db9ec 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2714,6 +2714,15 @@ void stereo_icBWE_preproc_fx( Word16 q_shb_speech_nonref /* i : Q SHB speech non-ref channel */ ); +void core_switching_pre_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz */ + const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ + const Word16 *old_inp_16k, /* i : old input signal @16kHz */ + const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ + const Word16 active_cnt, /* i : active frame counter */ + const Word16 last_element_mode /* i : last_element_mode */ +); #endif void QuantizeSpectrum_ivas_fx( diff --git a/lib_com/prot.h b/lib_com/prot.h index e882813532680a1a1b24c0476441a410b7722d75..df837c21f38acea83410e4bb488316923234f0ed 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -6859,24 +6859,11 @@ void init_coder_ace_plus( const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ ); -#ifdef IVAS_FLOAT_FIXED -void init_coder_ace_plus_ivas_fx( - Encoder_State *st, /* i : Encoder state */ - const Word32 last_total_brate, /* i : last total bitrate */ - const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ -); -#endif - void core_coder_reconfig( Encoder_State *st, /* i/o: encoder state structure */ const int32_t last_total_brate /* i : last total bitrate */ ); -#ifdef IVAS_FLOAT_FIXED -void core_coder_reconfig_ivas_fx( - Encoder_State *st ); -#endif - void core_coder_mode_switch( Encoder_State *st, /* i/o: encoder state structure */ const int32_t last_total_brate, /* i : last bitrate */ @@ -9939,15 +9926,6 @@ int16_t getTcxonly_ivas( const int16_t is_ism_format /* i : flag indicating ISM format */ ); -#ifdef IVAS_FLOAT_FIXED -Word16 getTcxonly_ivas_fx( - const Word16 element_mode, /* i : IVAS element mode */ - const Word32 total_brate, /* i : total bitrate */ - const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ - const Word16 is_ism_format /* i : flag indicating ISM format */ -); -#endif - int16_t getTnsAllowed( const int32_t total_brate, /* i : total bitrate */ const int16_t igf, /* i : flag indicating IGF activity*/ @@ -10093,16 +10071,6 @@ void IGFEncSetMode( const int16_t rf_mode /* i : flag to signal the RF mode */ ); -#ifdef IVAS_FLOAT_FIXED -void IGFEncSetMode_ivas_fx( - const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ - const Word32 total_brate, /* i : encoder total bitrate */ - const Word16 bwidth, /* i : encoder audio bandwidth */ - const Word16 element_mode, /* i : IVAS element mode */ - const Word16 rf_mode /* i : flag to signal the RF mode */ -); -#endif - /*! r: number of bits written per frame */ int16_t IGFEncWriteBitstream( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i : instance handle of IGF Encoder */ @@ -10318,24 +10286,4 @@ void init_tcx_cfg( const int16_t MCT_flag /* i : hMCT handle allocated (1) or not (0) */ ); -#ifdef IVAS_FLOAT_FIXED -void init_tcx_cfg_ivas_fx( - TCX_CONFIG_HANDLE hTcxCfg, - const Word32 total_brate, - const Word32 sr_core, - const Word32 input_Fs, - const Word16 L_frame, - const Word16 bwidth, - const Word16 L_frameTCX, - const Word16 fscale, - const Word16 preemph_fac, - const Word16 tcxonly, - const Word16 rf_mode, - const Word16 igf, - const Word16 infoIGFStopFreq, - const Word16 element_mode, - const Word16 ini_frame, - const Word16 MCT_flag ); -#endif - #endif diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index caf9ba2c3c8916dfeeca5959eeea183fa08c5155..9c6706c11a1c7ff49b454ed46e60187c943f08b4 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1468,6 +1468,22 @@ Word16 gsc_gainQ_fx( const Word16 bwidth /* i : i signal bandwidth */ ); +Word16 gsc_gainQ_ivas_fx( + BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ + const int16_t element_mode, /* i : element mode */ + const int16_t idchan, /* i : channel ID */ + const Word16 y_gain4[], + /* i : Energy per band */ // Q12 + Word16 y_gainQ[], + /* o : quantized energy per band */ // Q12 + const int32_t core_brate, /* i : Core rate */ + const int16_t coder_type, /* i : coding type */ + const int16_t bwidth, /* i : input signal bandwidth */ + const int16_t L_frame, /* i : frame length */ + const int16_t tdm_LRTD_flag, /* i : LRTD stereo mode flag */ + const int32_t core_brate_inp /* i : true core bitrate */ +); + // frame_ener.c void fer_energy_fx( const Word16 L_frame, /* i : frame length */ @@ -1653,6 +1669,13 @@ void Ener_per_band_comp_ivas_fx( const Word16 Eflag, /* i : flag of highest band */ const int16_t L_frame /* i : frame length */ ); +void Ener_per_band_comp_ivas_fx_2( + const Word16 exc_diff_fx[], /* i : target signal Q_exc_diff */ + Word16 y_gain4_fx[], /* o : Energy per band to quantize Q12 */ + const Word16 Q_exc, /* i : frame length */ + const Word16 Mband, /* i : Max band */ + const Word16 Eflag, /* i : flag of highest band */ + const Word16 L_frame ); void Comp_and_apply_gain_fx( Word16 exc_diffQ[], /* i/o: Quantized excitation */ Word16 Ener_per_bd_iQ[], /* i : Target ener per band Q13 */ @@ -1681,6 +1704,15 @@ void pre_echo_att_fx( const Word16 L_frame /* i : Frame length*/ ); + +void pre_echo_att_ivas_fx( + Word32 *Last_frame_ener_fx, /* i/o: Energy of the last frame 2*Q_new+1*/ + Word16 *exc_fx, /* i/o: Excitation of the current frame Q_new*/ + const Word16 gsc_attack_flag_fx, /* i : flag signalling attack encoded by AC mode (GSC) */ + const Word16 Q_new, + const Word16 last_coder_type, /* i : Last coding mode */ + const Word16 L_frame /* i : Frame length*/ +); // wtda_fx.c void tcx_get_windows_mode1( const Word16 left_mode, /* i: overlap mode of left window half */ @@ -3734,6 +3766,17 @@ void cng_params_postupd_fx( Word32 ho_env_circ[] /* i/o: Envelope buffer */ ); +void cng_params_postupd_ivas_fx( + const Word16 ho_circ_ptr, /* i : pointer for CNG averaging buffers Q0 */ + Word16 *cng_buf_cnt, /* i/o: counter for CNG store buffers Q0 */ + const Word16 *const cng_exc2_buf, /* i : Excitation buffer Q_exc */ + const Word16 *const cng_Qexc_buf, /* i : Q_exc buffer Q0 */ + const Word32 *const cng_brate_buf, /* i : bit rate buffer Q0 */ + Word32 ho_env_circ[], /* i/o: Envelope buffer */ + const Word16 element_mode, /* i : Element mode */ + const Word16 bwidth /* i : Audio bandwidth */ +); + void cng_params_upd_fx( const Word16 lsp_new[], /* i : LSP parameters Q15 */ const Word16 exc2[], /* i : current enhanced excitation Q_exc */ @@ -10569,4 +10612,66 @@ void calculate_hangover_attenuation_gain_ivas_fx( Word16 *att, /* o : attenuation factor */ const Word16 vad_hover_flag /* i : VAD hangover flag */ ); + +void init_coder_ace_plus_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +); + +void core_coder_reconfig_ivas_fx( + Encoder_State *st ); + +void core_coder_mode_switch_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word32 last_total_brate, /* i : last bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ +); + +void configureFdCngEnc_ivas_fx( + HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */ + const Word16 bwidth, + const Word32 total_brate ); + +Word16 getTcxonly_ivas_fx( + const Word16 element_mode, /* i : IVAS element mode */ + const Word32 total_brate, /* i : total bitrate */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0)*/ + const Word16 is_ism_format /* i : flag indicating ISM format */ +); + + +void SetModeIndex_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate */ + const Word16 last_element_mode, /* i : last IVAS element mode */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +); + +void IGFEncSetMode_ivas_fx( + const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */ + const Word32 total_brate, /* i : encoder total bitrate */ + const Word16 bwidth, /* i : encoder audio bandwidth */ + const Word16 element_mode, /* i : IVAS element mode */ + const Word16 rf_mode /* i : flag to signal the RF mode */ +); + +void init_tcx_cfg_ivas_fx( + TCX_CONFIG_HANDLE hTcxCfg, + const Word32 total_brate, + const Word32 sr_core, + const Word32 input_Fs, + const Word16 L_frame, + const Word16 bwidth, + const Word16 L_frameTCX, + const Word16 fscale, + const Word16 preemph_fac, + const Word16 tcxonly, + const Word16 rf_mode, + const Word16 igf, + const Word16 infoIGFStopFreq, + const Word16 element_mode, + const Word16 ini_frame, + const Word16 MCT_flag ); + #endif diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 0c4007783ff9caee33fb760a67277f623bdb5df3..b573bc5a9b82d8f698efc54fcf88938d2dc9983a 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -119,15 +119,15 @@ ivas_error acelp_core_enc( #if 1 Word16 Q_exc = 0; move16(); - Word16 A_fx[85]; + Word16 A_fx[85], Aw_fx[85]; Word16 old_exc_fx[L_EXC], *exc_fx; /* excitation signal buffer */ Word16 lsf_new_fx[M]; /* ISFs at the end of the frame */ Word16 Aq_fx[NB_SUBFR16k * ( M + 1 )]; /* A(z) quantized for the 4 subframes */ - // Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ - Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ + Word16 syn_fx[L_FRAME16k]; /* synthesis vector */ + Word16 res_fx[L_FRAME16k]; /* Residual signal for FER protection */ // Word16 exc2_fx[L_FRAME16k]; /* enhanced excitation */ - Word16 Es_pred_fx; /* predicited scaled innovation energy */ - // Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ + Word16 Es_pred_fx; /* predicited scaled innovation energy */ + Word16 tmp_noise_fx; /* NB post-filter long-term noise energy*/ // 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; @@ -145,6 +145,13 @@ ivas_error acelp_core_enc( // Word16 enr_index; // Word16 enr; +#ifdef MSAN_FIX + set_zero( old_bwe_exc, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); + set16_fx( old_bwe_exc_fx, 0, ( PIT16k_MAX + ( L_FRAME16k + 1 ) + L_SUBFR16k ) * 2 ); + set16_fx( old_exc_fx, 0, L_EXC ); + set16_fx( Aq_fx, 0, NB_SUBFR16k * ( M + 1 ) ); +#endif + Word16 tilt_code_bck_fx; Word32 gc_threshold_bck_fx; Word16 clip_var_bck_fx[6]; @@ -162,6 +169,15 @@ ivas_error acelp_core_enc( Word16 tmpF_fx; #endif #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 tmp; + set_zero( old_bwe_exc, 1380 ); + 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. + 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 ) @@ -170,7 +186,37 @@ ivas_error acelp_core_enc( floatToFixed_arr16( st->lsp_old16k, st->lsp_old16k_fx, 15, M ); floatToFixed_arr16( lsp_mid, lsp_mid_fx, 15, M ); floatToFixed_arr16( lsp_new, lsp_new_fx, 15, M ); - + IF( st->hLPDmem ) + { + 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 ); + } + st->gamma = float_to_fix16( st->gamma_flt, Q15 ); + for ( int ii = 0; ii < M; ii++ ) + { + st->mem_MA_fx[ii] = (Word16) ( ( st->mem_MA[ii] ) * 2.56f ); + st->mem_AR_fx[ii] = (Word16) ( ( st->mem_AR[ii] ) * 2.56f ); + st->lsf_old_fx[ii] = (Word16) ( ( st->lsf_old[ii] ) * 2.56f ); + } + Word16 inp_buff[L_FRAME16k + M + 1]; + Word16 *inp_fx; + inp_fx = &inp_buff[M + 1]; + Word16 e_mem_w0 = 0, 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 ); + floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); + Q_new = s_min( Q_new, q_comm_Bin - ( QSCALE - 2 ) ); + 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 ); + st->stab_fac_fx = float_to_fix16( st->stab_fac, Q15 ); #endif ivas_error error; @@ -366,31 +412,43 @@ ivas_error acelp_core_enc( Copy( GEWB_Ave_fx, st->mem_AR_fx, M ); set16_fx( st->mem_MA_fx, 0, M ); -#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( &A_fx[i * ( M + 1 )], &A[i * ( M + 1 )], 14 - norm_s( A_fx[i * ( M + 1 )] ), ( M + 1 ) ); - } - for ( i = 0; i < M; i++ ) - { - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; - st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; - st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; - } - fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); -#endif - /* update synthesis filter memories */ - synth_mem_updt2_flt( st->L_frame, st->last_L_frame, hLPDmem->old_exc_flt, hLPDmem->mem_syn_r_flt, hLPDmem->mem_syn2_flt, hLPDmem->mem_syn_flt, ENC ); - mvr2r( hLPDmem->old_exc_flt, old_exc_flt, L_EXC_MEM ); - mvr2r( hLPDmem->mem_syn2_flt, hLPDmem->mem_syn1_flt, M ); - mvr2r( hLPDmem->mem_syn2_flt, hLPDmem->mem_syn3_flt, M ); + synth_mem_updt2( st->L_frame, st->last_L_frame, hLPDmem->old_exc, hLPDmem->mem_syn_r, hLPDmem->mem_syn2, hLPDmem->mem_syn, ENC ); + Copy( hLPDmem->old_exc, old_exc_fx, L_EXC_MEM ); + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn3, M ); /* update Aw[] coefficients */ - weight_a_subfr( st->L_frame / L_SUBFR, A, Aw, st->gamma_flt, M ); + weight_a_subfr_fx( shr( st->L_frame, 6 ), A_fx, Aw_fx, st->gamma, M ); } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + + for ( i = 0; i < M; i++ ) + { + st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; + st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; + st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; + } + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); + 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 ); + } + 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 ); + 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( &A_fx[i * ( M + 1 )], &A[i * ( M + 1 )], 14 - norm_s( A_fx[i * ( M + 1 )] ), ( M + 1 ) ); + fixedToFloat_arr( &Aw_fx[i * ( M + 1 )], &Aw[i * ( M + 1 )], 14 - norm_s( Aw_fx[i * ( M + 1 )] ), ( M + 1 ) ); + } +#endif test(); test(); @@ -409,7 +467,22 @@ ivas_error acelp_core_enc( if ( st->cng_type == LP_CNG ) { /* Run CNG post parameter update */ +#if 1 +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( Word16 ii = 0; ii < HO_HIST_SIZE; ii++ ) + { + f2me_buf_16( &st->hTdCngEnc->cng_exc2_buf_flt[ii * L_FFT], &st->hTdCngEnc->cng_exc2_buf[ii * L_FFT], &st->hTdCngEnc->cng_Qexc_buf[ii], L_FFT ); + st->hTdCngEnc->cng_Qexc_buf[ii] = Q15 - st->hTdCngEnc->cng_Qexc_buf[ii]; + } + floatToFixed_arr32( st->hTdCngEnc->ho_env_circ, st->hTdCngEnc->ho_env_circ_fx, Q6, 160 ); +#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 + fixedToFloat_arrL( st->hTdCngEnc->ho_env_circ_fx, st->hTdCngEnc->ho_env_circ, Q6, 160 ); +#endif +#else cng_params_postupd( st->hTdCngEnc->ho_circ_ptr, &st->hTdCngEnc->cng_buf_cnt, st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_brate_buf, st->hTdCngEnc->ho_env_circ, st->element_mode, st->hFdCngEnc->hFdCngCom->CngBandwidth ); +#endif /* encode CNG parameters */ CNG_enc( st, Aq, inp, ener, lsp_mid, lsp_new, lsf_new, &allow_cn_step, q_env, &sid_bw ); @@ -494,38 +567,26 @@ ivas_error acelp_core_enc( { floatToFixed_arr( st->hDtxEnc->lspCNG, st->hDtxEnc->lspCNG_fx, Q15, M ); } - floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); for ( i = 0; i < M; i++ ) { st->lsf_old_fx[i] = (Word16) ( st->lsf_old[i] * 2.56f ); } st->mem_deemp_preQ_fx = (Word16) floatToFixed( st->mem_deemp_preQ, -1 ); - Word16 e_mem_syn_bck = 0, e_mem_w0 = 0, q_comm_Bin, Q_new /* Q_new will be later passed from parent function as arg */; IF( st->hLPDmem ) { st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); st->hLPDmem->gc_threshold = float_to_fix16( st->hLPDmem->gc_threshold_flt, Q16 ); - f2me_buf_16( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, &e_mem_syn_bck, M ); + f2me_buf_16( st->hLPDmem->mem_syn_flt, st->hLPDmem->mem_syn, &st->hLPDmem->e_mem_syn, M ); f2me_16( st->hLPDmem->mem_w0_flt, &st->hLPDmem->mem_w0, &e_mem_w0 ); } floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); - for ( int ii = 0; ii < M; ii++ ) - { - st->mem_MA_fx[ii] = (Word16) ( ( st->mem_MA[ii] ) * 2.56f ); - st->mem_AR_fx[ii] = (Word16) ( ( st->mem_AR[ii] ) * 2.56f ); - lsf_new_fx[ii] = (Word16) ( ( lsf_new[ii] ) * 2.56f ); - } st->clip_var_fx[0] = (Word16) ( st->clip_var[0] * 2.56f ); for ( i = 1; i < 6; i++ ) { st->clip_var_fx[i] = (Word16) ( st->clip_var[i] * ONE_IN_Q14 ); } - q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); - floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, q_comm_Bin, 128 ); - floatToFixed_arrL( st->Bin_E, st->Bin_E_fx, q_comm_Bin, 256 ); st->streaklimit_fx = (Word16) floatToFixed( st->streaklimit, Q15 ); - Q_new = q_comm_Bin - ( QSCALE - 2 ); FOR( Word16 idx = 0; idx < M; idx++ ) { st->lsf_adaptive_mean_fx[idx] = (Word16) ( st->lsf_adaptive_mean[idx] * 2.56f ); @@ -534,6 +595,17 @@ ivas_error acelp_core_enc( st->lsfoldbfi1_fx[idx] = (Word16) ( st->lsfoldbfi1[idx] * 2.56f ); st->lsfoldbfi0_fx[idx] = (Word16) ( st->lsfoldbfi0[idx] * 2.56f ); } + 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_old_bwe_exc, 1380 ); + 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 - hLPDmem->e_old_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 ); + + st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); + floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); #endif /*-----------------------------------------------------------------* * Configure ACELP bit allocation @@ -643,75 +715,6 @@ ivas_error acelp_core_enc( /* Check LSF stability (distance between old LSFs and current LSFs) */ st->stab_fac_fx = lsf_stab_fx( lsf_new_fx, st->lsf_old_fx, 0, st->L_frame ); // Q15 } -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - - st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); - tilt_code_bck = fix16_to_float( tilt_code_bck_fx, Q15 ); - gc_threshold_bck = fix_to_float( gc_threshold_bck_fx, Q16 ); - clip_var_bck[0] = (float) clip_var_bck_fx[0] / 2.56f; - for ( i = 1; i < 6; i++ ) - { - clip_var_bck[i] = (float) clip_var_bck_fx[i] / (float) ( ONE_IN_Q14 ); - } - clip_var = (float) clip_var_fx / 2.56f; - for ( int ii = 0; ii < M; ii++ ) - { - mem_AR[i] = (float) mem_AR_fx[i] / 2.56f; - mem_MA[i] = (float) mem_MA_fx[i] / 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, e_mem_syn_bck, mem_syn_bck, M ); - mem_w0_bck = me2f( mem_w0_bck_fx, e_mem_w0 ); - streaklimit = fixedToFloat( streaklimit_fx, Q15 ); - 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; - st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; - st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56f; - st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; - st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; - st->lsfoldbfi1[i] = st->lsfoldbfi1_fx[i] / 2.56f; - st->lsfoldbfi0[i] = st->lsfoldbfi0_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 ); - fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); - 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 ) ); - } - st->stab_fac = fixedToFloat( st->stab_fac_fx, Q15 ); -#endif -#endif - -#if 1 -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - 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_old_bwe_exc, 1380 ); - 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 - hLPDmem->e_old_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 ); - f2me_buf_16( hLPDmem->mem_syn_flt, hLPDmem->mem_syn, &hLPDmem->e_mem_syn, M ); - - st->preemph_fac = float_to_fix16( st->preemph_fac_flt, Q15 ); - Word16 inp_buff[L_FRAME16k + M + 1]; - Word16 *inp_fx; - inp_fx = &inp_buff[M + 1]; - Q_new = Q_factor_arr( &inp[-M - 1], L_FRAME16k + M + 1 ); - floatToFixed_arr( &inp[-M - 1], &inp_fx[-M - 1], Q_new, L_FRAME16k + M + 1 ); - floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); -#endif test(); IF( EQ_16( st->last_core, HQ_CORE ) && st->element_mode > EVS_MONO ) { @@ -777,9 +780,52 @@ ivas_error acelp_core_enc( push_indice( hBstr, IND_ES_PRED, i, nb_bits ); } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->mem_deemp_preQ = fixedToFloat( st->mem_deemp_preQ_fx, -1 ); + tilt_code_bck = fix16_to_float( tilt_code_bck_fx, Q15 ); + gc_threshold_bck = fix_to_float( gc_threshold_bck_fx, Q16 ); + clip_var_bck[0] = (float) clip_var_bck_fx[0] / 2.56f; + for ( i = 1; i < 6; i++ ) + { + clip_var_bck[i] = (float) clip_var_bck_fx[i] / (float) ( ONE_IN_Q14 ); + } + clip_var = (float) clip_var_fx / 2.56f; + for ( int ii = 0; ii < M; ii++ ) + { + mem_AR[i] = (float) mem_AR_fx[i] / 2.56f; + mem_MA[i] = (float) mem_MA_fx[i] / 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 ); + mem_w0_bck = me2f( mem_w0_bck_fx, e_mem_w0 ); + streaklimit = fixedToFloat( streaklimit_fx, Q15 ); + 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; + st->lsf_old[i] = st->lsf_old_fx[i] / 2.56f; + st->lsf_adaptive_mean[i] = st->lsf_adaptive_mean_fx[i] / 2.56f; + st->mem_MA[i] = st->mem_MA_fx[i] / 2.56f; + st->mem_AR[i] = st->mem_AR_fx[i] / 2.56f; + st->lsfoldbfi1[i] = st->lsfoldbfi1_fx[i] / 2.56f; + st->lsfoldbfi0[i] = st->lsfoldbfi0_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 ); + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, 15, M ); + 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 ) ); + } + st->stab_fac = fixedToFloat( st->stab_fac_fx, Q15 ); 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 ); - me2f_buf_16( hLPDmem->mem_syn, hLPDmem->e_mem_syn, hLPDmem->mem_syn_flt, M ); 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 ); @@ -789,12 +835,36 @@ ivas_error acelp_core_enc( /*------------------------------------------------------------* * Encode excitation according to coding type *------------------------------------------------------------*/ - - if ( tdm_low_rate_mode ) /* tdm stereo low rate mode */ + IF( tdm_low_rate_mode ) /* tdm stereo low rate mode */ { - if ( st->coder_type <= UNVOICED ) + IF( LE_16( st->coder_type, UNVOICED ) ) { - tdm_low_rate_enc( st, Aq, res, syn, exc, pitch_buf, voice_factors, bwe_exc, 0 /*attack_flag*/, lsf_new, &tmp_noise ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 pitch_buf_fx[NB_SUBFR]; + Word16 voice_factors_fx[NB_SUBFR16k]; + floatToFixed_arr( voice_factors, voice_factors_fx, Q15, NB_SUBFR16k ); + st->hGSCEnc->Last_frame_ener_fx = floatToFixed_32( st->hGSCEnc->Last_frame_ener, Q4 ); + f2me_buf_16( st->hGSCEnc->last_exc_dct_in, st->hGSCEnc->last_exc_dct_in_fx, &st->hGSCEnc->Q_last_exc_dct_in, L_FRAME16k ); + st->hGSCEnc->Q_last_exc_dct_in = Q15 - st->hGSCEnc->Q_last_exc_dct_in; + st->hGSCEnc->last_ener_fx = (Word16) st->hGSCEnc->last_ener; + IF( st->hLPDmem ) + st->hLPDmem->tilt_code = float_to_fix16( st->hLPDmem->tilt_code_flt, Q15 ); +#endif + Word16 Q_exc2 = add( Q_new, 1 ); + 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 ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( exc_fx, exc, Q_exc, L_FRAME ); + 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 } else /* GENERIC */ { @@ -1359,30 +1429,9 @@ ivas_error acelp_core_enc( lsp2lsf( lsp_new, lsf_new, M, 12800 ); Unified_weighting( &st->Bin_E[L_FFT / 2], lsf_new, lsf_wgts, st->bwidth == NB, st->coder_type == UNVOICED, st->sr_core, M ); -#ifdef IVAS_FLOAT_FIXED - Word16 lsf_new_fx[M]; - Word16 lsp_new_fx[M]; - Word16 tdm_lsfQ_PCh_fx[M]; - Word16 lsf_wgts_fx[M]; - for ( int ii = 0; ii < M; ii++ ) - { - lsf_new_fx[ii] = (Word16) ( ( lsf_new[ii] ) * 2.56f ); - tdm_lsfQ_PCh_fx[ii] = (Word16) ( ( tdm_lsfQ_PCh[ii] ) * 2.56f ); - lsf_wgts_fx[ii] = (Word16) ( ( lsf_wgts[ii] ) * 2.56f ); - } - floatToFixed_arr( lsp_new, lsp_new_fx, 15, M ); - - tdm_SCh_lsf_reuse_fx( ENC, st->element_brate, lsf_new_fx, lsp_new_fx, tdm_lsfQ_PCh_fx, lsf_wgts_fx, &beta_index ); - for ( int ii = 0; ii < M; ii++ ) - { - lsf_new[ii] = (Word16) ( ( lsf_new_fx[ii] ) / 2.56f ); - lsf_wgts[ii] = (Word16) ( ( lsf_wgts_fx[ii] ) / 2.56f ); - } - fixedToFloat_arr( lsp_new_fx, lsp_new, 15, M ); -#else tdm_SCh_lsf_reuse( ENC, st->element_brate, lsf_new, lsp_new, tdm_lsfQ_PCh, lsf_wgts, &beta_index ); -#endif + push_indice( hBstr, IND_IC_LSF_PRED, beta_index, TDM_IC_LSF_PRED_BITS ); } diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index e13e3e4d7f6e2ec9925b2db8954bf184c7405d0b..e5bf41ca4a85add9a0b79eeeaffabf4724bab242 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -39,12 +39,240 @@ #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" +#include "prot_fx.h" +#include "prot_fx_enc.h" + /*-------------------------------------------------------------------* * core_coder_mode_switch() * * *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void core_coder_mode_switch_ivas_fx( + Encoder_State *st, /* i/o: encoder state structure */ + const Word32 last_total_brate, /* i : last bitrate */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0)*/ +) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + Word16 i, fscale, switchWB; + Word32 sr_core; + Word16 bSwitchFromAmrwbIO; + Word16 tcxonly_tmp; + + switchWB = 0; + move16(); + bSwitchFromAmrwbIO = 0; + move16(); + + + IF( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + + /* force active frame for the first frame when switching from high bitrates when DTX is enabled*/ + sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + + fscale = sr2fscale_fx( sr_core ); + if ( EQ_16( st->last_codec_mode, MODE1 ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + tcxonly_tmp = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + + if ( NE_32( tcxonly_tmp, st->tcxonly ) ) + { + switchWB = 1; /*force init when coming from MODE1*/ + move16(); + } + + test(); + test(); + IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) + { + st->sr_core = sr_core; + move16(); + Word16 exp_res = 0; + move16(); + Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); + st->L_frame = shr( tmp, 15 - exp_res ); + move16(); + + st->tcxonly = getTcxonly_fx( st->element_mode, st->total_brate, MCT_flag, st->is_ism_format ); + move16(); + + Word16 exp_tmp1 = 0; + move16(); + Word16 tmp1 = BASOP_Util_Divide1616_Scale( ONE_IN_Q9, 128, &exp_tmp1 ); + + Word16 exp_tmp2 = 0; + move16(); + Word16 tmp2 = BASOP_Util_Divide3232_Scale( st->total_brate, 100, &exp_tmp2 ); + + Word16 exp_tmp3 = 0; + move16(); + Word16 tmp3 = BASOP_Util_Divide3232_Scale( st->L_frame, st->fscale, &exp_tmp3 ); + + Word32 tmp4 = L_mult0( tmp1, tmp2 ); // exp_tmp1 + exp_tmp2 + Word32 tmp5 = L_shl( Mpy_32_16_1( tmp4, tmp3 ), 1 ); // exp_tmp1 + exp_tmp2 + exp_tmp3 + st->bits_frame_nominal = (Word16) L_shr( tmp5, sub( 31, ( add( add( exp_tmp1, exp_tmp2 ), exp_tmp3 ) ) ) ); + move16(); + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + /* switch IGF configuration */ + IF( st->igf ) + { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IGFEncSetMode( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); +#endif + IGFEncSetMode_fx( st->hIGFEnc, st->total_brate, st->bwidth, st->element_mode, st->rf_mode ); + } + st->hTcxCfg->tcx_coded_lines = getNumTcxCodedLines( st->bwidth ); + move16(); + + st->hTcxCfg->bandwidth = getTcxBandwidth( st->bwidth ); + move16(); + st->hTcxCfg->tcxRateLoopOpt = ( st->tcxonly ) ? 2 : 0; + st->hTcxCfg->tcxRateLoopOpt = ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) ? 3 : st->hTcxCfg->tcxRateLoopOpt; + st->hTcxCfg->ctx_hm = getCtxHm( st->element_mode, st->total_brate, st->rf_mode ); + st->hTcxCfg->resq = getResq( st->total_brate ); + hTcxEnc->tcx_lpc_shaped_ari = getTcxLpcShapedAri( st->total_brate, st->rf_mode, st->element_mode ); + st->hTcxCfg->tcxRateLoopOpt = ( st->hTcxCfg->resq && !st->tcxonly ) ? 1 : st->hTcxCfg->tcxRateLoopOpt; + st->hTcxCfg->fIsTNSAllowed = getTnsAllowed( st->total_brate, st->igf, st->element_mode ); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + move16(); + + IF( st->hTcxCfg->fIsTNSAllowed ) + { + InitTnsConfigs_ivas_fx( st->bwidth, st->hTcxCfg->tcx_coded_lines, st->hTcxCfg->tnsConfig, st->hIGFEnc->infoStopFrequency, st->total_brate, st->element_mode, MCT_flag ); + + SetAllowTnsOnWhite( st->hTcxCfg->tnsConfig, st->element_mode == IVAS_CPE_MDCT ); + } + + IF( EQ_16( st->bwidth, NB ) ) + { + st->narrowBand = 1; + st->min_band = 1; + st->max_band = 16; + } + ELSE + { + st->narrowBand = 0; + st->min_band = 0; + st->max_band = 19; + } + + move16(); + move16(); + move16(); + + FOR( i = 0; i < FRAME_SIZE_NB; i++ ) + { + IF( FrameSizeConfig[i].frame_bits == st->bits_frame_nominal ) + { + st->frame_size_index = i; + st->bits_frame = FrameSizeConfig[i].frame_bits; + st->bits_frame_core = FrameSizeConfig[i].frame_net_bits; + move16(); + move16(); + move16(); + break; + } + } + + st->restrictedMode = getRestrictedMode( st->element_mode, st->total_brate, 0 ); + move16(); + core_coder_reconfig_ivas_fx( st ); + } + ELSE + { + st->igf = getIgfPresent_fx( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); + move16(); + init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); + } + + test(); + IF( st->igf && st->hBWE_TD != NULL ) + { + /* reset TBE */ + test(); + test(); + test(); + test(); + test(); + IF( ( EQ_16( st->bwidth, WB ) && NE_16( st->last_extl, WB_TBE ) ) || + ( EQ_16( st->bwidth, SWB ) && NE_16( st->last_extl, SWB_TBE ) ) || + ( EQ_16( st->bwidth, FB ) && NE_16( st->last_extl, FB_TBE ) ) ) + { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + TBEreset_enc( st->hBWE_TD, st->last_core, st->bwidth ); +#endif + TBEreset_enc_fx( st, st->bwidth ); + } + ELSE + { +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + set_f( st->hBWE_TD->state_lpc_syn, 0.0f, LPC_SHB_ORDER ); + set_f( st->hBWE_TD->state_syn_shbexc, 0.0f, L_SHB_LAHEAD ); + set_f( st->hBWE_TD->mem_stp_swb, 0.0f, LPC_SHB_ORDER ); + set_f( st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb = 1.0f; +#endif + set16_fx( st->hBWE_TD->state_lpc_syn_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->state_syn_shbexc_fx, 0, L_SHB_LAHEAD ); + set16_fx( st->hBWE_TD->mem_stp_swb_fx, 0, LPC_SHB_ORDER ); + set16_fx( st->hBWE_TD->mem_zero_swb_fx, 0, LPC_SHB_ORDER ); + st->hBWE_TD->gain_prec_swb_fx = ONE_IN_Q14; + move16(); + } + } + test(); + IF( st->envWeighted && !st->enableTcxLpc ) + { + /* Unweight the envelope */ + Word16 exp_res = 0, Q_res = 15; + move16(); + move16(); + st->inv_gamma = BASOP_Util_Divide1616_Scale( ONE_IN_Q14, st->gamma, &exp_res ); + Q_res = sub( Q_res, exp_res ); + st->inv_gamma = shr( st->inv_gamma, sub( Q14, Q_res ) ); + E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); + st->envWeighted = 0; + move16(); + } + + IF( GE_32( st->total_brate, HQ_48k ) ) + { + st->enablePlcWaveadjust = 1; + move16(); + } + ELSE + { + st->enablePlcWaveadjust = 0; + move16(); + } + + test(); + test(); + IF( ( GT_32( last_total_brate, HQ_32k ) || EQ_16( st->last_codec_mode, MODE1 ) ) && EQ_16( st->element_mode, EVS_MONO ) ) + { + st->glr_reset = 1; + move16(); + } + + return; +} +#endif void core_coder_mode_switch( Encoder_State *st, /* i/o: encoder state structure */ @@ -149,11 +377,7 @@ void core_coder_mode_switch( else { st->igf = getIgfPresent( st->element_mode, st->total_brate, st->bwidth, st->rf_mode ); -#ifdef IVAS_FLOAT_FIXED - init_coder_ace_plus_ivas_fx( st, last_total_brate, MCT_flag ); -#else init_coder_ace_plus( st, last_total_brate, MCT_flag ); -#endif } if ( st->igf && st->hBWE_TD != NULL ) diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index 119506fa9d0a44d105f3a3f5bb845225a8876039..075868e79569c1f2ea3b279ff9732337186e1447 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -45,6 +45,7 @@ #ifdef IVAS_FLOAT_FIXED #include "prot_fx.h" +#include "ivas_prot_fx.h" #endif /*---------------------------------------------------------------------* @@ -102,10 +103,6 @@ void core_switching_pre_enc( set_f( hHQ_core->last_ni_gain, 0, BANDS_MAX ); set_f( hHQ_core->last_env, 0, BANDS_MAX ); -#ifdef IVAS_FLOAT_FIXED - set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); - set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); -#endif hHQ_core->last_max_pos_pulse = 0; hHQ_core->mode_count = 0; @@ -354,6 +351,408 @@ void core_switching_pre_enc( return; } +#ifdef IVAS_FLOAT_FIXED +void core_switching_pre_enc_ivas_fx( + Encoder_State *st_fx, /* i/o: encoder state structure */ + const Word16 *old_inp_12k8, /* i : old input signal @12.8kHz */ + const Word16 q_old_inp_12k8, /* i : Q old input signal @12.8kHz */ + const Word16 *old_inp_16k, /* i : old input signal @16kHz */ + const Word16 q_old_inp_16k, /* i : Q old input signal @16kHz */ + const Word16 active_cnt, /* i : active frame counter */ + const Word16 last_element_mode /* i : last_element_mode */ +) +{ + Word16 Sample_Delay_HP, Sample_Delay_LP; + Word16 tmp16; + Word16 tmp; + SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR; + LPD_state_HANDLE hLPDmem = st_fx->hLPDmem; + HQ_ENC_HANDLE hHQ_core = st_fx->hHQ_core; + TD_BWE_ENC_HANDLE hBWE_TD = st_fx->hBWE_TD; + TCX_ENC_HANDLE hTcxEnc = st_fx->hTcxEnc; + FD_BWE_ENC_HANDLE hBWE_FD = st_fx->hBWE_FD; + + /* Mode switching */ + test(); + test(); + test(); + IF( EQ_16( st_fx->last_codec_mode, MODE2 ) || ( ( ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) && GT_16( st_fx->element_mode, EVS_MONO ) ) ) ) + { + IF( hLPDmem != NULL ) + { + st_fx->mem_deemph_fx = hLPDmem->syn[M]; + move16(); + Copy( hLPDmem->mem_syn2, hLPDmem->mem_syn1_fx, M ); + } + + if ( NE_16( st_fx->element_mode, IVAS_CPE_MDCT ) ) + { + st_fx->igf = 0; + move16(); + } + + IF( hBWE_TD != NULL ) + { + IF( NE_16( st_fx->last_core, ACELP_CORE ) ) + { + /* reset BWE memories */ + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = L_deposit_l( 0 ); + } + + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + test(); + IF( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) + { + if ( EQ_16( st_fx->element_mode, EVS_MONO ) ) + { + st_fx->last_core = HQ_CORE; + move16(); + } + IF( hHQ_core != NULL ) + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + } + /*ALDO overlap windowed past: also used in MODE2 but for other MDCT-LB*/ + IF( EQ_16( st_fx->element_mode, EVS_MONO ) && hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + test(); + IF( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( EQ_16( st_fx->last_L_frame, L_FRAME ) ) ) + { + Copy( st_fx->lsp_old_fx, st_fx->lsp_old16k_fx, M ); + + st_fx->rate_switching_reset_16kHz = lsp_convert_poly_fx( st_fx->lsp_old16k_fx, st_fx->L_frame, 0 ); + } + + st_fx->use_acelp_preq = 0; + move16(); + } + + test(); + test(); + test(); + IF( EQ_16( st_fx->last_core, -1 ) && ( EQ_16( st_fx->core, HQ_CORE ) || EQ_16( st_fx->core, TCX_20_CORE ) || EQ_16( st_fx->core, TCX_10_CORE ) ) ) + { + /* very first frame is HQ_CORE */ + st_fx->last_core = HQ_CORE; + move16(); + } + + test(); + test(); + IF( EQ_16( st_fx->core, HQ_CORE ) && ( EQ_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_core, AMR_WB_CORE ) ) ) /* HQ init */ + { + set32_fx( hHQ_core->last_ni_gain_fx, 0, BANDS_MAX ); + set16_fx( hHQ_core->last_env_fx, 0, BANDS_MAX ); + hHQ_core->last_max_pos_pulse = 0; + move16(); + + hHQ_core->mode_count = 0; + move16(); + hHQ_core->mode_count1 = 0; + move16(); + + set16_fx( hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); + hHQ_core->prev_frm_hfe2 = 0; + move16(); + hHQ_core->prev_stab_hfe2 = 0; + move16(); + + if ( hTcxEnc != NULL ) + { + set16_fx( hTcxEnc->old_out_fx, 0, L_FRAME32k ); + } + } + + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + test(); + test(); + IF( EQ_16( st_fx->core, ACELP_CORE ) && ( NE_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) ) ) + { + IF( hSC_VBR != NULL ) + { + hSC_VBR->last_last_ppp_mode = 0; + move16(); + hSC_VBR->last_ppp_mode = 0; + move16(); + hSC_VBR->last_nelp_mode = 0; + move16(); + } + } + + test(); + test(); + test(); + IF( EQ_16( st_fx->core, ACELP_CORE ) && ( NE_16( st_fx->last_core, ACELP_CORE ) || EQ_16( st_fx->last_codec_mode, MODE2 ) || LE_32( st_fx->last_total_brate, PPP_NELP_2k80 ) ) ) + { + st_fx->act_count = 3; + move16(); + st_fx->uv_count = 0; + move16(); + } + + test(); + test(); + IF( ( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && EQ_16( st_fx->last_core, HQ_CORE ) ) || + ( ( EQ_16( st_fx->element_mode, IVAS_CPE_DFT ) || EQ_16( st_fx->element_mode, IVAS_CPE_TD ) || ( EQ_16( st_fx->element_mode, IVAS_CPE_MDCT ) && EQ_16( last_element_mode, IVAS_CPE_DFT ) ) ) && EQ_16( active_cnt, 1 ) ) ) + { + IF( EQ_16( st_fx->L_frame, L_FRAME16k ) ) + { + Copy( TRWB2_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_16k ); + } + ELSE + { + Copy( TRWB_Ave_fx, st_fx->lsf_old_fx, M ); /* init of LSP */ + lsf2lsp_fx( st_fx->lsf_old_fx, st_fx->lsp_old_fx, M, INT_FS_FX ); + } + + st_fx->mem_deemph_fx = 0; + /* Reset ACELP parameters */ + IF( hLPDmem != NULL ) + { + move16(); + hLPDmem->syn[M] = 0; + move16(); + set16_fx( hLPDmem->mem_syn2, 0, M ); + set16_fx( hLPDmem->mem_syn, 0, M ); + set16_fx( hLPDmem->mem_syn1_fx, 0, M ); + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + /* set16_fx( st_fx->dispMem, 0, 8 ); */ + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + } + st_fx->Nb_ACELP_frames = 0; + move16(); + + set16_fx( st_fx->mem_MA_fx, 0, M ); + Copy( GEWB_Ave_fx, st_fx->mem_AR_fx, M ); + init_gp_clip_fx( st_fx->clip_var_fx ); + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = add( NB_SUBFR, 1 ); + move16(); + + if ( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + tmp16 = NB_SUBFR; + move16(); + } + + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old ACELP buffers */ + test(); + IF( EQ_16( st_fx->element_mode, EVS_MONO ) && hLPDmem != NULL ) + { + set16_fx( hLPDmem->old_exc, 0, L_EXC_MEM ); + } + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + + /* reset BWE memories */ + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + } + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); + } + } + test(); + test(); + test(); + IF( ( EQ_16( st_fx->core, ACELP_CORE ) || EQ_16( st_fx->core, AMR_WB_CORE ) ) && ( EQ_16( st_fx->last_core, TCX_20_CORE ) || EQ_16( st_fx->last_core, TCX_10_CORE ) ) ) + { + /* Reset the ACELP core in case of TCX->ACELP core switching */ + st_fx->Nb_ACELP_frames = 0; + move16(); + + IF( hLPDmem != NULL ) + { + hLPDmem->mem_w0 = 0; + move16(); + hLPDmem->tilt_code = 0; + move16(); + hLPDmem->gc_threshold = 0; + move32(); + init_gp_clip_fx( st_fx->clip_var_fx ); + set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 ); + hLPDmem->dm_fx.prev_state = 0; + move16(); + hLPDmem->dm_fx.prev_gain_code = L_deposit_l( 0 ); + } + + st_fx->last_coder_type = GENERIC; + move16(); + + tmp16 = shr( st_fx->L_frame, 6 ); + Copy( st_fx->old_pitch_buf_fx + tmp16, st_fx->old_pitch_buf_fx, tmp16 ); + set16_fx( st_fx->old_pitch_buf_fx + tmp16, L_SUBFR, tmp16 ); + + /* Reset old TD BWE buffers */ + IF( hBWE_TD != NULL ) + { + set16_fx( hBWE_TD->old_bwe_exc_fx, 0, PIT16k_MAX * 2 ); + hBWE_TD->bwe_non_lin_prev_scale_fx = 0; + move16(); + } + + /* reset BWE memories */ + IF( hBWE_FD != NULL ) + { + set16_fx( hBWE_FD->old_syn_12k8_16k_fx, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); /* TODO : this might not be needed */ + } + } + test(); + test(); + test(); + IF( GE_32( st_fx->input_Fs, 16000 ) && NE_16( st_fx->last_extl, WB_BWE ) && EQ_16( st_fx->extl, WB_BWE ) && hBWE_FD != NULL ) + { + test(); + IF( NE_16( st_fx->last_extl, SWB_BWE ) && NE_16( st_fx->last_extl, FB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + IF( ( GE_32( st_fx->input_Fs, 32000 ) && NE_16( st_fx->last_extl, SWB_BWE ) && EQ_16( st_fx->extl, SWB_BWE ) ) || + ( GE_32( st_fx->input_Fs, 48000 ) && NE_16( st_fx->last_extl, FB_BWE ) && EQ_16( st_fx->extl, FB_BWE ) ) ) + { + /* we are switching to SWB BWE - reset SWB BWE buffers */ + + IF( EQ_16( st_fx->L_frame, L_FRAME ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 12800, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS ); + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_12k8 ) ); + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_12k8, hBWE_FD->prev_Q_input_lp ) ); + hBWE_FD->prev_Q_input_lp = q_old_inp_12k8; + move16(); + Copy( old_inp_12k8 + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + ELSE + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS ); + Sample_Delay_LP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ); + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( EQ_16( st_fx->element_mode, IVAS_CPE_TD ) ) + { + Sample_Delay_HP = NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS + DELAY_FIR_RESAMPL_NS - DELAY_CLDFB_NS - L_MEM_RECALC_TBE_NS ); + } + Sample_Delay_HP = sub( Sample_Delay_HP, NS2SA( 16000, DELAY_FIR_RESAMPL_NS ) ); + } + IF( GT_16( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ) + { + Copy_Scale_sig( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP, sub( hBWE_FD->prev_Q_input_lp, q_old_inp_16k ) ); + } + ELSE + { + Scale_sig( hBWE_FD->old_input_lp_fx, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ), sub( q_old_inp_16k, hBWE_FD->prev_Q_input_lp ) ); + hBWE_FD->prev_Q_input_lp = q_old_inp_16k; + Copy( old_inp_16k + sub( L_INP_MEM + L_FRAME, Sample_Delay_LP ), hBWE_FD->old_input_lp_fx, Sample_Delay_LP ); + } + } + + tmp = sub( L_LOOK_16k + L_SUBFR16k, Sample_Delay_HP ); + Copy( &hBWE_TD->old_speech_shb_fx[tmp], hBWE_FD->new_input_hp_fx, Sample_Delay_HP ); + add( 0, 0 ); + + IF( NE_16( st_fx->last_extl, WB_BWE ) ) + { + hBWE_FD->prev_mode = NORMAL; + move16(); + hBWE_FD->modeCount = 0; + move16(); + } + hBWE_FD->EnergyLF_fx = L_deposit_l( 0 ); + hBWE_FD->prev_L_swb_norm1 = 8; + move16(); /*8.0 in Q0 */ + st_fx->EnergyLT_fx_exp = 30; + move16(); /* Set to a High Exponent so it is 1^-30 */ + } + /*---------------------------------------------------------------------* + * band-width switching from WB -> SWB/FB + *---------------------------------------------------------------------*/ + IF( GT_16( st_fx->element_mode, EVS_MONO ) ) + { + IF( st_fx->bwidth_sw_cnt == 0 ) + { + IF( GE_16( st_fx->bwidth, SWB ) && EQ_16( st_fx->last_bwidth, WB ) ) + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + } + } + ELSE + { + st_fx->bwidth_sw_cnt = add( st_fx->bwidth_sw_cnt, 1 ); + + IF( EQ_16( st_fx->bwidth_sw_cnt, BWS_TRAN_PERIOD ) ) + { + st_fx->bwidth_sw_cnt = 0; + move16(); + } + } + } + + return; +} +#endif /*---------------------------------------------------------------------* * core_switching_post_enc() diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 86e0bd27388ec1303c7ebe6616b0f2bab942f797..5dc4290c0516494c0afb783992292cb18c5180a5 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -263,6 +263,147 @@ void configureFdCngEnc( return; } +#ifdef IVAS_FLOAT_FIXED +void configureFdCngEnc_ivas_fx( + HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */ + const Word16 bwidth, + const Word32 total_brate ) +{ + HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom; + Word16 psizeDec[NPART]; + Word16 psizeDec_norm[NPART]; + Word16 psizeDec_norm_exp; + Word16 psize_invDec[NPART]; + + set16_fx( psizeDec, 0, NPART ); + + hsCom->CngBandwidth = bwidth; + move16(); + IF( EQ_16( hsCom->CngBandwidth, FB ) ) + { + hsCom->CngBandwidth = SWB; + move16(); + } + hsCom->CngBitrate = total_brate; + move32(); + + /* NB configuration */ + IF( EQ_16( bwidth, NB ) ) + { + hsCom->FdCngSetup = FdCngSetup_nb; /* PTR assignation -> no move needed*/ + move16(); + } + + /* WB configuration */ + ELSE IF( EQ_16( bwidth, WB ) ) + { + /* FFT 6.4kHz, no CLDFB */ + IF( LE_32( total_brate, ACELP_8k00 ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb1; + move16(); + } + /* FFT 6.4kHz, CLDFB 8.0kHz */ + ELSE IF( LE_32( total_brate, ACELP_13k20 ) ) + { + hsCom->FdCngSetup = FdCngSetup_wb2; + move16(); + } + /* FFT 8.0kHz, no CLDFB */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_wb3; + move16(); + } + } + + /* SWB/FB configuration */ + ELSE + { + /* FFT 6.4kHz, CLDFB 14kHz */ + IF( LE_32( total_brate, ACELP_13k20 ) ) + { + hsCom->FdCngSetup = FdCngSetup_swb1; + move16(); + } + /* FFT 8.0kHz, CLDFB 16kHz */ + ELSE + { + hsCom->FdCngSetup = FdCngSetup_swb2; + move16(); + } + } + hsCom->fftlen = hsCom->FdCngSetup.fftlen; + move16(); + hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; + move16(); + + /* Configure the SID quantizer and the Confort Noise Generator */ + + hFdCngEnc->startBandDec = hsCom->startBand; + move16(); + hFdCngEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); + move16(); + initPartitions( hsCom->FdCngSetup.sidPartitions, + hsCom->FdCngSetup.numPartitions, + hFdCngEnc->startBandDec, + hFdCngEnc->stopBandDec, + hFdCngEnc->partDec, + &hFdCngEnc->npartDec, + hFdCngEnc->midbandDec, + psizeDec, + psizeDec_norm, + &psizeDec_norm_exp, + psize_invDec, + 0 ); + IF( EQ_16( hFdCngEnc->stopFFTbinDec, 160 ) ) + { + hFdCngEnc->nFFTpartDec = 17; + move16(); + } + ELSE IF( EQ_16( hFdCngEnc->stopFFTbinDec, 256 ) ) + { + hFdCngEnc->nFFTpartDec = 20; + move16(); + } + ELSE + { + hFdCngEnc->nFFTpartDec = 21; + move16(); + } + + switch ( hsCom->fftlen ) + { + case 512: +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hsCom->fftSineTab_flt = NULL; + hsCom->olapWinAna_flt = olapWinAna512; + hsCom->olapWinSyn_flt = olapWinSyn256; +#endif + hsCom->fftSineTab_fx = NULL; + hsCom->olapWinAna_fx = olapWinAna512_fx; + hsCom->olapWinSyn_fx = olapWinSyn256_fx; + break; + case 640: +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hsCom->fftSineTab_flt = fftSineTab640; + hsCom->olapWinAna_flt = olapWinAna640; + hsCom->olapWinSyn_flt = olapWinSyn320; +#endif + hsCom->fftSineTab_fx = fftSineTab640_fx; + hsCom->olapWinAna_fx = olapWinAna640_fx; + hsCom->olapWinSyn_fx = olapWinSyn320_fx; + break; + default: + assert( !"Unsupported FFT length for FD-based CNG" ); + break; + } + hsCom->frameSize = shr( hsCom->fftlen, 1 ); + move16(); + + return; +} +#endif /*-------------------------------------------------------------------* * deleteFdCngEnc() diff --git a/lib_enc/gs_enc_fx.c b/lib_enc/gs_enc_fx.c index e2d1f4aa9233138ef1fddfc9d493a4d14466b89d..95557d238f21bdf285278953622cf26a0cd75d91 100644 --- a/lib_enc/gs_enc_fx.c +++ b/lib_enc/gs_enc_fx.c @@ -7,6 +7,7 @@ #include "rom_com_fx.h" #include "rom_com.h" //#include "prot_fx.h" +#include "prot.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ @@ -648,6 +649,301 @@ void gsc_enc_fx( return; } + +#ifdef IVAS_FLOAT_FIXED +void gsc_enc_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + Word16 res_dct_in_fx[], + /* i : dct of residual signal */ // Q_exc + Word16 exc_dct_in_fx[], + /* i/o: dct of pitch-only excitation / total excitation */ // Q_exc + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + const Word16 *lsf_new_fx, + /* i : ISFs at the end of the frame */ // Q15 + Word16 *exc_wo_nf_fx, + /* o : excitation (in f domain) without noisefill */ // Q_exc + Word16 *tmp_noise_fx, /* o : long-term noise energy */ + Word16 *Q_exc ) +{ + Word16 i; + GSC_ENC_HANDLE hGSCEnc; + BSTR_ENC_HANDLE hBstr; + Word16 exc_diffQ_fx[L_FRAME16k]; + Word16 exc_diff_fx[L_FRAME16k]; + Word16 bit; + Word16 nb_subbands; + Word16 pvq_len; + Word16 bits_per_bands[MBANDS_GN_BITALLOC16k]; /*Q3*/ + Word16 tmp_band; + Word16 concat_in_fx[L_FRAME16k]; + Word16 concat_out_fx[L_FRAME16k]; + Word16 max_ener_band[MBANDS_GN_BITALLOC16k], j; + Word16 Ener_per_bd_iQ_fx[MBANDS_GN16k]; + Word16 last_bin; + Word16 bitallocation_band[MBANDS_GN_BITALLOC16k]; + Word16 bitallocation_exc[2]; + Word16 npulses[NB_SFM]; + Word16 maxpulse[NB_SFM]; + Word16 mean_gain_fx; + Word16 seed_init; + Word32 L_tmp; + Word16 max_eq; + + /*--------------------------------------------------------------------------------------* + * Initialization + *--------------------------------------------------------------------------------------*/ + + hGSCEnc = st->hGSCEnc; + hBstr = st->hBstr; + + bit = bits_used; + move16(); + + test(); + test(); + test(); + if ( st->coder_type == INACTIVE && ( EQ_16( st->tdm_LRTD_flag, 1 ) || EQ_16( st->element_mode, IVAS_SCE ) ) && LE_32( st->core_brate, GSC_LRES_GAINQ_LIMIT ) ) + { + bit = add( bit, GSC_LRES_NB_NITS ); + } + + set16_fx( exc_diffQ_fx, 0, st->L_frame ); + set16_fx( Ener_per_bd_iQ_fx, 0, MBANDS_GN16k ); + + /*--------------------------------------------------------------------------------------* + * Calculate the difference between the residual spectrum and the spectrum of adaptive excitation + * (non valuable temporal content present in exc_dct_in is already zeroed) + *--------------------------------------------------------------------------------------*/ + + v_sub_16( res_dct_in_fx, exc_dct_in_fx, exc_diff_fx, st->L_frame ); + exc_diff_fx[0] = 0; + move16(); + + /*--------------------------------------------------------------------------------------* + * Multiply the difference spectrum with the normalized spectral shape of the residual signal + * This improves the stability of the differnece spectrum since the spectral shape of the + * residual signal is less suseptible to rapid changes than the difference spectrum + *--------------------------------------------------------------------------------------*/ + + IF( Diff_len == 0 ) + { + tmp_band = 0; + } + ELSE + { + tmp_band = hGSCEnc->mem_last_pit_band; + } + move16(); + + Ener_per_band_comp_ivas_fx_2( exc_diff_fx, Ener_per_bd_iQ_fx, *Q_exc, MBANDS_GN, 1, st->L_frame ); + + /*--------------------------------------------------------------------------------------* + * Gain quantizaion + *--------------------------------------------------------------------------------------*/ + + i = 0; + move16(); + + WHILE( LT_16( i, SIZE_BRATE_INTERMED_TBL ) ) + { + IF( LE_32( st->core_brate, brate_intermed_tbl[i] ) ) + { + break; + } + i = add( i, 1 ); + } + + test(); + test(); + test(); + IF( st->element_mode > EVS_MONO && EQ_16( st->coder_type, AUDIO ) && + LE_32( st->core_brate, STEREO_GSC_BIT_RATE_ALLOC ) && EQ_32( brate_intermed_tbl[i], ACELP_9k60 ) ) /* Bit allocation should be mapped to 8 kb/s instead of 9.6 kb/s in this case */ + { + i = sub( i, 1 ); + } + + mean_gain_fx = gsc_gainQ_ivas_fx( hBstr, st->element_mode, st->idchan, Ener_per_bd_iQ_fx, Ener_per_bd_iQ_fx, brate_intermed_tbl[i], st->coder_type, st->bwidth, st->L_frame, st->tdm_LRTD_flag, st->core_brate ); + + *tmp_noise_fx = mult( mean_gain_fx, 20480 ); // 20480 => 10 in Q11 + move16(); // Q8 + + /*--------------------------------------------------------------------------------------* + * PVQ encoder + *--------------------------------------------------------------------------------------*/ + + bands_and_bit_alloc_ivas_fx( hGSCEnc->cor_strong_limit, hGSCEnc->noise_lev, st->core_brate, Diff_len, bit, &bit, Ener_per_bd_iQ_fx, max_ener_band, bits_per_bands, &nb_subbands, exc_diff_fx, concat_in_fx, &pvq_len, st->coder_type, st->bwidth, st->GSC_noisy_speech, st->L_frame, st->element_mode, st->GSC_IVAS_mode ); + + set16_fx( npulses, 0, NB_SFM ); + + IF( bit == 0 ) + { + set16_fx( concat_out_fx, 0, L_FRAME16k ); + } + ELSE + { + Word16 Q_concat = Q12; + move16(); + bit = sub( bit, pvq_core_enc_ivas_fx( hBstr, concat_in_fx, concat_out_fx, &Q_concat, bit, nb_subbands, gsc_sfm_start, gsc_sfm_end, gsc_sfm_size, bits_per_bands, NULL, npulses, maxpulse, ACELP_CORE ) ); + } + + /* write unused bits */ + WHILE( bit > 0 ) + { + i = s_min( bit, 16 ); + push_indice( hBstr, IND_UNUSED, 0, i ); + bit = sub( bit, i ); + } + + /* Reorder Q bands */ + last_bin = 0; + move16(); + set16_fx( bitallocation_band, 0, MBANDS_GN_BITALLOC16k ); + seed_init = 0; + move16(); + + max_eq = 0; + move16(); + + test(); + test(); + test(); + test(); + IF( ( ( ( LT_32( st->core_brate, ACELP_7k20 ) && EQ_16( st->GSC_noisy_speech, 1 ) ) || LT_32( st->core_brate, 6000 ) ) && LE_16( st->coder_type, UNVOICED ) ) || GE_16( st->GSC_IVAS_mode, 1 ) ) + { + j = emaximum_fx( Q12, concat_out_fx, shl( nb_subbands, 4 ), &L_tmp ); + IF( LE_16( add( abs_s( concat_out_fx[j] ), 41 /* 0.01f in Q12 */ ), ONE_IN_Q12 ) ) + { + max_eq = 32767; + move16(); + } + ELSE + { + max_eq = div_s( ONE_IN_Q12, add( abs_s( concat_out_fx[j] ), 41 /* 0.01f in Q12 */ ) ); + } + } + + FOR( j = 0; j < nb_subbands; j++ ) + { + Copy( concat_out_fx + i_mult( j, 16 ), exc_diffQ_fx + i_mult( max_ener_band[j], 16 ), 16 ); + + IF( GT_16( max_ener_band[j], last_bin ) ) + { + last_bin = max_ener_band[j]; + move16(); + } + + bitallocation_band[max_ener_band[j]] = 1; + move16(); + + seed_init = add( seed_init, npulses[j] ); + } + test(); + IF( NE_16( st->last_coder_type, AUDIO ) /* First audio frame */ + && NE_16( st->last_coder_type, UNVOICED ) ) /* last_coder_type == INACTIVE is overwritten in update_enc to UNVOICED */ + { + FOR( j = 0; j < nb_subbands * 16; j++ ) + { + IF( concat_out_fx[j] > 0 ) + { + seed_init = (Word16) L_mult0( seed_init, 8 ); + move16(); + } + IF( concat_out_fx[j] < 0 ) + { +#ifdef FIX_1027_GSC_INT_OVERFLOW + seed_init = (Word16) L_add( seed_init, 3 ); +#else + seed_init += 3; +#endif + move16(); + } + } + + hGSCEnc->seed_tcx = seed_init; + move16(); + } + + test(); + IF( EQ_32( st->core_brate, ACELP_8k00 ) && st->bwidth != NB ) + { + bitallocation_exc[0] = 0; + move16(); + bitallocation_exc[1] = 0; + move16(); + + if ( exc_diffQ_fx[L_FRAME8k - 2] != 0 ) + { + bitallocation_exc[0] = 1; + move16(); + } + + if ( exc_diffQ_fx[L_FRAME8k - 1] != 0 ) + { + bitallocation_exc[1] = 1; + move16(); + } + } + + /*--------------------------------------------------------------------------------------* + * Skip adaptive (pitch) contribution frequency band (no noise added over the adaptive (pitch) contribution) + * Find x pulses between 1.6-3.2kHz to code in the spectrum of the residual signal + * Gain is based on the inter-correlation gain between the pulses found and residual signal + *--------------------------------------------------------------------------------------*/ + + test(); + test(); + test(); + IF( st->GSC_IVAS_mode >= 1 && st->GSC_noisy_speech == 1 ) + { + FOR( i = 64; i < st->L_frame; i++ ) + { + exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); + move16(); + } + } + ELSE IF( st->core_brate < ACELP_7k20 && st->GSC_noisy_speech == 1 && st->coder_type <= UNVOICED ) + { + FOR( i = 0; i < L_FRAME; i++ ) + { + exc_diffQ_fx[i] = mult( exc_diffQ_fx[i], max_eq ); + move16(); + } + } + ELSE + { + freq_dnw_scaling_fx( hGSCEnc->cor_strong_limit, st->coder_type, hGSCEnc->noise_lev, st->core_brate, exc_diffQ_fx, Q12, st->L_frame ); + } + + Word16 Q_exc_new = s_min( *Q_exc, hGSCEnc->Q_last_exc_dct_in ); + IF( NE_16( Q_exc_new, hGSCEnc->Q_last_exc_dct_in ) ) + { + Scale_sig( hGSCEnc->last_exc_dct_in_fx, st->L_frame, sub( Q_exc_new, hGSCEnc->Q_last_exc_dct_in ) ); + hGSCEnc->Q_last_exc_dct_in = Q_exc_new; + move16(); + } + ELSE + { + Scale_sig( exc_dct_in_fx, st->L_frame, sub( Q_exc_new, *Q_exc ) ); + *Q_exc = Q_exc_new; + move16(); + } + + /*--------------------------------------------------------------------------------------* + * Estimate noise level + *--------------------------------------------------------------------------------------*/ + highband_exc_dct_in_ivas_fx( st->core_brate, mfreq_bindiv_loc, last_bin, Diff_len, hGSCEnc->noise_lev, tmp_band, exc_diffQ_fx /* Q12 */, &hGSCEnc->seed_tcx, Ener_per_bd_iQ_fx, nb_subfr, exc_dct_in_fx /* Q_exc */, + st->last_coder_type, bitallocation_band, lsf_new_fx /* x2.56 */, hGSCEnc->last_exc_dct_in_fx /* Q_exc */, &hGSCEnc->last_ener_fx /* Q0 */, hGSCEnc->last_bitallocation_band, bitallocation_exc, 0, st->coder_type, + st->bwidth, exc_wo_nf_fx, Q12, Q_exc, st->GSC_noisy_speech, NULL, st->L_frame, st->element_mode, st->GSC_IVAS_mode ); + + exc_dct_in_fx[0] = 0; + move16(); + + return; +} +#endif + /*======================================================================*/ /* FUNCTION : edyn_fx() */ /*----------------------------------------------------------------------*/ diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 75e39103e787f9d1d25a67a5853a958477e5994f..31e075fd766ec928031c8437a7c06cd407fe7982 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -218,6 +218,10 @@ ivas_error init_encoder( st->stab_fac = 0.0f; +#ifdef IVAS_FLOAT_FIXED + st->stab_fac_fx = 0; + move16(); +#endif /* Bass post-filter memories - encoder side of MODE2 */ st->bpf_off = 0; st->pst_mem_deemp_err = 0.0f; diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index b32bb81183549db3a798b14cc9810492b8c92381..eb369c78a7a99ee4826e2d9165db3a7671a8a588 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -247,8 +247,40 @@ ivas_error ivas_core_enc( * Preprocessing (preparing) for ACELP/HQ core switching *---------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 last_core = st->last_core; + Word16 bwidth_sw_cnt = st->bwidth_sw_cnt; + floatToFixed_arr16( st->lsp_old, st->lsp_old_fx, 15, M ); + + Word16 q_old_inp_16k_fx; + Word16 q_old_inp_12k8_fx; + Word16 old_inp_16k_fx[L_INP]; + Word16 old_inp_12k8_fx[L_INP_12k8]; + + q_old_inp_12k8_fx = Q_factor_arr( old_inp_12k8[n], L_INP_12k8 ); + q_old_inp_16k_fx = Q_factor_arr( old_inp_16k[n], L_INP ); + + if ( st->hBWE_FD != NULL ) + { + st->hBWE_FD->prev_Q_input_lp = Q_factor_arr( st->hBWE_FD->old_input_lp, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ) ); + floatToFixed_arr16( st->hBWE_FD->old_input_lp, st->hBWE_FD->old_input_lp_fx, st->hBWE_FD->prev_Q_input_lp, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ) ); + } + + floatToFixed_arr16( old_inp_12k8[n], old_inp_12k8_fx, q_old_inp_12k8_fx, L_INP_12k8 ); + floatToFixed_arr16( old_inp_16k[n], old_inp_16k_fx, q_old_inp_16k_fx, L_INP ); + + core_switching_pre_enc( st, old_inp_12k8[n], old_inp_16k[n], sts[0]->active_cnt, last_element_mode ); + + st->last_core = last_core; + st->bwidth_sw_cnt = bwidth_sw_cnt; +#endif + +#ifdef IVAS_FLOAT_FIXED + core_switching_pre_enc_ivas_fx( st, old_inp_12k8_fx, q_old_inp_12k8_fx, old_inp_16k_fx, q_old_inp_16k_fx, sts[0]->active_cnt, last_element_mode ); +#endif + /*---------------------------------------------------------------------* * ACELP core encoding * TCX core encoding diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 03f93318436647a79e760e44856925a556571b56..50123f85702d0b21526a4d4fa0a1f4e14ebf91e3 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -39,6 +39,7 @@ #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" +#include "prot_fx.h" /*-------------------------------------------------------------------* @@ -141,7 +142,11 @@ ivas_error pre_proc_ivas( if ( st->hFdCngEnc != NULL && st->element_mode != IVAS_CPE_MDCT && ( ( st->hFdCngEnc->hFdCngCom->frameSize != st->L_frame ) || ( st->hFdCngEnc->hFdCngCom->CngBandwidth != st->input_bwidth ) ) ) { +#ifdef IVAS_FLOAT_FIXED + configureFdCngEnc_ivas_fx( st->hFdCngEnc, max( st->input_bwidth, WB ), st->L_frame == L_FRAME16k ? ACELP_16k40 : ACELP_9k60 ); +#else configureFdCngEnc( st->hFdCngEnc, max( st->input_bwidth, WB ), st->L_frame == L_FRAME16k ? ACELP_16k40 : ACELP_9k60 ); +#endif } if ( st->ini_frame == 0 ) @@ -236,7 +241,59 @@ ivas_error pre_proc_ivas( /* Configure TCX with the same bitrate as given when (re-)initializing TCX */ total_brate_tmp = st->total_brate; st->total_brate = st->bits_frame_nominal * FRAMES_PER_SEC; +#ifdef IVAS_FLOAT_FIXED + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( NE_32( st->last_bits_frame_nominal * FRAMES_PER_SEC, st->total_brate ) ) || + ( NE_16( st->last_bwidth, st->bwidth ) ) || + ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || + ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || + ( NE_16( st->rf_mode_last, st->rf_mode ) ) || + ( GT_16( st->element_mode, EVS_MONO ) && st->ini_frame == 0 ) ) + { + Word16 bSwitchFromAmrwbIO = 0, switchWB = 0, fscale; + Word32 sr_core; + move16(); + move16(); + + IF( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + fscale = sr2fscale_fx( sr_core ); + IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) + { + st->hTcxCfg->bandwidth_flt = getTcxBandwidth_flt( st->bwidth ); + } + IF( st->envWeighted && !st->enableTcxLpc ) + { + /* Unweight the envelope */ + floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); + st->gamma = (Word16) floatToFixed( st->gamma_flt, Q14 ); + } + } +#endif + SetModeIndex_ivas_fx( st, st->last_bits_frame_nominal * FRAMES_PER_SEC, last_element_mode, MCT_flag ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IF( st->envWeighted && !st->enableTcxLpc ) + { + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); + fixedToFloat_arr( st->lsf_old_fx, st->lsf_old, Q15, M ); + } +#endif +#else SetModeIndex( st, st->last_bits_frame_nominal * FRAMES_PER_SEC, last_element_mode, MCT_flag ); +#endif st->sr_core = getCoreSamplerateMode2_flt( element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); st->total_brate = total_brate_tmp; @@ -282,7 +339,58 @@ ivas_error pre_proc_ivas( { if ( st->core_brate != FRAME_NO_DATA ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + IF( ( NE_32( imult1616( st->last_bits_frame_nominal, FRAMES_PER_SEC ), st->total_brate ) ) || + ( NE_16( st->last_bwidth, st->bwidth ) ) || + ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || + ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || + ( NE_16( st->rf_mode_last, st->rf_mode ) ) || + ( GT_16( st->element_mode, EVS_MONO ) && st->ini_frame == 0 ) ) + { + Word16 bSwitchFromAmrwbIO = 0, switchWB = 0, fscale; + Word32 sr_core; + move16(); + move16(); + + IF( EQ_16( st->last_core, AMR_WB_CORE ) ) + { + bSwitchFromAmrwbIO = 1; + move16(); + } + sr_core = getCoreSamplerateMode2( st->element_mode, st->total_brate, st->bwidth, st->flag_ACELP16k, st->rf_mode, st->is_ism_format ); + fscale = sr2fscale_fx( sr_core ); + IF( EQ_32( fscale, st->fscale ) && !bSwitchFromAmrwbIO && !switchWB ) + { + st->hTcxCfg->bandwidth_flt = getTcxBandwidth_flt( st->bwidth ); + } + IF( st->envWeighted && !st->enableTcxLpc ) + { + /* Unweight the envelope */ + floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); + st->gamma = (Word16) floatToFixed( st->gamma_flt, Q14 ); + } + } +#endif + SetModeIndex_ivas_fx( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + IF( st->envWeighted && !st->enableTcxLpc ) + { + fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); + fixedToFloat_arr( st->lsf_old_fx, st->lsf_old, Q15, M ); + } +#endif +#else SetModeIndex( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); +#endif } if ( st->extl != -1 && st->extl != IGF_BWE && st->igf == 1 ) diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index b4cc9b9024374a1245b86a2afac335f51514a148..5167fe3f3bffcab1708f19f9ca08ccbed435c34c 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -76,13 +76,16 @@ ivas_error ivas_cpe_enc( CPE_ENC_HANDLE hCPE; Encoder_State **sts; int16_t n, n_CoreChannels; +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float old_inp_12k8[CPE_CHANNELS][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ + float old_inp_16k[CPE_CHANNELS][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ +#else float old_inp_12k8[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ -#ifdef IVAS_FLOAT_FIXED - Word32 old_inp_12k8_fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ #endif - float old_inp_16k[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ #ifdef IVAS_FLOAT_FIXED - Word32 old_inp_16k_fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ + Word32 old_inp_12k8_fx[CPE_CHANNELS][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + Word32 old_inp_16k_fx[CPE_CHANNELS][L_INP]; /* buffer of input signal @ 16kHz */ #endif float ener[CPE_CHANNELS]; /* residual energy from Levinson-Durbin */ float relE[CPE_CHANNELS]; /* frame relative energy */ diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 5d40b769072bc2f7be462dcfd33d8f6c4fdca8ce..80ace46765266d44ec4818bfa9f1a6e6d735873c 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -430,8 +430,13 @@ ivas_error ivas_ism_enc( SCE_ENC_HANDLE hSCE; Encoder_State *st; Word16 sce_id; - float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ - float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP]; /* buffer of input signal @ 16kHz */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ + float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ +#else + float old_inp_12k8[MAX_NUM_OBJECTS][1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[MAX_NUM_OBJECTS][1][L_INP]; /* buffer of input signal @ 16kHz */ +#endif Word16 vad_flag[MAX_NUM_OBJECTS]; /* VAD flag */ float ener[MAX_NUM_OBJECTS][1]; /* residual energy from Levinson-Durbin */ float relE[MAX_NUM_OBJECTS][1]; /* frame relative energy */ diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index ba641ef8618eef4e669e8a957320bf1618c5d658..9bf39785e2234827e1c2f5621d0bb83ab1ad4172 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -56,6 +56,72 @@ #define SILENT_CHANNEL_THRES 100 +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------* + * enc_prm_pre_mdct_fx() + * + * encode all side parameters up to MDCT whitening + *---------------------------------------------------------------*/ + +static void enc_prm_pre_mdct_fx( + Encoder_State *st, /* i/o: encoder state structure */ + Word16 param[], /* i : parameters */ + const Word16 *no_param_tns, /* i : number of TNS parameters per subframe */ + Word16 p_param[2], /* o : pointer to parameters for next round of bs writing */ + const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ + BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ +) +{ + Word16 nbits_start; + + nbits_start = hBstr->nb_bits_tot; + move16(); + + /*--------------------------------------------------------------------------------* + * Header + *--------------------------------------------------------------------------------*/ + + writeTCXMode( st, hBstr, MCT_flag, &nbits_start ); + + /* write last_core for core switching and error concealment */ + push_next_indice( hBstr, st->last_core != ACELP_CORE, 1 ); + + writeTCXWindowing( hBstr, st->hTcxCfg->tcx_curr_overlap_mode ); + IF( EQ_16( st->core, TCX_10_CORE ) ) + { + writeTCXWindowing( hBstr, st->hTcxCfg->tcx_last_overlap_mode ); + } + + IF( st->last_core != ACELP_CORE ) + { + push_next_indice( hBstr, st->hTcxEnc->kernel_type[0], 2 ); + } + ELSE + { + push_next_indice( hBstr, st->hTcxEnc->kernel_type[0], 1 ); + } + + IF( EQ_16( st->core, TCX_10_CORE ) ) + { + assert( ( st->hTcxEnc->kernel_type[0] & 1 ) == ( st->hTcxEnc->kernel_type[1] >> 1 ) ); + push_next_indice( hBstr, st->hTcxEnc->kernel_type[1] & 1, 1 ); + } + + st->glr_reset = 0; + move16(); + + /*--------------------------------------------------------------------------------* + * TCX20/TCX10 parameters + *--------------------------------------------------------------------------------*/ + + writeTCXparam_fx( st, hBstr, NULL, param, 0, 0, 0, no_param_tns, p_param, NULL, 0 ); + + st->side_bits_frame_channel = sub( hBstr->nb_bits_tot, nbits_start ); + move16(); + + return; +} +#else /*--------------------------------------------------------------* * enc_prm_pre_mdct() * @@ -101,22 +167,193 @@ static void enc_prm_pre_mdct( /*--------------------------------------------------------------------------------* * TCX20/TCX10 parameters *--------------------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED writeTCXparam( st, hBstr, NULL, param, 0, 0, 0, no_param_tns, p_param, NULL, 0 ); -#else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); -#endif - - writeTCXparam_fx( st, hBstr, NULL, param, 0, 0, 0, no_param_tns, p_param, NULL, 0 ); -#endif st->side_bits_frame_channel = hBstr->nb_bits_tot - nbits_start; return; } +#endif + +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------* + * kernel_switch_detect_fx() + * + * complex-valued detection method for transform kernel switching + *---------------------------------------------------------------*/ + +static Word16 kernel_switch_detect_fx( + Word32 *sigR0, /* i/o: MDCT samples of the 1st (left) channel */ + Word32 *sigR1, /* i/o: MDCT samples of the 2nd (right) channel */ + Word32 *sigI0, /* i/o: MDST samples of the 1st (left) channel */ + Word32 *sigI1, /* i/o: MDST samples of the 2nd (right) channel */ + const Word16 q_in, /* i : common Q for MDCT and MDST samples */ + const Word16 nSamplesCore, /* i : number of core-coded samples below IGF */ + const Word16 nSamplesMax, /* i : transform length (number of MCLT lines) */ + const Word16 tcxTransType, /* i : TCX transform type (2*5, 1*10, or 1*20) */ + Word16 *switchCovPrev, /* i/o: previous transform's correlation value */ + const UWord32 bitRateMode /* i : stereo bitrate mode (bps * L_frame) */ +) +{ + Word16 maxLength, anaLength, s; + Word32 cov00, cov90, sumR0, sumR1, sumI0, sumI1; + Word64 W_cov00, W_cov90, W_sumR0, W_sumR1, W_sumI0, W_sumI1; + Word16 q_shift, q_com; + Word32 L_tmp, L_tmp1; + Word16 exp_tmp, exp_tmp1; + + test(); + IF( nSamplesCore > 0 && LT_16( nSamplesCore, nSamplesMax ) ) + { + maxLength = nSamplesCore; + move16(); + } + ELSE + { + maxLength = nSamplesMax; + move16(); + } + anaLength = s_min( maxLength, extract_l( UL_and( UL_lshr( bitRateMode, 17 ), 0xFFFE ) ) ); + IF( LT_16( nSamplesMax, 512 ) ) + { + s = 2; /* exclude DC offset */ + move16(); + } + ELSE + { + s = 4; /* exclude DC offset */ + move16(); + } + + W_cov00 = 0; + W_cov90 = 0; + W_sumR0 = 0; + W_sumR1 = 0; + W_sumI0 = 0; + W_sumI1 = 0; + move64(); + move64(); + move64(); + move64(); + move64(); + move64(); + + IF( EQ_16( tcxTransType, TCX_5 ) ) + { + assert( nSamplesMax < 512 ); + anaLength = shr( anaLength, 1 ); + FOR( s = 1; s < anaLength; s++ ) + { + W_cov00 = W_add( W_cov00, W_add( W_mult0_32_32( sigR0[s], sigR1[s] ), W_mult0_32_32( sigI0[s], sigI1[s] ) ) ); + W_cov90 = W_add( W_cov90, W_sub( W_mult0_32_32( sigR0[s], sigI1[s] ), W_mult0_32_32( sigI0[s], sigR1[s] ) ) ); + W_sumR0 = W_add( W_sumR0, W_mult0_32_32( sigR0[s], sigR0[s] ) ); + W_sumR1 = W_add( W_sumR1, W_mult0_32_32( sigR1[s], sigR1[s] ) ); + W_sumI0 = W_add( W_sumI0, W_mult0_32_32( sigI0[s], sigI0[s] ) ); + W_sumI1 = W_add( W_sumI1, W_mult0_32_32( sigI1[s], sigI1[s] ) ); + } + anaLength = add( anaLength, shr( nSamplesMax, 1 ) ); + s = add( 1, shr( nSamplesMax, 1 ) ); /* 2nd TCX-5 spectrum is stacked onto 1st */ + } + FOR( ; s < anaLength; s++ ) + { + W_cov00 = W_add( W_cov00, W_add( W_mult0_32_32( sigR0[s], sigR1[s] ), W_mult0_32_32( sigI0[s], sigI1[s] ) ) ); + W_cov90 = W_add( W_cov90, W_sub( W_mult0_32_32( sigR0[s], sigI1[s] ), W_mult0_32_32( sigI0[s], sigR1[s] ) ) ); + W_sumR0 = W_add( W_sumR0, W_mult0_32_32( sigR0[s], sigR0[s] ) ); + W_sumR1 = W_add( W_sumR1, W_mult0_32_32( sigR1[s], sigR1[s] ) ); + W_sumI0 = W_add( W_sumI0, W_mult0_32_32( sigI0[s], sigI0[s] ) ); + W_sumI1 = W_add( W_sumI1, W_mult0_32_32( sigI1[s], sigI1[s] ) ); + } + + /* Convert back to 32-bit resolution */ + q_shift = W_norm( W_cov00 ); + q_shift = s_min( q_shift, W_norm( W_cov90 ) ); + q_shift = s_min( q_shift, W_norm( W_sumR0 ) ); + q_shift = s_min( q_shift, W_norm( W_sumR1 ) ); + q_shift = s_min( q_shift, W_norm( W_sumI0 ) ); + q_shift = s_min( q_shift, W_norm( W_sumI1 ) ); + cov00 = W_extract_l( W_shl( W_cov00, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + cov90 = W_extract_l( W_shl( W_cov90, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + sumR0 = W_extract_l( W_shl( W_sumR0, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + sumR1 = W_extract_l( W_shl( W_sumR1, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + sumI0 = W_extract_l( W_shl( W_sumI0, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + sumI1 = W_extract_l( W_shl( W_sumI1, sub( q_shift, 32 ) ) ); // 2 * q_in + q_shift - 32 + q_com = add( shl( q_in, 1 ), sub( q_shift, 32 ) ); + + // cov00 /= ( sqrtf( sumR0 * sumR1 ) + sqrtf( sumI0 * sumI1 ) + 1.f ); + L_tmp = Mpy_32_32( sumR0, sumR1 ); // 2 * q_com - 31 + exp_tmp = sub( Q31, sub( shl( q_com, 1 ), 31 ) ); + L_tmp = Sqrt32( L_tmp, &exp_tmp ); + L_tmp1 = Mpy_32_32( sumI0, sumI1 ); // 2 * q_com - 31 + exp_tmp1 = sub( Q31, sub( shl( q_com, 1 ), 31 ) ); + L_tmp1 = Sqrt32( L_tmp1, &exp_tmp1 ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, L_tmp1, exp_tmp1, &exp_tmp ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, ONE_IN_Q30, 1, &exp_tmp ); + cov00 = BASOP_Util_Divide3232_Scale_cadence( cov00, L_tmp, &exp_tmp1 ); + exp_tmp = add( exp_tmp1, sub( sub( Q31, q_com ), exp_tmp ) ); + /* Added saturation to handle overflows when value is very close to 1.f */ + cov00 = L_shl_sat( cov00, exp_tmp ); // Q31 + + // cov90 /= ( sqrtf( sumR0 * sumI1 ) + sqrtf( sumI0 * sumR1 ) + 1.f ); + L_tmp = Mpy_32_32( sumR0, sumI1 ); // 2 * q_com - 31 + exp_tmp = sub( Q31, sub( shl( q_com, 1 ), 31 ) ); + L_tmp = Sqrt32( L_tmp, &exp_tmp ); + L_tmp1 = Mpy_32_32( sumI0, sumR1 ); // 2 * q_com - 31 + exp_tmp1 = sub( Q31, sub( shl( q_com, 1 ), 31 ) ); + L_tmp1 = Sqrt32( L_tmp1, &exp_tmp1 ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, L_tmp1, exp_tmp1, &exp_tmp ); + L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, exp_tmp, ONE_IN_Q30, 1, &exp_tmp ); + cov90 = BASOP_Util_Divide3232_Scale_cadence( cov90, L_tmp, &exp_tmp1 ); + exp_tmp = add( exp_tmp1, sub( sub( Q31, q_com ), exp_tmp ) ); + /* Added saturation to handle overflows when value is very close to 1.f */ + cov90 = L_shl_sat( cov90, exp_tmp ); // Q31 + + sumI0 = L_max( 0, L_sub( L_abs( cov90 ), L_abs( cov00 ) ) ); // Q31 + IF( switchCovPrev != NULL ) + { + sumI1 = L_abs( L_deposit_h( *switchCovPrev ) ); // Q31 + } + ELSE + { + sumI1 = 0; // Q31 + move32(); + } + + IF( cov90 < 0 ) + { + s = -1; + move16(); + } + ELSE + { + s = 1; + move16(); + } + + IF( switchCovPrev != NULL ) /* update the decision smoothing history */ + { + IF( cov90 < 0 ) + { + *switchCovPrev = round_fx( L_negate( Madd_32_32( Mpy_32_32( 1879048192 /* 0.875f in Q31 */, sumI1 ), 268435456 /* 0.125f in Q31 */, sumI0 ) ) ); // Q15 + move16(); + } + ELSE + { + *switchCovPrev = round_fx( Madd_32_32( Mpy_32_32( 1879048192 /* 0.875f in Q31 */, sumI1 ), 268435456 /* 0.125f in Q31 */, sumI0 ) ); // Q15 + move16(); + } + } + + test(); + test(); + IF( ( GT_32( sumI0, L_sub( 1073741824 /* 0.5f in Q31 */, Mpy_32_32( 536870912 /* 0.25f in Q31 */, sumI1 ) ) ) || GT_32( L_abs( cov90 ), L_sub( 1610612736 /* 0.75f in Q31 */, Mpy_32_32( 1073741824 /* 0.5f in Q31 */, sumI1 ) ) ) ) && GT_32( sumI1, 134217728 /* 0.0625f in Q31 */ ) ) + { + return s; /* final decision */ + } + return 0; /* final decision */ +} +#else /*--------------------------------------------------------------* * kernel_switch_detect() * @@ -188,6 +425,7 @@ static int16_t kernel_switch_detect( return ( ( sumI0 > 0.5f - 0.25f * sumI1 || fabsf( cov90 ) > 0.75f - 0.5f * sumI1 ) && ( sumI1 > 0.0625f ) ? s : 0 ); /* final decision */ } +#endif static void kernel_switch_trafo( @@ -634,6 +872,8 @@ void ivas_mdct_core_whitening_enc( int16_t zero_side_flag[NB_DIV]; #ifdef IVAS_FLOAT_FIXED_CONVERSIONS Word16 q_com; + Word32 mdst_spectrum_fx[CPE_CHANNELS][NB_DIV][2 * L_FRAME48k]; + Word16 mdst_spectrum_e[CPE_CHANNELS][NB_DIV]; #endif push_wmops( "mdct_core_whitening" ); @@ -782,7 +1022,11 @@ void ivas_mdct_core_whitening_enc( hTcxEnc0 = sts[0]->hTcxEnc; hTcxEnc1 = sts[1]->hTcxEnc; +#ifdef IVAS_FLOAT_FIXED + init_tcx_enc_info_fx( sts[0], &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#else init_tcx_enc_info( sts[0], &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#endif if ( nSampCore == 0 ) { @@ -799,9 +1043,31 @@ void ivas_mdct_core_whitening_enc( { if ( hTcxEnc0->transform_type[n] == hTcxEnc1->transform_type[n] ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_com = L_get_q_buf1( hTcxEnc0->spectrum[n], hTcxEnc0->L_frameTCX / nSubframes ); + q_com = s_min( q_com, L_get_q_buf1( hTcxEnc1->spectrum[n], hTcxEnc1->L_frameTCX / nSubframes ) ); + q_com = s_min( q_com, L_get_q_buf1( mdst_spectrum[0][n], hTcxEnc0->L_frameTCX / nSubframes ) ); + q_com = s_min( q_com, L_get_q_buf1( mdst_spectrum[1][n], hTcxEnc1->L_frameTCX / nSubframes ) ); + + floatToFixed_arrL32( hTcxEnc0->spectrum[n], hTcxEnc0->spectrum_fx[n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); + floatToFixed_arrL32( hTcxEnc1->spectrum[n], hTcxEnc1->spectrum_fx[n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); + floatToFixed_arrL32( mdst_spectrum[0][n], mdst_spectrum_fx[0][n], q_com, hTcxEnc0->L_frameTCX / nSubframes ); + floatToFixed_arrL32( mdst_spectrum[1][n], mdst_spectrum_fx[1][n], q_com, hTcxEnc1->L_frameTCX / nSubframes ); + + hTcxEnc0->kernel_switch_corr_past = float_to_fix16( hTcxEnc0->kernel_switch_corr_past_flt, Q15 ); +#endif + const Word16 switchKernel = /* these 4 transform types can be applied: 0 = MDCT-IV, 1 = MDST-II, 2 = MDCT-II, 3 = MDST-IV */ + kernel_switch_detect_fx( hTcxEnc0->spectrum_fx[n], hTcxEnc1->spectrum_fx[n], mdst_spectrum_fx[0][n], mdst_spectrum_fx[1][n], q_com, nSampCore / nSubframes, + L_subframeTCX / nSubframes, hTcxEnc0->transform_type[n], &hTcxEnc0->kernel_switch_corr_past, ( totalRate * L_subframe ) / nSubframes ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hTcxEnc0->kernel_switch_corr_past_flt = fix16_to_float( hTcxEnc0->kernel_switch_corr_past, Q15 ); +#endif +#else const int16_t switchKernel = /* these 4 transform types can be applied: 0 = MDCT-IV, 1 = MDST-II, 2 = MDCT-II, 3 = MDST-IV */ kernel_switch_detect( hTcxEnc0->spectrum[n], hTcxEnc1->spectrum[n], mdst_spectrum[0][n], mdst_spectrum[1][n], nSampCore / nSubframes, L_subframeTCX / nSubframes, hTcxEnc0->transform_type[n], &hTcxEnc0->kernel_switch_corr_past_flt, ( totalRate * L_subframe ) / nSubframes ); +#endif if ( switchKernel ) /* apply MDST-IV coding in one of the channels */ { hTcxEnc0->kernel_type[n] = ( hTcxEnc0->kernel_symmetry_past ? 3 : 1 ) - max( 0, switchKernel ); @@ -874,7 +1140,11 @@ void ivas_mdct_core_whitening_enc( continue; } +#ifdef IVAS_FLOAT_FIXED + init_tcx_enc_info_fx( sts[ch], &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#else init_tcx_enc_info( sts[ch], &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#endif nSubframes = ( hTcxEncCh->tcxMode == TCX_20 ) ? 1 : NB_DIV; for ( n = 0; n < nSubframes; n++ ) @@ -909,7 +1179,11 @@ void ivas_mdct_core_whitening_enc( set_zero( chE, NB_DIV ); } +#ifdef IVAS_FLOAT_FIXED + init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#else init_tcx_enc_info( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#endif L_subframe = L_subframe / nSubframes; L_subframeTCX = ( mct_on ? L_subframeTCX / nSubframes : L_subframe ); @@ -1047,7 +1321,11 @@ void ivas_mdct_core_whitening_enc( } st = sts[ch]; nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; +#ifdef IVAS_FLOAT_FIXED + init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#else init_tcx_enc_info( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#endif L_subframe = L_subframe / nSubframes; L_subframeTCX = L_subframeTCX / nSubframes; @@ -1080,8 +1358,23 @@ void ivas_mdct_core_whitening_enc( { if ( st->hTcxEnc->transform_type[n] == TCX_5 ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->hTcxEnc->spectrum_e[n] = Q31 - L_get_q_buf1( st->hTcxEnc->spectrum[n], st->hTcxCfg->tcx5SizeFB * 2 ); + floatToFixed_arrL32( st->hTcxEnc->spectrum[n], st->hTcxEnc->spectrum_fx[n], ( Q31 - st->hTcxEnc->spectrum_e[n] ), st->hTcxCfg->tcx5SizeFB * 2 ); + mdst_spectrum_e[ch][n] = Q31 - L_get_q_buf1( mdst_spectrum[ch][n], st->hTcxCfg->tcx5SizeFB * 2 ); + floatToFixed_arrL32( mdst_spectrum[ch][n], mdst_spectrum_fx[ch][n], ( Q31 - mdst_spectrum_e[ch][n] ), st->hTcxCfg->tcx5SizeFB * 2 ); +#endif + tcx5SpectrumDeinterleaving_fx( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum_fx[n] ); + tcx5SpectrumDeinterleaving_fx( st->hTcxCfg->tcx5SizeFB, mdst_spectrum_fx[ch][n] ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arrL32( st->hTcxEnc->spectrum_fx[n], st->hTcxEnc->spectrum[n], ( Q31 - st->hTcxEnc->spectrum_e[n] ), st->hTcxCfg->tcx5SizeFB * 2 ); + fixedToFloat_arrL32( mdst_spectrum_fx[ch][n], mdst_spectrum[ch][n], ( Q31 - mdst_spectrum_e[ch][n] ), st->hTcxCfg->tcx5SizeFB * 2 ); +#endif +#else tcx5SpectrumDeinterleaving( st->hTcxCfg->tcx5SizeFB, st->hTcxEnc->spectrum[n] ); tcx5SpectrumDeinterleaving( st->hTcxCfg->tcx5SizeFB, mdst_spectrum[ch][n] ); +#endif } } } @@ -1098,7 +1391,11 @@ void ivas_mdct_core_whitening_enc( st = sts[ch]; nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; +#ifdef IVAS_FLOAT_FIXED + init_tcx_enc_info_fx( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#else init_tcx_enc_info( st, &L_subframe, &L_subframeTCX, &tcx_subframe_coded_lines ); +#endif L_subframe = L_subframe / nSubframes; L_subframeTCX = L_subframeTCX / nSubframes; @@ -1149,7 +1446,23 @@ void ivas_mdct_core_whitening_enc( continue; } +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); +#endif + test(); + test(); + IF( ( ch > 0 ) && ( add( sts[0]->hTcxEnc->fUseTns[0], sts[0]->hTcxEnc->fUseTns[1] ) > 0 ) && !mct_on ) + { + enc_prm_pre_mdct_fx( st, param_core[ch], tnsSize[ch], p_param[ch], mct_on, hBstr ); + } + ELSE + { + enc_prm_pre_mdct_fx( st, param_core[ch], NULL, p_param[ch], mct_on, hBstr ); + } +#else enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], mct_on, hBstr ); +#endif if ( ch > 0 && sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 && !mct_on ) { @@ -1663,6 +1976,55 @@ void ivas_mdct_quant_coder_fx( } #endif +#ifdef IVAS_FLOAT_FIXED +/*--------------------------------------------------------------* + * init_tcx_enc_info_fx() + * + * Initialize TCX parameters + *---------------------------------------------------------------*/ + +void init_tcx_enc_info_fx( + Encoder_State *st, /* i/o: coder memory state */ + Word16 *L_frame, + Word16 *L_frameTCX, + Word16 *L_spec ) +{ + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + TCX_CONFIG_HANDLE hTcxCfg = st->hTcxCfg; + Word16 tcx_offset, tcx_offsetFB; + + /* Init lengths */ + tcx_offset = hTcxCfg->tcx_offset; + move16(); + tcx_offsetFB = hTcxCfg->tcx_offsetFB; + move16(); + *L_frame = st->L_frame; + move16(); + *L_frameTCX = hTcxEnc->L_frameTCX; + move16(); + *L_spec = st->hTcxCfg->tcx_coded_lines; + move16(); + + IF( st->last_core == ACELP_CORE ) + { + /* if past frame is ACELP */ + *L_frame = add( *L_frame, tcx_offset ); + move16(); + *L_frameTCX = add( *L_frameTCX, tcx_offsetFB ); + move16(); + *L_spec = add( *L_spec, shr( st->hTcxCfg->tcx_coded_lines, 2 ) ); + move16(); + + assert( hTcxCfg->lfacNext <= 0 ); + *L_frame = sub( *L_frame, hTcxCfg->lfacNext ); + move16(); + *L_frameTCX = sub( *L_frameTCX, hTcxCfg->lfacNextFB ); + move16(); + } + + return; +} +#else /*--------------------------------------------------------------* * init_tcx_enc_info() * @@ -1700,3 +2062,4 @@ void init_tcx_enc_info( return; } +#endif diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index c85d39d1ebc2f83378e51ad1efb3d021b17944d6..ef5328d2b9641565559e752c8cf1720dbf1e2b43 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -65,8 +65,13 @@ ivas_error ivas_sce_enc( const int16_t nb_bits_metadata /* i : number of metadata bits */ ) { - float old_inp_12k8[1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ - float old_inp_16k[1][L_INP]; /* buffer of input signal @ 16kHz */ +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversion + float old_inp_12k8[1][L_INP_12k8] = { 0 }; /* buffer of input signal @ 12k8 */ + float old_inp_16k[1][L_INP] = { 0 }; /* buffer of input signal @ 16kHz */ +#else + float old_inp_12k8[1][L_INP_12k8]; /* buffer of input signal @ 12k8 */ + float old_inp_16k[1][L_INP]; /* buffer of input signal @ 16kHz */ +#endif float ener[1]; /* residual energy from Levinson-Durbin */ float relE[1]; /* frame relative energy */ float A[1][NB_SUBFR16k * ( M + 1 )]; /* A(z) unquantized for subframes */ diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index f294a3081646eba1438a4daa8e9d5c4e723b23e0..7da597f49db19f5ad5417f0796555307466949f2 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -1096,6 +1096,10 @@ void stereo_dft_enc_reset_fx( move16(); hStereoDft->dmx_res_all_prev_fx = 1; move32(); +#ifdef MSAN_FIX + hStereoDft->dmx_res_all_prev_fx_e = 31; + move16(); +#endif hStereoDft->last_res_cod_mode_modify_flag = 0; move16(); hStereoDft->res_cod_sw_flag = 0; diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 0c7908c317fcf98a44489f94016ffc587be8d8b2..21250b5e433cedeaa27acc966d76e81012714970 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -291,6 +291,9 @@ void stereo_tcx_core_enc( Word16 A_q_ind[M + 1]; /*for LPC-based AC*/ Word16 lspq_ind[M]; /*for LPC-based AC*/ +#ifdef MSAN_FIX + set_zero( lspmid_q, M ); +#endif /*TCX-LTP*/ Word16 T_op[3]; diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index ed39f0cb868b368522c46c19e9a973f96ae9f640..451506067602bca1ea3c5b04b50fc9e977c6882c 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -38,6 +38,8 @@ #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "prot.h" +#include "prot_fx.h" +#include "prot_fx_enc.h" #include "ivas_prot.h" #include "wmc_auto.h" @@ -48,6 +50,7 @@ * Encode secondary channel of TD Stereo with a low-bitrate encoder *-------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED void tdm_low_rate_enc( Encoder_State *st, /* i/o: State structure */ const float Aq[], /* i : 12k8 Lp coefficient */ @@ -155,6 +158,128 @@ void tdm_low_rate_enc( return; } +#else +void tdm_low_rate_enc( + Encoder_State *st, /* i/o: State structure */ + const Word16 Aq[], /* i : 12k8 Lp coefficient */ + const Word16 *res, /* i : residual signal */ + Word16 *synth, /* i/o: core synthesis */ + Word16 *exc_fx, /* i/o: current non-enhanced excitation */ + Word16 *pitch_buf, + /* i/o: floating pitch values for each subframe */ // Q6 + Word16 *voice_factors, /* o : voicing factors */ + Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */ + 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 ) +{ + const Word16 *p_Aq; + Word16 i_subfr, nb_subfr, last_pit_bin; + Word16 tmp_nb_bits_tot; + Word16 dct_res_fx[L_FRAME], dct_epit_fx[L_FRAME]; + Word16 exc_wo_nf_fx[L_FRAME]; + LPD_state_HANDLE hLPDmem = st->hLPDmem; + + /*---------------------------------------------------------------* + * Initialization + *---------------------------------------------------------------*/ + + nb_subfr = 2; + move16(); + + st->GSC_IVAS_mode = 0; + move16(); + st->GSC_noisy_speech = 1; + move16(); + st->hGSCEnc->noise_lev = 14; + move16(); + + hLPDmem->tilt_code = 0; + move16(); + set16_fx( dct_epit_fx, 0, L_FRAME ); + set16_fx( pitch_buf, L_SUBFR_Q6, NB_SUBFR ); + last_pit_bin = L_FRAME / 2; + move16(); + + /*---------------------------------------------------------------* + * DCT transform of the residual and create a subsample residual + *---------------------------------------------------------------*/ + + edct_16fx( res, dct_res_fx, L_FRAME, st->element_mode, *Q_new ); + + /*--------------------------------------------------------------------------------------* + * GSC encoder + *--------------------------------------------------------------------------------------*/ + + /* Find the current total number of bits used */ + tmp_nb_bits_tot = st->hBstr->nb_bits_tot; + move16(); + + if ( st->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 ); + } + + 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 ); + + /*--------------------------------------------------------------------------------------* + * iDCT transform + *--------------------------------------------------------------------------------------*/ + + edct_16fx( dct_epit_fx, exc_fx, L_FRAME, st->element_mode, Q_exc ); + + edct_16fx( exc_wo_nf_fx, exc_wo_nf_fx, L_FRAME, st->element_mode, Q_exc ); + + /*--------------------------------------------------------------------------------------* + * Remove potential pre-echo in case an onset has been detected + *--------------------------------------------------------------------------------------*/ + + pre_echo_att_ivas_fx( &st->hGSCEnc->Last_frame_ener_fx, exc_fx, attack_flag, Q_exc, st->last_coder_type, st->L_frame ); + + /*--------------------------------------------------------------------------------------* + * Update BWE excitation + *--------------------------------------------------------------------------------------*/ + + IF( st->hBWE_TD != NULL ) + { + set16_fx( voice_factors, 0, NB_SUBFR ); + + IF( st->tdm_LRTD_flag ) + { + interp_code_5over2_fx( exc_fx, bwe_exc_fx, L_FRAME ); + } + ELSE + { + set16_fx( bwe_exc_fx, 0, L_FRAME32k ); + } + } + + /*--------------------------------------------------------------------------------------* + * Synthesis + *--------------------------------------------------------------------------------------*/ + + p_Aq = Aq; + FOR( i_subfr = 0; i_subfr < L_FRAME; i_subfr += L_SUBFR ) + { + E_UTIL_synthesis( 0, p_Aq, &exc_wo_nf_fx[i_subfr], &synth[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1, M ); + p_Aq += ( M + 1 ); + } + + /*--------------------------------------------------------------------------------------* + * Updates + *--------------------------------------------------------------------------------------*/ + Copy( exc_wo_nf_fx, exc_fx, L_FRAME ); + + *Q_new = Q_exc; + move16(); + + return; +} +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index cd614158c204c6a6bdbb464f2e87a3cdafdd5ee8..44f07700bef5511512e7433240c8384ef31f1d6e 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -1563,7 +1563,7 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( if ( ( hEncoderConfig->Opt_RF_ON && ( hEncoderConfig->ivas_total_brate != ACELP_13k20 || hEncoderConfig->input_Fs == 8000 || hEncoderConfig->max_bwidth == NB ) ) || hEncoderConfig->rf_fec_offset == 0 ) { test(); - IF( EQ_16( hEncoderConfig->ivas_total_brate, ACELP_13k20 ) && EQ_16( hEncoderConfig->ivas_format, MONO_FORMAT ) ) + IF( EQ_32( hEncoderConfig->ivas_total_brate, ACELP_13k20 ) && EQ_32( hEncoderConfig->ivas_format, MONO_FORMAT ) ) { st_ivas->codec_mode = MODE1; move16(); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index efe00e51a2effb70e2af6dfbfa8db2edcfcdc2bc..c406c4389f9992d2de2ced560f804710718fcad6 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -708,6 +708,18 @@ void gsc_enc_fx( Word16 *tmp_noise, /* o : noise energy */ Word16 Q_exc ); +void gsc_enc_ivas_fx( + Encoder_State *st, /* i/o: State structure */ + Word16 res_dct_in_fx[], /* i : dct of residual signal */ + Word16 exc_dct_in_fx[], /* i/o: dct of pitch-only excitation / total excitation */ + const Word16 Diff_len, /* i : Lenght of the difference signal (before pure spectral)*/ + const Word16 bits_used, /* i : Number of bit used before frequency Q */ + const Word16 nb_subfr, /* i : Number of subframe considered */ + const Word16 *lsf_new_fx, /* i : ISFs at the end of the frame */ + Word16 *exc_wo_nf_fx, /* o : excitation (in f domain) without noisefill */ + Word16 *tmp_noise_fx, /* o : long-term noise energy */ + Word16 *Q_exc ); + void LPDmem_enc_init_fx( LPD_state_HANDLE hLPDmem /* i/o: LP memories */ ); diff --git a/lib_enc/pvq_core_enc_fx.c b/lib_enc/pvq_core_enc_fx.c index 445d75491630e9d6af2b9e02f2390bd90ef6d155..42ee79bc922f52bc8e6fa6e5d53f663a02329766 100644 --- a/lib_enc/pvq_core_enc_fx.c +++ b/lib_enc/pvq_core_enc_fx.c @@ -10,6 +10,7 @@ //#include "prot_fx.h" /* Function prototypes */ #include "prot_fx.h" /* Function prototypes */ #include "prot_fx_enc.h" /* Function prototypes */ +#include "ivas_prot_fx.h" /*-------------------------------------------------------------------* * Local function prototypes @@ -321,7 +322,7 @@ void pvq_encode_frame_ivas_fx( xy_corr = L_deposit_l( 0 ); yy_corr = L_deposit_l( 1 ); - shift = band_len_ener_shift[band_len_idx[shr( sfmsize[is], 3 )]]; + shift = ivas_band_len_ener_shift[ivas_band_len_idx[shr( sfmsize[is], 3 )]]; move16(); FOR( j = 0; j < sfmsize[i]; j++ ) { @@ -558,8 +559,8 @@ Word16 pvq_core_enc_ivas_fx( get_max_pulses_fx( sfm_start, sfm_end, ord, npulses, nb_sfm, pulse_vector, maxpulse ); /* Fine gain prediction */ - fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, - coefs_quant, pulse_vector, fg_pred, core ); + ivas_fine_gain_pred_fx( sfm_start, sfm_end, sfmsize, ord, npulses, maxpulse, R, nb_sfm, + coefs_quant, pulse_vector, fg_pred, core ); fine_gain_quant_ivas_fx( hBstr, ord, nb_sfm, gain_bits_array, fg_pred, gopt ); diff --git a/lib_enc/setmodeindex.c b/lib_enc/setmodeindex.c index 8e2205ae6ab4d1869ffc56164b16bf010a3595da..8077db8e8b8337934902fb41c3ca6b561a647807 100644 --- a/lib_enc/setmodeindex.c +++ b/lib_enc/setmodeindex.c @@ -40,6 +40,7 @@ #include "cnst.h" #include "ivas_cnst.h" #include "wmc_auto.h" +#include "prot_fx.h" /*--------------------------------------------------------------------------- @@ -80,3 +81,49 @@ void SetModeIndex( return; } + +#ifdef IVAS_FLOAT_FIXED +void SetModeIndex_ivas_fx( + Encoder_State *st, /* i : Encoder state */ + const Word32 last_total_brate, /* i : last total bitrate */ + const Word16 last_element_mode, /* i : last IVAS element mode */ + const Word16 MCT_flag /* i : hMCT handle allocated (1) or not (0) */ +) +{ + Word16 ini_frame_loc = st->ini_frame; + move16(); + + test(); + test(); + IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( last_element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) ) + { + st->ini_frame = 0; + move16(); + } + + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + test(); + /* Reconfigure the core coder */ + IF( ( NE_32( last_total_brate, st->total_brate ) ) || + ( NE_16( st->last_bwidth, st->bwidth ) ) || + ( EQ_16( st->last_codec_mode, MODE1 ) && EQ_16( st->element_mode, EVS_MONO ) ) || + ( ( NE_16( st->last_core, TCX_20_CORE ) && NE_16( st->last_core, TCX_10_CORE ) ) && GT_16( st->element_mode, EVS_MONO ) ) || + ( NE_16( st->rf_mode_last, st->rf_mode ) ) || + ( GT_16( st->element_mode, EVS_MONO ) && st->ini_frame == 0 ) ) + { + core_coder_mode_switch_ivas_fx( st, last_total_brate, MCT_flag ); + } + + st->ini_frame = ini_frame_loc; + move16(); + + return; +} +#endif diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 0d765c232df3544ae579cac0e747d861c895cf58..9c25e47114933744f6a482eab23cca3373505dca 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1109,9 +1109,10 @@ typedef struct gsc_enc_structure int16_t pit_exc_hangover; /* AC mode (GSC) - Hangover for the time contribution switching */ float last_exc_dct_in[L_FRAME16k]; /* AC mode (GSC) - previous excitation */ Word16 last_exc_dct_in_fx[L_FRAME16k]; /* AC mode (GSC) - previous exciation */ - float last_ener; /* AC mode (GSC) - previous energy */ - Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ - int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ + Word16 Q_last_exc_dct_in; + float last_ener; /* AC mode (GSC) - previous energy */ + Word16 last_ener_fx; /* AC mode (GSC) - previous energy */ + int16_t last_bitallocation_band[6]; /* AC mode (GSC) - previous bit allocation of each band */ float lt_gpitch; Word16 lt_gpitch_fx; /*Q15 */ @@ -1827,20 +1828,20 @@ typedef struct enc_core_structure LPD_state_HANDLE hLPDmem; /* ACELP LPDmem memories */ - float Bin_E[L_FFT]; /* per bin energy of two frames */ - float lsp_old1[M]; /* old unquantized LSP vector at the end of the frame at 12k8 */ - float lsf_old1[M]; /* old unquantized LSF vector at the end of the frame at 12k8 */ - float lsp_old[M]; /* old LSP vector at the end of the frame */ - float lsf_old[M]; /* old LSF vector at the end of the frame */ - float lsp_old16k[M]; /* old LSP vector at the end of the frame @16kHz */ - float lspold_enc[M]; /* old lsp (immittance spectral pairs) */ - Word32 Bin_E_fx[L_FFT]; /* Q_new + Q_SCALE -2 per bin energy of two frames */ - Word16 lsp_old1_fx[M]; /* old unquantized LSP vector at the end of the frame */ - Word16 lsf_old1_fx[M]; /* old LSF vector at the end of the frame */ - Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame */ - Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame */ - Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz */ - Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz */ + float Bin_E[L_FFT]; /* per bin energy of two frames */ + float lsp_old1[M]; /* old unquantized LSP vector at the end of the frame at 12k8 */ + float lsf_old1[M]; /* old unquantized LSF vector at the end of the frame at 12k8 */ + float lsp_old[M]; /* old LSP vector at the end of the frame */ + float lsf_old[M]; /* old LSF vector at the end of the frame */ + float lsp_old16k[M]; /* old LSP vector at the end of the frame @16kHz */ + float lspold_enc[M]; /* old lsp (immittance spectral pairs) */ + Word32 Bin_E_fx[L_FFT]; /* Q_new + Q_SCALE -2 per bin energy of two frames */ + Word16 lsp_old1_fx[M]; /* old unquantized LSP vector at the end of the frame */ + Word16 lsf_old1_fx[M]; /* old LSF vector at the end of the frame */ + Word16 lsp_old_fx[M]; /* old LSP vector at the end of the frame */ // Q15 + Word16 lsf_old_fx[M]; /* old LSF vector at the end of the frame */ + Word16 lsp_old16k_fx[M]; /* old LSP vector at the end of the frame @16kHz */ + Word16 lspold_enc_fx[M]; /* old LSP vector at the end of the frame @16kHz */ int16_t pstreaklen; /* LSF quantizer */ @@ -2232,7 +2233,7 @@ typedef struct enc_core_structure Word16 preemph_fac; /*Preemphasis factor*/ - Word16 gamma; + Word16 gamma; // Q15 Word16 inv_gamma; TRAN_DET_HANDLE hTranDet; diff --git a/lib_enc/swb_bwe_enc.c b/lib_enc/swb_bwe_enc.c index 569374756f43c9e2e8acba7ddadcbf800e449281..e7a802c98a415fffaad6137caf1cf895ae4b883b 100644 --- a/lib_enc/swb_bwe_enc.c +++ b/lib_enc/swb_bwe_enc.c @@ -1856,6 +1856,11 @@ void fd_bwe_enc_init( set_f( hBWE_FD->old_input, 0, NS2SA( 48000, DELAY_FD_BWE_ENC_12k8_NS + DELAY_FIR_RESAMPL_NS ) ); set_f( hBWE_FD->old_input_wb, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_12k8_NS ) ); set_f( hBWE_FD->old_input_lp, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_16k_NS ) ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS // required for float to fix conversions + set_f( hBWE_FD->old_input_lp, 0, NS2SA( 16000, ACELP_LOOK_NS + DELAY_FD_BWE_ENC_NS ) ); +#endif + set_f( hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); hBWE_FD->prev_mode = NORMAL;