diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 0b9544f2f8cea8f4294a8a3eafd9f387e38056bb..12642e406b211ddc5dbc781cee2ff618b9a7183e 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -247,6 +247,7 @@ enum{ #define INV_LOG_2_FX 23637 /*Q14*//* 1/log(2) */ #endif // IVAS_FLOAT_FIXED #define INV_SQRT_2 0.70710676908493f /* 1/sqrt(2) */ +#define INV_SQRT_2_Q30 759250112 /* 1/sqrt(2) in Q30*/ #define INV_SQRT_2_Q15 23170 /* 1/sqrt(2) in Q15 */ #define INV_SQRT_2_Q31 (Word32)1.51850022e+09 /* 1/sqrt(2) in Q31 */ @@ -3042,7 +3043,7 @@ enum #define EVS_2PI_FX 51472 /* 2 * pi in Q13 */ #define EVS_PI_FX_Q27 421657428 /* pi in Q28 */ #define EVS_2PI_FX_Q27 843314856 /* 2 * pi in Q28 */ -#define EVS_PI_BY_2_FX (Word16)(0x3244) +#define EVS_PI_BY_2_FX (Word16)(0x3244) // Q13 //#define EVS_PI_FX (Word16)(0x6488) #define LG10 24660 /* 10*log10(2) in Q13 */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 8c011856bca26c67dec234267aabf3ef933b7e93..6e9e94516b4d59028029c0094ecd18a0fc282307 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1456,12 +1456,13 @@ ISM_MODE ivas_ism_mode_select( ivas_error ivas_param_ism_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); - +#ifndef IVAS_FLOAT_FIXED void ivas_param_ism_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ float *data[MAX_NUM_OBJECTS], /* i : input signal */ const int16_t input_frame /* i : input frame length per channel */ ); +#endif void ivas_param_ism_enc_close( PARAM_ISM_CONFIG_HANDLE *hParamIsm, /* i/o: ParamISM handle */ @@ -1473,11 +1474,13 @@ void ivas_ism_metadata_close( const int16_t first_idx /* i : index of first handle to deallocate */ ); +#ifndef IVAS_FLOAT_FIXED void ivas_param_ism_stereo_dmx( Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ float *data[MAX_NUM_OBJECTS], /* i/o: input signal/stereo dmx */ const int16_t input_frame /* i : Length of input frame */ ); +#endif void ivas_param_ism_config( PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i/o: IVAS Param ISM Config Structure */ @@ -7828,19 +7831,28 @@ void ivas_filter_process_fx( /*----------------------------------------------------------------------------------* * OSBA prototypes *----------------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_osba_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +); +#else ivas_error ivas_osba_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ); - +#endif +#ifdef IVAS_FLOAT_FIXED +void ivas_osba_enc_close_fx( + OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */ +); +#else void ivas_osba_enc_close( OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */ ); - +#endif ivas_error ivas_osba_enc_reconfig( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); - +#ifndef IVAS_FLOAT_FIXED void ivas_osba_enc( OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ @@ -7852,7 +7864,20 @@ void ivas_osba_enc( const int32_t input_Fs, /* i : input sampling rate */ const int16_t sba_planar /* i : planar SBA flag */ ); - +#else +void ivas_osba_enc_fx( + OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ + Word32 *data_in_fx[], /* i/o: Input / transport audio signals */ + const int16_t input_frame, /* i : Input frame size */ + const int16_t nchan_ism, /* i : Number of objects for parameter analysis */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const int16_t sba_analysis_order, /* i : SBA order evaluated in DirAC/SPAR encoder */ + const int32_t input_Fs, /* i : input sampling rate */ + const int16_t sba_planar, /* i : planar SBA flag */ + Word16 *q_data + ); +#endif ivas_error ivas_osba_data_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ ); @@ -7952,6 +7977,7 @@ void ivas_omasa_set_config( #endif // !IVAS_FLOAT_FIXED +#ifndef IVAS_FLOAT_FIXED void ivas_omasa_enc( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */ @@ -7964,6 +7990,7 @@ void ivas_omasa_enc( float *data_separated_object, /* o : Separated object audio signal */ int16_t* idx_separated_object /* o : Index of the separated object */ ); +#endif // !IVAS_FLOAT_FIXED void ivas_set_surplus_brate_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 532d4e5e08f8991c35dab1e605d09857b0d9fe82..6315cb2da61a3582fb3e402be6ab24f6294adfa7 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2481,6 +2481,13 @@ ivas_error ivas_jbm_dec_render_fx( Word16 *data /* o : output synthesis signal */ ); +void ivas_sba_zero_vert_comp_fx( + Word32 *sba_data[], /* i : SBA signals */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sba_planar, /* i : SBA planar flag */ + const Word16 input_frame /* i : frame length */ +); + /*! r: MC format mode (MCT, McMASA, ParamMC) */ MC_MODE ivas_mc_mode_select_fx( const MC_LS_SETUP mc_ls_setup, /* i : MC loudspeaker setup */ @@ -3088,6 +3095,21 @@ void unclr_classifier_td_fx( ); #endif +#ifdef IVAS_FLOAT_FIXED + +void ivas_param_ism_stereo_dmx_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Word32 *data[MAX_NUM_OBJECTS], /* i/o: input signal/stereo dmx Qx */ + const Word16 input_frame /* i : Length of input frame */ +); + +void ivas_param_ism_enc_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + Word32 *data[MAX_NUM_OBJECTS], /* i : input signal q_pcm_in */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word16 q_pcm_in ); +#endif + ISM_MODE ivas_ism_mode_select( const Word16 nchan_inp, /* i : number of input objects */ const Word32 ivas_total_brate /* i : IVAS total bitrate */ @@ -3122,4 +3144,18 @@ Word16 ivas_omasa_ener_brate_fx( const Word16 input_frame, /* i : Input frame size */ Word16 data_e /*i:exponent for data_f */ ); +void ivas_omasa_enc( + OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ + MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ + float *data_in_f[], /* i/o: Input / transport audio signals */ + Word32 *data_in[], /* i/o: Input / transport audio signals */ + Word16 q_data, /* i:Q0 Stores the q for data_in_f */ + const int16_t input_frame, /* i : Input frame size */ + const int16_t nchan_transport, /* i : Number of transport channels */ + const int16_t nchan_ism, /* i : Number of objects for parameter analysis */ + const ISM_MODE ism_mode, /* i : ISM mode */ + float *data_separated_object, /* o : Separated object audio signal */ + int16_t *idx_separated_object /* o : Index of the separated object */ +); #endif diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index c5860c1c8287da6dfcd9cf0cc39df4512dddb0da..3aebb59f52cba1aebbf7b63b69147bd9b562be65 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -563,7 +563,35 @@ void ivas_sba_get_spar_hoa_md_flag_fx( * * Zero vertical Ambisonics components *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_sba_zero_vert_comp_fx( + Word32 *sba_data[], /* i : SBA signals */ + const Word16 sba_order, /* i : SBA order */ + const Word16 sba_planar, /* i : SBA planar flag */ + const Word16 input_frame /* i : frame length */ +) +{ + Word16 i, j; + /* Channels in the range i^2+1 to (i+1)^2 -1 are zeroed (retain only first and last channel for that order) */ + FOR( i = 1; i <= sba_order; i++ ) + { + test(); + /* Keep Z if not planar */ + IF( !sba_planar && EQ_16( i, 1 ) ) + { + continue; + } + + FOR( j = ( i * i + 1 ); j < ( ( i + 1 ) * ( i + 1 ) - 1 ); j++ ) + { + set_val_Word32( sba_data[j], 0, input_frame ); + } + } + + return; +} +#endif void ivas_sba_zero_vert_comp( float *sba_data[], /* i : SBA signals */ const int16_t sba_order, /* i : SBA order */ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index e0a60ea7d0eb752bdeb500c42aaf8ba951141c85..283896b865d9b25b10d65c38653ff7df4609bbe7 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -922,7 +922,7 @@ typedef struct ivas_param_ism_data_structure Word16 last_dmx_gain_fx; Word16 last_dmx_gain_e; - Word16 last_cardioid_left_fx[MAX_NUM_OBJECTS]; + Word16 last_cardioid_left_fx[MAX_NUM_OBJECTS]; // Q14 } PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE; #ifdef IVAS_FLOAT_FIXED diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index c1fabe13ed4f3fe5c91f3a7eb18d94716cb2f683..ca98212563e5d05d91068667ed03a6426d3d95c5 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -440,8 +440,11 @@ ivas_error init_encoder( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); } - +#ifndef IVAS_FLOAT_FIXED wb_vad_init( st->hVAD ); +#else + wb_vad_init_fx( st->hVAD ); +#endif } else { @@ -1555,9 +1558,6 @@ ivas_error init_encoder_ivas_fx( } wb_vad_init_ivas_fx( st->hVAD ); -#if 1 - wb_vad_init( st->hVAD ); -#endif } ELSE { diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index c71606d0af0b6684338c9f3dcb573b876a80b594..96c4cd8edd6e19e1134945f3ee4d5afbcb3f1ef1 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -1374,12 +1374,23 @@ ivas_error ivas_core_enc( #ifdef IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 nbSubFr; Word32 shb_speech_fx32[L_FRAME16k]; Word32 voice_factors_fx32[CPE_CHANNELS][NB_SUBFR16k]; Word16 q_shb_speech_fx32 = Q_factor_arrL( shb_speech, L_FRAME16k ); floatToFixed_arrL( shb_speech, shb_speech_fx32, q_shb_speech_fx32, L_FRAME16k ); f2me_buf_16( hStereoICBWE->mixExc16k, hStereoICBWE->mixExc16k_fx, &hStereoICBWE->mixExc16k_e, L_FRAME16k ); - f2me_buf_16( hStereoICBWE->nlExc16k, hStereoICBWE->nlExc16k_fx, &hStereoICBWE->nlExc16k_e, L_FRAME16k ); + IF( st->flag_ACELP16k == 0 ) + { + nbSubFr = NB_SUBFR; + move16(); + } + ELSE + { + nbSubFr = NB_SUBFR16k; + move16(); + } + f2me_buf_16( hStereoICBWE->nlExc16k, hStereoICBWE->nlExc16k_fx, &hStereoICBWE->nlExc16k_e, L_FRAME16k / nbSubFr ); q_new_swb_speech_buffer = Q_factor_arrL( new_swb_speech_buffer, input_frame ); floatToFixed_arrL( new_swb_speech_buffer, new_swb_speech_buffer_fx, q_new_swb_speech_buffer, input_frame ); Copy_Scale_sig_16_32( voice_factors_fx[0], voice_factors_fx32[0], NB_SUBFR16k, 16 ); // Q31 diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 797381826cdcce77ef1f614248fa04ed43011e88..935b76f69cd7b7e1d4c3f1e59f237bdf49b6a5b2 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1610,14 +1610,6 @@ ivas_error pre_proc_front_ivas_fx( floatToFixed_arrL( st->hNoiseEst->bckr, st->hNoiseEst->bckr_fx, Q_new + QSCALE, 20 ); floatToFixed_arrL( st->hNoiseEst->enrO, st->hNoiseEst->enrO_fx, Q_new + QSCALE, 20 ); st->flag_noisy_speech_snr_fx = (Word8) st->flag_noisy_speech_snr; - st->hVAD->bcg_flux_fx = float_to_fix16( st->hVAD->bcg_flux, 4 ); - st->hVAD->L_snr_sum_vad_fx = floatToFixed( st->hVAD->snr_sum_vad, 4 ); - st->hVAD->prim_act_quick_fx = float_to_fix16( st->hVAD->prim_act_quick, 15 ); - st->hVAD->prim_act_slow_fx = float_to_fix16( st->hVAD->prim_act_slow, 15 ); - st->hVAD->prim_act_fx = float_to_fix16( st->hVAD->prim_act, 15 ); - st->hVAD->prim_act_quick_he_fx = float_to_fix16( st->hVAD->prim_act_quick_he, 15 ); - st->hVAD->prim_act_slow_he_fx = float_to_fix16( st->hVAD->prim_act_slow_he, 15 ); - st->hVAD->prim_act_he_fx = float_to_fix16( st->hVAD->prim_act_he, 15 ); /*float to fix for dtx_hangover_addition_fx*/ st->hNoiseEst->Etot_lp_fx = (Word16) ( st->hNoiseEst->Etot_lp * ( 1 << 8 ) ); @@ -1799,15 +1791,7 @@ ivas_error pre_proc_front_ivas_fx( /*cleanup changes for wb_vad_ivas_fx*/ st->hNoiseEst->sign_dyn_lp = fixedToFloat( st->hNoiseEst->sign_dyn_lp_fx, 8 ); - st->hVAD->bcg_flux = fixedToFloat( st->hVAD->bcg_flux_fx, 4 ); st->flag_noisy_speech_snr = (Word16) st->flag_noisy_speech_snr_fx; - st->hVAD->snr_sum_vad = fixedToFloat( st->hVAD->L_snr_sum_vad_fx, 4 ); - st->hVAD->prim_act_quick = fixedToFloat( st->hVAD->prim_act_quick_fx, 15 ); - st->hVAD->prim_act_slow = fixedToFloat( st->hVAD->prim_act_slow_fx, 15 ); - st->hVAD->prim_act = fixedToFloat( st->hVAD->prim_act_fx, 15 ); - st->hVAD->prim_act_quick_he = fixedToFloat( st->hVAD->prim_act_quick_he_fx, 15 ); - st->hVAD->prim_act_slow_he = fixedToFloat( st->hVAD->prim_act_slow_he_fx, 15 ); - st->hVAD->prim_act_he = fixedToFloat( st->hVAD->prim_act_he_fx, 15 ); st->lt_mean_NB = (float) st->lt_mean_NB_fx / ( 1 << 11 ); st->lt_mean_WB = (float) st->lt_mean_WB_fx / ( 1 << 11 ); @@ -2322,18 +2306,6 @@ ivas_error pre_proc_front_ivas_fx( corr_shiftL_fx = float_to_fix16( corr_shiftL, Q15 ); corr_shiftR_fx = float_to_fix16( corr_shiftR, Q15 ); - st->hVAD->running_avg_fx = float_to_fix16( st->hVAD->running_avg, Q15 ); - st->hVAD->ra_deltasum_fx = float_to_fix16( st->hVAD->ra_deltasum, Q15 ); - - if ( lr_vad_enabled && st->idchan == 0 ) - { - for ( int j = 0; j < 2; j++ ) - { - hCPE->hFrontVad[j]->hVAD->running_avg_fx = float_to_fix16( hCPE->hFrontVad[j]->hVAD->running_avg, Q15 ); - hCPE->hFrontVad[j]->hVAD->ra_deltasum_fx = float_to_fix16( hCPE->hFrontVad[j]->hVAD->ra_deltasum, Q15 ); - } - } - st->bckr_tilt_lt = float_to_fix( st->bckr_tilt_lt_flt, Q16 ); @@ -2567,17 +2539,6 @@ ivas_error pre_proc_front_ivas_fx( fixedToFloat_arr( pitch_fr_fx, pitch_fr, Q6, NB_SUBFR ); fixedToFloat_arr( voicing_fr_fx, voicing_fr, Q15, NB_SUBFR ); - st->hVAD->running_avg = fixedToFloat_16( st->hVAD->running_avg_fx, Q15 ); - st->hVAD->ra_deltasum = fixedToFloat_16( st->hVAD->ra_deltasum_fx, Q15 ); - - if ( lr_vad_enabled && st->idchan == 0 ) - { - hCPE->hFrontVad[0]->hVAD->running_avg = fixedToFloat_16( hCPE->hFrontVad[0]->hVAD->running_avg_fx, Q15 ); - hCPE->hFrontVad[0]->hVAD->ra_deltasum = fixedToFloat_16( hCPE->hFrontVad[0]->hVAD->ra_deltasum_fx, Q15 ); - hCPE->hFrontVad[1]->hVAD->running_avg = fixedToFloat_16( hCPE->hFrontVad[1]->hVAD->running_avg_fx, Q15 ); - hCPE->hFrontVad[1]->hVAD->ra_deltasum = fixedToFloat_16( hCPE->hFrontVad[1]->hVAD->ra_deltasum_fx, Q15 ); - } - fixedToFloat_arrL32( ee_fx, ee, Q6, 2 ); fixedToFloat_arrL32( hp_E_fx, hp_E, q_fr_bands, 2 ); st->bckr_tilt_lt_flt = fixedToFloat_32( st->bckr_tilt_lt, Q16 ); diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index b4f4755ca66c3ac98cbc98b7d97e4f005a170ae3..e62c45e7e98bf0de63f89aac590a07449ce82f25 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -283,17 +283,6 @@ ivas_error ivas_cpe_enc( floatToFixed_arrL( hCPE->hFrontVad[n]->hNoiseEst->bckr, hCPE->hFrontVad[n]->hNoiseEst->bckr_fx, Q_new_old + QSCALE, 20 ); floatToFixed_arrL( hCPE->hFrontVad[n]->hNoiseEst->enrO, hCPE->hFrontVad[n]->hNoiseEst->enrO_fx, Q_new_old + QSCALE, 20 ); - - hCPE->hFrontVad[n]->hVAD->bcg_flux_fx = (Word16) hCPE->hFrontVad[n]->hVAD->bcg_flux * ( 1 << 4 ); - - - hCPE->hFrontVad[n]->hVAD->snr_sum_vad_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->snr_sum_vad * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_quick_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act_quick * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_slow_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act_slow * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_quick_he_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act_quick_he * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_slow_he_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act_slow_he * 32767 ); - hCPE->hFrontVad[n]->hVAD->prim_act_he_fx = (Word16) ( hCPE->hFrontVad[n]->hVAD->prim_act_he * 32767 ); } floatToFixed_arrL( &band_energies_LR[0], &band_energies_LR_fx[0], Q_new_old + QSCALE + 2, 40 ); } @@ -343,17 +332,6 @@ ivas_error ivas_cpe_enc( hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2 = (float) ( hCPE->hFrontVad[n]->hNoiseEst->Etot_v_h2_fx / ( 256.0 ) ); hCPE->hFrontVad[n]->hNoiseEst->totalNoise = (float) ( (float) hCPE->hFrontVad[n]->hNoiseEst->totalNoise_fx / ( 256.0 ) ); hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp = (float) ( hCPE->hFrontVad[n]->hNoiseEst->sign_dyn_lp_fx / ( 256.0 ) ); - hCPE->hFrontVad[n]->hVAD->bcg_flux = (float) ( hCPE->hFrontVad[n]->hVAD->bcg_flux_fx / ( 16.0 ) ); - hCPE->hFrontVad[n]->hVAD->snr_sum_vad = (float) ( hCPE->hFrontVad[n]->hVAD->snr_sum_vad_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act_quick = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_quick_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act_slow = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_slow_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act_quick_he = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_quick_he_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act_slow_he = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_slow_he_fx / 32767.0 ); - hCPE->hFrontVad[n]->hVAD->prim_act_he = (float) ( hCPE->hFrontVad[n]->hVAD->prim_act_he_fx / 32767.0 ); - - hCPE->hFrontVad[n]->hVAD->running_avg = fix16_to_float( hCPE->hFrontVad[n]->hVAD->running_avg_fx, Q15 ); - hCPE->hFrontVad[n]->hVAD->ra_deltasum = fix16_to_float( hCPE->hFrontVad[n]->hVAD->ra_deltasum_fx, Q15 ); fixedToFloat_arr( hCPE->hFrontVad[n]->hNoiseEst->old_S_fx, hCPE->hFrontVad[n]->hNoiseEst->old_S, Q7, 128 ); fixedToFloat_arr( hCPE->hFrontVad[n]->hNoiseEst->cor_map_fx, hCPE->hFrontVad[n]->hNoiseEst->cor_map, Q15, 128 ); hCPE->hFrontVad[n]->hNoiseEst->Etot_st_est = fix16_to_float( hCPE->hFrontVad[n]->hNoiseEst->Etot_st_est_fx, Q8 ); diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 657b7176115f69d6273d5bbd6afc2999f7fc4caa..0eda6be5328e1e7dd9b61f33acd39b0ad08cacdc 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -795,10 +795,48 @@ ivas_error ivas_enc( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + floatToFixed_arr32( data_f[i], data_fx[i], Q14, input_frame ); + } + for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + st_ivas->hIsmMetaData[i]->azimuth_fx = floatToFixed( st_ivas->hIsmMetaData[i]->azimuth, Q22 ); + st_ivas->hIsmMetaData[i]->elevation_fx = floatToFixed( st_ivas->hIsmMetaData[i]->elevation, Q22 ); + floatToFixed_arr32( st_ivas->hParamIsm->hFbMixer->ppFilterbank_prior_input[i], st_ivas->hParamIsm->hFbMixer->ppFilterbank_prior_input_fx[i], Q14, st_ivas->hParamIsm->hFbMixer->fb_cfg->prior_input_length ); + st_ivas->hParamIsm->last_cardioid_left_fx[i] = float_to_fix16( st_ivas->hParamIsm->last_cardioid_left[i], Q14 ); + } + st_ivas->hParamIsm->last_dmx_gain_e = 15 - norm_s( (Word16) st_ivas->hParamIsm->last_dmx_gain ); + st_ivas->hParamIsm->last_dmx_gain_fx = float_to_fix16( st_ivas->hParamIsm->last_dmx_gain, 15 - st_ivas->hParamIsm->last_dmx_gain_e ); +#endif + + ivas_param_ism_enc_fx( st_ivas, data_fx, input_frame, Q14 ); + + /* Stereo DMX generation */ + ivas_param_ism_stereo_dmx_fx( st_ivas, data_fx, input_frame ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + fixedToFloat_arrL32( data_fx[i], data_f[i], Q14, input_frame ); + } + for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + st_ivas->hIsmMetaData[i]->azimuth_fx = floatToFixed( st_ivas->hIsmMetaData[i]->azimuth, Q22 ); + fixedToFloat_arrL32( st_ivas->hParamIsm->hFbMixer->ppFilterbank_prior_input_fx[i], st_ivas->hParamIsm->hFbMixer->ppFilterbank_prior_input[i], Q14, st_ivas->hParamIsm->hFbMixer->fb_cfg->prior_input_length ); + st_ivas->hParamIsm->last_cardioid_left[i] = fixedToFloat_16( st_ivas->hParamIsm->last_cardioid_left_fx[i], Q14 ); + } + + st_ivas->hParamIsm->last_dmx_gain = fixedToFloat_16( st_ivas->hParamIsm->last_dmx_gain_fx, 15 - st_ivas->hParamIsm->last_dmx_gain_e ); +#endif +#else ivas_param_ism_enc( st_ivas, data_f, input_frame ); /* Stereo DMX generation */ ivas_param_ism_stereo_dmx( st_ivas, data_f, input_frame ); +#endif /* Core coding of Stereo DMX */ if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK ) @@ -910,7 +948,7 @@ ivas_error ivas_enc( if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) { /* Estimate MASA parameters for the objects */ - ivas_omasa_enc( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hIsmMetaData, data_f, input_frame, st_ivas->nchan_transport, hEncoderConfig->nchan_ism, st_ivas->ism_mode, data_separated_object, &idx_separated_object ); + ivas_omasa_enc( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hIsmMetaData, data_f, data_fx, st_ivas->q_data_fx, input_frame, st_ivas->nchan_transport, hEncoderConfig->nchan_ism, st_ivas->ism_mode, data_separated_object, &idx_separated_object ); } /* Encode ISMs transport channels */ @@ -979,10 +1017,25 @@ ivas_error ivas_enc( { int16_t planar_sba_orig; planar_sba_orig = hEncoderConfig->sba_planar; - +#ifdef IVAS_FLOAT_FIXED + /* Analyze objects and determine needed audio signals */ + ivas_osba_enc_fx( st_ivas->hOSba, st_ivas->hIsmMetaData, data_fx, input_frame, hEncoderConfig->nchan_ism, st_ivas->ism_mode, st_ivas->sba_analysis_order, hEncoderConfig->input_Fs, hEncoderConfig->sba_planar, &st_ivas->q_data_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 nchan; + if ( st_ivas->ism_mode == ISM_MODE_NONE ) + nchan = ( st_ivas->sba_analysis_order + 1 ) * ( st_ivas->sba_analysis_order + 1 ); + else + nchan = hEncoderConfig->nchan_ism; + for ( n = 0; n < nchan; n++ ) + { + fixedToFloat_arrL32( data_fx[n], data_f[n], st_ivas->q_data_fx, input_frame ); + } +#endif +#else /* Analyze objects and determine needed audio signals */ ivas_osba_enc( st_ivas->hOSba, st_ivas->hIsmMetaData, data_f, input_frame, hEncoderConfig->nchan_ism, st_ivas->ism_mode, st_ivas->sba_analysis_order, hEncoderConfig->input_Fs, hEncoderConfig->sba_planar ); +#endif if ( st_ivas->ism_mode == ISM_MODE_NONE ) { /*once SBA and ISM are combined into SBA signal then disable planar flag*/ diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index ea8c1a5c6fe242e76cfa34047148213259c71dc4..643339e10e6d955db3f71570bd916a6816ce8ac5 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -52,7 +52,7 @@ * * Standalone front-VAD module *-----------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED ivas_error front_vad( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ Encoder_State *st, /* i/o: encoder state structure */ @@ -242,7 +242,7 @@ ivas_error front_vad( pop_wmops(); return error; } -#ifdef IVAS_FLOAT_FIXED +#else ivas_error front_vad_fx( CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure, nullable */ Encoder_State *st, /* i/o: encoder state structure */ @@ -565,7 +565,6 @@ ivas_error front_vad_create( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); } - wb_vad_init( hFrontVad->hVAD ); hFrontVad->lp_speech = 45.0f; /* Initialize the long-term active speech level in dB */ hFrontVad->lp_noise = 0.0f; /* Initialize the long-term noise level in dB */ @@ -578,6 +577,8 @@ ivas_error front_vad_create( set16_fx( hFrontVad->mem_decim_fx, 0, shl( L_FILT_MAX, 1 ) ); set16_fx( hFrontVad->buffer_12k8_fx, 0, i_mult( 3, shr( L_FRAME, 1 ) ) ); hFrontVad->mem_preemph_fx = 0; +#else + wb_vad_init( hFrontVad->hVAD ); #endif hFrontVad->mem_preemph = 0; hFrontVad->ini_frame = 0; @@ -929,16 +930,6 @@ ivas_error front_vad_spar( floatToFixed_arrL( hFrontVad->hNoiseEst->bckr, hFrontVad->hNoiseEst->bckr_fx, Q_new_old + QSCALE + 2, 20 ); floatToFixed_arrL( hFrontVad->hNoiseEst->enrO, hFrontVad->hNoiseEst->enrO_fx, Q_new_old + QSCALE + 2, 20 ); st->flag_noisy_speech_snr_fx = (Word8) st->flag_noisy_speech_snr; - hFrontVad->hVAD->bcg_flux_fx = (Word16) hFrontVad->hVAD->bcg_flux * ( 1 << 4 ); - - - hFrontVad->hVAD->snr_sum_vad_fx = (Word16) ( hFrontVad->hVAD->snr_sum_vad * 32767 ); - hFrontVad->hVAD->prim_act_quick_fx = (Word16) ( hFrontVad->hVAD->prim_act_quick * 32767 ); - hFrontVad->hVAD->prim_act_slow_fx = (Word16) ( hFrontVad->hVAD->prim_act_slow * 32767 ); - hFrontVad->hVAD->prim_act_fx = (Word16) ( hFrontVad->hVAD->prim_act * 32767 ); - hFrontVad->hVAD->prim_act_quick_he_fx = (Word16) ( hFrontVad->hVAD->prim_act_quick_he * 32767 ); - hFrontVad->hVAD->prim_act_slow_he_fx = (Word16) ( hFrontVad->hVAD->prim_act_slow_he * 32767 ); - hFrontVad->hVAD->prim_act_he_fx = (Word16) ( hFrontVad->hVAD->prim_act_he * 32767 ); floatToFixed_arrL( &band_energies[0], &band_energies_fx[0], Q_new_old + QSCALE + 2, 40 ); #endif if ( ( error = front_vad_fx( NULL, st, hEncoderConfig, &hFrontVad, 0 /* MCT_flag */, input_frame, vad_flag_dtx, fr_bands_fx, Etot_fx, lf_E_fx, localVAD_HE_SAD, vad_hover_flag, band_energies_fx, &PS_fx[0], &st->lgBin_E_fx[0], Q_inp, &Q_buffer, Q_add, &front_create_flag ) ) != IVAS_ERR_OK ) @@ -969,18 +960,6 @@ ivas_error front_vad_spar( hFrontVad->hNoiseEst->Etot_v_h2 = (float) ( hFrontVad->hNoiseEst->Etot_v_h2_fx / ( 256.0 ) ); hFrontVad->hNoiseEst->sign_dyn_lp = (float) ( hFrontVad->hNoiseEst->sign_dyn_lp_fx / ( 256.0 ) ); - hFrontVad->hVAD->bcg_flux = (float) ( hFrontVad->hVAD->bcg_flux_fx / ( 16.0 ) ); - hFrontVad->hVAD->snr_sum_vad = (float) ( hFrontVad->hVAD->snr_sum_vad_fx / 32767.0 ); - hFrontVad->hVAD->prim_act_quick = (float) ( hFrontVad->hVAD->prim_act_quick_fx / 32767.0 ); - hFrontVad->hVAD->prim_act_slow = (float) ( hFrontVad->hVAD->prim_act_slow_fx / 32767.0 ); - hFrontVad->hVAD->prim_act = (float) ( hFrontVad->hVAD->prim_act_fx / 32767.0 ); - hFrontVad->hVAD->prim_act_quick_he = (float) ( hFrontVad->hVAD->prim_act_quick_he_fx / 32767.0 ); - hFrontVad->hVAD->prim_act_slow_he = (float) ( hFrontVad->hVAD->prim_act_slow_he_fx / 32767.0 ); - hFrontVad->hVAD->prim_act_he = (float) ( hFrontVad->hVAD->prim_act_he_fx / 32767.0 ); - // floatToFixed_arr( hFrontVad->mem_decim, hFrontVad->mem_decim_fx, Q_inp, 90 ); - // hFrontVad->mem_preemph_fx = (Word16) floatToFixed( hFrontVad->mem_preemph, Q_inp ); - - // fixedToFloat_arrL( band_energies_fx, band_energies, Q_buffer + QSCALE + 2, 40 ); fixedToFloat_arrL( &band_energies_fx[0], &band_energies[0], Q_buffer + QSCALE + 2 - band_ener_guardbits, 40 ); #endif #endif @@ -1245,8 +1224,6 @@ ivas_error front_vad_spar( #else MVR2R_WORD16( st->pitch, st->pitch, 3 ); corr_shift_fx = (Word16) floatToFixed( corr_shift, Q15 ); - hFrontVad->hVAD->running_avg_fx = (Word16) floatToFixed( hFrontVad->hVAD->running_avg, Q15 ); - hFrontVad->hVAD->ra_deltasum_fx = (Word16) floatToFixed( hFrontVad->hVAD->ra_deltasum, Q15 ); #ifdef MSAN_FIX floatToFixed_arr( A, A_fx, Q12, ( L_FRAME / L_SUBFR ) * ( M + 1 ) ); #else @@ -1254,9 +1231,6 @@ ivas_error front_vad_spar( #endif // MSAN_FIX floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); vad_param_updt_fx( st, st->pitch[1], corr_shift_fx, corr_shift_fx, A_fx, &hFrontVad, 1 ); - hFrontVad->hVAD->running_avg = fixedToFloat( hFrontVad->hVAD->running_avg_fx, Q15 ); - hFrontVad->hVAD->ra_deltasum = fixedToFloat( hFrontVad->hVAD->ra_deltasum_fx, Q15 ); - #endif /* 1st stage speech/music classification (GMM model) */ /* run only to get 'high_lpn_flag' parameter */ diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 3c8a506ea7466c02e032cd395d3ebeadc6d8e874..577cb9a75d4daf5e29646fbbce570b2d7da8dcd4 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -1044,11 +1044,17 @@ ivas_error ivas_init_encoder( return error; } } - +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_osba_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_osba_enc_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif } else if ( ivas_format == MC_FORMAT ) { @@ -1675,11 +1681,17 @@ ivas_error ivas_init_encoder_fx( return error; } } - +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_osba_enc_open_fx( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_osba_enc_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#endif } else if ( ivas_format == MC_FORMAT ) { @@ -2143,7 +2155,7 @@ void ivas_destroy_enc( ivas_omasa_enc_close( &( st_ivas->hOMasa ) ); /* OSBA handle */ - ivas_osba_enc_close( &( st_ivas->hOSba ) ); + ivas_osba_enc_close_fx( &( st_ivas->hOSba ) ); /* Stereo downmix for EVS encoder handle */ stereo_dmx_evs_close_encoder( &( st_ivas->hStereoDmxEVS ) ); diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 94794884299e4949d6f9d2fff0ab8feeef8a12db..d1b83331ef933735bbb16814b6a2a3fd163e19c5 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -50,7 +50,160 @@ * Local function definitions *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_compute_obj_parameters_fx( + const Word16 nchan_ism, /* i : number of ISM channels */ + Word64 reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX], /* i : Reference power Qx */ + PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM Enc Handle */ +) +{ + Word16 i, b, m, br, mr; + Word16 brange_start, brange_end, mrange_start, mrange_end, time_merge_fac; + Word16 power_ratios_m[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS]; + Word64 ref_power_local_frame[MAX_NUM_OBJECTS]; + Word64 tmp_ratio; + Word16 e_tmp, tmp1, tmp2; + Word64 Wtmp; + + set64_fx( ref_power_local_frame, 0, MAX_NUM_OBJECTS ); + + assert( nchan_ism == 3 || nchan_ism == 4 ); + + FOR( b = 0; b < hParamIsm->nbands; b++ ) + { + /* current frequency band borders */ + brange_start = hParamIsm->band_grouping[b]; + brange_end = hParamIsm->band_grouping[b + 1]; + move16(); + move16(); + + /* time slots to aggregate for current block */ + time_merge_fac = idiv1616( PARAM_ISM_MDFT_NO_SLOTS, hParamIsm->nblocks[b] ); + + FOR( m = 0; m < hParamIsm->nblocks[b]; m++ ) + { + Word16 index_1, index_2; + Word64 ref_power_local[MAX_NUM_OBJECTS]; + + /* initialize to 0 so unused entries are not considered later */ + set64_fx( ref_power_local, 0, MAX_NUM_OBJECTS ); + + /* current block borders */ + mrange_start = i_mult( m, time_merge_fac ); + mrange_end = i_mult( add( m, 1 ), time_merge_fac ); + + /* for each object, sum up reference power within current T/F tile */ + + FOR( i = 0; i < nchan_ism; i++ ) + { + FOR( mr = mrange_start; mr < mrange_end; mr++ ) + { + FOR( br = brange_start; br < brange_end; br++ ) + { + ref_power_local[i] = W_add( ref_power_local[i], reference_power_obj[i][mr][br] ); // Qx + move64(); + } + } + /* Sum up T/F tiles per object */ + ref_power_local_frame[i] = W_add( ref_power_local[i], ref_power_local_frame[i] ); // Qx + move64(); + } + + /* find two dominant objects and derive object indices for current T/F tile */ + IF( GE_64( ref_power_local[0], ref_power_local[1] ) ) + { + index_1 = 0; + index_2 = 1; + move16(); + move16(); + } + ELSE + { + index_1 = 1; + index_2 = 0; + move16(); + move16(); + } + + FOR( i = MAX_PARAM_ISM_WAVE; i < nchan_ism; i++ ) + { + IF( GT_64( ref_power_local[i], ref_power_local[index_1] ) ) + { + index_2 = index_1; + index_1 = i; + move16(); + move16(); + } + ELSE IF( GT_64( ref_power_local[i], ref_power_local[index_2] ) ) + { + index_2 = i; + move16(); + } + } + + /* Copy the quantized indices */ + hParamIsm->obj_indices[b][m][0] = index_1; + hParamIsm->obj_indices[b][m][1] = index_2; + move16(); + move16(); + + /* Compute power ratios */ + IF( W_add( ref_power_local[index_1], ref_power_local[index_2] ) == 0 ) + { + power_ratios_m[b][m] = ONE_IN_Q14 /* 0.5 in Q15 */; + move16(); + } + ELSE + { + tmp1 = W_norm( ref_power_local[index_1] ); + Wtmp = W_add( ref_power_local[index_1], ref_power_local[index_2] ); + tmp2 = W_norm( Wtmp ); + power_ratios_m[b][m] = BASOP_Util_Divide3232_Scale( W_extract_h( W_shl( ref_power_local[index_1], tmp1 ) ), W_extract_h( W_shl( Wtmp, tmp2 ) ), &e_tmp ); // ((Qx + tmp1) - 16) - ((Qx + tmp2) - 16) + 15 - e_tmp = 15 + tmp1 - tmp2 - e_tmp + power_ratios_m[b][m] = shl_sat( power_ratios_m[b][m], sub( e_tmp, sub( tmp1, tmp2 ) ) ); // Q15 + move16(); + move16(); + } + assert( ( power_ratios_m[b][m] >= ONE_IN_Q14 /* 0.5 in Q15 */ ) && ( power_ratios_m[b][m] <= ONE_IN_Q15 /* 1 in Q15 */ ) ); + + /* Quantize power ratios */ + /* Power ratio range [0.5,1] is mapped to [0,1] first, rounding via truncation float->integer */ + hParamIsm->power_ratios_idx[b][m] = extract_h( L_add( L_mult( shl( sub( power_ratios_m[b][m], ONE_IN_Q14 /* 0.5 in Q15 */ ), 1 ), ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ), ONE_IN_Q15 /* 0.5f in Q16 */ ) ); // Q0 + move16(); + assert( ( hParamIsm->power_ratios_idx[b][m] >= 0 ) && ( hParamIsm->power_ratios_idx[b][m] <= ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ) ); + } + } + /* Check if objects have roughly equal power by comparing reference power of first object against all others*/ + hParamIsm->flag_equal_energy = 1; + move16(); + FOR( i = 1; i < nchan_ism; i++ ) + { + IF( ref_power_local_frame[i] != 0 ) + { + tmp1 = W_norm( ref_power_local_frame[0] ); + tmp2 = W_norm( ref_power_local_frame[i] ); + tmp_ratio = BASOP_Util_Divide3232_Scale( W_extract_h( W_shl( ref_power_local_frame[0], tmp1 ) ), W_extract_h( W_shl( ref_power_local_frame[i], tmp2 ) ), &e_tmp ); // ((Qx + tmp1) - 16) - ((Qx + tmp2) - 16) + 15 - e_tmp = 15 + tmp1 - tmp2 - e_tmp + tmp_ratio = W_shl( tmp_ratio, sub( sub( e_tmp, 1 ), sub( tmp1, tmp2 ) ) ); // Q14 + + test(); + IF( GT_64( tmp_ratio, 15974 /* 0.975f in Q14 */ ) && LT_64( tmp_ratio, 16794 /* 1.025f in Q14*/ ) ) + { + hParamIsm->flag_equal_energy = s_and( hParamIsm->flag_equal_energy, 1 ); + move16(); + } + ELSE + { + hParamIsm->flag_equal_energy = s_and( hParamIsm->flag_equal_energy, 0 ); + move16(); + break; + } + } + } + + return; +} + +#else static void ivas_param_ism_compute_obj_parameters( const int16_t nchan_ism, /* i : number of ISM channels */ float reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX], /* i : Reference power */ @@ -173,52 +326,36 @@ static void ivas_param_ism_compute_obj_parameters( return; } +#endif #ifdef IVAS_FLOAT_FIXED -static void ivas_param_ism_enc_quantize_DOA( - const int16_t nchan_ism, /* i : number of ISM channels */ +static void ivas_param_ism_enc_quantize_DOA_fx( + const Word16 nchan_ism, /* i : number of ISM channels */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata */ PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM encoder handle */ ) { - int16_t i, azi_idx, ele_idx; - float valQ; -#ifdef IVAS_FLOAT_FIXED + Word16 i, azi_idx, ele_idx; Word32 valQ_fx; -#endif - /* Loop over objects */ - for ( i = 0; i < nchan_ism; i++ ) + FOR( i = 0; i < nchan_ism; i++ ) { -#ifdef IVAS_FLOAT_FIXED - /*===============================flt-2-fix======================================*/ - hIsmMetaData[i]->azimuth_fx = floatToFixed( hIsmMetaData[i]->azimuth, Q22 ); - hIsmMetaData[i]->elevation_fx = floatToFixed( hIsmMetaData[i]->elevation, Q22 ); - /*===============================flt-2-fix======================================*/ - /* Quantize the elevation and obtain quantized elevation value and index */ ele_idx = ism_quant_meta_fx( hIsmMetaData[i]->elevation_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); /* Obtain the index of quantized azimuth values */ azi_idx = ism_quant_meta_fx( hIsmMetaData[i]->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); - /*===============================fix-2-flt======================================*/ - valQ = fixedToFloat( valQ_fx, Q22 ); - /*===============================fix-2-flt======================================*/ -#else - /* Quantize the elevation and obtain quantized elevation value and index */ - ele_idx = ism_quant_meta( hIsmMetaData[i]->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); - - /* Obtain the index of quantized azimuth values */ - azi_idx = ism_quant_meta( hIsmMetaData[i]->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); -#endif /*Replace azimuth with quantized values */ - hIsmMetaData[i]->azimuth = valQ; + hIsmMetaData[i]->azimuth_fx = valQ_fx; + move32(); /* Copy the quantized indices */ hParamIsm->azi_index[i] = azi_idx; + move16(); hParamIsm->ele_index[i] = ele_idx; + move16(); } return; @@ -261,6 +398,199 @@ static void ivas_param_ism_enc_quantize_DOA( * * Downmix input channels to stereo *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_ism_stereo_dmx_fx( + Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ + Word32 *data[MAX_NUM_OBJECTS], /* i/o: input signal/stereo dmx Qx */ + const Word16 input_frame /* i : Length of input frame */ +) +{ + Word16 i, j; + Word32 tmp; + Word16 alpha, azi_shift; + Word16 tmp_1, tmp_2, one_by_input_frame; + Word16 cardioid_left[MAX_NUM_OBJECTS], cardioid_right[MAX_NUM_OBJECTS]; // Q14 + Word32 stereo_dmx[2][L_FRAME48k]; + Word16 dmx_gain, dmx_gain_e; + Word64 ene_data, ene_dmx; + Word16 grad; + Word16 last_dmx_gain, last_dmx_gain_e; + Word16 last_cardioid_left; // Q14 + ISM_METADATA_HANDLE hIsmMetaData; + + push_wmops( "ivas_param_ism_st_dmx" ); + + /*Initialization*/ + alpha = ONE_IN_Q14 /* 0.5 in Q15 */; + move16(); + azi_shift = 0; // Q13 + move16(); + dmx_gain = 0; + move16(); + ene_dmx = 0; + move64(); + ene_data = 0; + move64(); + last_dmx_gain = st_ivas->hParamIsm->last_dmx_gain_fx; + move16(); + last_dmx_gain_e = st_ivas->hParamIsm->last_dmx_gain_e; + move16(); + + /* Set the stereo dmx to zero */ + set_zero_fx( stereo_dmx[0], L_FRAME48k ); + set_zero_fx( stereo_dmx[1], L_FRAME48k ); + + one_by_input_frame = BASOP_Util_Divide1616_Scale( 1, input_frame, &tmp_1 ); + one_by_input_frame = shl( one_by_input_frame, tmp_1 ); // Q15 + + /* Loop over all objects */ + FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + hIsmMetaData = st_ivas->hIsmMetaData[i]; + last_cardioid_left = st_ivas->hParamIsm->last_cardioid_left_fx[i]; + move16(); + /*Compute the Cardioids for the corresponding object direction */ + tmp = Mpy_32_32( hIsmMetaData->azimuth_fx, PI_OVER_180_FX ); // Q22 + tmp_1 = add( EVS_PI_BY_2_FX, azi_shift ); // Q13 + tmp = L_sub( L_shr( tmp, Q22 - Q13 ), L_deposit_l( tmp_1 ) ); + IF( LT_32( tmp, -EVS_PI_FX ) ) + { + tmp = L_add( tmp, 2 * EVS_PI_FX ); + } + cardioid_left[i] = add( shr( alpha, 1 ), mult( sub( ONE_IN_Q15 - 1, alpha ), getCosWord16( extract_l( tmp ) ) ) ); // Q14 + move16(); + + IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 ) + { + Word16 last_cardioid_right; + last_cardioid_right = sub( ONE_IN_Q14 /* 1.0f in Q14 */, last_cardioid_left ); + /* Smoothing */ + cardioid_left[i] = add( mult( 24576 /* 0.75f in Q15 */, cardioid_left[i] ), mult( 8192 /* 0.25f in Q15 */, last_cardioid_left ) ); // Q14 + move16(); + grad = mult( sub( cardioid_left[i], last_cardioid_left ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ); /* Q14 */ /* for the right cardioid, multiply with -1 */ + /* Cardioids sum up to 1 */ + cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */ + move16(); + /* Loop over all samples */ + FOR( j = 0; j < shr( input_frame, 1 ); j++ ) + { + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_left, mult0( j, grad ) ) ), 15 ) ); + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + move32(); + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, add( last_cardioid_right, negate( mult0( j, grad ) ) ) ), 15 ) ); + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + move32(); + ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ + } + FOR( ; j < input_frame; j++ ) + { + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + move32(); + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + move32(); + ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ + } + } + ELSE + { + /* Cardioids sum up to 1 */ + cardioid_right[i] = sub( ONE_IN_Q14 /* 1.0f in Q14 */, cardioid_left[i] ); /* corresponds to: alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 ); */ + move16(); + /* Loop over all samples */ + FOR( j = 0; j < input_frame; j++ ) + { + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_left[i] ), 15 ) ); + stereo_dmx[0][j] = L_add( stereo_dmx[0][j], tmp ); /* Qx DMX Left */ + move32(); + tmp = data[i][j]; + move32(); + tmp = W_extract_l( W_shr( W_mult_32_16( tmp, cardioid_right[i] ), 15 ) ); + stereo_dmx[1][j] = L_add( stereo_dmx[1][j], tmp ); /* Qx DMX Right */ + move32(); + ene_data = W_add( ene_data, W_mult_32_32( data[i][j], data[i][j] ) ); /* 2 * Qx + 1 energy of all objects combined */ + } + } + st_ivas->hParamIsm->last_cardioid_left_fx[i] = cardioid_left[i]; + move16(); + } + + /* Energy compensation */ + FOR( j = 0; j < input_frame; j++ ) + { + ene_dmx = W_mac_32_32( W_mac_32_32( ene_dmx, stereo_dmx[0][j], stereo_dmx[0][j] ), stereo_dmx[1][j], stereo_dmx[1][j] ); /* 2 * Qx + 1 */ + } + tmp_1 = W_norm( ene_data ); + tmp_2 = W_norm( ene_dmx ); + ene_data = W_shl( ene_data, tmp_1 ); + ene_dmx = W_add( W_shl( ene_dmx, tmp_2 ), 1 ); + dmx_gain = BASOP_Util_Divide3232_Scale( W_extract_h( ene_data ), W_extract_h( ene_dmx ), &dmx_gain_e ); + dmx_gain_e = sub( dmx_gain_e, sub( tmp_1, tmp_2 ) ); + dmx_gain = Sqrt16( dmx_gain, &dmx_gain_e ); + + /* Smoothing */ + IF( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 ) + { + dmx_gain_e = BASOP_Util_Add_MantExp( mult( 24576 /* 0.75f */, dmx_gain ), dmx_gain_e, mult( 8192 /* 0.25f */, last_dmx_gain ), last_dmx_gain_e, &dmx_gain ); + /* 10ms ramp */ + tmp = L_shl( last_dmx_gain, last_dmx_gain_e ); // Q15 + grad = extract_l( Mpy_32_16_r( L_sub( L_shl( dmx_gain, dmx_gain_e ), tmp ), shl( one_by_input_frame, 1 ) /* 2.0f / (float) input_frame*/ ) ); /* Q15 */ /* slope between two consecutive gains, 480 samples length */ + + tmp_1 = 15 + 1; + move16(); + FOR( i = 0; i < shr( input_frame, 1 ); i++ ) + { + stereo_dmx[0][i] = W_extract_l( W_shr( W_mult_32_32( stereo_dmx[0][i], L_add( tmp, mult0( i, grad ) ) ), tmp_1 ) ); // Qx + move32(); + stereo_dmx[1][i] = W_extract_l( W_shr( W_mult_32_32( stereo_dmx[1][i], L_add( tmp, mult0( i, grad ) ) ), tmp_1 ) ); // Qx + move32(); + } + tmp_1 = add( sub( 15, dmx_gain_e ), 1 ); + FOR( ; i < input_frame; i++ ) + { + stereo_dmx[0][i] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[0][i], dmx_gain ), tmp_1 ) ); // Qx + move32(); + stereo_dmx[1][i] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[1][i], dmx_gain ), tmp_1 ) ); // Qx + move32(); + } + } + ELSE + { + tmp_1 = add( sub( 15, dmx_gain_e ), 1 ); + FOR( j = 0; j < input_frame; j++ ) + { + stereo_dmx[0][j] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[0][j], dmx_gain ), tmp_1 ) ); // Qx + move32(); + stereo_dmx[1][j] = W_extract_l( W_shr( W_mult_32_16( stereo_dmx[1][j], dmx_gain ), tmp_1 ) ); // Qx + move32(); + } + } + st_ivas->hParamIsm->last_dmx_gain_fx = dmx_gain; + move16(); + st_ivas->hParamIsm->last_dmx_gain_e = dmx_gain_e; + move16(); + + /* Copy the stereo dmx to data variable */ + Copy32( stereo_dmx[0], data[0], input_frame ); // Qx + Copy32( stereo_dmx[1], data[1], input_frame ); // Qx + + pop_wmops(); + + return; +} + +#else void ivas_param_ism_stereo_dmx( Encoder_Struct *st_ivas, /* i : IVAS encoder structure */ @@ -382,7 +712,7 @@ void ivas_param_ism_stereo_dmx( return; } - +#endif /*-------------------------------------------------------------------------* * ivas_param_ism_enc_open() @@ -563,6 +893,75 @@ void ivas_param_ism_enc_close( * Parametric ISM encoder *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_ism_enc_fx( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + Word32 *data[MAX_NUM_OBJECTS], /* i : input signal q_pcm_in */ + const Word16 input_frame, /* i : input frame length per channel */ + const Word16 q_pcm_in ) +{ + Word16 i, j, ts, l_ts; + Word16 nchan_ism; + Word16 num_time_slots; + Word16 q_p_fb_Buffer; + Word32 *pcm_in[MAX_NUM_OBJECTS]; + Word32 fb_RealBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX]; + Word32 fb_ImagBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX]; + Word32 *p_fb_RealBuffer[MAX_NUM_OBJECTS]; + Word32 *p_fb_ImagBuffer[MAX_NUM_OBJECTS]; + Word64 reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX]; + PARAM_ISM_CONFIG_HANDLE hParamIsm; + + nchan_ism = st_ivas->hEncoderConfig->nchan_ism; + move16(); + hParamIsm = st_ivas->hParamIsm; + + push_wmops( "ivas_param_ism_enc" ); + + l_ts = shr( input_frame, 2 ); /* input_frame / PARAM_ISM_MDFT_NO_SLOTS */ + num_time_slots = PARAM_ISM_MDFT_NO_SLOTS; + move16(); + + FOR( i = 0; i < nchan_ism; i++ ) + { + pcm_in[i] = data[i]; + + set_zero_fx( fb_RealBuffer[i], DIRAC_NO_FB_BANDS_MAX ); + set_zero_fx( fb_ImagBuffer[i], DIRAC_NO_FB_BANDS_MAX ); + p_fb_RealBuffer[i] = &fb_RealBuffer[i][0]; + p_fb_ImagBuffer[i] = &fb_ImagBuffer[i][0]; + } + + Word16 gb = find_guarded_bits_fx( l_ts ); + q_p_fb_Buffer = sub( q_pcm_in, gb ); + + FOR( ts = 0; ts < num_time_slots; ts++ ) + { + ivas_fb_mixer_get_windowed_fr_fx( hParamIsm->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans, gb ); + + ivas_fb_mixer_update_prior_input_fx( hParamIsm->hFbMixer, pcm_in, l_ts, hParamIsm->hFbMixer->fb_cfg->num_in_chans ); + + FOR( i = 0; i < nchan_ism; i++ ) + { + pcm_in[i] += l_ts; + FOR( j = 0; j < DIRAC_NO_FB_BANDS_MAX; j++ ) + { + reference_power_obj[i][ts][j] = W_shr( W_add( W_mult0_32_32( fb_RealBuffer[i][j], fb_RealBuffer[i][j] ), W_mult0_32_32( fb_ImagBuffer[i][j], fb_ImagBuffer[i][j] ) ), shl( q_p_fb_Buffer, 1 ) ); // Q0 + move64(); + } + } + } + + ivas_param_ism_enc_quantize_DOA_fx( nchan_ism, st_ivas->hIsmMetaData, hParamIsm ); + + ivas_param_ism_compute_obj_parameters_fx( nchan_ism, reference_power_obj, hParamIsm ); + + pop_wmops(); + return; +} + +#else + void ivas_param_ism_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ float *data[MAX_NUM_OBJECTS], /* i : input signal */ @@ -623,7 +1022,7 @@ void ivas_param_ism_enc( pop_wmops(); return; } - +#endif /*-------------------------------------------------------------------* * ivas_param_ism_compute_noisy_speech_flag() diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index ed2cc5a68ef7067addd4aaca52cd89e6335e70cd..963af28a843df9f8e76443af8a61dab78bb07c79 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -38,7 +38,9 @@ #include "ivas_rom_enc.h" #include "rom_com.h" #include "prot.h" +#include "prot_fx.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "wmc_auto.h" @@ -48,13 +50,11 @@ * Local function prototypes *------------------------------------------------------------------------*/ -static void ivas_param_mc_dmx( PARAM_MC_ENC_HANDLE hParamMC, float *data_f[], float data_dmx[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_input, const int16_t nchan_transport ); static void ivas_param_mc_param_est_enc( PARAM_MC_ENC_HANDLE hParamMC, float *data_f[], float Cy_sum[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], float Cx_sum[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const int16_t input_frame, const int16_t nchan_input, const int16_t nchan_transport ); static void ivas_param_mc_parameter_quantizer( const float *x, const int16_t L, const int16_t sz_quantizer, const float *quantizer, int16_t *quant_idx, float *y ); -static void ivas_param_mc_transient_detection( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, int16_t *bAttackPresent, int16_t *attackIdx ); #ifndef FIX_901_PARAMMC_DEAD_CODE static void ivas_param_mc_enc_find_icc_map( PARAM_MC_ENC_HANDLE hParamMC, float Cx_sum[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], float Cy_sum[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], float ILD_q[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP], const int16_t nchan_input, const int16_t nchan_transport ); @@ -72,6 +72,22 @@ static void ivas_param_mc_encode_parameter( int16_t *idx_in, HANDLE_IVAS_PARAM_M static void ivas_param_mc_range_encoder( const int16_t *seq_in, const int16_t num_symbols, const uint16_t *cum_freq, const uint16_t *sym_freq, const uint16_t tot_shift, const int16_t max_nb_bits, uint16_t *bit_buffer, int16_t *bit_pos ); +#ifdef IVAS_FLOAT_FIXED + +#define ATTACKTHRESHOLD_E 4 + +static void ivas_param_mc_dmx_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f_fx[], Word32 data_dmx_fx[][L_FRAME48k], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport ); + +static void ivas_param_mc_transient_detection_fx( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, Word16 *bAttackPresent, Word16 *attackIdx ); + +#else + +static void ivas_param_mc_dmx( PARAM_MC_ENC_HANDLE hParamMC, float *data_f[], float data_dmx[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_input, const int16_t nchan_transport ); + +static void ivas_param_mc_transient_detection( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, int16_t *bAttackPresent, int16_t *attackIdx ); + +#endif + /*------------------------------------------------------------------------- * ivas_param_mc_enc_open() * @@ -133,6 +149,9 @@ ivas_error ivas_param_mc_enc_open( /* get dmx factors */ hParamMC->dmx_factors = ivas_param_mc_conf[config_index].dmx_fac; +#ifdef IVAS_FLOAT_FIXED + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; +#endif /* set FB config. */ if ( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, nchan_inp, 0, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) @@ -278,6 +297,9 @@ ivas_error ivas_param_mc_enc_reconfig( /* get dmx factors */ hParamMC->dmx_factors = ivas_param_mc_conf[config_index].dmx_fac; +#ifdef IVAS_FLOAT_FIXED + hParamMC->dmx_factors_fx = ivas_param_mc_conf[config_index].dmx_fac_fx; +#endif #ifndef FIX_901_PARAMMC_DEAD_CODE /* deallocate the full icc map, gets newly allocated in the metadata open function */ @@ -397,6 +419,215 @@ void ivas_param_mc_enc_close( * Parametric MC Encoder main encoding function *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_mc_enc( + Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ + BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ + float *data_f[], /* i/o: input/transport MC data */ + const int16_t input_frame /* i : input frame length */ +) +{ + int16_t k; +#ifdef IVAS_FLOAT_FIXED + Word32 *data_f_fx[12]; + for ( k = 0; k < 12; k++ ) + { + data_f_fx[k] = (Word32 *) malloc( input_frame * sizeof( Word32 ) ); + } +#endif + float Cy_sum[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + float Cx_sum[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; + float ILD_q[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP]; + int16_t ILD_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP]; + int16_t ICC_idx[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP]; + uint16_t bit_buffer[PARAM_MC_MAX_BITS]; + int16_t bit_pos; + int16_t band_step; + float data_dmx[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k]; +#ifdef IVAS_FLOAT_FIXED + Word32 data_dmx_fx[PARAM_MC_MAX_TRANSPORT_CHANS][L_FRAME48k]; +#endif + int16_t ch; + int16_t band; + PARAM_MC_ENC_HANDLE hParamMC; + int16_t nchan_inp; + + push_wmops( "param_mc_enc" ); + + /* initializations */ + hParamMC = st_ivas->hParamMC; + bit_pos = 0; + band_step = 1; + nchan_inp = st_ivas->hEncoderConfig->nchan_inp; + + for ( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ ) + { + for ( ch = 0; ch < MAX_CICP_CHANNELS; ch++ ) + { + set_zero( Cy_sum[band][ch], MAX_CICP_CHANNELS ); + } + for ( ch = 0; ch < PARAM_MC_MAX_TRANSPORT_CHANS; ch++ ) + { + set_zero( Cx_sum[band][ch], PARAM_MC_MAX_TRANSPORT_CHANS ); + } + } + + for ( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ ) + { + set_zero( ILD_q[band], PARAM_MC_SZ_ILD_MAP ); + } + set_s( ILD_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP ); + set_s( ICC_idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ICC_MAP ); + + /* update parameter frame index */ + hParamMC->hMetadataPMC.param_frame_idx = ( hParamMC->hMetadataPMC.param_frame_idx + 1 ) % PARAM_MC_PARAMETER_FRAMES; + + /* DMX generation*/ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int i = 0; i < nchan_inp; i++ ) + { + floatToFixed_arrL( data_f[i], data_f_fx[i], 11, input_frame ); + } +#endif + ivas_param_mc_dmx_fx( hParamMC, data_f_fx, data_dmx_fx, input_frame, nchan_inp, st_ivas->nchan_transport ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int i = 0; i < 3; i++ ) + { + fixedToFloat_arrL( data_dmx_fx[i], data_dmx[i], 11, input_frame ); + } +#endif +#else + ivas_param_mc_dmx( hParamMC, data_f, data_dmx, input_frame, nchan_inp, st_ivas->nchan_transport ); +#endif + + /* Transient Detector */ + switch ( st_ivas->nchan_transport ) + { + case 2: + case 3: + case 4: + { + int16_t bAttackPresent[PARAM_MC_MAX_TRANSPORT_CHANS]; + int16_t attackIdx[PARAM_MC_MAX_TRANSPORT_CHANS]; + + set16_fx( attackIdx, -1, PARAM_MC_MAX_TRANSPORT_CHANS ); + set16_fx( bAttackPresent, 0, PARAM_MC_MAX_TRANSPORT_CHANS ); + + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + Word16 cpe_idx = ch / 2; + + RunTransientDetection( data_dmx[ch], input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet ); +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + f2me_buf( st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.subblockNrg_flt, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.subblockNrg, &st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.subblockNrg_e, NSUBBLOCKS + MAX_TD_DELAY ); + f2me_buf( st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.accSubblockNrg_flt, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.accSubblockNrg, &st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->subblockEnergies.accSubblockNrg_e, NSUBBLOCKS + MAX_TD_DELAY + 1 ); + st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->transientDetector.attackRatioThreshold = float_to_fix16( st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet->transientDetector.attackRatioThreshold_flt, Q15 - ATTACKTHRESHOLD_E ); +#endif + ivas_param_mc_transient_detection_fx( hParamMC, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, &bAttackPresent[ch], &attackIdx[ch] ); +#else + ivas_param_mc_transient_detection( hParamMC, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet, &bAttackPresent[ch], &attackIdx[ch] ); +#endif + } + + /* if more than one attack, use the earlier */ + hParamMC->hMetadataPMC.bAttackPresent = 0; + hParamMC->hMetadataPMC.attackIndex = 16; + + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + hParamMC->hMetadataPMC.bAttackPresent = max( hParamMC->hMetadataPMC.bAttackPresent, bAttackPresent[ch] ); + } + + if ( hParamMC->hMetadataPMC.bAttackPresent ) + { + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + hParamMC->hMetadataPMC.attackIndex = min( hParamMC->hMetadataPMC.attackIndex, attackIdx[ch] ); + } + } + else + { + hParamMC->hMetadataPMC.attackIndex = 0; + } + } + break; + } + + /* Encoding */ + /* parameter estimation*/ + ivas_param_mc_param_est_enc( hParamMC, data_f, Cy_sum, Cx_sum, input_frame, nchan_inp, st_ivas->nchan_transport ); + + band_step = hParamMC->hMetadataPMC.bAttackPresent ? PARAM_MC_TRANSIENT_BAND_STEP : 1; + + + /* ILD parameter quantization */ + for ( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step ) + { + ivas_param_mc_quantize_ilds( hParamMC, Cy_sum[k], Cx_sum[k], k, nchan_inp, st_ivas->nchan_transport, ILD_idx, ILD_q[k] ); + } + +#ifndef FIX_901_PARAMMC_DEAD_CODE + /* get icc map */ + if ( hParamMC->hMetadataPMC.flag_use_adaptive_icc_map == 1 ) + { + ivas_param_mc_enc_find_icc_map( hParamMC, Cx_sum, Cy_sum, ILD_q, nchan_inp, st_ivas->nchan_transport ); + } + else + { + ivas_param_mc_default_icc_map( hParamMC->hMetadataPMC.icc_mapping_conf, hParamMC->hMetadataPMC.icc_mapping[hParamMC->hMetadataPMC.param_frame_idx] ); + } + +#endif + /* ICC parameter quantization */ + for ( k = 0; k < hParamMC->hMetadataPMC.nbands_coded; k += band_step ) + { + ivas_param_mc_quantize_iccs( hParamMC, Cy_sum[k], k, nchan_inp, ICC_idx ); + } + + /* time domain DMX generation*/ + /* just copy data_dmx generated above, contains already the downmix */ + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + mvr2r( data_dmx[ch], data_f[ch], input_frame ); + } + + /* we have to run the transient detector on the second channel of the last CPE if we + have an odd number of transport channels */ + if ( st_ivas->nchan_transport > 2 ) + { + for ( ; ch < st_ivas->nCPE * CPE_CHANNELS; ch++ ) + { + int16_t cpe_idx = ch / 2; + + set_zero( data_f[ch], input_frame ); + + RunTransientDetection( data_f[ch], input_frame, st_ivas->hCPE[cpe_idx]->hCoreCoder[ch - cpe_idx * CPE_CHANNELS]->hTranDet ); + } + } + + /* write Parametric MC side info bitstream into temporary buffer*/ + ivas_param_mc_write_bs( hParamMC, ILD_idx, ICC_idx, bit_buffer, &bit_pos ); + + /* push the Parametric MC side info from the temporary buffer into the medatdata bitstream*/ + push_next_bits( hMetaData, bit_buffer, bit_pos ); + + /* updates */ + hParamMC->hMetadataPMC.last_coded_bwidth = hParamMC->hMetadataPMC.coded_bwidth; + +#ifdef IVAS_FLOAT_FIXED + for ( k = 0; k < 12; k++ ) + { + free( data_f_fx[k] ); + } +#endif + + pop_wmops(); + + return; +} +#else void ivas_param_mc_enc( Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */ @@ -563,6 +794,7 @@ void ivas_param_mc_enc( return; } +#endif /*****************************************************************************************/ @@ -575,6 +807,7 @@ void ivas_param_mc_enc( * Computes the time domain down mix signal *------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void ivas_param_mc_dmx( PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */ float *data_f[], /* i : Input frame */ @@ -607,6 +840,42 @@ static void ivas_param_mc_dmx( return; } +#else +static void ivas_param_mc_dmx_fx( + PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */ + Word32 *data_f_fx[], /* i : Input frame Q_x */ + Word32 data_dmx_fx[][L_FRAME48k], /* o : Down mixed frame Q_x - 11 */ + const Word16 input_frame, /* i : Input frame length */ + const Word16 nchan_input, /* i : number of input channels */ + const Word16 nchan_transport /* i : number of transport channels */ +) +{ + Word16 i; + const Word16 *idx; + Word16 dmx_ch; + Word16 inp_ch; + const Word32 *p_dmx_fac_fx; + + idx = Param_MC_index; + FOR( i = 0; i < input_frame; i++ ) + { + p_dmx_fac_fx = hParamMC->dmx_factors_fx; + FOR( dmx_ch = 0; dmx_ch < nchan_transport; dmx_ch++ ) + { + Word32 *dmx_sample_fx = &data_dmx_fx[idx[dmx_ch]][i]; + *dmx_sample_fx = 0; + move16(); + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + ( *dmx_sample_fx ) = Madd_32_32( ( *dmx_sample_fx ), data_f_fx[idx[inp_ch]][i], ( *( p_dmx_fac_fx++ ) ) ); + move16(); + } + } + } + + return; +} +#endif /*------------------------------------------------------------------------- @@ -1518,6 +1787,7 @@ static void ivas_param_mc_parameter_quantizer( * Detect if the current frame has a transient *------------------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void ivas_param_mc_transient_detection( PARAM_MC_ENC_HANDLE hParamMC, /* i : Parametric MC encoder handle */ TRAN_DET_HANDLE hTranDet, /* i : Transient detector handle from core coder for a transport channel */ @@ -1566,7 +1836,70 @@ static void ivas_param_mc_transient_detection( return; } +#else +static void ivas_param_mc_transient_detection_fx( + PARAM_MC_ENC_HANDLE hParamMC, /* i : Parametric MC encoder handle */ + TRAN_DET_HANDLE hTranDet, /* i : Transient detector handle from core coder for a transport channel */ + Word16 *pbIsAttackPresent, /* o : Flag for indicating a found transient */ + Word16 *pAttackIndex /* o : Attack position (0 if no attack) */ +) +{ + Word16 i; + Word16 bIsAttackPresent, attackIndex; + Word32 *pSubblockNrg_fx; + Word16 pSubblockNrg_e; + Word32 *pAccSubblockNrg_fx; + Word16 pAccSubblockNrg_e; + Word16 attackRatioThreshold_fx; + + push_wmops( "param_mc_trn_det" ); + + attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold; + pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay]; + pSubblockNrg_e = hTranDet->subblockEnergies.subblockNrg_e; + move16(); + pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; + pAccSubblockNrg_e = hTranDet->subblockEnergies.accSubblockNrg_e; + move16(); + + bIsAttackPresent = FALSE; + move16(); + attackIndex = 16; + move16(); + + /* Search for the last attack in the subblocks, + * if we had an attack very late in the last frame, + * make the current frame also a transient one... */ + test(); + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], pSubblockNrg_e, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), add( pAccSubblockNrg_e, ATTACKTHRESHOLD_E ) ), 1 ) || + EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], pSubblockNrg_e, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), add( pAccSubblockNrg_e, ATTACKTHRESHOLD_E ) ), 1 ) ) + { + bIsAttackPresent = TRUE; + move16(); + attackIndex = 0; + move16(); + } + + FOR( i = 0; i < NSUBBLOCKS; i++ ){ + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], pSubblockNrg_e, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), add( pAccSubblockNrg_e, ATTACKTHRESHOLD_E ) ), 1 ) ){ + bIsAttackPresent = TRUE; + move16(); + attackIndex = i; + move16(); +} +} + +/* avoid post-echos on click sounds (very short transients) due to TNS aliasing */ +*pAttackIndex = attackIndex; +move16(); +*pbIsAttackPresent = bIsAttackPresent; +move16(); +pop_wmops(); + +return; +} +#endif /*------------------------------------------------------------------------- * ivas_param_mc_entropy_encoder() @@ -1574,6 +1907,119 @@ static void ivas_param_mc_transient_detection( * Write the metadata bitstream *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_write_bs( + const PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder Handle */ + Word16 *ILD_idx, /* i : ILD quantizer indices sequence */ + Word16 *ICC_idx, /* i : ICC quantizer indices sequence */ + UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o : Output bit buffer */ + Word16 *bit_pos /* o : Number of bits used */ +) +{ + Word16 i, pos; + Word16 nbands; + Word16 band_step; + /*buffers are not getting used in the function*/ + // Word16 seq_tmp[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP]; + // float seq_tmp_uni[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP]; + Word16 icc_map_size_wo_lfe; + Word16 icc_map_size; + Word16 ild_map_size_wo_lfe; + Word16 ild_map_size; + + push_wmops( "param_mc_prm_enc" ); + + /* Init */ + /*buffers are not getting used in the function */ + // set_zero( seq_tmp_uni, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP ); + // set_s( seq_tmp, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_SZ_ILD_MAP ); + nbands = hParamMC->hMetadataPMC.nbands_in_param_frame[hParamMC->hMetadataPMC.param_frame_idx]; + move16(); + icc_map_size_wo_lfe = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_wo_lfe; + move16(); + icc_map_size = hParamMC->hMetadataPMC.icc_mapping_conf->icc_map_size_lfe; + move16(); + ild_map_size_wo_lfe = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe; + move16(); + ild_map_size = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe; + move16(); + + /*-----------------------------------------------------------------* + * Signaling bits + *-----------------------------------------------------------------*/ + + /* reserved bit */ + bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.lfe_on; + move16(); + + /* write coded band width */ + i = hParamMC->hMetadataPMC.coded_bwidth; + move16(); + FOR( pos = 0; pos < 2; pos++ ) + { + bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( i, pos ), 1 ); + move16(); + } + + /* write param frame indicator */ + bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.param_frame_idx; + move16(); + + /* write transient frame indicator */ + bit_buffer[( *bit_pos )++] = hParamMC->hMetadataPMC.bAttackPresent; + move16(); + + band_step = 1; + move16(); + IF( hParamMC->hMetadataPMC.bAttackPresent ) + { + band_step = PARAM_MC_TRANSIENT_BAND_STEP; + move16(); + FOR( pos = 2; pos >= 0; --pos ) + { + bit_buffer[( *bit_pos )++] = (UWord16) s_and( shr( hParamMC->hMetadataPMC.attackIndex, pos ), 1 ); + move16(); + } + IF( ( hParamMC->hMetadataPMC.nbands_coded % band_step ) ) + { + nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 1 ); + } + ELSE + { + nbands = add( idiv1616( hParamMC->hMetadataPMC.nbands_coded, band_step ), 0 ); + } + } + +#ifndef FIX_901_PARAMMC_DEAD_CODE + /* Encoding of the ICC mapping done as simple bitmap */ + if ( hParamMC->hMetadataPMC.flag_use_adaptive_icc_map == 1 ) + { + uint16_t *bit_buffer_icc_mapping = &bit_buffer[*bit_pos]; + + for ( i = 0; i < hParamMC->hMetadataPMC.icc_map_size_full - 1; i++ ) + { + bit_buffer_icc_mapping[i] = 0; + } + + for ( i = 0; i < icc_map_size_wo_lfe; i++ ) + { + bit_buffer_icc_mapping[hParamMC->icc_map_index[hParamMC->hMetadataPMC.param_frame_idx][i]] = 1; + } + + *bit_pos += hParamMC->hMetadataPMC.icc_map_size_full - 1; + } + +#endif + ivas_param_mc_encode_parameter( ICC_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.icc_coding, + nbands, band_step, icc_map_size_wo_lfe, icc_map_size, bit_buffer, bit_pos ); + + ivas_param_mc_encode_parameter( ILD_idx, &hParamMC->hMetadataPMC, &hParamMC->hMetadataPMC.ild_coding, + nbands, band_step, ild_map_size_wo_lfe, ild_map_size, bit_buffer, bit_pos ); + pop_wmops(); + + return; +} +#else static void ivas_param_mc_write_bs( const PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder Handle */ int16_t *ILD_idx, /* i : ILD quantizer indices sequence */ @@ -1663,6 +2109,7 @@ static void ivas_param_mc_write_bs( return; } +#endif /*------------------------------------------------------------------------- @@ -1671,6 +2118,148 @@ static void ivas_param_mc_write_bs( * (entropy) encode a sequence of parameter indices *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_encode_parameter( + int16_t *quant_idx, /* i : indices sequence to encode */ + HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata handle */ + HANDLE_PARAM_MC_PARAMETER_CODING_INFO hParameterCodingInfo, /* i : parameter quantization and coding info */ + const Word16 nbands, /* i : number of parameter bands to encode */ + const Word16 band_step, /* i : parameter band step */ + const Word16 map_size_wo_lfe, /* i : number of parameters per band (w/o LFE) */ + const Word16 map_size, /* i : number of parameters per band */ + UWord16 bit_buffer[PARAM_MC_MAX_BITS], /* o : Output bit buffer */ + Word16 *bit_pos /* o : Number of bits used */ +) +{ + Word16 sz_seq; + Word16 idx_prev; + Word16 idx_offset; + Word16 bit_cnt_uni; + Word16 bit_cnt_range; + Word16 bit_cnt_range_diff; + Word16 bit_cnt_range_min; + Word16 bit_pos_tmp; + Word16 i, j; + Word16 idx; + Word16 seq_delta[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + Word16 seq[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE]; + UWord16 tmp_bit_buffer[PARAM_MC_MAX_BITS]; + UWord16 tmp_bit_buffer_diff[PARAM_MC_MAX_BITS]; + + /* Inits */ + sz_seq = i_mult( nbands, ( map_size_wo_lfe ) ); + + /* Computing Delta Sequence */ + idx_prev = sub( add( shr( hParameterCodingInfo->quantizer_size, 1 ), hParameterCodingInfo->quantizer_size % 2 ), 1 ); + idx_offset = sub( hParameterCodingInfo->quantizer_size, 1 ); + + FOR( j = 0; j < map_size_wo_lfe; ++j ) + { + Word16 coding_band = 0; + move16(); + + FOR( i = 0; i < hMetadataPMC->nbands_coded; i += band_step ) + { + test(); + IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) ) + { + idx = quant_idx[i * map_size + j]; + move16(); + seq[coding_band + j * nbands] = idx; + move16(); + seq_delta[coding_band + j * nbands] = add( sub( idx, idx_prev ), idx_offset ); + move16(); + idx_prev = idx; + move16(); + coding_band = add( coding_band, 1 ); + } + } + } + + /* LFE */ + IF( hMetadataPMC->lfe_on ) + { + FOR( i = 0; i < PARAM_MC_MAX_BAND_LFE; i += band_step ) + { + test(); + IF( hMetadataPMC->bAttackPresent || EQ_16( hMetadataPMC->param_frame_idx, hMetadataPMC->coding_band_mapping[i] ) ) + { + /* LFE ICC/ILDs are always the last ones in coding band 0 */ + Word16 n_lfe_idx, k; + n_lfe_idx = sub( map_size, map_size_wo_lfe ); + FOR( k = 0; k < n_lfe_idx; k++ ) + { + idx = quant_idx[( i + 1 ) * map_size - n_lfe_idx + k]; + move16(); + seq[sz_seq] = idx; + move16(); + seq_delta[sz_seq] = add( sub( idx, idx_prev ), idx_offset ); + move16(); + idx_prev = idx; + move16(); + sz_seq = add( sz_seq, 1 ); + } + } + } + } + + + bit_cnt_uni = sub( i_mult( sz_seq, hParameterCodingInfo->uni_bits ), 1 ); /* -1 for the additional diff/direct signaling bit for the range encoder*/ + + /* code the direct index sequence */ + ivas_param_mc_range_encoder( seq, sz_seq, hParameterCodingInfo->cum_freq, hParameterCodingInfo->sym_freq, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer[0], &bit_cnt_range ); + + /* Coding the delta index sequence */ + ivas_param_mc_range_encoder( seq_delta, sz_seq, hParameterCodingInfo->cum_freq_delta, hParameterCodingInfo->sym_freq_delta, PARAM_MC_RANGE_CODER_TOT_SHIFT, bit_cnt_uni, &tmp_bit_buffer_diff[0], &bit_cnt_range_diff ); + + bit_cnt_range_min = s_min( bit_cnt_range, bit_cnt_range_diff ); + + /* uniform fallback */ + IF( GT_16( bit_cnt_range_min, bit_cnt_uni ) ) + { + /* Uniform coding is used */ + bit_buffer[( *bit_pos )++] = 0; + move16(); + bit_pos_tmp = 0; + move16(); + + FOR( i = 0; i < sz_seq; ++i ) + { + ivas_param_mc_dec2bin( seq[i], hParameterCodingInfo->uni_bits, &bit_buffer[*( bit_pos ) + bit_pos_tmp] ); + bit_pos_tmp = add( bit_pos_tmp, hParameterCodingInfo->uni_bits ); + } + *bit_pos = add( *bit_pos, bit_pos_tmp ); + } + ELSE + { + /* Range Coding is used */ + bit_buffer[( *bit_pos )++] = 1; + move16(); + IF( bit_cnt_range_diff < bit_cnt_range ) + { + bit_buffer[( *bit_pos )++] = 1; + move16(); + FOR( i = 0; i < bit_cnt_range_diff; i++ ) + { + bit_buffer[( *bit_pos )++] = tmp_bit_buffer_diff[i]; + move16(); + } + } + ELSE + { + bit_buffer[( *bit_pos )++] = 0; + move16(); + FOR( i = 0; i < bit_cnt_range; i++ ) + { + bit_buffer[( *bit_pos )++] = tmp_bit_buffer[i]; + move16(); + } + } + } + + return; +} +#else static void ivas_param_mc_encode_parameter( int16_t *quant_idx, /* i : indices sequence to encode */ HANDLE_IVAS_PARAM_MC_METADATA hMetadataPMC, /* i : Parametric MC metadata handle */ @@ -1793,6 +2382,7 @@ static void ivas_param_mc_encode_parameter( return; } +#endif /*------------------------------------------------------------------------- @@ -1801,6 +2391,26 @@ static void ivas_param_mc_encode_parameter( * Decimal to binary routine *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_dec2bin( + const Word16 val, /* i : value to encode */ + const Word16 N, /* i : number of bits for encoding the value */ + UWord16 bits[PARAM_MC_MAX_BITS] ) /* o : encoded bits buffer */ +{ + Word16 idx; + + idx = 0; + move16(); + /* convert value to bitstream, MSB first */ + FOR( idx = 0; idx < N; idx++ ) + { + bits[idx] = (UWord16) s_and( shr( val, sub( N, sub( 1, idx ) ) ), 1 ); + move16(); + } + + return; +} +#else static void ivas_param_mc_dec2bin( const int16_t val, /* i : value to encode */ const int16_t N, /* i : number of bits for encoding the value */ @@ -1817,6 +2427,7 @@ static void ivas_param_mc_dec2bin( return; } +#endif /*-------------------------------------------------------------------* @@ -1825,6 +2436,95 @@ static void ivas_param_mc_dec2bin( * Parametric MC Range encoder *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_range_encoder( + const Word16 *seq_in, /* i : input sequence */ + const Word16 num_symbols, /* i : Number of symbole to encode */ + const UWord16 *cum_freq, /* i : cumulated frequencies */ + const UWord16 *sym_freq, /* i : symbol frequencies */ + const UWord16 tot_shift, /* i : max cumulative freq as power of 2 */ + const Word16 max_nb_bits, /* i : Maximum number of bits allowed */ + UWord16 *bit_buffer, /* o : output bit buffer */ + Word16 *bit_pos /* o : number of bits used */ +) +{ + RangeUniEncState rc_st_enc; + Word16 rc_tot_bits; /* No. of bits returned by range coder */ + Word16 i; + UWord8 k, byte; + UWord16 *bits; + + /* Initialize range encoder */ + rc_uni_enc_init( &rc_st_enc ); + + /* Main loop over the length of the sequence */ + FOR( i = 0; i < num_symbols; ++i ) + { + rc_uni_enc_encode_symbol_fastS( &rc_st_enc, (UWord16) seq_in[i], cum_freq, sym_freq, tot_shift ); + + IF( GT_16( rc_uni_enc_virtual_finish( &rc_st_enc ), max_nb_bits ) ) + { + /* we alread have exceeded the maximum number of bits allowed, i.e. the uniform fallback */ + *bit_pos = MAX_BITS_PER_FRAME; + return; + } + } + + /* Finish range encoder */ + rc_tot_bits = rc_uni_enc_finish( &rc_st_enc ); /* No. of bits consumed by range coder */ + + /* Push range coded bits from byte_buffer to bitstream */ + + /* 1) Push all complete bytes, one byte at a time */ + FOR( i = 0; i < shr( rc_tot_bits, 3 ); ++i ) + { + /* use rc_st_enc.byte_buffer */ + bits = &bit_buffer[shl( i, 3 )]; + + byte = rc_st_enc.byte_buffer[i]; + move16(); + + bits[0] = (UWord16) s_and( shr( (Word16) byte, 7 ), 1 ); + move16(); + bits[1] = (UWord16) s_and( shr( (Word16) byte, 6 ), 1 ); + move16(); + bits[2] = (UWord16) s_and( shr( (Word16) byte, 5 ), 1 ); + move16(); + bits[3] = (UWord16) s_and( shr( (Word16) byte, 4 ), 1 ); + move16(); + bits[4] = (UWord16) s_and( shr( (Word16) byte, 3 ), 1 ); + move16(); + bits[5] = (UWord16) s_and( shr( (Word16) byte, 2 ), 1 ); + move16(); + bits[6] = (UWord16) s_and( shr( (Word16) byte, 1 ), 1 ); + move16(); + bits[7] = (UWord16) s_and( (Word16) byte, 1 ); + move16(); + } + + /* 2) Push remaining bits */ + IF( s_and( rc_tot_bits, 7 ) != 0 ) + { + UWord8 rem_bits = (UWord8) s_and( rc_tot_bits, 7 ); + + bits = &bit_buffer[shl( i, 3 )]; + byte = rc_st_enc.byte_buffer[i]; + move16(); + + FOR( k = 0; k < rem_bits; k++ ) + { + bits[k] = (UWord16) s_and( shr( (Word16) byte, sub( 7, k ) ), 1 ); + move16(); + } + } + + /* Update output number of bits */ + *bit_pos = rc_tot_bits; + move16(); + + return; +} +#else static void ivas_param_mc_range_encoder( const int16_t *seq_in, /* i : input sequence */ const int16_t num_symbols, /* i : Number of symbole to encode */ @@ -1900,3 +2600,4 @@ static void ivas_param_mc_range_encoder( return; } +#endif diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 6b4618eb02e308dd1836da54f97fb1a7d0df5882..c8710785991b1c867b5095689a7b513b876277cc 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -960,12 +960,12 @@ static void ivas_mc_paramupmix_param_est_enc( move32(); } - Word16 gb = find_guarded_bits_fx( hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans ) + 1; #endif l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; #ifdef IVAS_FLOAT_FIXED + Word16 gb = find_guarded_bits_fx( l_ts ); FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { ivas_fb_mixer_get_windowed_fr_fx( hMCParamUpmix->hFbMixer, pcm_in_fx, pp_in_fr_real_fx, pp_in_fr_imag_fx, l_ts, l_ts, hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans, gb ); diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 73e70cbbaaad79bc6bf8df19577d598d39321a81..71e395178dfab26df15d96dd64d11b42487c78e3 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -55,8 +55,20 @@ static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DAT static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, float *data_f[], const int16_t input_frame, const int16_t nchan_inp ); +#ifndef IVAS_FLOAT_FIXED static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] ); - +#else +static void ivas_omasa_dmx_fx( + Word32 *data_in[], /*i:Qx*/ + Word32 data_out[][L_FRAME48k], /*i:Qx*/ + const Word16 input_frame, /*i:q0*/ + const Word16 nchan_transport, /*i:q0*/ + const Word16 nchan_ism, /*i:q0*/ + ISM_METADATA_HANDLE hIsmMeta[], /*i*/ + Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/ + const Word16 interpolator[L_FRAME48k] /*i:q15*/ +); +#endif // IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED static void computeIntensityVector_enc_fx( const Word16 *band_grouping, /* i : Band grouping for estimation */ @@ -488,6 +500,262 @@ void ivas_omasa_set_config( * * Main OMASA encoding function *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_omasa_enc( + OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ + MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ + float *data_in_f[], /* i/o: Input / transport audio signals */ + Word32 *data_in[], /* i/o: Input / transport audio signals */ + Word16 q_data, /* i:Q0 Stores the q for data_in_f */ + const int16_t input_frame, /* i : Input frame size */ + const int16_t nchan_transport, /* i : Number of transport channels */ + const int16_t nchan_ism, /* i : Number of objects for parameter analysis */ + const ISM_MODE ism_mode, /* i : ISM mode */ + float *data_separated_object, /* o : Separated object audio signal */ + int16_t *idx_separated_object /* o : Index of the separated object */ +) +{ + int16_t i, j; + float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k]; +#ifdef IVAS_FLOAT_FIXED + Word32 data_out[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k]; +#endif // IVAS_FLOAT_FIXED + + /* Determine separated object (when applicable) */ + if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + float broadband_energy[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS]; + int16_t loudest_object; + int16_t selected_object; + int16_t nchan_all_inp; + float alpha; + uint8_t fade_out_separate_object; + uint8_t fade_in_separate_object; + + /* Estimate broadband energies */ + nchan_all_inp = nchan_ism + nchan_transport; + set_zero( broadband_energy, nchan_all_inp ); + for ( i = 0; i < nchan_all_inp; i++ ) + { + for ( j = 0; j < input_frame; j++ ) + { + broadband_energy[i] += data_in_f[i][j] * data_in_f[i][j]; + } + } + + /* Temporal averaging */ + alpha = 0.8f; + for ( i = 0; i < nchan_all_inp; i++ ) + { + hOMasa->broadband_energy_sm[i] = ( 1.0f - alpha ) * broadband_energy[i] + alpha * hOMasa->broadband_energy_sm[i]; + } + + /* Determine loudest object */ + loudest_object = 0; + for ( i = 1; i < nchan_ism; i++ ) + { + if ( hOMasa->broadband_energy_sm[i] > hOMasa->broadband_energy_sm[loudest_object] ) + { + loudest_object = i; + } + } + + /* Determine object to separate */ + selected_object = hOMasa->prev_selected_object; + fade_out_separate_object = 0; + fade_in_separate_object = 0; + if ( hOMasa->changing_object ) + { + hOMasa->changing_object = 0; + selected_object = loudest_object; + fade_in_separate_object = 1; + } + else + { + if ( loudest_object != hOMasa->prev_selected_object ) + { + float selected_ene; + float total_ene; + float selected_ratio; + float adaptive_threshold_dB; + float ratio_objects_dB; + float hardswitch_threshold = 0.25f; + + /* Compute the energy of the current and the previous selected object in the current and the previous frame */ + selected_ene = broadband_energy[loudest_object] + broadband_energy[hOMasa->prev_selected_object] + hOMasa->broadband_energy_prev[loudest_object] + hOMasa->broadband_energy_prev[hOMasa->prev_selected_object]; + + /* Compute the energy of all objects and MASA channels in the current and the previous frame */ + total_ene = 0.0f; + for ( i = 0; i < nchan_all_inp; i++ ) + { + total_ene += broadband_energy[i] + hOMasa->broadband_energy_prev[i]; + } + + /* Compute the ratio */ + selected_ratio = selected_ene / ( total_ene + EPSILON ); + + adaptive_threshold_dB = selected_ratio * 9.0f + 1.0f; /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */ + ratio_objects_dB = 10.0f * log10f( hOMasa->broadband_energy_sm[loudest_object] / ( hOMasa->broadband_energy_sm[hOMasa->prev_selected_object] + EPSILON ) ); + + /* Adaptively determine whether to change the separated object. If they are quiet compared to the total energy, change easier, as other signals mask the change. */ + if ( ratio_objects_dB > adaptive_threshold_dB ) + { + if ( selected_ratio < hardswitch_threshold ) /* If low level compared to all audio channels, perform hardswitch */ + { + selected_object = loudest_object; + } + else /* If high level compared to all audio channels, perform switch via fade out fade in */ + { + hOMasa->changing_object = 1; + fade_out_separate_object = 1; + } + } + } + } + + /* Set values for next frame */ + for ( i = 0; i < nchan_all_inp; i++ ) + { + hOMasa->broadband_energy_prev[i] = broadband_energy[i]; + } + hOMasa->prev_selected_object = selected_object; + + /* Separate the selected object */ + *idx_separated_object = selected_object; + mvr2r( data_in_f[selected_object], data_separated_object, input_frame ); + if ( fade_out_separate_object ) + { + v_mult( data_separated_object, hOMasa->fade_out_gain, data_separated_object, input_frame ); + v_mult( data_in_f[selected_object], hOMasa->fade_in_gain, data_in_f[selected_object], input_frame ); + } + else if ( fade_in_separate_object ) + { + v_mult( data_separated_object, hOMasa->fade_in_gain, data_separated_object, input_frame ); + v_mult( data_in_f[selected_object], hOMasa->fade_out_gain, data_in_f[selected_object], input_frame ); + } + else + { + set_zero( data_in_f[selected_object], input_frame ); + } + } + + /* Analysis */ + if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */ + OMASA_SPATIAL_META_HANDLE hOMasaMeta; + uint8_t n_bands_orig, n_subframes_orig; + uint8_t numCodingBands_orig, joinedSubframes_orig; + + hOMasaMeta = &OMasaMeta; + hOMasaMeta->num_dirs = 1; + + /* merge MASA directions before adding ISM to the mixture */ + if ( hMasa->config.numberOfDirections == 2 ) + { + n_bands_orig = hMasa->config.numCodingBands; + hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS; + + ivas_masa_combine_directions( hMasa ); + + hMasa->config.numCodingBands = (int8_t) n_bands_orig; + } + + /* force computation into high resolution */ + + n_subframes_orig = hOMasa->nSubframes; + hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES; + + /* Estimate MASA parameters from the objects */ + /* NB: only first direction is populated */ + /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */ + ivas_omasa_param_est_enc( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in_f, hOMasaMeta->directional_meta[0].elevation, hOMasaMeta->directional_meta[0].azimuth, hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].spread_coherence, hOMasaMeta->common_meta.surround_coherence[0], + hOMasaMeta->common_meta.diffuse_to_total_ratio[0], input_frame, nchan_ism ); + + /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */ + for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS ); + mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS ); + mvr2r( hOMasaMeta->common_meta.diffuse_to_total_ratio[0], hOMasaMeta->common_meta.diffuse_to_total_ratio[i], MASA_FREQUENCY_BANDS ); + } + + /* restore resolution parameters */ + hOMasa->nSubframes = n_subframes_orig; + + /* perform MASA+ISM merge in full resolution */ + numCodingBands_orig = hMasa->config.numCodingBands; + joinedSubframes_orig = hMasa->config.joinedSubframes; + + hMasa->config.numCodingBands = hOMasa->nbands; + hMasa->config.joinedSubframes = 0; + + ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */ + + hMasa->config.numCodingBands = numCodingBands_orig; + hMasa->config.joinedSubframes = joinedSubframes_orig; + } + else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + /* Estimate energies and ratios */ + ivas_omasa_energy_and_ratio_est( hOMasa, hMasa->data.hOmasaData, data_in_f, input_frame, nchan_ism ); + } + + /* Downmix */ +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + for ( j = 0; j < nchan_ism; j++ ) + { + for ( int k = 0; k < input_frame; k++ ) + { + data_in[j][k] = float_to_fix( data_in_f[j][k], q_data ); + } + } + for ( i = 0; i < nchan_ism; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + hOMasa->prev_object_dm_gains_fx[i][j] = float_to_fix16( hOMasa->prev_object_dm_gains[i][j], 15 ); + } + } + for ( i = 0; i < input_frame; i++ ) + { + hOMasa->interpolator_fx[i] = float_to_fix16( hOMasa->interpolator[i], 15 ); + } + FOR( i = 0; i < nchan_ism; i++ ) + { + hIsmMeta[i]->azimuth_fx = float_to_fix( hIsmMeta[i]->azimuth, Q22 ); + hIsmMeta[i]->elevation_fx = float_to_fix( hIsmMeta[i]->elevation, Q22 ); + } +#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED + ivas_omasa_dmx_fx( data_in, data_out, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains_fx, hOMasa->interpolator_fx ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + for ( i = 0; i < nchan_transport; i++ ) + { + fixedToFloat_arrL( data_out[i], data_out_f[i], q_data, input_frame ); + } + for ( i = 0; i < nchan_ism; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + hOMasa->prev_object_dm_gains[i][j] = fixedToFloat( hOMasa->prev_object_dm_gains_fx[i][j], 15 ); + } + } +#endif + + /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */ + if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + hIsmMeta[0]->azimuth = hIsmMeta[*idx_separated_object]->azimuth; + hIsmMeta[0]->elevation = hIsmMeta[*idx_separated_object]->elevation; + } + + /* Merge transport signals */ + ivas_merge_masa_transports( data_out_f, &( data_in_f[nchan_ism] ), data_in_f, input_frame, nchan_transport ); + + return; +} +#else void ivas_omasa_enc( OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */ @@ -700,6 +968,7 @@ void ivas_omasa_enc( return; } +#endif // IVAS_FLOAT_FIXED /*-------------------------------------------------------------------------* @@ -1608,6 +1877,62 @@ static void ivas_omasa_energy_and_ratio_est( /* Compute downmix */ +#ifdef IVAS_FLOAT_FIXED +static void ivas_omasa_dmx_fx( + Word32 *data_in[], /*i:Qx*/ + Word32 data_out[][L_FRAME48k], /*i:Qx*/ + const Word16 input_frame, /*i:q0*/ + const Word16 nchan_transport, /*i:q0*/ + const Word16 nchan_ism, /*i:q0*/ + ISM_METADATA_HANDLE hIsmMeta[], /*i*/ + Word16 prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], /*o:q15*/ + const Word16 interpolator[L_FRAME48k] /*i:q15*/ +) +{ + Word16 i, j, k; + Word16 azimuth, elevation; + Word16 gains[MASA_MAX_TRANSPORT_CHANNELS]; + Word16 g1, g2; + + FOR( i = 0; i < nchan_transport; i++ ) + { + set_zero_fx( data_out[i], input_frame ); + } + + FOR( i = 0; i < nchan_ism; i++ ) + { + azimuth = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, ONE_IN_Q21 ), 22 ) ); /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/ + elevation = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, ONE_IN_Q21 ), 22 ) ); /* scaling from q22 to q0 for ivas_get_stereo_panning_gains_fx*/ + + /*gains is q15*/ + /*azimuth is q0*/ + /*elevation is q0*/ + ivas_get_stereo_panning_gains_fx( azimuth, elevation, gains ); + + /* Downmix using the panning gains */ + FOR( j = 0; j < nchan_transport; j++ ) + { + test(); + IF( abs_s( gains[j] ) > 0 || abs_s( prev_gains[i][j] ) > 0 ) + { + FOR( k = 0; k < input_frame; k++ ) + { + g1 = interpolator[k]; + move16(); + g2 = sub( MAX_WORD16, g1 ); /*q15*/ + data_out[j][k] = L_add( data_out[j][k], Mpy_32_32( L_add( L_mult( g1, gains[j] ), L_mult( g2, prev_gains[i][j] ) ) /*q31*/, data_in[i][k] ) ); /*Qx*/ + move32(); + } + } + prev_gains[i][j] = gains[j]; /*q15*/ + move16(); + } + } + + return; +} +#else + static void ivas_omasa_dmx( float *data_in_f[], float data_out_f[][L_FRAME48k], @@ -1653,7 +1978,7 @@ static void ivas_omasa_dmx( return; } - +#endif #ifdef IVAS_FLOAT_FIXED void computeIntensityVector_enc_fx( diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index b170b0066565665698de119764afe6f344889653..6e4d19a361588b1e897648b2f369967091f012e3 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -49,15 +49,52 @@ /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void ivas_osba_render_ism_to_sba( float *data_in_f[], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_sba, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MAX_INPUT_CHANNELS], const float interpolator[L_FRAME48k] ); - +#else +static void ivas_osba_render_ism_to_sba_fx( + Word32 *data_in_fx[], + Word32 data_out_fx[][L_FRAME48k], + const Word16 input_frame, + const Word16 sba_analysis_order, + const Word16 nchan_ism, + ISM_METADATA_HANDLE hIsmMeta[], + Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], + const Word32 interpolator_fx[L_FRAME48k], + Word16 *Q_data ); +#endif /*-------------------------------------------------------------------* * ivas_merge_sba_transports() * * Merge SBA transport channels *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_merge_sba_transports_fx( + Word32 data_in_f1[][L_FRAME48k], + Word32 *data_in_f2[], + Word32 *data_out_f[], + const Word16 input_frame, + const Word16 sba_analysis_order, + Word16 Q_f1, + Word16 Q_f2, + Word16 *Q_out ) +{ + Word16 i, j, nchan_sba; + nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); + + FOR( i = 0; i < nchan_sba; i++ ) + { + FOR( j = 0; j < input_frame; j++ ) + { + data_out_f[i][j] = L_add( L_shr( data_in_f1[i][j], 1 ), L_shr( data_in_f2[i][j], sub( Q_f2, sub( Q_f1, 1 ) ) ) ); + move32(); + } + } + *Q_out = sub( Q_f1, 1 ); + return; +} +#else static void ivas_merge_sba_transports( float data_in_f1[][L_FRAME48k], float *data_in_f2[], @@ -79,13 +116,63 @@ static void ivas_merge_sba_transports( return; } - +#endif /*--------------------------------------------------------------------------* * ivas_osba_enc_open() * * Allocate and initialize OMASA handle *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_osba_enc_open_fx( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +) +{ + Word16 i; + OSBA_ENC_HANDLE hOSba; + Word16 input_frame; + ivas_error error; + Word16 len; + error = IVAS_ERR_OK; + IF( ( hOSba = (OSBA_ENC_HANDLE) malloc( sizeof( OSBA_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) ); + } + FOR( i = 0; i < MAX_NUM_OBJECTS; i++ ) + { + set_val_Word32( hOSba->prev_object_dm_gains_fx[i], INV_SQRT_2_Q30, MAX_INPUT_CHANNELS ); + } + len = NS2SA( st_ivas->hEncoderConfig->input_Fs, IVAS_FB_ENC_DELAY_NS ); + move16(); + FOR( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + IF( ( hOSba->input_data_mem_fx[i] = (Word32 *) malloc( len * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OSBA input buffers" ); + } + set_val_Word32( hOSba->input_data_mem_fx[i], 0, len ); + } + FOR( ; i < MAX_NUM_OBJECTS; i++ ) + { + hOSba->input_data_mem_fx[i] = NULL; + } + Word16 tmp_e; + Word32 tmp32 = L_deposit_h( BASOP_Util_Divide3216_Scale( st_ivas->hEncoderConfig->input_Fs, FRAMES_PER_SEC, &tmp_e ) ); + tmp32 = L_shr( tmp32, sub( 15, tmp_e ) ); + input_frame = extract_l( tmp32 ); + + for ( i = 0; i < input_frame; i++ ) + { + tmp32 = L_deposit_h( BASOP_Util_Divide1616_Scale( i, input_frame, &tmp_e ) ); + hOSba->interpolator_fx[i] = L_shl( tmp32, tmp_e ); + move32(); + } + + st_ivas->hOSba = hOSba; + + return error; +} +#else ivas_error ivas_osba_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) @@ -133,14 +220,38 @@ ivas_error ivas_osba_enc_open( return error; } - +#endif /*--------------------------------------------------------------------------* * ivas_omasa_enc_close() * * Close OMASA handle *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_osba_enc_close_fx( + OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */ +) +{ + Word16 n; + test(); + IF( hOSba == NULL || *hOSba == NULL ) + { + return; + } + FOR( n = 0; n < MAX_NUM_OBJECTS; n++ ) + { + IF( ( *hOSba )->input_data_mem_fx[n] != NULL ) + { + free( ( *hOSba )->input_data_mem_fx[n] ); + ( *hOSba )->input_data_mem_fx[n] = NULL; + } + } + free( *hOSba ); + ( *hOSba ) = NULL; + return; +} +#else void ivas_osba_enc_close( OSBA_ENC_HANDLE *hOSba /* i/o: encoder OSBA handle */ ) @@ -164,7 +275,7 @@ void ivas_osba_enc_close( return; } - +#endif /*--------------------------------------------------------------------------* * ivas_osba_enc_reconfig() @@ -628,13 +739,70 @@ ivas_error ivas_osba_enc_reconfig( return error; } #endif - +#ifdef IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------* * ivas_osba_enc() * * Main OSBA encoding function *--------------------------------------------------------------------------*/ +void ivas_osba_enc_fx( + OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ + Word32 *data_in_fx[], /* i/o: Input / transport audio signals */ + const Word16 input_frame, /* i : Input frame size */ + const Word16 nchan_ism, /* i : Number of objects for parameter analysis */ + const ISM_MODE ism_mode, /* i : ISM mode */ + const Word16 sba_analysis_order, /* i : SBA order evaluated in DirAC/SPAR encoder */ + const Word32 input_Fs, /* i : input sampling rate */ + const Word16 sba_planar, /* i : planar SBA flag */ + Word16 *q_data ) +{ + Word32 data_out_fx[MAX_INPUT_CHANNELS][L_FRAME48k]; + Word16 Q_out = *q_data; + move16(); + Word16 n, delay_s; + delay_s = NS2SA( input_Fs, IVAS_FB_ENC_DELAY_NS ); + IF( ism_mode == ISM_MODE_NONE ) + { + /*keep the delay buffer up to date*/ + FOR( n = 0; n < nchan_ism; n++ ) + { + MVR2R_WORD32( &data_in_fx[n][input_frame - delay_s], hOSba->input_data_mem_fx[n], delay_s ); + } + /* Convert ISM to SBA */ + + ivas_osba_render_ism_to_sba_fx( data_in_fx, data_out_fx, input_frame, sba_analysis_order, nchan_ism, hIsmMeta, hOSba->prev_object_dm_gains_fx, hOSba->interpolator_fx, &Q_out ); + + IF( sba_planar ) + { + ivas_sba_zero_vert_comp_fx( &( data_in_fx[nchan_ism] ), sba_analysis_order, sba_planar, input_frame ); + } + + + /* Merge SBA signals */ + ivas_merge_sba_transports_fx( data_out_fx, &( data_in_fx[nchan_ism] ), data_in_fx, input_frame, sba_analysis_order, Q_out, *q_data, q_data ); + } + ELSE + { + Word16 azimuth_fx, elevation_fx; + /* delay ISM input channels to match the SBA encoder delay */ + FOR( n = 0; n < nchan_ism; n++ ) + { + delay_signal_fx( data_in_fx[n], input_frame, hOSba->input_data_mem_fx[n], delay_s ); + + azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[n]->azimuth_fx, 2097152 ), Q22 ) ); + elevation_fx = extract_l( L_shr( L_add( hIsmMeta[n]->elevation_fx, 2097152 ), Q22 ) ); + ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, hOSba->prev_object_dm_gains_fx[n], sba_analysis_order, Q30 ); + } + } + + /* Set the number of objects */ + hOSba->nchan_ism = nchan_ism; + move16(); + return; +} +#else void ivas_osba_enc( OSBA_ENC_HANDLE hOSba, /* i/o: OSBA encoder handle */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */ @@ -691,12 +859,87 @@ void ivas_osba_enc( return; } - +#endif /*--------------------------------------------------------------------------* * Local functions *--------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/* Render ISMs to SBA */ +static void ivas_osba_render_ism_to_sba_fx( + Word32 *data_in_fx[], + Word32 data_out_fx[][L_FRAME48k], + const Word16 input_frame, + const Word16 sba_analysis_order, + const Word16 nchan_ism, + ISM_METADATA_HANDLE hIsmMeta[], + Word32 prev_gains_fx[][MAX_INPUT_CHANNELS], + const Word32 interpolator_fx[L_FRAME48k], + Word16 *Q_data ) +{ + Word16 i, j, k; + Word16 azimuth_fx, elevation_fx; + Word32 gains_fx[MAX_INPUT_CHANNELS]; + Word32 g1_fx, g2_fx; + Word32 output_gain_fx; + Word16 nchan_sba; + nchan_sba = imult1616( add( sba_analysis_order, 1 ), add( sba_analysis_order, 1 ) ); + + FOR( i = 0; i < nchan_sba; i++ ) + { + set_val_Word32( data_out_fx[i], 0, input_frame ); + } + + FOR( i = 0; i < nchan_ism; i++ ) + { + // azimuth = (int16_t) floorf( hIsmMeta[i]->azimuth + 0.5f ); + azimuth_fx = extract_l( L_shr( L_add( hIsmMeta[i]->azimuth_fx, 2097152 ), Q22 ) ); + // elevation = (int16_t) floorf( hIsmMeta[i]->elevation + 0.5f ); + elevation_fx = extract_l( L_shr( L_add( hIsmMeta[i]->elevation_fx, 2097152 ), Q22 ) ); + + ivas_dirac_dec_get_response_fx( azimuth_fx, elevation_fx, gains_fx, sba_analysis_order, Q30 ); + + /* Render using the sh gains */ + FOR( j = 0; j < nchan_sba; j++ ) + { + IF( L_abs( gains_fx[j] ) > 0 || L_abs( prev_gains_fx[i][j] ) > 0 ) + { + FOR( k = 0; k < input_frame; k++ ) + { + // g1 = interpolator[k]; + g1_fx = interpolator_fx[k]; + move32(); + // g2 = 1.0f - g1; + g2_fx = L_sub( ONE_IN_Q31, g1_fx ); + move32(); + // data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k]; + data_out_fx[j][k] = L_add( data_out_fx[j][k], L_shr( Mpy_32_32( L_add( Mpy_32_32( g1_fx, gains_fx[j] ), Mpy_32_32( g2_fx, prev_gains_fx[i][j] ) ), data_in_fx[i][k] ), 1 ) ); // Q_data-2 + move32(); + } + } + prev_gains_fx[i][j] = gains_fx[j]; + move32(); + } + } + *Q_data = sub( *Q_data, 2 ); + /* Gain with loudness-matching gains */ + // output_gain = 0.7499f; + output_gain_fx = 1610397988; // 0.7499f in Q31 + move32(); + FOR( j = 0; j < nchan_sba; j++ ) + { + FOR( k = 0; k < input_frame; k++ ) + { + // data_out_f[j][k] *= output_gain; + data_out_fx[j][k] = Mpy_32_32( data_out_fx[j][k], output_gain_fx ); + move32(); + } + } + + return; +} +#else /* Render ISMs to SBA */ static void ivas_osba_render_ism_to_sba( float *data_in_f[], @@ -758,3 +1001,5 @@ static void ivas_osba_render_ism_to_sba( return; } + +#endif diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index e19ec84afbf0457800de2c82a77e5b75985048f4..2e44e50ae7dbf07153538380b1d236290a120c3a 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1082,6 +1082,8 @@ typedef struct ivas_param_mc_enc_data_structure int16_t transient_detector_delay; const float *dmx_factors; + const Word32 *dmx_factors_fx; + /* Multichannel Specific Parameters */ IVAS_PARAM_MC_METADATA hMetadataPMC; int16_t band_grouping[PARAM_MC_MAX_PARAMETER_BANDS + 1]; @@ -1122,6 +1124,10 @@ typedef struct ivas_mc_paramupmix_enc_data_structure typedef struct ivas_omasa_enc_state_structure { +#ifdef IVAS_FLOAT_FIXED + Word16 interpolator_fx[L_FRAME48k]; /*q15*/ + Word16 prev_object_dm_gains_fx[MAX_NUM_OBJECTS][MASA_MAX_TRANSPORT_CHANNELS]; /*q15*/ +#endif // IVAS_FLOAT_FIXED uint8_t nbands; uint8_t nCodingBands; uint8_t nSubframes; @@ -1296,12 +1302,25 @@ typedef struct ivas_mcmasa_enc_data_structure typedef struct ivas_osba_enc_data_structure { + +#ifdef IVAS_FLOAT_FIXED + Word32 interpolator_fx[L_FRAME48k]; +#else float interpolator[L_FRAME48k]; - float prev_object_dm_gains[MAX_NUM_OBJECTS][MAX_INPUT_CHANNELS]; +#endif +#ifdef IVAS_FLOAT_FIXED + Word32 prev_object_dm_gains_fx[MAX_NUM_OBJECTS][MAX_INPUT_CHANNELS]; +#else + float prev_object_dm_gains[MAX_NUM_OBJECTS][MAX_INPUT_CHANNELS]; +#endif int16_t nchan_ism; - float *input_data_mem[MAX_NUM_OBJECTS]; +#ifdef IVAS_FLOAT_FIXED + Word32 *input_data_mem_fx[MAX_NUM_OBJECTS]; +#else + float *input_data_mem[MAX_NUM_OBJECTS]; +#endif } OSBA_ENC_DATA, *OSBA_ENC_HANDLE; /*----------------------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 31aadab524359cc17d2b18be471674b042b78844..0c21dde3aab42da61478479a36a1e1cfdd589ef9 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -101,9 +101,8 @@ static ivas_error allocate_CoreCoder_enc_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); } #ifdef IVAS_FLOAT_FIXED - wb_vad_init_fx( st->hVAD ); + wb_vad_init_ivas_fx( st->hVAD ); #endif - wb_vad_init( st->hVAD ); } IF( st->hSpMusClas == NULL ) @@ -164,7 +163,11 @@ static ivas_error allocate_CoreCoder_enc( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for VAD\n" ) ); } +#ifndef IVAS_FLOAT_FIXED wb_vad_init( st->hVAD ); +#else + wb_vad_init_fx( st->hVAD ); +#endif } if ( st->hSpMusClas == NULL ) diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 699ec832561476b09d00ae024609f1c9744bb0ee..a4776eeb801fde98fde2acf0e00ad08e67aaa3f3 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -226,21 +226,23 @@ typedef struct vad_structure int16_t hangover_cnt_dtx; int16_t hangover_cnt_music; - +#ifndef IVAS_FLOAT_FIXED float bcg_flux; +#endif Word16 bcg_flux_fx; // Q4 int16_t soft_hangover; int16_t voiced_burst; int16_t bcg_flux_init; int16_t nb_active_frames_he1; int16_t hangover_cnt_he1; - - float prim_act_quick; /* Noise estimator - primary activity quick */ - float prim_act_slow; /* Noise estimator - primary activity slow */ - float prim_act; /* Noise estimator - primary activity slow rise quick fall */ - float prim_act_quick_he; /* Noise estimator - primary activity quick */ - float prim_act_slow_he; /* Noise estimator - primary activity slow */ - float prim_act_he; /* Noise estimator - primary activity slow rise quick fall */ +#ifndef IVAS_FLOAT_FIXED + float prim_act_quick; /* Noise estimator - primary activity quick */ + float prim_act_slow; /* Noise estimator - primary activity slow */ + float prim_act; /* Noise estimator - primary activity slow rise quick fall */ + float prim_act_quick_he; /* Noise estimator - primary activity quick */ + float prim_act_slow_he; /* Noise estimator - primary activity slow */ + float prim_act_he; /* Noise estimator - primary activity slow rise quick fall */ +#endif Word16 prim_act_quick_fx; /*Q15 */ /* Noise estimator - primary activity quick */ Word16 prim_act_slow_fx; /*Q15 */ /* Noise estimator - primary activity slow */ Word16 prim_act_fx; /*Q15 */ /* Noise estimator - primary activity slow rise quick fall */ @@ -250,11 +252,15 @@ typedef struct vad_structure int16_t spectral_tilt_reset; int16_t consec_inactive; +#ifndef IVAS_FLOAT_FIXED float ra_deltasum; +#endif Word16 ra_deltasum_fx; int16_t trigger_SID; +#ifndef IVAS_FLOAT_FIXED float running_avg; float snr_sum_vad; +#endif Word16 snr_sum_vad_fx; /*Q15 */ Word16 running_avg_fx; /*Q15 */ Word32 L_snr_sum_vad_fx; /*Q4*/ diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 4881d9f8baec0e8cb89deb35b3b33c4790fab825..b7901de5bd138c7397a22398151422e80fb3e543 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -5966,7 +5966,6 @@ static void singlevectortest_gain_fx( Word16 k, interNum, flag; Word32 meanU, meanQ; Word16 least[4]; - Word32 L_tmp; interNum = 4; move16(); @@ -5976,7 +5975,6 @@ static void singlevectortest_gain_fx( meanU = sum32_fx( inp, dimen ); /* Q18 */ Copy32( codebook + dimen * least[0], recon, dimen ); - L_tmp = L_shl( Mult_32_16( meanU, 18022 ), 1 ); /* Q18 */ index[0] = least[0]; move16(); flag = 0; @@ -5986,7 +5984,8 @@ static void singlevectortest_gain_fx( IF( flag == 0 ) { meanQ = sum32_fx( codebook + dimen * least[k], dimen ); /* Q18 */ - IF( LE_32( meanQ, L_tmp ) ) + /* if ( meanQ <= 1.1 * meanU ) */ + IF( LE_32( Mpy_32_16_1( meanQ, 29789 /* 1/1.1 in Q15*/ ), meanU ) ) { flag = 1; move16(); diff --git a/lib_enc/vad.c b/lib_enc/vad.c index 24f194ac86e19c83bfc0e3cdb2ba0ed105d9d67f..0ba928ad35502da29aebe420c52b4c01e04dac91 100644 --- a/lib_enc/vad.c +++ b/lib_enc/vad.c @@ -74,7 +74,7 @@ * * VAD initializations *---------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void wb_vad_init( VAD_HANDLE hVAD /* i/o: VAD data handle */ ) @@ -116,21 +116,17 @@ void wb_vad_init( hVAD->trigger_SID = 0; hVAD->snr_sum_vad = 0; -#ifdef IVAS_FLOAT_FIXED - hVAD->L_snr_sum_vad_fx = 0; -#endif - hVAD->hangover_terminate_flag = 0; return; } - +#endif /*-----------------------------------------------------------------* * sing_thr_snr_acc() * * accumulate snr_sum with significance thresholds *-----------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void sign_thr_snr_acc( float *snr_sum, float snr, @@ -148,13 +144,13 @@ static void sign_thr_snr_acc( return; } - +#endif /*-----------------------------------------------------------------* * dtx_hangover_addition() * * accumulate snr_sum with significance thresholds *-----------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED int16_t dtx_hangover_addition( Encoder_State *st, /* i/o: encoder state structure */ const int16_t vad_flag, /* i : VAD flag */ @@ -313,14 +309,14 @@ int16_t dtx_hangover_addition( return flag_dtx; } - +#endif /*-----------------------------------------------------------------* * wb_vad() * * Voice Activity Detector *-----------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED int16_t wb_vad( Encoder_State *st, /* i/o: encoder state structure */ const float fr_bands[], /* i : per band input energy (contains 2 vectors) */ @@ -1101,3 +1097,4 @@ int16_t wb_vad( return flag; } +#endif diff --git a/lib_enc/vad_fx.c b/lib_enc/vad_fx.c index fbb3f5161831f9732c1519c3ca67bdc3eeab5d9a..6723304c71f5fdebe1f216aa28f029cdb4965445 100644 --- a/lib_enc/vad_fx.c +++ b/lib_enc/vad_fx.c @@ -137,6 +137,8 @@ void wb_vad_init_ivas_fx( VAD_HANDLE hVAD /* i/o: VAD data handle */ ) { + hVAD->L_snr_sum_vad_fx = 0; + move32(); hVAD->hangover_cnt = 0; move16(); /* Hangover counter initialized to 0 */ hVAD->nb_active_frames = ACTIVE_FRAMES_FX; @@ -195,8 +197,6 @@ void wb_vad_init_ivas_fx( move16(); hVAD->trigger_SID = 0; move16(); - hVAD->snr_sum_vad = 0; - move16(); hVAD->hangover_terminate_flag = 0; move16(); return; diff --git a/lib_enc/vad_param_updt.c b/lib_enc/vad_param_updt.c index 6f52d2be915d1f1db93619d319d448134d222a3f..9a472c1be15200f9721cb61fccfaf5897a4671cf 100644 --- a/lib_enc/vad_param_updt.c +++ b/lib_enc/vad_param_updt.c @@ -46,7 +46,7 @@ * * Update parameters used by the VAD or DTX *--------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED void vad_param_updt( Encoder_State *st, /* i/o: encoder state structure */ const float corr_shift, /* i : correlation shift */ @@ -171,3 +171,4 @@ void vad_param_updt( return; } +#endif