diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index c015e5738d730286664ff79239531369517fce28..fa7a11611d6b446372e40d1e2989024ee272dcb8 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -2808,6 +2808,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17036; hs->scale = cldfb_scale_2_5ms[0]; hs->p_filter = CLDFB80_10_fx; @@ -2824,6 +2828,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->p_filter = LDQMF_10_fx; hs->scale = cldfb_scale_5_0ms[0]; @@ -2859,6 +2867,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17051; hs->p_filter = CLDFB80_16_fx; hs->scale = cldfb_scale_2_5ms[1]; @@ -2875,6 +2887,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->p_filter = LDQMF_16_fx; hs->scale = cldfb_scale_5_0ms[1]; @@ -2916,6 +2932,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17050; hs->p_filter = CLDFB80_20_fx; hs->scale = cldfb_scale_2_5ms[2]; @@ -2932,6 +2952,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15390; hs->p_filter = LDQMF_20_fx; hs->scale = cldfb_scale_5_0ms[2]; @@ -2973,6 +2997,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17051; hs->scale = cldfb_scale_2_5ms[6]; hs->p_filter = CLDFB80_30_fx; @@ -2989,6 +3017,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->scale = cldfb_scale_5_0ms[6]; hs->p_filter = LDQMF_30_fx; @@ -3024,6 +3056,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17050; hs->p_filter = CLDFB80_32_fx; hs->scale = cldfb_scale_2_5ms[3]; @@ -3040,6 +3076,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = rot_vec_delay_re_LDQMF; hs->rot_vec_syn_delay_im = rot_vec_delay_im_LDQMF; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15392; hs->scale = cldfb_scale_5_0ms[3]; hs->p_filter = LDQMF_32_fx; @@ -3081,6 +3121,10 @@ static void cldfb_init_proto_and_twiddles_enc( hs->rot_vec_syn_delay_re = NULL; hs->rot_vec_syn_delay_im = NULL; #ifdef IVAS_FLOAT_FIXED + hs->rot_vec_ana_delay_re_fx = NULL; + hs->rot_vec_ana_delay_im_fx = NULL; + hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17051; hs->q_scale = norm_s( (Word16) CLDFB80_40_SCALE ); hs->scale = cldfb_scale_2_5ms[4]; diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c index 52845b2ed2edc8051baa88f9032d6bc5532ac178..d1e24e065df58147930e9cc4b4c45e6a83cffb91 100644 --- a/lib_com/cng_exc.c +++ b/lib_com/cng_exc.c @@ -49,6 +49,7 @@ #define A2 0.2f #define GAIN_VAR 0.000011f +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------* * CNG_exc() * @@ -469,6 +470,7 @@ void cng_params_postupd( return; } +#endif /*-------------------------------------------------------* diff --git a/lib_com/guided_plc_util.c b/lib_com/guided_plc_util.c index af03981fe3874d4c5f564a434b628fcfd2edf83b..c3976bdb806d8bb1ac9e44a992ac86a85498f425 100644 --- a/lib_com/guided_plc_util.c +++ b/lib_com/guided_plc_util.c @@ -40,13 +40,12 @@ #include "rom_com.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * Local function prototypes *-------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED static void reorder_lsfs_flt( float *lsf, float min_dist, const int16_t n, const int32_t sr_core ); -#endif /*-------------------------------------------------------------------* @@ -141,7 +140,7 @@ void getConcealedLP_flt( * * *-------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED + void RecLpcSpecPowDiffuseLc_flt( float *lspq, float *lsp_old, @@ -184,7 +183,6 @@ void RecLpcSpecPowDiffuseLc_flt( return; } -#endif /*-------------------------------------------------------------------* * modify_lsf_flt() @@ -238,7 +236,6 @@ void modify_lsf_flt( * *-------------------------------------------------------------------*/ -#ifndef IVAS_FLOAT_FIXED static void reorder_lsfs_flt( float *lsf, /* i/o: vector of lsfs in the frequency domain (0..0.5)*/ float min_dist, /* i : minimum required distance */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 7c23752cfb36b045ff2234961ef0997b89c16d0d..029c82634c0a19c10b9e4ddac02da4504ded2dad 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1550,9 +1550,11 @@ typedef enum #define PARAM_MC_ENER_LIMIT_MAX_DELTA_FAC (15.0f) #define PARAM_MC_NUM_ATTACK_ILD_THRESH (3) #define PARAM_MC_LFE_ON_THRESH (8000.0f) +#define PARAM_MC_LFE_ON_THRESH_FX 8000 //Q0 #define PARAM_MC_BAND_TO_MDCT_BAND_RATIO 16 /* Ratio of resolution of CLDFB Bands to MDCT Bands */ #define PARAM_MC_SLOT_ENC_NS 2500000L #define PARAM_MC_MDFT_NO_SLOTS 8 +#define INV_PARAM_MC_MDFT_NO_SLOTS_FX 4096 //Q15 #define PARAM_MC_CLDFB_TO_MDFT_FAC 2 /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com.c index 379fe55628a96f9d07c2b9e525735f23e5d8c6ad..2af6a9cc5e1aded3e56c50f657a7b174180fe812 100644 --- a/lib_com/ivas_mc_param_com.c +++ b/lib_com/ivas_mc_param_com.c @@ -254,6 +254,9 @@ void ivas_param_mc_metadata_open( hMetadataPMC->icc_mapping_conf = ivas_param_mc_conf[config_index].icc_mapping_conf; hMetadataPMC->ild_mapping_conf = ivas_param_mc_conf[config_index].ild_mapping_conf; hMetadataPMC->ild_factors = ivas_param_mc_conf[config_index].ild_factors; +#ifdef IVAS_FLOAT_FIXED + hMetadataPMC->ild_factors_fx = ivas_param_mc_conf[config_index].ild_factors_fx; /*Q15*/ +#endif #ifndef FIX_901_PARAMMC_DEAD_CODE /* set default ICC maps */ diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b352b4803c386a6ef89082867955c2845c09f56e..54ed0a26b5c331bb46225bf7ce31c9237fb61856 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5146,10 +5146,9 @@ void calculate_hodirac_sector_parameters( ); #ifdef IVAS_FLOAT_FIXED -void ivas_mc_paramupmix_enc( +void ivas_mc_paramupmix_enc_fx( 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 */ Word32 *data_fx[], const int16_t input_frame /* i : input frame length */ ); @@ -6186,7 +6185,25 @@ ivas_error ivas_spar_md_enc_open_fx( void ivas_spar_md_enc_close( ivas_spar_md_enc_state_t **hMdEnc /* i/o: SPAR MD encoder handle */ ); - +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_spar_md_enc_process_fx( + ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *cov_dtx_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + const int16_t dtx_vad, + const int16_t nchan_inp, + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + float *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH], /* i : prior mixer_matrix */ + const int16_t dyn_active_w_flag, /* i : flag to indicate dynamic active W */ + const int16_t dirac_mono_flag /* i : flag to indicate mono only mode in SBA */ +); +#else ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ @@ -6200,7 +6217,7 @@ ivas_error ivas_spar_md_enc_process( const int16_t dyn_active_w_flag, /* i : flag to indicate dynamic active W */ const int16_t dirac_mono_flag /* i : flag to indicate mono only mode in SBA */ ); - +#endif void ivas_compute_spar_params( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index ad8fe5a8d1b4ce26dc98f9dbfc498a4762411c51..d0f437e70f554699f4c4d37b86607af27f1c9974 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -1531,6 +1531,26 @@ const Word32 delta_theta_masa_fx[NO_SPHERICAL_GRIDS - 2] = { 188743680, 188743680, 150994944, 106954752, 83886080, 62914560, 45214596, 28101836, 20971520 }; +// q = 14 +const Word16 coherence_cb0_masa_Q14[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] = { + 783, 4173, 9036, 16163, 22238, 27587, 32234, 0, + 1984, 6755, 11464, 16636, 23260, 29444, 0, 0, + 2644, 9296, 15906, 22444, 28438, 0, 0, 0, + 3849, 11970, 19744, 27111, 0, 0, 0, 0, + 3901, 11772, 19264, 26763, 0, 0, 0, 0, + 3932, 11513, 18689, 26613, 0, 0, 0, 0, + 5764, 15398, 26958, 0, 0, 0, 0, 0, + 16384, 0, 0, 0, 0, 0, 0, 0, + 2367, 5623, 8767, 12327, 16540, 21643, 28507, 0, + 3280, 7286, 11254, 15717, 21447, 27900, 0, 0, + 4288, 9103, 14164, 19964, 26298, 0, 0, 0, + 5436, 11158, 17113, 24101, 0, 0, 0, 0, + 5446, 10794, 16351, 23206, 0, 0, 0, 0, + 5535, 10908, 16399, 23378, 0, 0, 0, 0, + 6531, 13507, 22161, 0, 0, 0, 0, 0, + 16384, 0, 0, 0, 0, 0, 0, 0 +}; + // q = 21 const Word32 coherence_cb0_masa_fx[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] = { 100243, 534144, 1156579, 2068840, 2846464, 3531184, 4125936, 0, 253965, 864655, 1467377, @@ -1544,6 +1564,15 @@ const Word32 coherence_cb0_masa_fx[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH] = 1728892, 2836607, 0, 0, 0, 0, 0, 2097152, 0, 0, 0, 0, 0, 0, 0 }; +// q = 15 +const Word16 coherence_cb1_masa_Q15[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS] = { + -62, 8510, -8834, 20542, -20627, + -180, 8461, -9123, 21211, -21424, + -95, 8212, -8618, 21293, -21430, + -13, 8343, -8451, 22449, -22095, + 56, 8261, -8123, 23649, -23452 +}; + // q = 21 const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS] = { -3984, 544630, -565392, 1314704, -1320157, -11534, 541484, -583847, 1357486, -1371118, diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index 67dabdce32a7028ec56b6e7f62a6b34bac99073e..ffb6692aab95733ed10e177e6b512f085acd9c1e 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -166,8 +166,10 @@ extern const Word16 ivas_param_mc_quant_icc_fx[PARAM_MC_SZ_ICC_QUANTIZER]; extern const Word32 no_phi_masa_inv_fx[NO_SPHERICAL_GRIDS][MAX_NO_THETA]; extern const Word32 azimuth_cb_fx[8]; extern const Word32 delta_theta_masa_fx[NO_SPHERICAL_GRIDS - 2]; +extern const Word16 coherence_cb0_masa_Q14[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH]; extern const Word32 coherence_cb0_masa_fx[DIRAC_DIFFUSE_LEVELS * 2 * MASA_NO_CV_COH]; -extern const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS]; /* 25 */ +extern const Word16 coherence_cb1_masa_Q15[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS]; /* 25 */ +extern const Word32 coherence_cb1_masa_fx[MASA_NO_CV_COH1 * MASA_MAXIMUM_CODING_SUBBANDS]; /* 25 */ /* Multi-channel input and output setups */ extern const Word16 ls_azimuth_CICP2_idx[2]; diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index 34a0e6f89cdde2ce745ac60b7f0695793eb9053b..4d063b5b0fc3012e5b0705bd9bee8fd0b89216fc 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -1658,6 +1658,7 @@ void lsf2lsp( } +#ifndef IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------- * tcvq_Dec() * @@ -1779,6 +1780,7 @@ static void tcvq_Dec( return; } + /*--------------------------------------------------------------------------- * qlsf_ARSN_tcvq_Dec_16k() * @@ -2000,6 +2002,7 @@ void lsf_update_memory_float( return; } +#endif /*--------------------------------------------------------------------------* * tcxlpc_get_cdk() diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index 14254283dff1cdeee42944490b7b2a320c0888d6..4b8d785b48ee09f686b9b275076a4f115a5c5669 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -225,6 +225,8 @@ int16_t modify_Fs( return lg_out; } + +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * modify_Fs_intcub3m_sup() * @@ -473,6 +475,8 @@ int16_t modify_Fs_intcub3m_sup( return lg_out; } +#endif + /*-------------------------------------------------------------------* * Interpolate_allpass_steep() diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index aec2805a07fb4ec07fc468433241b4dcfc9853dc..139e15c44039b8f26cbf7b94a8a797bd215decf3 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -53,9 +53,11 @@ *-----------------------------------------------------------------*/ static void create_random_vector( float output[], const int16_t length, int16_t seed[] ); +#ifndef IVAS_FLOAT_FIXED static void flip_spectrum( const float input[], float output[], const int16_t length ); static void Hilbert_transform( float tmp_R[], float tmp_I[], float *tmpi_R, float *tmpi_I, const int16_t length, const int16_t HB_stage_id ); static void Estimate_mix_factors( const float *shb_res, const float *exc16kWhtnd, const float *White_exc16k, const float pow1, const float pow22, float *vf_modified, int16_t *vf_ind ); +#endif /*-------------------------------------------------------------------* * swb_tbe_reset() @@ -124,6 +126,7 @@ int16_t tbe_celp_exc_offset_flt( } +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * flip_and_downmix_generic() * @@ -302,6 +305,7 @@ void flip_spectrum( return; } +#endif /*-------------------------------------------------------------------* * flip_spectrum_and_decimby4() @@ -488,6 +492,7 @@ void GenShapedWBExcitation( return; } +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * GenWBSynth() * @@ -1176,7 +1181,6 @@ void GenShapedSHBExcitation( return; } -#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * GenSHBSynth() * @@ -1869,6 +1873,7 @@ void wb_tbe_extras_reset_synth( return; } +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * elliptic_bpf_48k_generic() * @@ -2064,6 +2069,7 @@ static void Estimate_mix_factors( return; } +#endif /*-------------------------------------------------------------------* * tbe_celp_exc_flt() * diff --git a/lib_com/window_ola.c b/lib_com/window_ola.c index e0281ce1814ac48017e1212d361c875f3d599e4e..c237e423bf1729917488f528d124b92243df8691 100644 --- a/lib_com/window_ola.c +++ b/lib_com/window_ola.c @@ -42,6 +42,7 @@ #include "prot.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------------- * window_ola() * @@ -602,3 +603,4 @@ void sinq( return; } +#endif diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index e45d7a974e05aee643384065c8e291810f027815..f13ac41ff824821d65ca057a0d7fec238240303f 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -213,7 +213,6 @@ ivas_error acelp_core_enc( floatToFixed_arr( st->hLPDmem->mem_syn3_flt, st->hLPDmem->mem_syn3, Q_temp, 16 ); floatToFixed_arr( st->hLPDmem->mem_syn_r_flt, st->hLPDmem->mem_syn_r, Q_temp, 60 ); } - st->gamma = float_to_fix16( st->gamma_flt, Q15 ); for ( int ii = 0; ii < M; ii++ ) { st->mem_MA_fx[ii] = (Word16) ( ( st->mem_MA[ii] ) * 2.56f ); @@ -601,7 +600,15 @@ ivas_error acelp_core_enc( { if ( st->core_brate == SID_2k40 && st->element_mode != IVAS_CPE_MDCT ) { - FdCng_encodeSID( st ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + f2me_buf( st->hFdCngEnc->msNoiseEst, st->hFdCngEnc->msNoiseEst_fx, &st->hFdCngEnc->msNoiseEst_fx_exp, st->hFdCngEnc->npartDec ); +#endif + FdCng_encodeSID_ivas_fx( st ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + me2f_buf( st->hFdCngEnc->hFdCngCom->sidNoiseEst, st->hFdCngEnc->hFdCngCom->sidNoiseEstExp, st->hFdCngEnc->hFdCngCom->sidNoiseEst_flt, st->hFdCngEnc->npartDec ); + me2f_buf( st->hFdCngEnc->hFdCngCom->cngNoiseLevel, st->hFdCngEnc->hFdCngCom->cngNoiseLevelExp, st->hFdCngEnc->hFdCngCom->cngNoiseLevel_flt, FFTCLDFBLEN ); + fixedToFloat_arr( st->hFdCngEnc->hFdCngCom->A_cng, st->hFdCngEnc->hFdCngCom->A_cng_flt, 14 - norm_s( st->hFdCngEnc->hFdCngCom->A_cng[0] ), M + 1 ); +#endif st->hDtxEnc->last_CNG_L_frame = st->L_frame; } @@ -1190,7 +1197,20 @@ ivas_error acelp_core_enc( config_acelp1_IVAS( ENC, st->total_brate, st->core_brate, st->core, st->extl, st->extl_brate, st->L_frame, -1, &( st->acelp_cfg ), hBstr->nb_bits_tot, st->coder_type, tc_subfr, 0, &nb_bits, unbits, 0, &uc_two_stage_flag, 0, 0, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); /* redo LSF quantization */ +#ifdef IVAS_FLOAT_FIXED + lsf_enc_ivas_fx( st, lsf_new_fx, lsp_new_fx, lsp_mid_fx, Aq_fx, tdm_low_rate_mode, 0, NULL, Q_new ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < M; i++ ) + { + + lsf_new[i] = lsf_new_fx[i] / 2.56f; + } + fixedToFloat_arr( Aq_fx, Aq, 12, NB_SUBFR16k * ( M + 1 ) ); + fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); +#endif +#else lsf_enc( st, lsf_new, lsp_new, lsp_mid, Aq, tdm_low_rate_mode, 0, NULL ); +#endif /* recalculation of LP residual (filtering through A[z] filter) */ calc_residu( inp, res, Aq, st->L_frame ); diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c index 4e0e4692aaabbc9587d4db9a515061761f741636..332d33d3b6336b2be4b183b2bb069e379e3bf6f6 100644 --- a/lib_enc/cod_ace.c +++ b/lib_enc/cod_ace.c @@ -41,6 +41,7 @@ #include "rom_com.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * coder_acelp() * @@ -425,3 +426,4 @@ void coder_acelp( return; } +#endif diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index 887fb759b425dc60845f80054fe88da166afcee2..a3dfe262a7c42dfe9d6b4f66d7ffafe698be03e3 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -1133,6 +1133,7 @@ static void init_core_sig_ana( st->preemph_fac_flt = PREEMPH_FAC_SWB_FLT; /*SWB*/ } +#ifndef IVAS_FLOAT_FIXED if ( st->sr_core == INT_FS_16k ) { st->gamma_flt = GAMMA16k_FLT; @@ -1141,6 +1142,7 @@ static void init_core_sig_ana( { st->gamma_flt = GAMMA1_FLT; } +#endif if ( st->narrowBand ) { @@ -1177,10 +1179,14 @@ static void init_core_sig_ana_ivas_fx( Encoder_State *st ) st->gamma = GAMMA1; move16(); + st->inv_gamma = GAMMA1_INV; + move16(); IF( EQ_32( st->sr_core, 16000 ) ) { st->gamma = GAMMA16k; move16(); + st->inv_gamma = GAMMA16k_INV; + move16(); } diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index ba125469f1643fad4b32e0f025fc5ca2d757ccc7..4b11e2b8d69397362307d4898a1cd80b84e144c2 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -61,12 +61,14 @@ void core_coder_mode_switch_ivas_fx( Word16 i, fscale, switchWB; Word32 sr_core; Word16 bSwitchFromAmrwbIO; - Word16 tcxonly_tmp; + Word16 tcxonly_tmp, exp_res; switchWB = 0; move16(); bSwitchFromAmrwbIO = 0; move16(); + exp_res = 0; + move16(); IF( EQ_16( st->last_core, AMR_WB_CORE ) ) @@ -99,8 +101,6 @@ void core_coder_mode_switch_ivas_fx( { st->sr_core = sr_core; move16(); - Word16 exp_res = 0; - move16(); Word16 tmp = BASOP_Util_Divide3232_Scale( sr_core, FRAMES_PER_SEC, &exp_res ); st->L_frame = shr( tmp, 15 - exp_res ); move16(); @@ -242,12 +242,10 @@ void core_coder_mode_switch_ivas_fx( IF( st->envWeighted && !st->enableTcxLpc ) { /* Unweight the envelope */ - Word16 exp_res = 0, Q_res = 15; + st->inv_gamma = BASOP_Util_Divide1616_Scale( MAX16B, st->gamma, &exp_res ); move16(); + st->inv_gamma = shr( st->inv_gamma, sub( Q1, exp_res ) ); /* Q14 */ move16(); - st->inv_gamma = BASOP_Util_Divide1616_Scale( ONE_IN_Q14, st->gamma, &exp_res ); - Q_res = sub( Q_res, exp_res ); - st->inv_gamma = shr( st->inv_gamma, sub( Q14, Q_res ) ); E_LPC_lsp_unweight( st->lsp_old_fx, st->lsp_old_fx, st->lsf_old_fx, st->inv_gamma, M ); st->envWeighted = 0; move16(); diff --git a/lib_enc/decision_matrix_enc.c b/lib_enc/decision_matrix_enc.c index addccb333d06cb2d2866e55f6131c6693c14f191..9b18819d454b5d5043437612b4ba97089a79ab94 100644 --- a/lib_enc/decision_matrix_enc.c +++ b/lib_enc/decision_matrix_enc.c @@ -45,6 +45,7 @@ #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* * decision_matrix_enc() * @@ -649,6 +650,7 @@ void signaling_enc( return; } + /*---------------------------------------------------------------------* * signaling_enc_rf() * @@ -714,3 +716,4 @@ void signaling_enc_rf( return; } +#endif diff --git a/lib_enc/enc_ppp.c b/lib_enc/enc_ppp.c index 4337797bcdb59e1a1aea6573b36db11902d2b609..c432bc231edd93b85b911bda8c4cdb795e3ea049 100644 --- a/lib_enc/enc_ppp.c +++ b/lib_enc/enc_ppp.c @@ -40,6 +40,7 @@ #include "prot.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*------------------------------------------------------------------- * encod_ppp() * @@ -203,3 +204,4 @@ ivas_error encod_ppp( return error; } +#endif diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 7c58087d982bfd70386641a6141d4185fc129c4b..fbc576dec0713351c98a1ea03c63812873c8fd83 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -389,6 +389,7 @@ void writeTCXWindowing( #endif +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * writeLPCparam() * @@ -881,6 +882,7 @@ void enc_prm_rf( return; } + /*-----------------------------------------------------------------* * Function enc_prm() * * ~~~~~~~~~~~~~~~~~~~~~~ * @@ -1063,3 +1065,4 @@ void enc_prm( return; } +#endif diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 718666927012fb41189034a440bc50ad5a484472..2a7e7cd5adeab26877a7ab6bc40d4ead9b60aefa 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -677,7 +677,227 @@ void AdjustFirstSID( * * Generate a bitstream out of the partition levels *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void FdCng_encodeSID_ivas_fx( + Encoder_State *st /* i/o: encoder state structure */ +) +{ + Word16 N; + HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc; + HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; + BSTR_ENC_HANDLE hBstr = st->hBstr; + + Word32 *invTrfMatrix_fx, *E_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 v_fx[32], gain_fx, e_fx, temp; + Word16 w_fx[32], indices[32], exp[32]; + Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; + Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; + Word16 v_e, gain_q_offset, preemph_fac; + Word16 i, index; + + gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + + if ( st->element_mode == EVS_MONO ) + { + gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; + move16(); + } + + preemph_fac = st->preemph_fac; // Q15 + move16(); + + /* Init */ + N = hFdCngEnc->npartDec; + move16(); + + E_fx = hFdCngEnc->msNoiseEst_fx; + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ + + set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); + + /* Convert to LOG */ + e_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + v_fx[i] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_add_sat( E_fx[i], L_shr( 214748 /* 1e-4f in Q31*/, hFdCngEnc->msNoiseEst_fx_exp ) ), hFdCngEnc->msNoiseEst_fx_exp ) ); // Q21 = 27+25-31 + move32(); + e_fx = L_add( e_fx, v_fx[i] ); // Q21 + } + + /* Normalize MSVQ input */ + gain_fx = 0; + move32(); + FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q21 + } + + /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ + gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q21 + + FOR( i = 0; i < N; i++ ) + { + v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q21 + move32(); + } + + v_e = 10; // Q21 + move16(); + + /* MSVQ encoder */ + set_val_Word16( w_fx, ONE_IN_Q8, N ); + + IF( st->element_mode != EVS_MONO ) + { + /* DCT domain compressed/truncated indices used for first stage */ + /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched + in FDCNG band domain + */ + IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) + { + /* truncated DCT21 analysis */ + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + dctT2_N_apply_matrix_fx( v_fx /*Q21*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q21 + + /* truncated IDCT21 extension to 24 bands */ + extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q21 + + Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q21 + } + + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 + + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + ELSE + { /* EVS_MONO tables */ + msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices ); + + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 ); + + v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); + } + + /* Compute gain */ + gain_fx = 0; + move32(); + FOR( i = 0; i < N; i++ ) + { + gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e + } + + e_fx = L_shl( e_fx, sub( 10, v_e ) ); // Q = 31 - v_e + gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e + gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 + + /* Apply bitrate-dependant scale */ + IF( st->element_mode > EVS_MONO ) + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); + } + ELSE + { + apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); + } + + /* Quantize gain */ + temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 + index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 + + if ( index < 0 ) + { + index = 0; + move16(); + } + + if ( GT_16( index, 127 ) ) + { + index = 127; + move16(); + } + + gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e + + /* Apply gain and undo log */ + FOR( i = 0; i < N; i++ ) + { + temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e + hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); + move32(); + } + + maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); + + FOR( i = 0; i < N; i++ ) + { + hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp + move32(); + } + + /* NB last band energy compensation */ + IF( hFdCngCom->CngBandwidth == NB ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); + move32(); + } + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); + move32(); + } + + /* Write bitstream */ + IF( EQ_16( st->codec_mode, MODE2 ) ) + { + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_next_indice( hBstr, indices[i], bits_37bits[i] ); + } + + push_next_indice( hBstr, index, 7 ); + } + ELSE + { + Word16 is_frame_len_16k = 0; + move16(); + if ( EQ_16( st->L_frame, L_FRAME16k ) ) + { + is_frame_len_16k = 1; + move16(); + } + push_indice( hBstr, IND_SID_TYPE, 1, 1 ); + push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 ); + push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); + + FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) + { + push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); + } + + push_indice( hBstr, IND_ENERGY, index, 7 ); + } + + /* Interpolate the bin/band-wise levels from the partition levels */ + scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); + + return; +} +#else void FdCng_encodeSID( Encoder_State *st /* i/o: encoder state structure */ ) @@ -700,21 +920,11 @@ void FdCng_encodeSID( float tot_sig_ext[FDCNG_VQ_MAX_LEN]; const float gain_q_offset = ( st->element_mode == EVS_MONO ) ? GAIN_Q_OFFSET_EVS : GAIN_Q_OFFSET_IVAS; -#ifdef IVAS_FLOAT_FIXED - Word32 *invTrfMatrix_fx; - Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; - Word32 v_fx[32]; - Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; - Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; -#endif - /* Init */ N = hFdCngEnc->npartDec; invTrfMatrix = (float *) tmpRAM; /* dynamically filled */ -#ifdef IVAS_FLOAT_FIXED - invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ -#endif + set_zero( v, FDCNG_VQ_MAX_LEN ); /* Convert to LOG */ @@ -753,43 +963,17 @@ void FdCng_encodeSID( create_IDCT_N_Matrix( invTrfMatrix, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); /* truncated DCT21 analysis */ -#ifdef IVAS_FLOAT_FIXED - Word16 Q = 24; - move16(); - create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 -#endif - dctT2_N_apply_matrix( (const float *) v, dct_target, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); /* truncated IDCT21 extension to 24 bands */ -#ifdef IVAS_FLOAT_FIXED - floatToFixed_arr32( v, v_fx, Q, FDCNG_VQ_MAX_LEN ); - floatToFixed_arr32( dct_target, dct_target_fx, Q, FDCNG_VQ_DCT_MAXTRUNC ); - extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); - fixedToFloat_arrL( tot_sig_ext_fx, tot_sig_ext, Q, FDCNG_VQ_MAX_LEN ); -#else extend_dctN_input( v, dct_target, N, tot_sig_ext, FDCNG_VQ_MAX_LEN, invTrfMatrix, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); -#endif + mvr2r( tot_sig_ext, v, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ } create_IDCT_N_Matrix( invTrfMatrix, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM ) / ( sizeof( float ) ) ); -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - Word16 v_e; - Word16 w_fx[24]; - - f2me_buf( v, v_fx, &v_e, N ); - floatToFixed_arrL( invTrfMatrix, invTrfMatrix_fx, Q31, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); - floatToFixed_arr( w, w_fx, Q8, 24 ); -#endif - msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL( invTrfMatrix_fx, invTrfMatrix, Q31, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); -#endif -#else msvq_enc( cdk_37bits_ivas, NULL, NULL, v, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w, N, FD_CNG_maxN_37bits, 1, invTrfMatrix, indices ); -#endif + msvq_dec_float( cdk_37bits_ivas, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix, v, NULL ); } else @@ -882,7 +1066,7 @@ void FdCng_encodeSID( return; } - +#endif /*-------------------------------------------------------------------* * generate_comfort_noise_enc() diff --git a/lib_enc/guided_plc_enc.c b/lib_enc/guided_plc_enc.c index dd966dc8b9b2d633786190e88c79394cd4081a56..63d085011fc278b7c4e794df6edcf9706d20a2f2 100644 --- a/lib_enc/guided_plc_enc.c +++ b/lib_enc/guided_plc_enc.c @@ -41,6 +41,7 @@ #include "stat_enc.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * coderLookAheadInnovation() * @@ -384,3 +385,4 @@ void updateSpecPowDiffuseIdx( return; } +#endif diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 386466a08c651e6a018d1f7ba73d116736949a84..30b05f580fd5f77e9f150596774b47c0a1afd18c 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -276,8 +276,13 @@ ivas_error init_encoder( #endif /* FEC */ st->last_clas = UNVOICED_CLAS; +#ifndef IVAS_FLOAT_FIXED st->prev_fmerit_flt = 0.0f; st->fmerit_dt_flt = 0.0f; +#else + st->prev_fmerit = 0; + st->fmerit_dt = 0; +#endif st->Last_pulse_pos = 0; for ( i = 0; i < 2 * NB_SUBFR16k; i++ ) @@ -1244,8 +1249,10 @@ ivas_error init_encoder_ivas_fx( st->last_totalNoise = 0.f; set_f( st->totalNoise_increase_hist, 0.f, TOTALNOISE_HIST_SIZE ); st->min_alpha = 1; +#ifndef IVAS_FLOAT_FIXED st->prev_fmerit_flt = 0; st->fmerit_dt_flt = 0; +#endif st->pst_mem_deemp_err = 0.0f; st->pst_lp_ener = 0.0f; diff --git a/lib_enc/isf_enc_amr_wb.c b/lib_enc/isf_enc_amr_wb.c index f926c5712f2adf92ed64f2d65c2ed5a5f01d1a53..62df186479ae5e1f33ae18bbf42f4c56eb3ce6c9 100644 --- a/lib_enc/isf_enc_amr_wb.c +++ b/lib_enc/isf_enc_amr_wb.c @@ -42,6 +42,7 @@ #include "prot.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* * Local constants *-----------------------------------------------------------------*/ @@ -186,7 +187,6 @@ static void qisf_ns_28b( return; } - /*---------------------------------------------------------------------* * qisf_2s_36b() * @@ -521,3 +521,4 @@ static int16_t sub_VQ( } return index; } +#endif diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index e219c00be7a6efe42facdc8c1c5165a251e4a86b..ecf48f8d62d4580fc5dc319d25ab49ffaaed3f95 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -217,7 +217,6 @@ ivas_error ivas_core_enc( Word16 q_fft_buff; Word16 e_enerBuffer; - st->gamma = (Word16) floatToFixed( st->gamma_flt, Q15 ); st->preemph_fac = (Word16) floatToFixed( st->preemph_fac_flt, Q15 ); floatToFixed_arr16( st->lsp_old, st->lsp_old_fx, Q15, M ); @@ -312,7 +311,6 @@ ivas_error ivas_core_enc( } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - st->gamma_flt = fixedToFloat_16( st->gamma, Q15 ); st->preemph_fac_flt = fixedToFloat_16( st->preemph_fac, Q15 ); fixedToFloat_arr( st->lsp_old_fx, st->lsp_old, Q15, M ); @@ -467,16 +465,6 @@ ivas_error ivas_core_enc( // floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); // floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); - if ( (Word16) ( st->gamma_flt * 100 ) == 92 ) - { - st->gamma = GAMMA1; - st->inv_gamma = GAMMA1_INV; - } - else if ( (Word16) ( st->gamma_flt * 100 ) == 94 ) - { - st->gamma = GAMMA16k; - st->inv_gamma = GAMMA16k_INV; - } st->hTcxEnc->noiseTiltFactor = float_to_fix16( st->hTcxEnc->noiseTiltFactor_flt, Q15 ); st->hTcxCfg->preemph_fac = float_to_fix16( st->hTcxCfg->preemph_fac_flt, Q15 ); @@ -1534,12 +1522,10 @@ ivas_error ivas_core_enc( IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) { st->preemph_fac_flt = PREEMPH_FAC_FLT; - st->gamma_flt = GAMMA1_FLT; } ELSE { st->preemph_fac_flt = PREEMPH_FAC_16k_FLT; - st->gamma_flt = GAMMA16k_FLT; } } diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index f80542a568d6d065157352882aeda80cbae5394a..e50b53cda3004b1dc67d240a7a9753d19840c673 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -1974,9 +1974,25 @@ ivas_error pre_proc_front_ivas_fx( { st->cng_type = LP_CNG; } - +#ifndef IVAS_FLOAT_FIXED dtx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8 ); +#else +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 Q_inp_12k8 = Q_factor_arr( inp_12k8, L_FRAME ); + floatToFixed_arr( inp_12k8, inp_12k8_fx, Q_inp_12k8, L_FRAME ); + // Q_lp_noise = Q_factor( st->lp_noise ); + st->lp_noise_fx = float_to_fix16( st->lp_noise, Q8 ); +#endif + dtx_ivas_fx( st, ivas_total_brate, *vad_flag_dtx, inp_12k8_fx ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 guard_bits = find_guarded_bits_fx( L_FRAME ); + IF( st->Opt_DTX_ON ) + { + st->hDtxEnc->frame_ener = fixedToFloat( st->hDtxEnc->frame_ener_fx, 2 * Q_inp_12k8 - guard_bits ); // 2*Q_speech + } +#endif +#endif if ( hCPE != NULL && hCPE->hStereoDft != NULL && st->core_brate == SID_2k40 ) { /* Add another period of expected xcorr updates */ @@ -2372,9 +2388,6 @@ ivas_error pre_proc_front_ivas_fx( L_Extract( epsP_fx[j], &epsP_h[j], &epsP_l[j] ); } - - floatToFixed_arr16( st->hSpMusClas->past_log_enr, st->hSpMusClas->past_log_enr_fx, Q8, NB_BANDS_SPMUS ); - st->hNoiseEst->Etot_lp_fx = float_to_fix16( st->hNoiseEst->Etot_lp, Q8 ); st->hNoiseEst->Etot_v_h2_fx = float_to_fix16( st->hNoiseEst->Etot_v_h2, Q8 ); st->hNoiseEst->Etot_l_lp_fx = float_to_fix16( st->hNoiseEst->Etot_l_lp, Q8 ); @@ -2517,8 +2530,6 @@ ivas_error pre_proc_front_ivas_fx( fixedToFloat_arrL32( st->hNoiseEst->ave_enr_fx, st->hNoiseEst->ave_enr, q_fr_bands, NB_BANDS ); fixedToFloat_arrL32( st->hNoiseEst->ave_enr2_fx, st->hNoiseEst->ave_enr2, q_fr_bands, NB_BANDS ); - fixedToFloat_arr( st->hSpMusClas->past_log_enr_fx, st->hSpMusClas->past_log_enr, Q8, NB_BANDS_SPMUS ); - st->hNoiseEst->Etot_lp = fixedToFloat_16( st->hNoiseEst->Etot_lp_fx, Q8 ); st->hNoiseEst->Etot_v_h2 = fixedToFloat_16( st->hNoiseEst->Etot_v_h2_fx, Q8 ); st->hNoiseEst->Etot_l_lp = fixedToFloat_16( st->hNoiseEst->Etot_l_lp_fx, Q8 ); @@ -2622,14 +2633,11 @@ ivas_error pre_proc_front_ivas_fx( floatToFixed_arrL( ee, ee_fx, Q6, 2 ); relE_fx = float_to_fix16( *relE, Q8 ); floatToFixed_arr( st->voicing, st->voicing_fx, Q15, 3 ); - st->prev_fmerit = float_to_fix16( st->prev_fmerit_flt, Q15 ); #endif st->clas = signal_clas_fx( st, inp_12k8_fx, ee_fx, relE_fx, L_look, tdm_SM_last_clas ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS fixedToFloat_arr( st->voicing_fx, st->voicing, Q15, 3 ); - st->prev_fmerit_flt = fix16_to_float( st->prev_fmerit, Q15 ); - st->fmerit_dt_flt = fix16_to_float( st->fmerit_dt, Q15 ); #endif #else st->clas = signal_clas( st, inp_12k8, ee, *relE, L_look, tdm_SM_last_clas ); @@ -2691,9 +2699,6 @@ ivas_error pre_proc_front_ivas_fx( Word16 non_sta_fx = float_to_fix16( non_staX, Q6 ); Word16 Etot_fx_0 = float_to_fix16( Etot, Q8 ); floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); - hSpMusClas->wdlp_0_95_sp_32fx = float_to_fix( hSpMusClas->wdlp_0_95_sp, Q24 ); - hSpMusClas->wdlp_xtalk_fx = floatToFixed( hSpMusClas->wdlp_xtalk, Q19 ); - hSpMusClas->wrise_fx = float_to_fix16( hSpMusClas->wrise, 9 ); relE_fx = float_to_fix16( *relE, 8 ); floatToFixed_arr16( st->voicing, st->voicing_fx, 15, 3 ); Word16 Qfact_PS = Q_factor_arrL( PS, 128 ); @@ -2703,29 +2708,10 @@ ivas_error pre_proc_front_ivas_fx( Q_esp = sub( 31, e_esp ); Word16 Qfact_PS_past = Q_factor_arrL( hSpMusClas->past_PS, 67 ); floatToFixed_arr32( hSpMusClas->past_PS, hSpMusClas->past_PS_fx, Qfact_PS_past, 67 ); - hSpMusClas->dlp_var_LT_fx = float_to_fix( hSpMusClas->dlp_var_LT, Q19 ); - hSpMusClas->dlp_mean_LT_fx = float_to_fix( hSpMusClas->dlp_mean_LT, Q19 ); - hSpMusClas->dlp_mean_ST_fx = float_to_fix( hSpMusClas->dlp_mean_ST, Q19 ); - floatToFixed_arr32( hSpMusClas->past_dlp_mean_ST, hSpMusClas->past_dlp_mean_ST_fx, Q19, 7 ); - floatToFixed_arr32( hSpMusClas->prev_FV, hSpMusClas->prev_FV_fx, Q20, 15 ); - floatToFixed_arr32( hSpMusClas->FV_st, hSpMusClas->FV_st_fx, Q20, 15 ); #endif smc_dec = ivas_smc_gmm_fx( st, hStereoClassif, localVAD_HE_SAD, Etot_fx_0, lsp_new_fx, extract_l( L_shr( cor_map_sum_fx, sub( 23, cor_map_sum_e ) ) ) /*q8*/, epsP_fx, PS_fx, non_sta_fx, relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, Q_esp, Qfact_PS_past ); #if 1 - fixedToFloat_arr( hSpMusClas->past_dlp_fx, hSpMusClas->past_dlp, Q9, HANG_LEN - 1 ); - hSpMusClas->lpm = fixedToFloat( hSpMusClas->lpm_fx, Q7 ); // Q7 - hSpMusClas->lps = fixedToFloat( hSpMusClas->lps_fx, Q7 ); // Q7 - hSpMusClas->wdrop = fixedToFloat( hSpMusClas->wdrop_fx, Q9 ); // Q8 - hSpMusClas->wrise = fixedToFloat( hSpMusClas->wrise_fx, Q9 ); // Q8 - hSpMusClas->wdlp_0_95_sp = fixedToFloat( hSpMusClas->wdlp_0_95_sp_32fx, Q24 ); - hSpMusClas->dlp_mean_LT = fixedToFloat_32( hSpMusClas->dlp_mean_LT_fx, Q19 ); - hSpMusClas->wdlp_xtalk = fixedToFloat( hSpMusClas->wdlp_xtalk_fx, Q19 ); - hSpMusClas->dlp_var_LT = fixedToFloat_32( hSpMusClas->dlp_var_LT_fx, Q19 ); fixedToFloat_arrL32( hSpMusClas->past_PS_fx, hSpMusClas->past_PS, Qfact_PS_past, 67 ); - fixedToFloat_arrL32( hSpMusClas->FV_st_fx, hSpMusClas->FV_st, Q20, 15 ); - fixedToFloat_arrL32( hSpMusClas->prev_FV_fx, hSpMusClas->prev_FV, Q20, 15 ); - fixedToFloat_arrL32( hSpMusClas->past_dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST, Q19, 7 ); - hSpMusClas->dlp_mean_ST = fixedToFloat( hSpMusClas->dlp_mean_ST_fx, Q19 ); #endif #endif @@ -2831,7 +2817,6 @@ ivas_error pre_proc_front_ivas_fx( { /* Unweight the envelope */ floatToFixed_arr( st->lsp_old, st->lsp_old_fx, Q15, M ); - st->gamma = (Word16) floatToFixed( st->gamma_flt, Q14 ); } } #endif @@ -3089,13 +3074,10 @@ ivas_error pre_proc_front_ivas_fx( floatToFixed_arrL( st->hSpMusClas->tod_lt_Bin_E, st->hSpMusClas->tod_lt_Bin_E_fx, Q_new + Q_SCALE - 2, TOD_NSPEC ); floatToFixed_arr( S_map, S_map_fx, Q7, L_FFT / 2 ); floatToFixed_arr( st->hSpMusClas->gsc_lt_diff_etot, st->hSpMusClas->gsc_lt_diff_etot_fx, Q8, MAX_LT ); - st->hSpMusClas->gsc_mem_etot_fx = float_to_fix16( st->hSpMusClas->gsc_mem_etot, Q8 ); - floatToFixed_arr( st->hSpMusClas->gsc_thres, st->hSpMusClas->gsc_thres_fx, Q11, 4 ); st->old_corr_fx = float_to_fix16( st->old_corr, Q15 ); floatToFixed_arrL( st->hSpMusClas->finc_prev, st->hSpMusClas->finc_prev_fx, 2 * Q_new, ATT_NSEG ); st->hSpMusClas->lt_finc_fx = floatToFixed( st->hSpMusClas->lt_finc, 2 * Q_new ); st->lp_noise_fx = float_to_fix16( st->lp_noise, Q8 ); - st->hSpMusClas->wdlp_0_95_sp_fx = float_to_fix16( st->hSpMusClas->wdlp_0_95_sp, Q8 ); st->hSpMusClas->mold_corr_fx = float_to_fix16( st->hSpMusClas->mold_corr, Q15 ); #endif // IVAS_FLOAT_FIXED_CONVERSIONS @@ -3104,7 +3086,6 @@ ivas_error pre_proc_front_ivas_fx( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS fixedToFloat_arr( st->hSpMusClas->gsc_lt_diff_etot_fx, st->hSpMusClas->gsc_lt_diff_etot, Q8, MAX_LT ); - st->hSpMusClas->gsc_mem_etot = fix16_to_float( st->hSpMusClas->gsc_mem_etot_fx, Q8 ); fixedToFloat_arrL( st->hSpMusClas->finc_prev_fx, st->hSpMusClas->finc_prev, 2 * Q_new, ATT_NSEG ); st->hSpMusClas->lt_finc = fixedToFloat( st->hSpMusClas->lt_finc_fx, 2 * Q_new ); fixedToFloat_arrL( st->hSpMusClas->tod_lt_Bin_E_fx, st->hSpMusClas->tod_lt_Bin_E, Q_new + Q_SCALE - 2, TOD_NSPEC ); diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 91aaf3cc1b6c33e3db195032a434e3c9070516b7..bdf6f5f2485bb3fedeead0d541e56176f6eed054 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -211,11 +211,6 @@ ivas_error ivas_cpe_enc( if ( sts[0]->ini_frame > 0 && st_ivas->hMCT == NULL ) { #ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - hCPE->hCoreCoder[0]->hSpMusClas->past_dlp_fx[0] = float_to_fix16( hCPE->hCoreCoder[0]->hSpMusClas->past_dlp[0], Q9 ); - hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk_fx = floatToFixed( hCPE->hCoreCoder[0]->hSpMusClas->wdlp_xtalk, Q19 ); -#endif - hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); #else hCPE->element_mode = select_stereo_mode( hCPE, ivas_format ); diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 1d327f291a2e1cc75e52ed61e28148161a6d46de..4e79d4e2d5e293bf35ecf2632f4da995aad1f152 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -508,8 +508,8 @@ ivas_error ivas_dirac_enc( for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) { fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, hQMetaData->q_direction[i].band_data[j].energy_ratio, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); - fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); - fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + /*fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES );*/ fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, hQMetaData->q_direction[i].band_data[j].q_azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation_fx, hQMetaData->q_direction[i].band_data[j].q_elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); } diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 2e966212cffefedcfa76ac3c95f93b8de0fb4b24..191d3e97ecbb97242da6de16f4c639deae5d51ab 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -1150,7 +1150,33 @@ ivas_error ivas_enc( { /* encode MC ParamUpmix parameters and write bitstream */ #ifdef IVAS_FLOAT_FIXED - ivas_mc_paramupmix_enc( st_ivas, hMetaData, data_f, data_fx, input_frame ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 4; i < 12; i++ ) + { + for ( int l = 0; l < input_frame; l++ ) + { + data_fx[i][l] = floatToFixed( data_f[i][l], st_ivas->q_data_fx ); + } + } +#endif + ivas_mc_paramupmix_enc_fx( st_ivas, hMetaData, data_fx, input_frame ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + for ( int ch_idx = 0; ch_idx < st_ivas->hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans; ch_idx++ ) + { + fixedToFloat_arrL( st_ivas->hMCParamUpmix->hFbMixer->ppFilterbank_prior_input_fx[ch_idx], st_ivas->hMCParamUpmix->hFbMixer->ppFilterbank_prior_input[ch_idx], Q14, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } + for ( i = 4; i < 12; i++ ) + { + for ( int l = 0; l < input_frame; l++ ) + { + data_f[i][l] = fixedToFloat( data_fx[i][l], st_ivas->q_data_fx ); + } + } +#endif #else ivas_mc_paramupmix_enc( st_ivas, hMetaData, data_f, input_frame ); diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 34eab69e8b064177d95219881921556c32ed51aa..93d5725f99388030a3dae5918d0eebd708720f11 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -1155,9 +1155,6 @@ ivas_error front_vad_spar( // Word32 epsP_fx[M + 1]; Word16 Etot_fx_0 = float_to_fix16( Etot[0], Q8 ); floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); - hSpMusClas->wdlp_0_95_sp_32fx = float_to_fix( hSpMusClas->wdlp_0_95_sp, Q24 ); - hSpMusClas->wdlp_xtalk_fx = floatToFixed( hSpMusClas->wdlp_xtalk, Q19 ); - hSpMusClas->wrise_fx = float_to_fix16( hSpMusClas->wrise, 9 ); relE_fx = float_to_fix16( relE, 8 ); floatToFixed_arr16( st->voicing, st->voicing_fx, 15, 3 ); Word16 Qfact_PS = Q_factor_arrL( PS, 128 ); @@ -1167,29 +1164,10 @@ ivas_error front_vad_spar( Q_esp = sub( 31, e_esp ); Word16 Qfact_PS_past = Q_factor_arrL( hSpMusClas->past_PS, 67 ); floatToFixed_arr32( hSpMusClas->past_PS, hSpMusClas->past_PS_fx, Qfact_PS_past, 67 ); - hSpMusClas->dlp_var_LT_fx = float_to_fix( hSpMusClas->dlp_var_LT, Q19 ); - hSpMusClas->dlp_mean_LT_fx = float_to_fix( hSpMusClas->dlp_mean_LT, Q19 ); - hSpMusClas->dlp_mean_ST_fx = float_to_fix( hSpMusClas->dlp_mean_ST, Q19 ); - floatToFixed_arr32( hSpMusClas->past_dlp_mean_ST, hSpMusClas->past_dlp_mean_ST_fx, Q19, 7 ); - floatToFixed_arr32( hSpMusClas->prev_FV, hSpMusClas->prev_FV_fx, Q20, 15 ); - floatToFixed_arrL( hSpMusClas->FV_st, hSpMusClas->FV_st_fx, Q20, 15 ); #endif ivas_smc_gmm_fx( st, NULL, localVAD_HE_SAD[0], Etot_fx_0, lsp_new_fx, cor_map_sum_fx, epsP_fx, PS_fx, non_sta_fx, relE_fx, &high_lpn_flag, flag_spitch, Qfact_PS, Q_esp, Qfact_PS_past ); #if 1 - fixedToFloat_arr( hSpMusClas->past_dlp_fx, hSpMusClas->past_dlp, Q9, HANG_LEN - 1 ); - hSpMusClas->lpm = fixedToFloat( hSpMusClas->lpm_fx, Q7 ); // Q7 - hSpMusClas->lps = fixedToFloat( hSpMusClas->lps_fx, Q7 ); // Q7 - hSpMusClas->wdrop = fixedToFloat( hSpMusClas->wdrop_fx, Q9 ); // Q9 - hSpMusClas->wrise = fixedToFloat( hSpMusClas->wrise_fx, Q9 ); // Q9 - hSpMusClas->wdlp_0_95_sp = fixedToFloat( hSpMusClas->wdlp_0_95_sp_32fx, Q24 ); // Q24 - hSpMusClas->dlp_mean_LT = fixedToFloat_32( hSpMusClas->dlp_mean_LT_fx, Q19 ); - hSpMusClas->wdlp_xtalk = fixedToFloat( hSpMusClas->wdlp_xtalk_fx, Q19 ); - hSpMusClas->dlp_var_LT = fixedToFloat_32( hSpMusClas->dlp_var_LT_fx, Q19 ); fixedToFloat_arrL32( hSpMusClas->past_PS_fx, hSpMusClas->past_PS, Qfact_PS_past, 67 ); - fixedToFloat_arrL32( hSpMusClas->FV_st_fx, hSpMusClas->FV_st, Q20, 15 ); - hSpMusClas->dlp_mean_ST = fixedToFloat( hSpMusClas->dlp_mean_ST_fx, Q19 ); - fixedToFloat_arrL32( hSpMusClas->past_dlp_mean_ST_fx, hSpMusClas->past_dlp_mean_ST, Q19, 7 ); - fixedToFloat_arrL32( hSpMusClas->prev_FV_fx, hSpMusClas->prev_FV, Q20, 15 ); #endif #endif #if 0 diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 7794f0cfefc73cc653ec53b969463e6d0918f9b4..1d268b40debe6b2fcc592a0125997696bc6d3f50 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -564,8 +564,8 @@ ivas_error ivas_masa_encode( for ( j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) { fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].energy_ratio_fx, hQMetaData->q_direction[i].band_data[j].energy_ratio, Q30, MAX_PARAM_SPATIAL_SUBFRAMES ); - fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); - fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + /*fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].azimuth_fx, hQMetaData->q_direction[i].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].elevation_fx, hQMetaData->q_direction[i].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES );*/ fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_azimuth_fx, hQMetaData->q_direction[i].band_data[j].q_azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); fixedToFloat_arrL( hQMetaData->q_direction[i].band_data[j].q_elevation_fx, hQMetaData->q_direction[i].band_data[j].q_elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); } diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 12eded9c0870f383e95151e6c9de18d70422d46b..3e9f14f46bdfc497727d5103ec3da09ad793efcc 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -55,8 +55,6 @@ *------------------------------------------------------------------------*/ -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 ); @@ -84,12 +82,16 @@ static void ivas_param_mc_dmx_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f_f static void ivas_param_mc_transient_detection_fx( PARAM_MC_ENC_HANDLE hParamMC, TRAN_DET_HANDLE hTranDet, Word16 *bAttackPresent, Word16 *attackIdx ); +static void ivas_param_mc_param_est_enc_fx( PARAM_MC_ENC_HANDLE hParamMC, Word32 *data_f[], Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], const Word16 input_frame, const Word16 nchan_input, const Word16 nchan_transport ); + #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 ); +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 ); + #endif /*------------------------------------------------------------------------- @@ -431,7 +433,7 @@ void ivas_param_mc_enc( const int16_t input_frame /* i : input frame length */ ) { - int16_t k; + int16_t i, j, k; #ifdef IVAS_FLOAT_FIXED Word32 *data_f_fx[12]; for ( k = 0; k < 12; k++ ) @@ -450,6 +452,10 @@ void ivas_param_mc_enc( 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]; + Word32 Cy_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word16 Cy_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word32 Cx_sum_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 Cx_sum_e[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; #endif int16_t ch; int16_t band; @@ -475,6 +481,21 @@ void ivas_param_mc_enc( set_zero( Cx_sum[band][ch], PARAM_MC_MAX_TRANSPORT_CHANS ); } } +#ifdef IVAS_FLOAT_FIXED + FOR( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ ) + { + FOR( ch = 0; ch < MAX_CICP_CHANNELS; ch++ ) + { + set32_fx( Cy_sum_fx[band][ch], 0, MAX_CICP_CHANNELS ); + set16_fx( Cy_sum_e[band][ch], 0, MAX_CICP_CHANNELS ); + } + FOR( ch = 0; ch < PARAM_MC_MAX_TRANSPORT_CHANS; ch++ ) + { + set32_fx( Cx_sum_fx[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS ); + set16_fx( Cx_sum_e[band][ch], 0, PARAM_MC_MAX_TRANSPORT_CHANS ); + } + } +#endif for ( band = 0; band < PARAM_MC_MAX_PARAMETER_BANDS; band++ ) { @@ -489,14 +510,14 @@ void ivas_param_mc_enc( /* DMX generation*/ #ifdef IVAS_FLOAT_FIXED #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( int i = 0; i < nchan_inp; i++ ) + for ( 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++ ) + for ( i = 0; i < 3; i++ ) { fixedToFloat_arrL( data_dmx_fx[i], data_dmx[i], 11, input_frame ); } @@ -559,9 +580,42 @@ void ivas_param_mc_enc( break; } - /* Encoding */ - /* parameter estimation*/ + /* Encoding */ + /* parameter estimation*/ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) + { + floatToFixed_arrL( hParamMC->prev_ilds[i], hParamMC->prev_ilds_fx[i], Q21, PARAM_MC_SZ_ILD_MAP ); + } +#endif + ivas_param_mc_param_est_enc_fx( hParamMC, data_f_fx, Cy_sum_fx, Cy_sum_e, Cx_sum_fx, Cx_sum_e, input_frame, nchan_inp, st_ivas->nchan_transport ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ ) + { + for ( j = 0; j < MAX_CICP_CHANNELS; j++ ) + { + for ( k = 0; k < MAX_CICP_CHANNELS; k++ ) + { + Cy_sum[i][j][k] = me2f( Cy_sum_fx[i][j][k], Cy_sum_e[i][j][k] ); + } + } + for ( j = 0; j < PARAM_MC_MAX_TRANSPORT_CHANS; j++ ) + { + for ( k = 0; k < PARAM_MC_MAX_TRANSPORT_CHANS; k++ ) + { + Cx_sum[i][j][k] = me2f( Cx_sum_fx[i][j][k], Cx_sum_e[i][j][k] ); + } + } + } + for ( i = 0; i < hParamMC->hFbMixer->fb_cfg->num_in_chans; i++ ) + { + fixedToFloat_arrL( hParamMC->hFbMixer->ppFilterbank_prior_input_fx[i], hParamMC->hFbMixer->ppFilterbank_prior_input[i], Q11, input_frame / PARAM_MC_MDFT_NO_SLOTS ); + } +#endif +#else ivas_param_mc_param_est_enc( hParamMC, data_f, Cy_sum, Cx_sum, input_frame, nchan_inp, st_ivas->nchan_transport ); +#endif band_step = hParamMC->hMetadataPMC.bAttackPresent ? PARAM_MC_TRANSIENT_BAND_STEP : 1; @@ -1005,6 +1059,566 @@ static void ivas_param_mc_dmx_fx( * estimate the input and down mix covariances *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_mc_param_est_enc_fx( + PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */ + Word32 *data_f_fx[], /* i : Input frame in the time domain Q11 */ + Word32 Cy_sum_fx[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame */ + Word16 Cy_sum_e[][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS], /* o : Covariance matrix for the original frame */ + Word32 Cx_sum_fx[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame */ + Word16 Cx_sum_e[][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS], /* o : Covariance matrix for the downmixed frame */ + 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, cur_cldfb_band, cur_param_band, ch_idx1, ch_idx2, inp_ch; + Word16 ts; + Word16 l_ts; + Word16 num_time_slots; + Word16 num_parameter_bands; + Word16 brange[2]; + Word16 band_step; + const Word16 *map_ls = Param_MC_index; /* Loudspeakers mapping */ + Word16 idx_ls; + Word16 start_ts; + + Word32 *pcm_in_fx[MAX_CICP_CHANNELS]; + Word32 slot_frame_f_real_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - real part */ + Word32 slot_frame_f_imag_fx[MAX_CICP_CHANNELS][DIRAC_NO_FB_BANDS_MAX]; /* Output of the MDFT FB - imag part */ + Word32 *p_slot_frame_f_real_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - real part */ + Word32 *p_slot_frame_f_imag_fx[MAX_CICP_CHANNELS]; /* Output of the MDFT FB - imag part */ + + Word32 dmx_real_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Real Part */ + Word16 dmx_real_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Real Part */ + Word32 dmx_imag_fx[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ + Word16 dmx_imag_e[PARAM_MC_MAX_TRANSPORT_CHANS]; /* Downmix channel - Imag Part */ + Word32 a_fx, b_fx, c_fx, d_fx; /* Tmp complex values */ + Word16 a_e, b_e, c_e, d_e; /* Tmp complex values */ + Word32 Cy_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word16 Cy_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; + Word32 Cx_sum_imag_fx[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; + Word16 Cx_sum_imag_e[PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC][PARAM_MC_MAX_TRANSPORT_CHANS][PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 real_part_fx, imag_part_fx; + Word16 real_part_e, imag_part_e; + const Word32 *p_dmx_fac_fx; + Word32 L_tmp; + Word16 tmp_e; + + push_wmops( "param_mc_prm_est" ); + + /* initializations */ + l_ts = Mpy_32_16_1( input_frame, INV_PARAM_MC_MDFT_NO_SLOTS_FX ); + num_time_slots = PARAM_MC_MDFT_NO_SLOTS; + move16(); + IF( hParamMC->hMetadataPMC.bAttackPresent ) + { + start_ts = hParamMC->hMetadataPMC.attackIndex; + move16(); + } + ELSE + { + start_ts = 0; + move16(); + } + num_parameter_bands = hParamMC->hMetadataPMC.nbands_coded; + move16(); + band_step = 1; + move16(); + + FOR( cur_param_band = 0; cur_param_band < PARAM_MC_MAX_PARAM_BAND_ABS_COV_ENC; cur_param_band++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < MAX_CICP_CHANNELS; ch_idx1++ ) + { + set32_fx( Cy_sum_imag_fx[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); + set16_fx( Cy_sum_imag_e[cur_param_band][ch_idx1], 0, MAX_CICP_CHANNELS ); + } + + FOR( ch_idx1 = 0; ch_idx1 < PARAM_MC_MAX_TRANSPORT_CHANS; ch_idx1++ ) + { + set32_fx( Cx_sum_imag_fx[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS ); + set16_fx( Cx_sum_imag_e[cur_param_band][ch_idx1], 0, PARAM_MC_MAX_TRANSPORT_CHANS ); + } + } + + /* Copy current frame to memory for delay compensation */ + FOR( i = 0; i < nchan_input; i++ ) + { + idx_ls = map_ls[i]; + move16(); + pcm_in_fx[i] = data_f_fx[idx_ls]; + p_slot_frame_f_real_fx[i] = &slot_frame_f_real_fx[i][0]; + p_slot_frame_f_imag_fx[i] = &slot_frame_f_imag_fx[i][0]; + } + + FOR( ts = 0; ts < start_ts; ts++ ) + { + ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans ); + FOR( i = 0; i < nchan_input; i++ ) + { + pcm_in_fx[i] += l_ts; + } + } + + FOR( ts = start_ts; ts < num_time_slots; ts++ ) + { + Word16 gb = find_guarded_bits_fx( l_ts ); + ivas_fb_mixer_get_windowed_fr_fx( hParamMC->hFbMixer, pcm_in_fx, p_slot_frame_f_real_fx, p_slot_frame_f_imag_fx, l_ts, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans, gb ); + ivas_fb_mixer_update_prior_input_fx( hParamMC->hFbMixer, pcm_in_fx, l_ts, hParamMC->hFbMixer->fb_cfg->num_in_chans ); + + /* slot_frame_f buffer Q = 11 - gb : exponent = 20 + gb */ + + FOR( i = 0; i < nchan_input; i++ ) + { + pcm_in_fx[i] += l_ts; + } + /* Computing the downmix */ + FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ ) + { + brange[0] = hParamMC->band_grouping[cur_param_band]; + move16(); + brange[1] = hParamMC->band_grouping[cur_param_band + 1]; + move16(); + + FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ ) + { + /* Cx for DMX */ + /* Real Part */ + p_dmx_fac_fx = hParamMC->dmx_factors_fx; + + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + dmx_real_fx[ch_idx1] = 0; + move32(); + dmx_real_e[ch_idx1] = 0; + move16(); + dmx_imag_fx[ch_idx1] = 0; + move32(); + dmx_imag_e[ch_idx1] = 0; + move16(); + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + dmx_real_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( dmx_real_fx[ch_idx1], dmx_real_e[ch_idx1], L_tmp, add( 20, gb ), &dmx_real_e[ch_idx1] ); + move32(); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + dmx_imag_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( dmx_imag_fx[ch_idx1], dmx_imag_e[ch_idx1], L_tmp, add( 20, gb ), &dmx_imag_e[ch_idx1] ); + move32(); + p_dmx_fac_fx++; + } + } + + /* Cx for transport channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) + { + a_fx = dmx_real_fx[ch_idx1]; + move32(); + a_e = dmx_real_e[ch_idx1]; + move16(); + b_fx = dmx_imag_fx[ch_idx1]; + move32(); + b_e = dmx_imag_e[ch_idx1]; + move16(); + c_fx = dmx_real_fx[ch_idx2]; + move32(); + c_e = dmx_real_e[ch_idx2]; + move16(); + d_fx = dmx_imag_fx[ch_idx2]; + move32(); + d_e = dmx_imag_e[ch_idx2]; + move16(); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], + L_tmp, tmp_e, &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, d_fx ), add( a_e, d_e ), L_negate( Mpy_32_32( b_fx, c_fx ) ), add( b_e, c_e ), &tmp_e ); + Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], + L_tmp, tmp_e, &Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + } + } + + /* Cy for input channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); + b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); + c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); + d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], + L_tmp, tmp_e, &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, d_fx ), add( a_e, d_e ), L_negate( Mpy_32_32( b_fx, c_fx ) ), add( b_e, c_e ), &tmp_e ); + Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], + L_tmp, tmp_e, &Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + } + } + } + } + + FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ ) + { + brange[0] = hParamMC->band_grouping[cur_param_band]; + move16(); + brange[1] = hParamMC->band_grouping[cur_param_band + 1]; + move16(); + + FOR( cur_cldfb_band = brange[0]; cur_cldfb_band < brange[1]; cur_cldfb_band++ ) + { + /* Cx for DMX */ + /* Real Part */ + p_dmx_fac_fx = hParamMC->dmx_factors_fx; // Q31 + + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + dmx_real_fx[ch_idx1] = 0; + move32(); + dmx_real_e[ch_idx1] = 0; + move16(); + dmx_imag_fx[ch_idx1] = 0; + move32(); + dmx_imag_e[ch_idx1] = 0; + move16(); + + FOR( inp_ch = 0; inp_ch < nchan_input; inp_ch++ ) + { + L_tmp = Mpy_32_32( slot_frame_f_real_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + dmx_real_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( dmx_real_fx[ch_idx1], dmx_real_e[ch_idx1], L_tmp, add( 20, gb ), &dmx_real_e[ch_idx1] ); + move32(); + L_tmp = Mpy_32_32( slot_frame_f_imag_fx[inp_ch][cur_cldfb_band], ( *p_dmx_fac_fx ) ); + dmx_imag_fx[ch_idx1] = BASOP_Util_Add_Mant32Exp( dmx_imag_fx[ch_idx1], dmx_imag_e[ch_idx1], L_tmp, add( 20, gb ), &dmx_imag_e[ch_idx1] ); + move32(); + p_dmx_fac_fx++; + } + } + + /* Cx for transport channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) + { + a_fx = dmx_real_fx[ch_idx1]; + move32(); + a_e = dmx_real_e[ch_idx1]; + move16(); + b_fx = dmx_imag_fx[ch_idx1]; + move32(); + b_e = dmx_imag_e[ch_idx1]; + move16(); + c_fx = dmx_real_fx[ch_idx2]; + move32(); + c_e = dmx_real_e[ch_idx2]; + move16(); + d_fx = dmx_imag_fx[ch_idx2]; + move32(); + d_e = dmx_imag_e[ch_idx2]; + move16(); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, + &Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + } + } + + /* Cy for input channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + a_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &a_e ); + b_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx1][cur_cldfb_band], add( 20, gb ), 0, 0, &b_e ); + c_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_real_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &c_e ); + d_fx = BASOP_Util_Add_Mant32Exp( slot_frame_f_imag_fx[ch_idx2][cur_cldfb_band], add( 20, gb ), 0, 0, &d_e ); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = BASOP_Util_Add_Mant32Exp( Mpy_32_32( a_fx, c_fx ), add( a_e, c_e ), Mpy_32_32( b_fx, d_fx ), add( b_e, d_e ), &tmp_e ); + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], L_tmp, tmp_e, + &Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] ); + move32(); + } + } + } + } + } + + /* make sure energy and correlation is zero above the relevant LFE bands for LFE + * avoids wrong energy in case of band combining at transients */ + IF( hParamMC->lfe_index >= 0 ) + { + FOR( cur_param_band = PARAM_MC_MAX_BAND_LFE; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move32(); + Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move16(); + Cy_sum_fx[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move32(); + Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move16(); + Cy_sum_imag_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move32(); + Cy_sum_imag_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move16(); + Cy_sum_imag_fx[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move32(); + Cy_sum_imag_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move16(); + } + } + + FOR( ; cur_param_band < num_parameter_bands; cur_param_band++ ) + { + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + Cy_sum_fx[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move32(); + Cy_sum_e[cur_param_band][hParamMC->lfe_index][ch_idx1] = 0; + move16(); + Cy_sum_fx[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move32(); + Cy_sum_e[cur_param_band][ch_idx1][hParamMC->lfe_index] = 0; + move16(); + } + } + } + + IF( !hParamMC->hMetadataPMC.bAttackPresent ) + { + const PARAM_MC_ILD_MAPPING *h_ild_mapping; + Word16 ild_attack; + ild_attack = 0; + move16(); + h_ild_mapping = hParamMC->hMetadataPMC.ild_mapping_conf; + /* create ILDs for to non transmitted parameter bands (only lower half) */ + FOR( cur_param_band = 0; cur_param_band < hParamMC->hMetadataPMC.num_parameter_bands / 2; cur_param_band++ ) + { + Word32 ILD_fx[PARAM_MC_SZ_ILD_MAP]; + Word16 k; + Word16 num_ilds_to_code; + + IF( GE_16( cur_param_band, PARAM_MC_MAX_BAND_LFE ) ) + { + num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_wo_lfe; + move16(); + } + ELSE + { + num_ilds_to_code = hParamMC->hMetadataPMC.ild_mapping_conf->ild_map_size_lfe; + move16(); + } + IF( NE_16( hParamMC->hMetadataPMC.param_frame_idx, hParamMC->hMetadataPMC.coding_band_mapping[cur_param_band] ) ) + { + Word32 Nrg_fx[MAX_CICP_CHANNELS]; + Word16 Nrg_e[MAX_CICP_CHANNELS]; + + /* get ICLDs */ + FOR( k = 0; k < nchan_input; ++k ) + { + Nrg_fx[k] = Cy_sum_fx[cur_param_band][k][k]; + move32(); + Nrg_e[k] = Cy_sum_e[cur_param_band][k][k]; + move16(); + } + FOR( k = 0; k < num_ilds_to_code; ++k ) + { + Word32 ref_ener_fx = 0; + move32(); + Word16 ref_ener_e = 0; + move16(); + Word16 ref_channel_cnt; + Word16 ref_channel_idx; + + FOR( ref_channel_cnt = 0; ref_channel_cnt < h_ild_mapping->num_ref_channels[k]; ref_channel_cnt++ ) + { + ref_channel_idx = h_ild_mapping->ref_channel_idx[k][ref_channel_cnt]; + move16(); + ref_ener_fx = BASOP_Util_Add_Mant32Exp( ref_ener_fx, ref_ener_e, Cx_sum_fx[cur_param_band][ref_channel_idx][ref_channel_idx], + Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx], &ref_ener_e ); + ref_ener_e = Cx_sum_e[cur_param_band][ref_channel_idx][ref_channel_idx]; + move16(); + } + L_tmp = Mpy_32_16_1( ref_ener_fx, hParamMC->hMetadataPMC.ild_factors_fx[k] ); + L_tmp = L_deposit_h( BASOP_Util_Divide3232_Scale( Nrg_fx[h_ild_mapping->ild_index[k]], L_tmp, &tmp_e ) ); + + tmp_e = add( sub( Nrg_e[h_ild_mapping->ild_index[k]], ref_ener_e ), tmp_e ); + + /*1342177280 = 10 in Q27*/ + ILD_fx[k] = Mpy_32_32( 1342177280, BASOP_Util_Log10( L_tmp, tmp_e ) ); // Q25 + Q27 - Q31 = Q21 + move32(); + + if ( GT_32( L_sub( hParamMC->prev_ilds_fx[cur_param_band][k], ILD_fx[k] ), param_mc_ild_diff_threshold_fx[cur_param_band] ) ) + { + ild_attack = add( ild_attack, 1 ); + } + } + } + } + /* check if the ILDs change too much -> go into transient mode... */ + if ( GT_16( ild_attack, PARAM_MC_NUM_ATTACK_ILD_THRESH ) ) + { + hParamMC->hMetadataPMC.bAttackPresent = 1; + move16(); + } + } + + + IF( hParamMC->hMetadataPMC.bAttackPresent ) + { + /* combine bands */ + FOR( cur_param_band = 1; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += 2 ) + { + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) + { + Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], + &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], + &Cx_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + } + } + + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], + &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_imag_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2], + &Cy_sum_imag_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + } + } + } + + FOR( ; cur_param_band < num_parameter_bands; cur_param_band += 2 ) + { + IF( LT_16( cur_param_band, num_parameter_bands ) ) + { + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 ) + { + FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ++ch_idx2 ) + { + Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cx_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cx_sum_e[cur_param_band][ch_idx1][ch_idx2], + &Cx_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + } + } + + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ++ch_idx1 ) + { + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ++ch_idx2 ) + { + Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2] = BASOP_Util_Add_Mant32Exp( Cy_sum_fx[cur_param_band - 1][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2], + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2], Cy_sum_e[cur_param_band][ch_idx1][ch_idx2], + &Cy_sum_e[cur_param_band - 1][ch_idx1][ch_idx2] ); + move32(); + } + } + } + } + + band_step = 2; + move16(); + } + + + /* map complex covariances to real values */ + FOR( cur_param_band = 0; cur_param_band < hParamMC->max_param_band_abs_cov; cur_param_band += band_step ) + { + /* Cx for transport channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_transport; ch_idx1++ ) + { + FOR( ch_idx2 = 0; ch_idx2 < nchan_transport; ch_idx2++ ) + { + real_part_fx = Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2]; + move32(); + real_part_e = Cx_sum_e[cur_param_band][ch_idx1][ch_idx2]; + move16(); + imag_part_fx = Cx_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; + move32(); + imag_part_e = Cx_sum_imag_e[cur_param_band][ch_idx1][ch_idx2]; + move16(); + + real_part_fx = Mpy_32_32( real_part_fx, real_part_fx ); + imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx ); + L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, L_shl( real_part_e, 1 ), imag_part_fx, L_shl( imag_part_e, 1 ), &tmp_e ); + + /* (a-ib)(c+id) = ac + bd + i(ad-bc) */ + L_tmp = Sqrt32( L_tmp, &tmp_e ); + Cx_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp; + move32(); + Cx_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e; + move16(); + } + } + + /* Cy for transport channels */ + FOR( ch_idx1 = 0; ch_idx1 < nchan_input; ch_idx1++ ) + { + FOR( ch_idx2 = ch_idx1; ch_idx2 < nchan_input; ch_idx2++ ) + { + real_part_fx = Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2]; + move32(); + real_part_e = Cy_sum_e[cur_param_band][ch_idx1][ch_idx2]; + move16(); + imag_part_fx = Cy_sum_imag_fx[cur_param_band][ch_idx1][ch_idx2]; + move32(); + imag_part_e = Cy_sum_imag_e[cur_param_band][ch_idx1][ch_idx2]; + move16(); + + real_part_fx = Mpy_32_32( real_part_fx, real_part_fx ); + imag_part_fx = Mpy_32_32( imag_part_fx, imag_part_fx ); + + L_tmp = BASOP_Util_Add_Mant32Exp( real_part_fx, L_shl( real_part_e, 1 ), imag_part_fx, L_shl( imag_part_e, 1 ), &tmp_e ); + L_tmp = Sqrt32( L_tmp, &tmp_e ); + + Cy_sum_fx[cur_param_band][ch_idx1][ch_idx2] = L_tmp; + move32(); + Cy_sum_e[cur_param_band][ch_idx1][ch_idx2] = tmp_e; + move16(); + } + } + } + + IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( Cy_sum_fx[0][LFE_CHANNEL][LFE_CHANNEL], Cy_sum_e[0][LFE_CHANNEL][LFE_CHANNEL], PARAM_MC_LFE_ON_THRESH_FX, 31 ), -1 ) ) + { + hParamMC->hMetadataPMC.lfe_on = 0; + move16(); + } + ELSE + { + hParamMC->hMetadataPMC.lfe_on = 1; + move16(); + } + + pop_wmops(); + + return; +} +#else static void ivas_param_mc_param_est_enc( PARAM_MC_ENC_HANDLE hParamMC, /* i/o: Parametric MC encoder handle */ float *data_f[], /* i : Input frame in the time domain */ @@ -1377,6 +1991,7 @@ static void ivas_param_mc_param_est_enc( return; } +#endif #ifndef FIX_901_PARAMMC_DEAD_CODE /*------------------------------------------------------------------------- diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index c547a60bd175e0dbb2844f18bab4536c7043f516..b56db211bc339568e484bd0bfc4f5ac30ea19a6e 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -42,6 +42,7 @@ #include "ivas_prot_fx.h" #include "prot_fx.h" #include "basop_util.h" +#include "ivas_rom_com_fx.h" #endif #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -67,17 +68,42 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( MC_PARAMUPMIX_ENC_HANDLE static void ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); #endif +#ifdef IVAS_FLOAT_FIXED +static void get_huff_table_fx( const PAR_TYPE par_type, HUFF_TAB *df0, HUFF_TAB *df ); +#else static void get_huff_table( const PAR_TYPE par_type, HUFF_TAB *df0, HUFF_TAB *df ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void write_huff_bits_fx( const Word32 value, const UWord16 length, UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], Word16 *bit_pos ); +#else static void write_huff_bits( const int32_t value, const uint16_t length, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void huffman_encode_fx( const Word32 *vqPrev, const Word32 *vq, const PAR_TYPE parType, const Word16 nq, UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], Word16 *bit_pos ); +#else static void huffman_encode( const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void put_ec_data_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const Word16 ch, const Word32 pars_fx[IVAS_MAX_NUM_BANDS], Word16 exp_paras, const Word32 alphas_fx[IVAS_MAX_NUM_BANDS], Word16 exp_alphas, const PAR_TYPE parType, UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], Word16 *bit_pos ); +#else static void put_ec_data( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const int16_t ch, const float pars[IVAS_MAX_NUM_BANDS], const float alphas[IVAS_MAX_NUM_BANDS], const PAR_TYPE parType, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void quantize_alpha_fx( const Word32 *alpha_fx, Word16 exp_alpha, Word16 *pnq, Word32 aq[IVAS_MAX_NUM_BANDS], Word32 *adeq_fx, Word16 *exp_adeq ); +#else static void quantize_alpha( const float *alpha, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); +#endif + +#ifdef IVAS_FLOAT_FIXED +static void quantize_pars_fx( const Word32 *v_fx, Word16 exp_v, const Word16 nq, const Word32 *data_fx, Word32 vq[IVAS_MAX_NUM_BANDS], Word32 *vdeq_fx, Word16 *exp_vdeq ); +#else static void quantize_pars( const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); +#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_enc() @@ -86,20 +112,17 @@ static void quantize_pars( const float *v, const int16_t nq, const float *data, *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -void ivas_mc_paramupmix_enc( +void ivas_mc_paramupmix_enc_fx( Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */ BSTR_ENC_HANDLE hBStr, /* i/o: IVAS Metadata bitstream handle */ - float *data_f[], /* i/o: input/transport MC data */ Word32 *data_fx[], - const int16_t input_frame /* i : input frame length */ + const Word16 input_frame /* i : input frame length */ ) { MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix; - int16_t i; - float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS]; - int16_t bit_pos; + Word16 i; + UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS]; + Word16 bit_pos; push_wmops( "mc_paramupmix_enc" ); @@ -107,7 +130,6 @@ void ivas_mc_paramupmix_enc( bit_pos = 0; /* Parameter estimation */ -#ifdef IVAS_FLOAT_FIXED Word32 alphas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; Word32 betas_fx[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; Word16 exp_alphas = 31, exp_betas = 31; @@ -116,88 +138,18 @@ void ivas_mc_paramupmix_enc( ivas_mc_paramupmix_param_est_enc_fx( hMCParamUpmix, data_fx, st_ivas->q_data_fx, input_frame, alphas_fx, &exp_alphas, betas_fx, &exp_betas ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( int ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) - { - for ( int ch_idx = 0; ch_idx < hMCParamUpmix->hFbMixer->fb_cfg->num_in_chans; ch_idx++ ) - { - fixedToFloat_arrL( hMCParamUpmix->hFbMixer->ppFilterbank_prior_input_fx[ch_idx], hMCParamUpmix->hFbMixer->ppFilterbank_prior_input[ch_idx], Q14, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); - } - } - - for ( int b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) - { - for ( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) - { - for ( int j = 0; j < MC_PARAMUPMIX_NCH; j++ ) - { - for ( int k = 0; k < hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; k++ ) - { - hMCParamUpmix->cov_real[b][i][j][k] = me2f( hMCParamUpmix->cov_real_fx[b][i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_state->q_cov_real_per_band[i][j][k] ) ); - hMCParamUpmix->cov_dtx_real[b][i][j][k] = me2f( hMCParamUpmix->cov_dtx_real_fx[b][i][j][k], sub( Q31, hMCParamUpmix->hCovEnc[b]->pCov_dtx_state->q_cov_real_per_band[i][j][k] ) ); - } - } - } - } - - Word16 len = hMCParamUpmix->hFbMixer->pFb->filterbank_num_bands; - if ( len < IVAS_MAX_NUM_BANDS ) - { - len = IVAS_MAX_NUM_BANDS; - } - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - for ( int j = 0; j < len; j++ ) - { - alphas[i][j] = me2f( alphas_fx[i][j], exp_alphas ); - betas[i][j] = me2f( betas_fx[i][j], exp_betas ); - } - } -#endif -#else - ivas_mc_paramupmix_param_est_enc( hMCParamUpmix, data_f, input_frame, alphas, betas ); -#endif - - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { - put_ec_data( hMCParamUpmix, i, alphas[i], NULL, ALPHA, bit_buffer, &bit_pos ); - put_ec_data( hMCParamUpmix, i, betas[i], alphas[i], BETA, bit_buffer, &bit_pos ); + put_ec_data_fx( hMCParamUpmix, i, alphas_fx[i], exp_alphas, NULL, 0, ALPHA, bit_buffer, &bit_pos ); + put_ec_data_fx( hMCParamUpmix, i, betas_fx[i], exp_betas, alphas_fx[i], exp_alphas, BETA, bit_buffer, &bit_pos ); } /* push the PARAM UPMIX MC side info from the temporary buffer into the medatdata bitstream*/ push_next_bits( hBStr, bit_buffer, bit_pos ); /* DMX generation*/ -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( i = 4; i < 12; i++ ) - { - for ( int l = 0; l < input_frame; l++ ) - { - data_fx[i][l] = floatToFixed( data_f[i][l], st_ivas->q_data_fx ); - } - } -#endif ivas_mc_paramupmix_dmx_fx( hMCParamUpmix, data_fx, input_frame ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - for ( int k = 0; k < MC_PARAMUPMIX_NCH; k++ ) - { - fixedToFloat_arrL( hMCParamUpmix->midside_fx[i][k], hMCParamUpmix->midside[i][k], st_ivas->q_data_fx, input_frame ); - } - } - for ( i = 4; i < 12; i++ ) - { - for ( int l = 0; l < input_frame; l++ ) - { - data_f[i][l] = fixedToFloat( data_fx[i][l], st_ivas->q_data_fx ); - } - } -#endif -#else - ivas_mc_paramupmix_dmx( hMCParamUpmix, data_f, input_frame ); -#endif + pop_wmops(); return; @@ -249,7 +201,146 @@ void ivas_mc_paramupmix_enc( * * Initialize MC ParamUpmix encoder handle *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_mc_paramupmix_enc_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ +) +{ + IVAS_FB_CFG *fb_cfg; + MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix; + Word32 input_Fs; + Word32 input_frame; + Word16 i, k, b, j; + ivas_error error; + + error = IVAS_ERR_OK; + move16(); + input_Fs = st_ivas->hEncoderConfig->input_Fs; + move16(); + input_frame = (Word32) extract_l( Mpy_32_32( st_ivas->hEncoderConfig->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + + /* Sanity Checks */ + IF( ( hMCParamUpmix = (MC_PARAMUPMIX_ENC_HANDLE) malloc( sizeof( MC_PARAMUPMIX_ENC_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MC_MODE_PARAMUPMIX\n" ) ); + } + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + FOR( k = 0; k < MC_PARAMUPMIX_NCH; k++ ) + { + IF( ( hMCParamUpmix->midside_fx[i][k] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MC_MODE_PARAMUPMIX\n" ) ); + } + set_zero_fx( hMCParamUpmix->midside_fx[i][k], (Word16) input_frame ); + } + } + hMCParamUpmix->first_frame = 1; + move16(); + + /* MC_LS_SETUP_5_1_2 is the only current configuration */ + st_ivas->nchan_transport = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS; + move16(); + + /* set core coder dependent on the number of transport channels */ + SWITCH( st_ivas->nchan_transport ) + { + case 8: + st_ivas->nCPE = 4; + move16(); + st_ivas->nSCE = 0; + move16(); + st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + move16(); + break; + } + + /* Transient Detector handle */ + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( error = ivas_transient_det_open( &( hMCParamUpmix->hTranDet[i] ), input_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* set FB config. */ + /* need to set num output channels to a value > 0 to get pFb != NULL */ + IF( ( error = ivas_fb_set_cfg( &fb_cfg, MC_FORMAT, MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH, MC_PARAMUPMIX_COMBINATIONS, 0, input_Fs, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + fb_cfg->remix_order = mc_paramupmix_fb_remix_order; + move16(); + /* override latency, could be moved to ivas_fb_set_cfg */ + /* assuming parameters are calculated at end of frame, compensate for MCT delay and half of decoder fb */ + /* still 1.5ms off, since MCT delay is not large enough */ + /* param at end of frame */ + fb_cfg->prior_input_length = (int16_t) ( NS2SA( input_Fs, 12000000L ) + NS2SA( input_Fs, DELAY_FB_4_NS / 2 ) - input_frame / 2 - NS2SA( input_Fs, DELAY_FB_1_NS / 2 ) ); + fb_cfg->prior_input_length = (int16_t) max( fb_cfg->prior_input_length, input_frame / MAX_PARAM_SPATIAL_SUBFRAMES ); + + /* Allocate and initialize FB mixer handle */ + IF( ( error = ivas_FB_mixer_open( &( hMCParamUpmix->hFbMixer ), input_Fs, fb_cfg, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + /* Covariance handle */ + IF( NE_32( ( error = ivas_spar_covar_enc_open_fx( &( hMCParamUpmix->hCovEnc[i] ), hMCParamUpmix->hFbMixer->pFb, input_Fs, MC_PARAMUPMIX_NCH + 1, COV_SMOOTH_MC, st_ivas->hEncoderConfig->ivas_total_brate ) ), IVAS_ERR_OK ) ) + { + return error; + } + } + + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b] = (Word32 ***) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b][i] = (Word32 **) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( hMCParamUpmix->cov_real_fx[b][i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov real matrix" ); + } + } + } + + IF( ( hMCParamUpmix->cov_dtx_real_fx[b] = (Word32 ***) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( hMCParamUpmix->cov_dtx_real_fx[b][i] = (Word32 **) malloc( MC_PARAMUPMIX_NCH * sizeof( Word32 * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( hMCParamUpmix->cov_dtx_real_fx[b][i][j] = (Word32 *) malloc( IVAS_MAX_NUM_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR cov dtx real matrix" ); + } + } + } + } + st_ivas->hMCParamUpmix = hMCParamUpmix; + + return error; +} +#else ivas_error ivas_mc_paramupmix_enc_open( Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */ ) @@ -437,14 +528,101 @@ ivas_error ivas_mc_paramupmix_enc_open( return error; } - +#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_enc_close() * * Close MC Param-Upmix encoder handle *------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_mc_paramupmix_enc_close( + MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ + const Word32 input_Fs /* i : input sampling rate */ +) +{ + Word16 i, k; + Word16 b, j; + + IF( hMCParamUpmix == NULL || *hMCParamUpmix == NULL ) + { + return; + } + + FOR( b = 0; b < MC_PARAMUPMIX_COMBINATIONS; b++ ) + { + IF( ( *hMCParamUpmix )->cov_real_fx[b] != NULL ) + { + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( *hMCParamUpmix )->cov_real_fx[b][i] != NULL ) + { + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( *hMCParamUpmix )->cov_real_fx[b][i][j] != NULL ) + { + free( ( *hMCParamUpmix )->cov_real_fx[b][i][j] ); + } + } + free( ( *hMCParamUpmix )->cov_real_fx[b][i] ); + } + } + free( ( *hMCParamUpmix )->cov_real_fx[b] ); + } + + IF( ( *hMCParamUpmix )->cov_dtx_real_fx[b] != NULL ) + { + FOR( i = 0; i < MC_PARAMUPMIX_NCH; i++ ) + { + IF( ( *hMCParamUpmix )->cov_dtx_real_fx[b][i] != NULL ) + { + FOR( j = 0; j < MC_PARAMUPMIX_NCH; j++ ) + { + IF( ( *hMCParamUpmix )->cov_dtx_real_fx[b][i][j] != NULL ) + { + free( ( *hMCParamUpmix )->cov_dtx_real_fx[b][i][j] ); + } + } + free( ( *hMCParamUpmix )->cov_dtx_real_fx[b][i] ); + } + } + free( ( *hMCParamUpmix )->cov_dtx_real_fx[b] ); + } + } + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + FOR( k = 0; k < MC_PARAMUPMIX_NCH; k++ ) + { + free( ( *hMCParamUpmix )->midside_fx[i][k] ); + } + } + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + ivas_transient_det_close( &( *hMCParamUpmix )->hTranDet[i] ); + } + + IF( ( *hMCParamUpmix )->hFbMixer != NULL ) + { + ivas_FB_mixer_close( &( *hMCParamUpmix )->hFbMixer, input_Fs, 0 ); + } + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + /* Covariance handle */ + IF( ( *hMCParamUpmix )->hCovEnc[i] != NULL ) + { + ivas_spar_covar_enc_close_fx( &( *hMCParamUpmix )->hCovEnc[i], ( MC_PARAMUPMIX_NCH + 1 ) ); + } + } + + free( *hMCParamUpmix ); + *hMCParamUpmix = NULL; + + return; +} +#else void ivas_mc_paramupmix_enc_close( MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */ const int32_t input_Fs /* i : input sampling rate */ @@ -503,9 +681,6 @@ void ivas_mc_paramupmix_enc_close( { for ( k = 0; k < MC_PARAMUPMIX_NCH; k++ ) { -#ifdef IVAS_FLOAT_FIXED - free( ( *hMCParamUpmix )->midside_fx[i][k] ); -#endif free( ( *hMCParamUpmix )->midside[i][k] ); } } @@ -525,11 +700,7 @@ void ivas_mc_paramupmix_enc_close( /* Covariance handle */ if ( ( *hMCParamUpmix )->hCovEnc[i] != NULL ) { -#ifdef IVAS_FLOAT_FIXED - ivas_spar_covar_enc_close_fx( &( *hMCParamUpmix )->hCovEnc[i], ( MC_PARAMUPMIX_NCH + 1 ) ); -#else ivas_spar_covar_enc_close( &( *hMCParamUpmix )->hCovEnc[i], ( MC_PARAMUPMIX_NCH + 1 ) ); -#endif } } @@ -538,12 +709,115 @@ void ivas_mc_paramupmix_enc_close( return; } - +#endif /*****************************************************************************************/ /* local functions */ /*****************************************************************************************/ +#ifdef IVAS_FLOAT_FIXED +static void get_huff_table_fx( + const PAR_TYPE par_type, + HUFF_TAB *df0, + HUFF_TAB *df ) +{ + SWITCH( par_type ) + { + case ALPHA: + df0->value = huff_alpha_table.df0.value; + move16(); + df0->length = huff_alpha_table.df0.length; + move16(); + df->value = huff_alpha_table.df.value; + move16(); + df->length = huff_alpha_table.df.length; + move16(); + break; + case BETA: + df0->value = huff_beta_table.df0.value; + move16(); + df0->length = huff_beta_table.df0.length; + move16(); + df->value = huff_beta_table.df.value; + move16(); + df->length = huff_beta_table.df.length; + move16(); + break; + } + + return; +} + + +static void write_huff_bits_fx( + const Word32 value, + const UWord16 length, + UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], + Word16 *bit_pos ) +{ + Word16 k; + + FOR( k = length - 1; k >= 0; k-- ) + { + bit_buffer[( *bit_pos )++] = (UWord16) ( ( L_shr( value, k ) ) & 1 ); + } + + return; +} + +static void huffman_encode_fx( + const Word32 *vqPrev, + const Word32 *vq, + const PAR_TYPE parType, + const Word16 nq, + UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], + Word16 *bit_pos ) +{ + Word16 iv; + Word32 icode; + Word16 offset; + HUFF_TAB df0, df; + + get_huff_table_fx( parType, &df0, &df ); + + offset = sub( nq, 1 ); /* range [-(nquant - 1), nquant - 1] */ + + FOR( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) + { + IF( iv == 0 ) + { + icode = vq[iv]; + } + ELSE + { + icode = L_add( L_sub( vq[iv], vq[iv - 1] ), offset ); + } + move16(); + + icode = L_add( L_sub( vq[iv], vqPrev[iv] ), offset ); + } + + /* Write the bitstream */ + bit_buffer[( *bit_pos )++] = (UWord16) 0 & 1; + move16(); + FOR( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) + { + IF( iv == 0 ) + { + icode = vq[iv]; + move32(); + write_huff_bits_fx( df0.value[icode], df0.length[icode], bit_buffer, bit_pos ); + } + ELSE + { + icode = L_add( L_sub( vq[iv], vq[iv - 1] ), offset ); + write_huff_bits_fx( df.value[icode], df.length[icode], bit_buffer, bit_pos ); + } + } + + return; +} +#else static void get_huff_table( const PAR_TYPE par_type, HUFF_TAB *df0, @@ -568,7 +842,6 @@ static void get_huff_table( return; } - static void write_huff_bits( const int32_t value, const uint16_t length, @@ -585,7 +858,6 @@ static void write_huff_bits( return; } - static void huffman_encode( const int32_t *vqPrev, const int32_t *vq, @@ -635,8 +907,71 @@ static void huffman_encode( return; } +#endif + +#ifdef IVAS_FLOAT_FIXED +static void quantize_pars_fx( + const Word32 *v_fx, + Word16 exp_v, + const Word16 nq, + const Word32 *data_fx, + Word32 vq[IVAS_MAX_NUM_BANDS], + Word32 *vdeq_fx, + Word16 *exp_vdeq ) +{ + Word16 iv, iq, iq0, iq1; + + FOR( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) + { + iq0 = 0; + iq1 = sub( nq, 1 ); + + WHILE( GT_16( sub( iq1, iq0 ), 1 ) ) + { + iq = shr( add( iq0, iq1 ), 1 ); + Word16 cmp_1 = BASOP_Util_Cmp_Mant32Exp( v_fx[iv], exp_v, data_fx[iq], 31 - Q28 ); + IF( EQ_16( cmp_1, negate( 1 ) ) ) + { + iq1 = iq; + } + ELSE + { + iq0 = iq; + } + } + + Word16 exp_var1 = 0; + move16(); + Word32 var1 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq0] ), 31 - Q28, &exp_var1 ); + var1 = abs( var1 ); + Word16 exp_var2 = 0; + move16(); + Word32 var2 = BASOP_Util_Add_Mant32Exp( v_fx[iv], exp_v, L_negate( data_fx[iq1] ), 31 - Q28, &exp_var2 ); + var2 = abs( var2 ); + + Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); + + IF( EQ_16( cmp_2, negate( 1 ) ) ) + { + vq[iv] = iq0; + vdeq_fx[iv] = data_fx[iq0]; + } + ELSE + { + vq[iv] = iq1; + vdeq_fx[iv] = data_fx[iq1]; + } + move16(); + move32(); + } + *exp_vdeq = sub( 31, Q28 ); + move16(); + + return; +} +#else static void quantize_pars( const float *v, const int16_t nq, @@ -678,8 +1013,32 @@ static void quantize_pars( return; } +#endif + +#ifdef IVAS_FLOAT_FIXED +static void quantize_alpha_fx( + const Word32 *alpha_fx, + Word16 exp_alpha, + Word16 *pnq, + Word32 aq[IVAS_MAX_NUM_BANDS], + Word32 *adeq_fx, + Word16 *exp_adeq ) +{ + Word16 nq; + const Word32 *data_fx; + + nq = ivas_mc_paramupmix_alpha_quant_table.nquant; + move16(); + data_fx = ivas_mc_paramupmix_alpha_quant_table_fx.data; // Q28 + quantize_pars_fx( alpha_fx, exp_alpha, nq, data_fx, aq, adeq_fx, exp_adeq ); + *pnq = nq; + move16(); + + return; +} +#else static void quantize_alpha( const float *alpha, int16_t *pnq, @@ -697,8 +1056,82 @@ static void quantize_alpha( return; } +#endif + +#ifdef IVAS_FLOAT_FIXED +static void quantize_beta_fx( + const Word32 *beta_fx, + Word16 exp_beta, + const Word32 aq[IVAS_MAX_NUM_BANDS], + Word16 *pnq, + Word32 bq[IVAS_MAX_NUM_BANDS], + Word32 *bdeq_fx, + Word16 *exp_bdeq ) +{ + Word16 iv, iq, iq0, iq1; + + const ACPL_QUANT_TABLE_FX *tables_fx = ivas_mc_paramupmix_beta_quant_table_fx; // Q28 + + ACPL_QUANT_TABLE_FX quant_table_fx; + + FOR( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) + { + quant_table_fx = tables_fx[ivas_param_upmx_mx_qmap[aq[iv]]]; + + iq0 = 0; + move16(); + iq1 = sub( quant_table_fx.nquant, 1 ); + + WHILE( GT_16( sub( iq1, iq0 ), 1 ) ) + { + iq = shr( add( iq0, iq1 ), 1 ); + + Word16 cmp_1 = BASOP_Util_Cmp_Mant32Exp( beta_fx[iv], exp_beta, quant_table_fx.data[iq], 31 - Q28 ); + + IF( EQ_16( cmp_1, negate( 1 ) ) ) + { + iq1 = iq; + } + ELSE + { + iq0 = iq; + } + move16(); + } + + Word16 exp_var1 = 0; + move16(); + Word32 var1 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq0] ), 31 - Q28, &exp_var1 ); + var1 = abs( var1 ); + + Word16 exp_var2 = 0; + move16(); + Word32 var2 = BASOP_Util_Add_Mant32Exp( beta_fx[iv], exp_beta, L_negate( quant_table_fx.data[iq1] ), 31 - Q28, &exp_var2 ); + var2 = abs( var2 ); + + Word16 cmp_2 = BASOP_Util_Cmp_Mant32Exp( var1, exp_var1, var2, exp_var2 ); + + IF( EQ_16( cmp_2, negate( 1 ) ) ) + { + bq[iv] = iq0; + bdeq_fx[iv] = quant_table_fx.data[iq0]; + } + ELSE + { + bq[iv] = iq1; + bdeq_fx[iv] = quant_table_fx.data[iq1]; + } + move16(); + move32(); + } + *exp_bdeq = sub( 31, Q28 ); + *pnq = ivas_mc_paramupmix_beta_quant_table[0].nquant; + move16(); + return; +} +#else static void quantize_beta( const float *beta, const int32_t aq[IVAS_MAX_NUM_BANDS], @@ -746,8 +1179,74 @@ static void quantize_beta( return; } +#endif + +#ifdef IVAS_FLOAT_FIXED +static void put_ec_data_fx( + MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, + const Word16 ch, + const Word32 pars_fx[IVAS_MAX_NUM_BANDS], + Word16 exp_paras, + const Word32 alphas_fx[IVAS_MAX_NUM_BANDS], + Word16 exp_alphas, + const PAR_TYPE parType, + UWord16 bit_buffer[MC_PARAMUPMIX_MAX_BITS], + Word16 *bit_pos ) +{ + Word16 nq; + Word32 alphaQuant[IVAS_MAX_NUM_BANDS]; + Word32 betaQuant[IVAS_MAX_NUM_BANDS]; + Word32 alphaDequant_fx[IVAS_MAX_NUM_BANDS]; + Word32 betaDequant_fx[IVAS_MAX_NUM_BANDS]; + Word16 exp_alphaDequant = 31, exp_betaDequant = 31; + + + IF( EQ_16( parType, ALPHA ) ) + { + quantize_alpha_fx( pars_fx, exp_paras, &nq, alphaQuant, alphaDequant_fx, &exp_alphaDequant ); + } + ELSE + { + quantize_alpha_fx( alphas_fx, exp_alphas, &nq, alphaQuant, alphaDequant_fx, &exp_alphaDequant ); + quantize_beta_fx( pars_fx, exp_paras, alphaQuant, &nq, betaQuant, betaDequant_fx, &exp_betaDequant ); + } + + IF( hMCParamUpmix->first_frame ) + { + Copy32( &( alphaQuant[0] ), &( hMCParamUpmix->alpha_quant_prev[ch][0] ), IVAS_MAX_NUM_BANDS ); + IF( EQ_16( parType, BETA ) ) + { + Copy32( &( betaQuant[0] ), &( hMCParamUpmix->beta_quant_prev[ch][0] ), IVAS_MAX_NUM_BANDS ); + if ( EQ_16( ch, ( MC_PARAMUPMIX_COMBINATIONS - 1 ) ) ) + { + hMCParamUpmix->first_frame = 0; + move16(); + } + } + } + + /* Always one parameter set per frame for transient frames. Original PS framing is used internally. */ + IF( EQ_16( parType, ALPHA ) ) + { + huffman_encode_fx( hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, nq, bit_buffer, bit_pos ); + } + ELSE + { + huffman_encode_fx( hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, nq, bit_buffer, bit_pos ); + } + IF( EQ_16( parType, ALPHA ) ) + { + Copy32( alphaQuant, hMCParamUpmix->alpha_quant_prev[ch], IVAS_MAX_NUM_BANDS ); + } + ELSE + { + Copy32( betaQuant, hMCParamUpmix->beta_quant_prev[ch], IVAS_MAX_NUM_BANDS ); + } + return; +} +#else static void put_ec_data( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const int16_t ch, @@ -807,7 +1306,7 @@ static void put_ec_data( return; } - +#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_dmx() @@ -816,7 +1315,6 @@ static void put_ec_data( *------------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED - static void ivas_mc_paramupmix_dmx_fx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, /* i/o: MC ParamUpmix encoder handle */ Word32 *data_fx[], @@ -1027,6 +1525,22 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( } } + FOR( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) + { + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH; i++ ) + { + pcm_in_fx[i] -= l_ts; + pp_in_fr_real_fx[i] -= l_ts; + pp_in_fr_imag_fx[i] -= l_ts; + } + } + + FOR( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + Scale_sig32( pcm_in_fx[2 * i], input_frame, Q_data_f - Q14 ); + Scale_sig32( pcm_in_fx[2 * i + 1], input_frame, Q_data_f - Q14 ); + } + /*-----------------------------------------------------------------------------------------* * Covariance process *-----------------------------------------------------------------------------------------*/ @@ -1137,7 +1651,6 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( } Word16 exp_betas_var = add( exp_sqrt_wetaux, 1 ); - move16(); alphas_fx[b][bnd] = L_deposit_h( alpha_fx ); move16(); @@ -1194,6 +1707,7 @@ static ivas_error ivas_mc_paramupmix_param_est_enc_fx( } } + return IVAS_ERR_OK; } #else diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index d30e12f1c3b44936357b7d6efee9412bd1fd49c4..c4576e04585d65593b287bbf049f4b346de9a268 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -912,12 +912,10 @@ ivas_error ivas_mct_enc( IF( EQ_32( st->sr_core, INT_FS_12k8 ) ) { st->preemph_fac_flt = PREEMPH_FAC_FLT; - st->gamma_flt = GAMMA1_FLT; } ELSE { st->preemph_fac_flt = PREEMPH_FAC_16k_FLT; - st->gamma_flt = GAMMA16k_FLT; } } diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 2bcaf05aff4e77caf6a2d871956a678cd184053e..67542e0307c71e3c6bbc3565de8778c03b06a8f8 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -50,8 +50,25 @@ /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED +static void ivas_omasa_param_est_enc_fx( + OMASA_ENC_HANDLE hOMasa, + OMASA_ENCODER_DATA_HANDLE hOmasaData, + ISM_METADATA_HANDLE hIsmMeta[], + Word32 *data[], /*i:q_data*/ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/ + Word32 energyRatio_fx[MASA_FREQUENCY_BANDS], /*o:Q30*/ + Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:Q15*/ + Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS], /*o:Q15*/ + Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS], /*o:q30*/ + const Word16 input_frame, + const Word16 nchan_ism, + Word16 q_data /*i: Qfactor for data*/ +); +#else static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, ISM_METADATA_HANDLE hIsmMeta[], float *data_f[], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MASA_FREQUENCY_BANDS], float diffuseness_m[MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp ); +#endif // IVAS_FLOAT_FIXED 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 ); @@ -83,7 +100,7 @@ static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldf #ifndef IVAS_FLOAT_FIXED static void computeReferencePower_omasa( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float *reference_power, const int16_t enc_param_start_band, const int16_t num_freq_bands ); #else -static void computeReferencePower_omasa_ivas_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 *reference_power, const Word16 enc_param_start_band, const Word16 num_freq_bands, Word16 *ref_exp ); +static void computeReferencePower_omasa_ivas_fx( const Word16 *band_grouping, Word32 Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], Word32 *reference_power, const Word16 enc_param_start_band, const Word16 num_freq_bands, Word16 q_Cldfb, Word16 *ref_exp ); #endif /*--------------------------------------------------------------------------* * ivas_omasa_enc_open() @@ -129,6 +146,28 @@ ivas_error ivas_omasa_enc_open( /* intensity 3-dim */ for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) { +#ifdef IVAS_FLOAT_FIXED + hOMasa->direction_vector_m_fx[i] = (Word32 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word32 * ) ); + + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + if ( ( hOMasa->direction_vector_m_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) ); + } + set_zero_fx( hOMasa->direction_vector_m_fx[i][j], MASA_FREQUENCY_BANDS ); + } + hOMasa->direction_vector_e[i] = (Word16 **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( Word16 * ) ); + + for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + if ( ( hOMasa->direction_vector_e[i][j] = (Word16 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) ); + } + set16_fx( hOMasa->direction_vector_e[i][j], 0, MASA_FREQUENCY_BANDS ); + } +#endif // IVAS_FLOAT_FIXED hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) ); for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) @@ -145,6 +184,13 @@ ivas_error ivas_omasa_enc_open( { for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) { +#ifdef IVAS_FLOAT_FIXED + IF( ( hOMasa->buffer_intensity_real_fx[i][j] = (Word32 *) malloc( MASA_FREQUENCY_BANDS * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) ); + } + set_zero_fx( hOMasa->buffer_intensity_real_fx[i][j], MASA_FREQUENCY_BANDS ); +#endif // IVAS_FLOAT_FIXED if ( ( hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA data\n" ) ); @@ -152,6 +198,11 @@ ivas_error ivas_omasa_enc_open( set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS ); } } +#ifdef IVAS_FLOAT_FIXED + set16_fx( hOMasa->buffer_intensity_real_q, 31, DIRAC_NO_COL_AVG_DIFF ); + set_zero_fx( hOMasa->buffer_energy_fx, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS ); + set16_fx( hOMasa->buffer_energy_q, 31, DIRAC_NO_COL_AVG_DIFF ); +#endif // IVAS_FLOAT_FIXED set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS ); @@ -206,16 +257,29 @@ void ivas_omasa_enc_close( { for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) { +#ifdef IVAS_FLOAT_FIXED + free( ( *hOMasa )->direction_vector_m_fx[i][j] ); + ( *hOMasa )->direction_vector_m_fx[i][j] = NULL; + free( ( *hOMasa )->direction_vector_e[i][j] ); + ( *hOMasa )->direction_vector_e[i][j] = NULL; +#endif // IVAS_FLOAT_FIXED free( ( *hOMasa )->direction_vector_m[i][j] ); ( *hOMasa )->direction_vector_m[i][j] = NULL; } for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ ) { +#ifdef IVAS_FLOAT_FIXED + free( ( *hOMasa )->buffer_intensity_real_fx[i][j] ); + ( *hOMasa )->buffer_intensity_real_fx[i][j] = NULL; +#endif // IVAS_FLOAT_FIXED free( ( *hOMasa )->buffer_intensity_real[i][j] ); ( *hOMasa )->buffer_intensity_real[i][j] = NULL; } - +#ifdef IVAS_FLOAT_FIXED + free( ( *hOMasa )->direction_vector_m_fx[i] ); + ( *hOMasa )->direction_vector_m_fx[i] = NULL; +#endif // IVAS_FLOAT_FIXED free( ( *hOMasa )->direction_vector_m[i] ); ( *hOMasa )->direction_vector_m[i] = NULL; } @@ -670,8 +734,85 @@ void ivas_omasa_enc( /* 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 ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + 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 ); + } + Word16 norm_data_in = MAX16B; + + 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 ); + } + norm_data_in = s_min( norm_data_in, L_norm_arr( data_in[j], input_frame ) ); + } + norm_data_in -= 6; /*guard bit is 3->to handle overflow in cldfbAnalysis*/ + for ( j = 0; j < nchan_ism; j++ ) + { + Scale_sig32( data_in[j], input_frame, norm_data_in ); + } + q_data = q_data + norm_data_in; + for ( i = 0; i < nchan_ism; i++ ) + { + floatToFixed_arr32( hOMasa->cldfbAnaEnc[i]->cldfb_state, hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, q_data, hOMasa->cldfbAnaEnc[i]->cldfb_state_length ); + } +#endif + ivas_omasa_param_est_enc_fx( hOMasa, hMasa->data.hOmasaData, hIsmMeta, data_in, hOMasaMeta->directional_meta[0].elevation_fx, hOMasaMeta->directional_meta[0].azimuth_fx, hOMasaMeta->directional_meta[0].energy_ratio_fx[0], hOMasaMeta->directional_meta[0].spread_coherence_fx, hOMasaMeta->common_meta.surround_coherence_fx[0], + hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0], input_frame, nchan_ism, q_data ); +#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED + Word16 block_m_idx, band_m_idx; + for ( i = 0; i < nchan_ism; i++ ) + { + fixedToFloat_arrL( hOMasa->cldfbAnaEnc[i]->cldfb_state_fx, hOMasa->cldfbAnaEnc[i]->cldfb_state, q_data, hOMasa->cldfbAnaEnc[i]->cldfb_state_length ); + } + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 32; j++ ) + { + for ( int k = 0; k < MASA_FREQUENCY_BANDS; k++ ) + { + hOMasa->buffer_intensity_real[i][j][k] = fixedToFloat( hOMasa->buffer_intensity_real_fx[i][j][k], hOMasa->buffer_intensity_real_q[j] ); + } + } + } + for ( i = 0; i < DIRAC_NO_COL_AVG_DIFF; i++ ) + { + for ( j = 0; j < MASA_FREQUENCY_BANDS; j++ ) + { + hOMasa->buffer_energy[i * MASA_FREQUENCY_BANDS + j] = fixedToFloat( hOMasa->buffer_energy_fx[i * MASA_FREQUENCY_BANDS + j], hOMasa->buffer_energy_q[i] ); + } + } + FOR( i = 0; i < nchan_ism; i++ ) + { + hOMasa->chnlToFoaMtx[0][i] = fixedToFloat( hOMasa->chnlToFoaMtx_fx[0][i], 31 ); /*q31*/ + hOMasa->chnlToFoaMtx[1][i] = fixedToFloat( hOMasa->chnlToFoaMtx_fx[1][i], 31 ); /*q31*/ + hOMasa->chnlToFoaMtx[2][i] = fixedToFloat( hOMasa->chnlToFoaMtx_fx[2][i], 31 ); /*q31*/ + hOMasa->chnlToFoaMtx[3][i] = fixedToFloat( hOMasa->chnlToFoaMtx_fx[3][i], 31 ); /*q31*/ + } + for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) + { + fixedToFloat_arrL( hMasa->data.hOmasaData->energy_ism_fx[block_m_idx], hMasa->data.hOmasaData->energy_ism[block_m_idx], sub( 31, hMasa->data.hOmasaData->energy_ism_e[block_m_idx] ), hOMasa->nbands ); + for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + { + hOMasaMeta->directional_meta[0].spread_coherence[block_m_idx][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].spread_coherence_fx[block_m_idx][band_m_idx], Q15 ); + hOMasaMeta->common_meta.surround_coherence[0][band_m_idx] = fixedToFloat( hOMasaMeta->common_meta.surround_coherence_fx[0][band_m_idx], Q15 ); + hOMasaMeta->directional_meta[0].azimuth[block_m_idx][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].azimuth_fx[block_m_idx][band_m_idx], Q22 ); + hOMasaMeta->directional_meta[0].elevation[block_m_idx][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].elevation_fx[block_m_idx][band_m_idx], Q22 ); + hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = fixedToFloat( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], sub( 31, hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] ) ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = fixedToFloat( hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], sub( 31, hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] ) ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = fixedToFloat( hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], sub( 31, hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] ) ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + } + } + for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + { + hOMasaMeta->common_meta.diffuse_to_total_ratio[0][band_m_idx] = fixedToFloat( hOMasaMeta->common_meta.diffuse_to_total_ratio_fx[0][band_m_idx], Q30 ); + hOMasaMeta->directional_meta[0].energy_ratio[0][band_m_idx] = fixedToFloat( hOMasaMeta->directional_meta[0].energy_ratio_fx[0][band_m_idx], Q30 ); + } +#endif // DEBUG /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */ for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) @@ -1320,284 +1461,308 @@ int16_t ivas_omasa_ener_brate( /* Estimate MASA parameters from the objects */ #ifdef IVAS_FLOAT_FIXED -static void ivas_omasa_param_est_enc( +static void ivas_omasa_param_est_enc_fx( OMASA_ENC_HANDLE hOMasa, OMASA_ENCODER_DATA_HANDLE hOmasaData, ISM_METADATA_HANDLE hIsmMeta[], - float *data_f[], - float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - float energyRatio[MASA_FREQUENCY_BANDS], - float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], - float surroundingCoherence[MASA_FREQUENCY_BANDS], - float diffuseness_m[MASA_FREQUENCY_BANDS], - const int16_t input_frame, - const int16_t nchan_ism ) + Word32 *data[], /*i:q_data*/ + Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/ + Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:q22*/ + Word32 energyRatio_fx[MASA_FREQUENCY_BANDS], /*o:Q30*/ + Word16 spreadCoherence_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], /*o:Q15*/ + Word16 surroundingCoherence_fx[MASA_FREQUENCY_BANDS], /*o:Q15*/ + Word32 diffuseness_m_fx[MASA_FREQUENCY_BANDS], /*o:q30*/ + const Word16 input_frame, + const Word16 nchan_ism, + Word16 q_data /*i: Qfactor for data*/ +) { - float reference_power[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; -#ifdef IVAS_FLOAT_FIXED Word32 reference_power_fx[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; // Q(31-ref_exp) Word16 ref_exp; -#endif - int16_t ts, i, j, d, k; - int16_t num_freq_bins, num_freq_bands, index; - float dir_v[DIRAC_NUM_DIMS]; -#ifdef IVAS_FLOAT_FIXED_ - Word32 elevation_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; - Word32 azimuth_m_values_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 ts, i, j, d, k; + Word16 num_freq_bins, num_freq_bands, index; Word32 dir_v_fx[DIRAC_NUM_DIMS]; -#endif - int16_t l_ts; - float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX]; - float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX]; - float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; - float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; -#ifdef IVAS_FLOAT_FIXED - Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; // Q6 - Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; // Q6 -#endif - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; -#ifdef IVAS_FLOAT_FIXED + Word16 dir_v_e; + Word16 l_ts; + Word32 Chnl_RealBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX]; + Word32 Chnl_ImagBuffer_fx[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX]; + Word16 norm_buff; + Word32 Foa_RealBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; + Word32 Foa_ImagBuffer_fx[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX]; Word32 intensity_real_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; - Word16 Foa_RealBuffer_e; /*exponent for Foa_RealBuffer_fx*/ - Word16 Foa_ImagBuffer_e; /*exponent for Foa_ImagBuffer_fx*/ + Word32 direction_vector_fx[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; Word16 intensity_real_e; /*exponent for intensity_real_fx*/ -#endif // IVAS_FLOAT_FIXED - float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS]; - float diffuseness_vector[MASA_FREQUENCY_BANDS]; - int16_t band_m_idx, block_m_idx; - float renormalization_factor_diff[MASA_FREQUENCY_BANDS]; - float norm_tmp; - int16_t mrange[2], brange[2]; - -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - /*To be removed later*/ - set_f( &Foa_RealBuffer[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); - set_f( &Foa_ImagBuffer[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); - set_f( &intensity_real[0][0], 0, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); - /*To be removed later*/ -#endif - set32_fx( &Foa_RealBuffer_fx[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); - set32_fx( &Foa_ImagBuffer_fx[0][0], 0, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); - set32_fx( &intensity_real_fx[0][0], 0, DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); -#endif // IVAS_FLOAT_FIXED - + Word32 diffuseness_vector_fx[MASA_FREQUENCY_BANDS]; + Word16 q_diffuseness_vector; + Word32 norm_tmp_fx; + Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; + Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS]; + Word16 band_m_idx, block_m_idx; + Word16 mrange[2], brange[2]; + Word16 diffuseness_e[MASA_FREQUENCY_BANDS]; + Word16 azimuth_16, elevation_16; + Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff; + Word16 q; /*stores q for cldfb buffers*/ + + ref_exp = 0; + norm_buff = MAX16B; + dir_v_e = MIN_16; num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels; num_freq_bands = hOMasa->nbands; - l_ts = input_frame / CLDFB_NO_COL_MAX; + l_ts = input_frame / CLDFB_NO_COL_MAX; /*division by power of 2 so basop not used*/ + move16(); + move16(); + move16(); + move16(); + move16(); /* Need to initialize renormalization_factors, and variables to be normalized */ - set_zero( renormalization_factor_diff, hOMasa->nbands ); - set_zero( diffuseness_m, hOMasa->nbands ); - + set_zero_fx( renormalization_factor_diff_fx, hOMasa->nbands ); + set_zero_fx( diffuseness_m_fx, hOMasa->nbands ); + set16_fx( renormalization_factor_diff_e, 0, hOMasa->nbands ); + set16_fx( diffuseness_e, 0, hOMasa->nbands ); /* Compute ISM to FOA matrices */ - for ( i = 0; i < nchan_ism; i++ ) + FOR( i = 0; i < nchan_ism; i++ ) { - hOMasa->chnlToFoaMtx[0][i] = 1.0f; - hOMasa->chnlToFoaMtx[1][i] = sinf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) ); - hOMasa->chnlToFoaMtx[2][i] = sinf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) ); - hOMasa->chnlToFoaMtx[3][i] = cosf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) ); + azimuth_16 = extract_l( Mpy_32_32( hIsmMeta[i]->azimuth_fx, 46603 /*1<<24/360*/ ) ); /*q15*/ + elevation_16 = extract_l( Mpy_32_32( hIsmMeta[i]->elevation_fx, 46603 /*1<<24/360*/ ) ); /*q15*/ + hOMasa->chnlToFoaMtx_fx[0][i] = ONE_IN_Q31; /*q31*/ + hOMasa->chnlToFoaMtx_fx[1][i] = L_mult( getSineWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) ); /*q31*/ + hOMasa->chnlToFoaMtx_fx[2][i] = L_deposit_h( getSineWord16R2( elevation_16 ) ); /*q31*/ + hOMasa->chnlToFoaMtx_fx[3][i] = L_mult( getCosWord16R2( azimuth_16 ), getCosWord16R2( elevation_16 ) ); /*q31*/ + move32(); + move32(); + move32(); + move32(); } + q = q_data; + move16(); /* do processing over all CLDFB time slots */ - for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) + FOR( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ ) { mrange[0] = hOMasa->block_grouping[block_m_idx]; mrange[1] = hOMasa->block_grouping[block_m_idx + 1]; + move16(); + move16(); - for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f; - hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f; - hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f; + hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = 0; + hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = 0; + hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = 0; + hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] = 0; + hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] = 0; + hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] = 0; + move32(); + move32(); + move32(); + move16(); + move16(); + move16(); } - - set_zero( hOmasaData->energy_ism[block_m_idx], num_freq_bands ); - - for ( ts = mrange[0]; ts < mrange[1]; ts++ ) + set_zero_fx( hOmasaData->energy_ism_fx[block_m_idx], num_freq_bands ); + hOmasaData->energy_ism_e[block_m_idx] = 0; + move16(); + FOR( ts = mrange[0]; ts < mrange[1]; ts++ ) { - for ( i = 0; i < nchan_ism; i++ ) + norm_buff = MAX16B; + move16(); + FOR( i = 0; i < nchan_ism; i++ ) { - cldfbAnalysis_ts_ivas( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] ); + q = q_data; + move16(); + cldfbAnalysis_ts_fx_fixed_q( &( data[i][l_ts * ts] ), Chnl_RealBuffer_fx[i], Chnl_ImagBuffer_fx[i], l_ts, hOMasa->cldfbAnaEnc[i], &q ); /*q_data-5*/ + norm_buff = s_min( norm_buff, L_norm_arr( Chnl_RealBuffer_fx[i], 60 ) ); + norm_buff = s_min( norm_buff, L_norm_arr( Chnl_ImagBuffer_fx[i], 60 ) ); } - /* Compute energy */ - for ( i = 0; i < num_freq_bands; i++ ) + FOR( i = 0; i < num_freq_bands; i++ ) + { + band_grouping_diff[i] = sub( hOMasa->band_grouping[i + 1], hOMasa->band_grouping[i] ); + move16(); + } + maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff ); + guard_bits = find_guarded_bits_fx( L_mult0( max_band_grouping_diff, nchan_ism ) ); + norm_buff = sub( norm_buff, guard_bits ); + FOR( i = 0; i < nchan_ism; i++ ) + { + scale_sig32( Chnl_RealBuffer_fx[i], 60, norm_buff ); + scale_sig32( Chnl_ImagBuffer_fx[i], 60, norm_buff ); + } + q = add( q, norm_buff ); + IF( GT_16( hOmasaData->energy_ism_e[block_m_idx], sub( 62, shl( q, 1 ) ) ) ) + { + norm_buff = sub( q, shr( sub( 62, hOmasaData->energy_ism_e[block_m_idx] ), 1 ) ); + } + ELSE + { + norm_buff = 0; + norm_buff = 0; + move16(); + move16(); + FOR( i = 0; i < num_freq_bands; i++ ) + { + hOmasaData->energy_ism_fx[block_m_idx][i] = L_shr( hOmasaData->energy_ism_fx[block_m_idx][i], sub( sub( 62, shl( q, 1 ) ), hOmasaData->energy_ism_e[block_m_idx] ) ); + move32(); + } + hOmasaData->energy_ism_e[block_m_idx] = sub( 62, shl( q, 1 ) ); + move16(); + } + FOR( i = 0; i < num_freq_bands; i++ ) { brange[0] = hOMasa->band_grouping[i]; brange[1] = hOMasa->band_grouping[i + 1]; - for ( j = brange[0]; j < brange[1]; j++ ) + move16(); + move16(); + FOR( k = 0; k < nchan_ism; k++ ) { - for ( k = 0; k < nchan_ism; k++ ) + FOR( j = brange[0]; j < brange[1]; j++ ) { - hOmasaData->energy_ism[block_m_idx][i] += Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j]; + Word32 scaled_real_buffer = L_shr( Chnl_RealBuffer_fx[k][j], norm_buff ); /*scaling the real and imaginary buffers to match the scale factor of hOmasaData->energy_ism_fx*/ + Word32 scaled_imag_buffer = L_shr( Chnl_ImagBuffer_fx[k][j], norm_buff ); + hOmasaData->energy_ism_fx[block_m_idx][i] = L_add( hOmasaData->energy_ism_fx[block_m_idx][i], L_add( Mpy_32_32( scaled_real_buffer, scaled_real_buffer ), Mpy_32_32( scaled_imag_buffer, scaled_imag_buffer ) ) ); /*2q-31*/ + move32(); } } } /* Compute FOA */ /* W */ - mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins ); - mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins ); - for ( i = 1; i < nchan_ism; i++ ) + Copy32( Chnl_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); /*q*/ + Copy32( Chnl_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); /*q*/ + FOR( i = 1; i < nchan_ism; i++ ) { - v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins ); - v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins ); + v_add_32( Chnl_RealBuffer_fx[i], Foa_RealBuffer_fx[0], Foa_RealBuffer_fx[0], num_freq_bins ); + v_add_32( Chnl_ImagBuffer_fx[i], Foa_ImagBuffer_fx[0], Foa_ImagBuffer_fx[0], num_freq_bins ); } /* Y */ - v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins ); - for ( i = 1; i < nchan_ism; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[1][0], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/ + FOR( i = 1; i < nchan_ism; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_RealBuffer_fx[1], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[1][i], Foa_ImagBuffer_fx[1], num_freq_bins ); /*q*/ } /* Z */ - v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins ); - for ( i = 1; i < nchan_ism; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[2][0], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/ + FOR( i = 1; i < nchan_ism; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_RealBuffer_fx[2], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[2][i], Foa_ImagBuffer_fx[2], num_freq_bins ); /*q*/ } + /* X */ - v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins ); - v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins ); - for ( i = 1; i < nchan_ism; i++ ) + v_multc_fixed( Chnl_RealBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/ + v_multc_fixed( Chnl_ImagBuffer_fx[0], hOMasa->chnlToFoaMtx_fx[3][0], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/ + FOR( i = 1; i < nchan_ism; i++ ) { - v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins ); - v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins ); + v_multc_acc_32_32( Chnl_RealBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_RealBuffer_fx[3], num_freq_bins ); /*q*/ + v_multc_acc_32_32( Chnl_ImagBuffer_fx[i], hOMasa->chnlToFoaMtx_fx[3][i], Foa_ImagBuffer_fx[3], num_freq_bins ); /*q*/ } - /* Direction estimation */ -#ifdef IVAS_FLOAT_FIXED -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - f2me_buf( &Foa_RealBuffer[0][0], &Foa_RealBuffer_fx[0][0], &Foa_RealBuffer_e, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); - f2me_buf( &Foa_ImagBuffer[0][0], &Foa_ImagBuffer_fx[0][0], &Foa_ImagBuffer_e, FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); -#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED - /*scaling real and imaginary buffers so they have same exponent for computeIntensityVector_enc*/ - IF( GT_16( Foa_ImagBuffer_e, Foa_RealBuffer_e ) ) - { - Scale_sig32( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX, sub( Foa_RealBuffer_e, Foa_ImagBuffer_e ) ); - Foa_RealBuffer_e = Foa_ImagBuffer_e; - move16(); - } - ELSE - { - Scale_sig32( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX, sub( Foa_ImagBuffer_e, Foa_RealBuffer_e ) ); - Foa_ImagBuffer_e = Foa_RealBuffer_e; - move16(); - } - Word16 band_grouping_diff[MASA_FREQUENCY_BANDS], guard_bits, max_band_grouping_diff; - FOR( i = 0; i < num_freq_bands; i++ ) - { - band_grouping_diff[i] = sub( hOMasa->band_grouping[i + 1], hOMasa->band_grouping[i] ); - move16(); - } - maximum_abs_16_fx( band_grouping_diff, num_freq_bands, &max_band_grouping_diff ); - guard_bits = add( find_guarded_bits_fx( max_band_grouping_diff ), 1 ); + norm_buff = L_norm_arr( &Foa_RealBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ); + norm_buff = s_min( norm_buff, L_norm_arr( &Foa_ImagBuffer_fx[0][0], FOA_CHANNELS * CLDFB_NO_CHANNELS_MAX ) ); + guard_bits = find_guarded_bits_fx( max_band_grouping_diff ); + guard_bits = add( guard_bits, sub( 1, norm_buff ) ); computeIntensityVector_enc_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, num_freq_bands, intensity_real_fx, guard_bits ); - intensity_real_e = add( add( Foa_RealBuffer_e, Foa_ImagBuffer_e ), guard_bits ); -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - me2f_buf( &intensity_real_fx[0][0], intensity_real_e, &intensity_real[0][0], DIRAC_NUM_DIMS * MASA_FREQUENCY_BANDS ); -#endif // IVAS_FLOAT_FIXED_TO_BE_REMOVED -#endif // IVAS_FLOAT_FIXED - computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] ); + intensity_real_e = sub( add( 62, guard_bits ), shl( q, 1 ) ); + + computeDirectionVectors_fixed( intensity_real_fx[0], intensity_real_fx[1], intensity_real_fx[2], 0, num_freq_bands, direction_vector_fx[0], direction_vector_fx[1], direction_vector_fx[2], intensity_real_e ); /* Power estimation for diffuseness */ -#ifndef IVAS_FLOAT_FIXED - computeReferencePower_omasa( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], 0, num_freq_bands ); -#else -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - // Q for Foa_RealBuffer_fx and Foa_ImagBuffer is assumed to be 6 - for ( int r = 0; r < FOA_CHANNELS; r++ ) - { - floatToFixed_arrL( Foa_RealBuffer[r], Foa_RealBuffer_fx[r], 6, CLDFB_NO_CHANNELS_MAX ); - floatToFixed_arrL( Foa_ImagBuffer[r], Foa_ImagBuffer_fx[r], 6, CLDFB_NO_CHANNELS_MAX ); - } -#endif - computeReferencePower_omasa_ivas_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], 0, num_freq_bands, &ref_exp ); -#ifdef IVAS_FLOAT_FIXED_CONVERSIONS - fixedToFloat_arrL( reference_power_fx[ts], reference_power[ts], 31 - ref_exp, num_freq_bands ); -#endif -#endif + + computeReferencePower_omasa_ivas_fx( hOMasa->band_grouping, Foa_RealBuffer_fx, Foa_ImagBuffer_fx, reference_power_fx[ts], 0, num_freq_bands, q, &ref_exp ); + /* Fill buffers of length "averaging_length" time slots for intensity and energy */ - hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */ + hOMasa->index_buffer_intensity = add( ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ), 1 ); /* averaging_length = 32 */ index = hOMasa->index_buffer_intensity; - for ( i = 0; i < DIRAC_NUM_DIMS; i++ ) + move16(); + move16(); + FOR( i = 0; i < DIRAC_NUM_DIMS; i++ ) { /* only real part needed */ - mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands ); + Copy32( intensity_real_fx[i], &( hOMasa->buffer_intensity_real_fx[i][index - 1][0] ), num_freq_bands ); } - mvr2r( reference_power[ts], &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands ); - - computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector ); + hOMasa->buffer_intensity_real_q[index - 1] = sub( 31, intensity_real_e ); + move16(); + Copy32( reference_power_fx[ts], &( hOMasa->buffer_energy_fx[( index - 1 ) * num_freq_bands] ), num_freq_bands ); + hOMasa->buffer_energy_q[( index - 1 )] = sub( 31, ref_exp ); + move16(); + computeDiffuseness_fixed( hOMasa->buffer_intensity_real_fx, hOMasa->buffer_energy_fx, num_freq_bands, diffuseness_vector_fx, hOMasa->buffer_intensity_real_q, hOMasa->buffer_energy_q, &q_diffuseness_vector ); - for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] ); - - hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx]; - hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx]; - hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx]; - - diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx]; - renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx]; + norm_tmp_fx = Mpy_32_32( reference_power_fx[ts][band_m_idx], L_sub( L_shl( 1, q_diffuseness_vector ), diffuseness_vector_fx[band_m_idx] ) ); /*30+(31-ref_exp)-31*/ + + hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[0][block_m_idx][band_m_idx], hOMasa->direction_vector_e[0][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[0][band_m_idx] ), ref_exp + 2, &hOMasa->direction_vector_e[0][block_m_idx][band_m_idx] ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[1][block_m_idx][band_m_idx], hOMasa->direction_vector_e[1][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[1][band_m_idx] ), ref_exp + 2, &hOMasa->direction_vector_e[1][block_m_idx][band_m_idx] ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx] = BASOP_Util_Add_Mant32Exp( hOMasa->direction_vector_m_fx[2][block_m_idx][band_m_idx], hOMasa->direction_vector_e[2][block_m_idx][band_m_idx], Mpy_32_32( norm_tmp_fx, direction_vector_fx[2][band_m_idx] ), ref_exp + 2, &hOMasa->direction_vector_e[2][block_m_idx][band_m_idx] ); /*q_diffuseness_vector+(31-ref_exp)-31-1*/ + move32(); + move32(); + move32(); + + diffuseness_m_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( diffuseness_m_fx[band_m_idx], diffuseness_e[band_m_idx], Mpy_32_32( reference_power_fx[ts][band_m_idx], diffuseness_vector_fx[band_m_idx] ), ref_exp + 1, &diffuseness_e[band_m_idx] ); /*(30-ref_exp)*/ + renormalization_factor_diff_fx[band_m_idx] = BASOP_Util_Add_Mant32Exp( renormalization_factor_diff_fx[band_m_idx], renormalization_factor_diff_e[band_m_idx], reference_power_fx[ts][band_m_idx], ref_exp, &renormalization_factor_diff_e[band_m_idx] ); + move32(); + move32(); } } - for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + dir_v_e = MIN_16; + move16(); + FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) { - dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx]; + dir_v_fx[d] = hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx]; + move32(); + dir_v_e = s_max( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) + 1; + } + FOR( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + dir_v_fx[d] = L_shr( hOMasa->direction_vector_m_fx[d][block_m_idx][band_m_idx], sub( dir_v_e, hOMasa->direction_vector_e[d][block_m_idx][band_m_idx] ) ); + move32(); } -#ifdef IVAS_FLOAT_FIXED_ - /*==========================================flt-2-fix======================================================*/ - Word16 q_dir_e = 0; - f2me_buf( dir_v, dir_v_fx, &q_dir_e, 3 ); - Scale_sig32( dir_v_fx, 3, -1 ); - /*==========================================flt-2-fix======================================================*/ - - ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, Q30, &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] ); - - /*==========================================fix-2-flt======================================================*/ - azimuth_m_values[block_m_idx][band_m_idx] = fixedToFloat( azimuth_m_values_fx[block_m_idx][band_m_idx], Q22 ); - elevation_m_values[block_m_idx][band_m_idx] = fixedToFloat( elevation_m_values_fx[block_m_idx][band_m_idx], Q22 ); - /*==========================================fix-2-flt======================================================*/ -#else - ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] ); -#endif + ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( dir_v_fx, sub( 31, dir_v_e ), &azimuth_m_values_fx[block_m_idx][band_m_idx], &elevation_m_values_fx[block_m_idx][band_m_idx] ); } /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */ - for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - spreadCoherence[block_m_idx][band_m_idx] = 0.0f; - surroundingCoherence[band_m_idx] = 0.0f; + spreadCoherence_fx[block_m_idx][band_m_idx] = 0; + surroundingCoherence_fx[band_m_idx] = 0; + move16(); + move16(); } } /* Determine energy ratios */ - for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) + FOR( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ ) { - if ( renormalization_factor_diff[band_m_idx] > EPSILON ) + Word16 temp_e; + IF( GT_32( BASOP_Util_Log10( renormalization_factor_diff_fx[band_m_idx], ref_exp ), -( 15 << 25 ) ) ) { - diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx]; + diffuseness_m_fx[band_m_idx] = BASOP_Util_Divide3232_Scale( diffuseness_m_fx[band_m_idx], renormalization_factor_diff_fx[band_m_idx], &temp_e ); + temp_e = add( temp_e, sub( diffuseness_e[band_m_idx], renormalization_factor_diff_e[band_m_idx] ) ); } - else + ELSE { - diffuseness_m[band_m_idx] = 0.0f; + diffuseness_m_fx[band_m_idx] = 0; + temp_e = 0; + move16(); } - - energyRatio[band_m_idx] = 1.0f - diffuseness_m[band_m_idx]; + move32(); + diffuseness_m_fx[band_m_idx] = L_shl( diffuseness_m_fx[band_m_idx], 15 + temp_e ); + energyRatio_fx[band_m_idx] = L_sub( ONE_IN_Q30, diffuseness_m_fx[band_m_idx] ); + move32(); + move32(); } - return; } #else @@ -2108,6 +2273,7 @@ static void computeReferencePower_omasa_ivas_fx( Word32 *reference_power, /* o : Estimated power Q(31-ref_exp)*/ const Word16 enc_param_start_band, /* i : first band to process */ const Word16 num_freq_bands, /* i : Number of frequency bands */ + Word16 q_Cldfb, Word16 *ref_exp ) { Word16 brange[2]; @@ -2156,7 +2322,7 @@ static void computeReferencePower_omasa_ivas_fx( } // ref_exp = 31- ((13+ref_Q) -32) - *ref_exp = sub( 31, ( sub( add( ref_Q, 13 ), 32 ) ) ); + *ref_exp = sub( 31, ( sub( add( ref_Q, 2 * q_Cldfb + 1 ), 32 ) ) ); move16(); return; } diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 4d246daa0f7f682d29e77941604fdf971091770d..5421f1809935496849f6517ac2ccae44927a7308 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -116,15 +116,67 @@ static ivas_error write_ec_direction( int16_t *num_bits_written, BSTR_ENC_HANDLE static int16_t write_fixed_rate_direction( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t j_idx, const int16_t len ); +#ifdef IVAS_FLOAT_FIXED +static Word16 ivas_qmetadata_quantize_coherence_fx( + IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */ + const Word16 idx_d, /* i : current direction index */ + const Word16 all_coherence_zero, /* i : all coherence is zero - flag */ + BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */ + const Word16 write_flag, /* i : flag to actually write the data or not */ + Word16 *indice_coherence, + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +); +#else static int16_t ivas_qmetadata_quantize_coherence( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t write_flag, int16_t *indice_coherence, const int16_t hrmasa_flag ); +#endif +#ifdef IVAS_FLOAT_FIXED +static void dct4_transform_fx( + uint8_t *v, /* i : input 4D vector */ + Word32 *dct_v /* o : output transformed vector Q31 */ +); +#else static void dct4_transform( uint8_t *v, float *dct_v ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word32 quantize_DCT_0_coh_fx( // o:Q21 + const Word16 x, /* i : input value Q14 */ + const int16_t j, /* i : subband index */ + const Word16 *coherence_cb, /* i : coherence codebook Q14 */ + const Word16 delta_var, /* i : azimuth variance threshold Q6 */ + const int16_t no_cb, /* i : maximum number of codewords */ + IVAS_QDIRECTION *q_direction, /* i : quantized metadata */ + UWord16 *idx_x, /* o : codewords index */ + Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +); +#else static float quantize_DCT_0_coh( const float x, const int16_t j, const float *coherence_cb, const float delta_var, const int16_t no_cb, IVAS_QDIRECTION *q_direction, uint16_t *idx_x, int16_t *p_no_cb, const int16_t hrmasa_flag ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word16 encode_coherence_indexesDCT0_fx( + UWord16 *idx_dct, /* i : indexes to be encoded */ + const Word16 len, /* i : number of indexes */ + Word16 *no_cb_vec, /* i : number of codewords for each position */ + BSTR_ENC_HANDLE hMetaData, + const Word16 indice_coherence, + const Word16 nbits, + const Word16 nbits1 ); +#else static int16_t encode_coherence_indexesDCT0( uint16_t *idx_dct, const int16_t len, int16_t *no_cb_vec, BSTR_ENC_HANDLE hMetaData, const int16_t indice_coherence, const int16_t nbits, const int16_t nbits1 ); +#endif +#ifdef IVAS_FLOAT_FIXED +static Word16 encode_coherence_indexesDCT1_fx( + UWord16 *idx_dct, /* i : data to be encoded */ + const Word16 len, /* i : number of data */ + BSTR_ENC_HANDLE hMetaData /* i : metadata handle */ +); +#else static int16_t encode_coherence_indexesDCT1( uint16_t *idx_dct, const int16_t len, BSTR_ENC_HANDLE hMetaData ); +#endif #ifdef IVAS_FLOAT_FIXED static UWord64 create_combined_index( uint16_t *idx_dct, const int16_t len, const int16_t *no_cb_vec ); @@ -175,8 +227,10 @@ static void transform_azimuth_dir2_fx( static void transform_azimuth_dir2( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *dir2_bands ); #endif -static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t diffuseness_index_max_ec_frame, const float avg_azimuth, float *avg_azimuth_out ); #ifndef IVAS_FLOAT_FIXED + +static int16_t calc_var_azi( const IVAS_QDIRECTION *q_direction, const int16_t diffuseness_index_max_ec_frame, const float avg_azimuth, float *avg_azimuth_out ); + static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, const int16_t bits_dir_hr, BSTR_ENC_HANDLE hMetaData ); static int16_t ivas_qmetadata_quantize_coherence_hr_512( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t bits_coh ); @@ -184,6 +238,8 @@ static int16_t ivas_qmetadata_quantize_coherence_hr_512( IVAS_QMETADATA *hQMetaD static Word16 ivas_qmetadata_quantize_coherence_hr_512_fx( IVAS_QMETADATA *hQMetaData, const Word16 idx_d, const Word16 all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const Word16 bits_coh ); static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512_fx( IVAS_QMETADATA_HANDLE hQMetaData, Word16 *needed_bits, const Word16 bits_dir_hr, BSTR_ENC_HANDLE hMetaData ); + +static Word16 calc_var_azi_fx( const IVAS_QDIRECTION *q_direction, const Word16 diffuseness_index_max_ec_frame, const Word32 avg_azimuth, Word32 *avg_azimuth_out ); #endif static int16_t encode_surround_coherence_hr( IVAS_QMETADATA *hQMetaData, BSTR_ENC_HANDLE hMetaData ); @@ -431,8 +487,17 @@ ivas_error ivas_qmetadata_enc_encode( IF( EQ_16( all_coherence_zero, 0 ) ) { - bits_coherence[d] = ivas_qmetadata_quantize_coherence( hQMetaData, d, all_coherence_zero, hMetaData, 0, &indice_coherence, 0 ); + bits_coherence[d] = ivas_qmetadata_quantize_coherence_fx( hQMetaData, d, all_coherence_zero, hMetaData, 0, &indice_coherence, 0 ); + move16(); + } + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + for ( int j = hQMetaData->q_direction[0].cfg.start_band; j < hQMetaData->q_direction[0].cfg.nbands; ++j ) + { + fixedToFloat_arrL( hQMetaData->q_direction[d].band_data[j].azimuth_fx, hQMetaData->q_direction[d].band_data[j].azimuth, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); + fixedToFloat_arrL( hQMetaData->q_direction[d].band_data[j].elevation_fx, hQMetaData->q_direction[d].band_data[j].elevation, Q22, MAX_PARAM_SPATIAL_SUBFRAMES ); } +#endif IF( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_5_1 || q_direction->cfg.mc_ls_setup == MC_LS_SETUP_7_1 ) { @@ -581,7 +646,7 @@ ivas_error ivas_qmetadata_enc_encode( { bit_pos_start = hMetaData->nb_bits_tot; hMetaData->nb_bits_tot = bit_pos_start_coh; - ivas_qmetadata_quantize_coherence( hQMetaData, d, all_coherence_zero, hMetaData, 1, &indice_coherence, 0 ); + ivas_qmetadata_quantize_coherence_fx( hQMetaData, d, all_coherence_zero, hMetaData, 1, &indice_coherence, 0 ); hMetaData->nb_bits_tot = bit_pos_start; } @@ -3830,7 +3895,42 @@ static int16_t ivas_qmetadata_entropy_encode_dir( use_adapt_avg = 0; if ( ( nbands - start_band >= 5 ) && ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) && ( nblocks > 1 ) ) { +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word32 avg_azimuth_fx; // Q22 + avg_azimuth_fx = float_to_fix( avg_azimuth, Q22 ); + for ( i = 0; i < q_direction->cfg.nbands; i++ ) + { + if ( q_direction->band_data[i].energy_ratio_index_mod[0] < diffuseness_index_max_ec_frame ) + { + for ( j = 0; j < q_direction->cfg.nblocks; j++ ) + { + q_direction->band_data[i].azimuth_fx[j] = floatToFixed( q_direction->band_data[i].azimuth[j], Q22 ); + q_direction->band_data[i].elevation_fx[j] = floatToFixed( q_direction->band_data[i].elevation[j], Q22 ); + } + } + } + +#endif + use_adapt_avg = calc_var_azi_fx( q_direction, diffuseness_index_max_ec_frame, L_sub( avg_azimuth_fx, 754974720 ), &avg_azimuth_fx ); // 180.Q22 + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + avg_azimuth = fix_to_float( avg_azimuth_fx, Q22 ); + for ( i = 0; i < q_direction->cfg.nbands; i++ ) + { + if ( q_direction->band_data[i].energy_ratio_index_mod[0] < diffuseness_index_max_ec_frame ) + { + for ( j = 0; j < q_direction->cfg.nblocks; j++ ) + { + q_direction->band_data[i].azimuth[j] = fixedToFloat( q_direction->band_data[i].azimuth_fx[j], Q22 ); + q_direction->band_data[i].elevation[j] = fixedToFloat( q_direction->band_data[i].elevation_fx[j], Q22 ); + } + } + } +#endif +#else use_adapt_avg = calc_var_azi( q_direction, diffuseness_index_max_ec_frame, avg_azimuth - 180, &avg_azimuth ); +#endif avg_azimuth_index = (uint16_t) ( quantize_phi( avg_azimuth + 180, 0, &avg_azimuth, avg_azimuth_alphabet ) ); } avg_azimuth_index_initial = avg_azimuth_index; /* avg_azimuth_index;*/ @@ -5587,98 +5687,74 @@ static int16_t encode_directions_subband( *-------------------------------------------------------------------*/ #ifdef IVAS_FLOAT_FIXED -static int16_t calc_var_azi( +static Word16 calc_var_azi_fx( const IVAS_QDIRECTION *q_direction, - const int16_t diffuseness_index_max_ec_frame, - const float avg_azimuth, - float *avg_azimuth_out ) + const Word16 diffuseness_index_max_ec_frame, + const Word32 avg_azimuth, /* Q22 */ + Word32 *avg_azimuth_out /* Q22 */ ) { - float var_band, dif; - float avg_direction_vector_band[3], avg_azimuth_band[24], direction_vector[3]; - float avg_elevation; -#ifdef IVAS_FLOAT_FIXED - Word32 /* avg_direction_vector_band_fx[3], avg_azimuth_band_fx[24],*/ direction_vector_fx[3]; - // Word32 avg_elevation_fx; -#endif - int16_t i, j, idx; + Word32 var_band, dif; /* Q22 */ + Word32 avg_direction_vector_band[3], direction_vector[3]; /* Q25 */ + Word32 avg_azimuth_band[24]; /* Q22 */ + Word32 avg_elevation; /* Q22 */ + Word16 i, j, idx; idx = 0; - set_zero( avg_azimuth_band, 24 ); + move16(); + set32_fx( avg_azimuth_band, 0, 24 ); - for ( i = 0; i < q_direction->cfg.nbands; i++ ) + FOR( i = 0; i < q_direction->cfg.nbands; i++ ) { - set_zero( avg_direction_vector_band, 3 ); - if ( q_direction->band_data[i].energy_ratio_index_mod[0] <= diffuseness_index_max_ec_frame ) + set32_fx( avg_direction_vector_band, 0, 3 ); + IF( LE_16( q_direction->band_data[i].energy_ratio_index_mod[0], diffuseness_index_max_ec_frame ) ) { - for ( j = 0; j < q_direction->cfg.nblocks; j++ ) + FOR( j = 0; j < q_direction->cfg.nblocks; j++ ) { /*compute the average direction */ -#ifdef IVAS_FLOAT_FIXED - /*==========================================flt-2-fix======================================================*/ - q_direction->band_data[i].azimuth_fx[j] = floatToFixed( q_direction->band_data[i].azimuth[j], Q22 ); - q_direction->band_data[i].elevation_fx[j] = floatToFixed( q_direction->band_data[i].elevation[j], Q22 ); - /*==========================================flt-2-fix======================================================*/ - - ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector_fx ); - - /*==========================================fix-2-flt======================================================*/ - fixedToFloat_arrL( direction_vector_fx, direction_vector, Q30, 3 ); - /*==========================================fix-2-flt======================================================*/ -#else - ivas_qmetadata_azimuth_elevation_to_direction_vector( q_direction->band_data[i].azimuth[j], q_direction->band_data[i].elevation[j], direction_vector ); -#endif - v_add( avg_direction_vector_band, direction_vector, avg_direction_vector_band, 3 ); + ivas_qmetadata_azimuth_elevation_to_direction_vector_fx( q_direction->band_data[i].azimuth_fx[j], q_direction->band_data[i].elevation_fx[j], direction_vector ); + v_shr_32( direction_vector, direction_vector, 3, 5 ); // Q30 -> Q25 + v_add_32( avg_direction_vector_band, direction_vector, avg_direction_vector_band, 3 ); } -#ifdef IVAS_FLOAT_FIXED_ - /*==========================================flt-2-fix======================================================*/ - Word16 q_dir_e = 0; - f2me_buf( avg_direction_vector_band, avg_direction_vector_band_fx, &q_dir_e, 3 ); - Scale_sig32( avg_direction_vector_band_fx, 3, -1 ); - /*==========================================flt-2-fix======================================================*/ - - ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_band_fx, Q30, &avg_azimuth_band_fx[idx], &avg_elevation_fx ); - - /*==========================================fix-2-flt======================================================*/ - avg_azimuth_band[idx] = fixedToFloat( avg_azimuth_band_fx[idx], Q22 ); - // avg_elevation = fixedToFloat( avg_elevation_fx, Q22 ); - /*==========================================fix-2-flt======================================================*/ -#else - ivas_qmetadata_direction_vector_to_azimuth_elevation( avg_direction_vector_band, &avg_azimuth_band[idx], &avg_elevation ); -#endif - idx++; + ivas_qmetadata_direction_vector_to_azimuth_elevation_fx( avg_direction_vector_band, 30 - 5, &avg_azimuth_band[idx], &avg_elevation ); + idx += 1; } } - var_band = 0.0f; + var_band = 0; /* Q11 */ + move32(); - for ( i = 0; i < idx; i++ ) + FOR( i = 0; i < idx; i++ ) { - dif = ( avg_azimuth_band[idx] - avg_azimuth ); + dif = L_sub( avg_azimuth_band[idx], avg_azimuth ); if ( dif < 0 ) { - dif = -dif; + dif = L_negate( dif ); } - if ( dif > 180 ) + if ( GT_32( dif, DEGREE_180_Q_22 ) ) { - dif = 360 - dif; + dif = L_sub( DEGREE_360_Q_22, dif ); } - var_band += dif * dif; + var_band = Madd_32_32( var_band, dif, dif ); /* Q11 */ } - if ( idx > 0 ) + IF( idx > 0 ) { - var_band = var_band / idx; + Word16 mul = div_s( 1, idx ); + var_band = Mpy_32_16_1( var_band, mul ); /* Q11 */ + var_band = L_shr_r( var_band, 11 ); /* Q0 */ } - if ( var_band <= VAR_AZI_THRESH ) + IF( LE_32( var_band, VAR_AZI_THRESH ) ) { *avg_azimuth_out = avg_azimuth; + move32(); return 0; } - else + ELSE { *avg_azimuth_out = avg_azimuth_band[0]; + move32(); return 1; } } @@ -6343,6 +6419,91 @@ static uint64_t create_combined_index( /*-----------------------------------------------------------------------* * encoding DCT0 coeffs with joint index *-----------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: number of bits written */ +static Word16 encode_coherence_indexesDCT0_fx( + UWord16 *idx_dct, /* i : indexes to be encoded */ + const Word16 len, /* i : number of indexes */ + Word16 *no_cb_vec, /* i : number of codewords for each position */ + BSTR_ENC_HANDLE hMetaData, + const Word16 indice_coherence, + const Word16 nbits, + const Word16 nbits1 ) +{ + Word16 i; + UWord64 idx; + Word16 no_idx16; + Word16 k; + Word16 half_len, j; + UWord64 idx1; + + /* calculate bits for dct0 components with joint encoding */ + IF( nbits1 > 0 ) + { + half_len = shr( len, 1 ); + idx = create_combined_index( idx_dct, half_len, no_cb_vec ); + idx1 = create_combined_index( &idx_dct[half_len], half_len, &no_cb_vec[half_len] ); + } + ELSE + { + idx = create_combined_index( idx_dct, len, no_cb_vec ); + idx1 = 0; + move16(); + } + + // if ( nbits % 16 == 0 ) + IF( s_and( nbits, 15 ) == 0 ) + { + no_idx16 = shr( nbits, 4 ); + } + ELSE + { + // no_idx16 = (int16_t) round_f( ( nbits / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits, ONE_IN_Q3 ), 4 ); + } + + k = nbits; + move16(); + i = 0; + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) + { + k = sub( k, 16 ); + hMetaData->ind_list[indice_coherence + i].value = ( ( idx >> k ) & 65535 ); /* 16 bits */ + move16(); + } + hMetaData->ind_list[indice_coherence + i].value = ( idx & ( ( 1 << k ) - 1 ) ); + move16(); + + IF( nbits1 > 0 ) + { + // if ( nbits1 % 16 == 0 ) + IF( s_and( nbits1, 15 ) == 0 ) + { + no_idx16 = shr( nbits1, 4 ); + } + ELSE + { + // no_idx16 = (int16_t) round_f( ( nbits1 / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits1, ONE_IN_Q3 ), 4 ); + } + + k = nbits1; + move16(); + + FOR( j = i + 1; j < no_idx16 + i; j++ ) + { + k = sub( k, 16 ); + hMetaData->ind_list[indice_coherence + j].value = ( ( idx1 >> k ) & 65535 ); /* 16 bits */ + move16(); + } + hMetaData->ind_list[indice_coherence + j].value = ( idx1 & ( ( 1 << k ) - 1 ) ); + move16(); + } + + return add( nbits, nbits1 ); +} +#else /*! r: number of bits written */ static int16_t encode_coherence_indexesDCT0( @@ -6415,7 +6576,7 @@ static int16_t encode_coherence_indexesDCT0( return nbits + nbits1; } - +#endif /*-------------------------------------------------------------------* * coherence_coding_length() @@ -6586,114 +6747,340 @@ static int16_t coherence_coding_length( * * Encoding spread coherence for 1 subframe bands *-------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED /*! r: number of bits written */ -static int16_t encode_spread_coherence_1sf( +static Word16 encode_spread_coherence_1sf_fx( IVAS_QMETADATA *q_metadata, /* i : quantized metadata */ - const int16_t idx_d, /* i : current direction index */ + const Word16 idx_d, /* i : current direction index */ BSTR_ENC_HANDLE hMasaMetaData, /* i/o: metadata bitstream handle */ - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ ) { - int16_t i, j, k; - int16_t idx_ER; - int16_t nbits, nbits_fr; - uint16_t idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; - uint16_t mr_idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t GR_ord, bits_GR; - uint64_t idx, idx1; - int16_t no_idx16; - int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 i, j, k; + Word16 idx_ER; + Word16 nbits, nbits_fr; + UWord16 idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; // Q15 + UWord16 mr_idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 GR_ord, bits_GR; + UWord64 idx, idx1; + Word16 no_idx16; + Word16 no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; IVAS_QDIRECTION *q_direction; - int16_t half_coding_subbands, nbits_fr1, coding_subbands; - uint16_t idx_sp_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; - uint8_t idx_shift; - int16_t max_val = 0, nbits_max; - int16_t extra_cv; - int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; + Word16 half_coding_subbands, nbits_fr1, coding_subbands; + UWord16 idx_sp_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; + UWord8 idx_shift; + Word16 max_val = 0, nbits_max; + move16(); + Word16 extra_cv; + Word16 no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; coding_subbands = q_metadata->q_direction[idx_d].cfg.nbands; + move16(); q_direction = &( q_metadata->q_direction[idx_d] ); nbits = 0; + move16(); GR_ord = 1; + move16(); idx_shift = 0; + move16(); /* number of codevectors added dependent on number of subbands */ - extra_cv = coding_subbands / MASA_FACTOR_CV_COH; - for ( j = 0; j < coding_subbands; j++ ) + // extra_cv = coding_subbands / MASA_FACTOR_CV_COH; + Word16 tmp = 0; + move16(); + extra_cv = -1; + move16(); + WHILE( LE_16( tmp, coding_subbands ) ) { - if ( hrmasa_flag ) + tmp = add( tmp, 6 ); + extra_cv = add( extra_cv, 1 ); + } + FOR( j = 0; j < coding_subbands; j++ ) + { + IF( hrmasa_flag ) { - idx_ER = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> 1 ) + extra_cv; + idx_ER = add( sub( 7, shr( q_direction->band_data[j].energy_ratio_index_mod[0], 1 ) ), extra_cv ); } - else + ELSE { - idx_ER = 7 - q_direction->band_data[j].energy_ratio_index_mod[0] + extra_cv; + idx_ER = add( sub( 7, q_direction->band_data[j].energy_ratio_index_mod[0] ), extra_cv ); } - if ( idx_ER > 0 ) + IF( idx_ER > 0 ) { - idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) ); - q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) ); + // idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) ); + idx_sp_coh[j] = extract_l( Mpy_32_32_r( imult1616( q_direction->coherence_band_data[j].spread_coherence[0], idx_ER ), 8421505 ) ); + move16(); + // q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) ); + IF( idx_sp_coh[j] ) + { + q_direction->coherence_band_data[j].spread_coherence[0] = (UWord8) idiv1616( imult1616( idx_sp_coh[j], 255 ), idx_ER ); + move16(); + } + ELSE + { + q_direction->coherence_band_data[j].spread_coherence[0] = 0; + move16(); + } } - else + ELSE { idx_sp_coh[j] = 0; + move16(); q_direction->coherence_band_data[j].spread_coherence[0] = 0; + move16(); } - no_cv[j] = idx_ER + 1; + no_cv[j] = add( idx_ER, 1 ); + move16(); no_cv_shift[idx_shift] = no_cv[j]; + move16(); idx_sp_coh_shift[idx_shift++] = idx_sp_coh[j]; + move16(); } - if ( sum_s( no_cv, coding_subbands ) == coding_subbands ) + IF( EQ_16( sum16_fx( no_cv, coding_subbands ), coding_subbands ) ) { return 0; } nbits_max = 0; - if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + move16(); + if ( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) { - j = maximum_s( (int16_t *) idx_sp_coh, coding_subbands, &max_val ); - for ( j = 0; j < coding_subbands; j++ ) + j = maximum_s( (Word16 *) idx_sp_coh, coding_subbands, &max_val ); + FOR( j = 0; j < coding_subbands; j++ ) { - if ( no_cv[j] > max_val + 1 ) + if ( GT_16( no_cv[j], add( max_val, 1 ) ) ) { - no_cv[j] = max_val + 1; + no_cv[j] = add( max_val, 1 ); + move16(); } } - nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val + extra_cv; + nbits_max = add( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), extra_cv ); } nbits = coherence_coding_length( idx_sp_coh_shift, idx_shift, coding_subbands, no_cv, mr_idx_sp_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 ); half_coding_subbands = 0; + move16(); idx1 = 0; + move16(); - if ( nbits_fr + nbits_fr1 + nbits_max < nbits ) + IF( LT_16( add( add( nbits_fr, nbits_fr1 ), nbits_max ), nbits ) ) { /* write flag*/ push_next_indice( hMasaMetaData, 0, 1 ); /* create combined index */ - nbits = nbits_fr + nbits_fr1 + 1; + nbits = add( add( nbits_fr, nbits_fr1 ), 1 ); - if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + IF( GT_16( coding_subbands, MASA_LIMIT_NO_BANDS_SUR_COH ) ) { /* write max value*/ bits_GR = hMasaMetaData->nb_bits_tot; - ivas_qmetadata_encode_extended_gr( hMasaMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1 + extra_cv, MASA_MAX_NO_CV_SUR_COH + extra_cv, 0 ); - nbits += hMasaMetaData->nb_bits_tot - bits_GR; + move16(); + ivas_qmetadata_encode_extended_gr( hMasaMetaData, add( sub( sub( MASA_MAX_NO_CV_SUR_COH, max_val ), 1 ), extra_cv ), add( MASA_MAX_NO_CV_SUR_COH, extra_cv ), 0 ); + nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); } - if ( nbits_fr1 > 0 ) + IF( nbits_fr1 > 0 ) { - half_coding_subbands = coding_subbands / 2; + half_coding_subbands = shr( coding_subbands, 1 ); idx = create_combined_index( idx_sp_coh, half_coding_subbands, no_cv ); idx1 = create_combined_index( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); } - else + ELSE + { + idx = create_combined_index( idx_sp_coh, coding_subbands, no_cv ); + } + + // if ( nbits_fr % 16 == 0 ) + IF( s_and( nbits_fr, 15 ) == 0 ) + { + no_idx16 = shr( nbits_fr, 4 ); + } + ELSE + { + // no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 ); + } + + /* write combined index */ + k = nbits_fr; + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) + { + k = sub( k, 16 ); + push_next_indice( hMasaMetaData, ( ( idx >> k ) & 65535 ), 16 ); /* 16 bits */ + } + + push_next_indice( hMasaMetaData, ( idx & ( ( 1 << k ) - 1 ) ), k ); + + IF( nbits_fr1 > 0 ) + { + // if ( nbits_fr1 % 16 == 0 ) + IF( s_and( nbits_fr1, 15 ) == 0 ) + { + no_idx16 = shr( nbits_fr1, 4 ); + } + ELSE + { + // no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 ); + } + + assert( no_idx16 <= 4 ); + + k = nbits_fr1; + move16(); + FOR( i = 0; i < no_idx16 - 1; i++ ) + { + k = sub( k, 16 ); + push_next_indice( hMasaMetaData, ( ( idx1 >> k ) & 65535 ), 16 ); /* 16 bits */ + } + push_next_indice( hMasaMetaData, ( idx1 & ( ( 1 << k ) - 1 ) ), k ); + } + } + ELSE + { + /* write flag */ + nbits = 1; + move16(); + + /* write flag*/ + push_next_indice( hMasaMetaData, 1, 1 ); + + /* write GR_ord */ + push_next_indice( hMasaMetaData, GR_ord, 1 ); + nbits = add( nbits, 1 ); + + /* write the min */ + bits_GR = hMasaMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMasaMetaData, min_idx, MASA_MAX_NO_CV_SUR_COH + extra_cv, 0 ); + nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); + + /* write GR data */ + FOR( j = 0; j < idx_shift; j++ ) + { + bits_GR = hMasaMetaData->nb_bits_tot; + move16(); + ivas_qmetadata_encode_extended_gr( hMasaMetaData, mr_idx_sp_coh[j], no_cv_shift[j], GR_ord ); + nbits = add( nbits, sub( hMasaMetaData->nb_bits_tot, bits_GR ) ); + } + } + + return nbits; +} +#else +/*! r: number of bits written */ +static int16_t encode_spread_coherence_1sf( + IVAS_QMETADATA *q_metadata, /* i : quantized metadata */ + const int16_t idx_d, /* i : current direction index */ + BSTR_ENC_HANDLE hMasaMetaData, /* i/o: metadata bitstream handle */ + const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +) +{ + int16_t i, j, k; + int16_t idx_ER; + int16_t nbits, nbits_fr; + uint16_t idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + uint16_t mr_idx_sp_coh[MASA_MAXIMUM_CODING_SUBBANDS]; + int16_t GR_ord, bits_GR; + uint64_t idx, idx1; + int16_t no_idx16; + int16_t no_cv[MASA_MAXIMUM_CODING_SUBBANDS]; + IVAS_QDIRECTION *q_direction; + int16_t half_coding_subbands, nbits_fr1, coding_subbands; + uint16_t idx_sp_coh_shift[MASA_MAXIMUM_CODING_SUBBANDS]; + uint8_t idx_shift; + int16_t max_val = 0, nbits_max; + int16_t extra_cv; + int16_t no_cv_shift[MASA_MAXIMUM_CODING_SUBBANDS], min_idx; + + coding_subbands = q_metadata->q_direction[idx_d].cfg.nbands; + q_direction = &( q_metadata->q_direction[idx_d] ); + nbits = 0; + GR_ord = 1; + idx_shift = 0; + + /* number of codevectors added dependent on number of subbands */ + extra_cv = coding_subbands / MASA_FACTOR_CV_COH; + for ( j = 0; j < coding_subbands; j++ ) + { + if ( hrmasa_flag ) + { + idx_ER = 7 - ( q_direction->band_data[j].energy_ratio_index_mod[0] >> 1 ) + extra_cv; + } + else + { + idx_ER = 7 - q_direction->band_data[j].energy_ratio_index_mod[0] + extra_cv; + } + + if ( idx_ER > 0 ) + { + idx_sp_coh[j] = (uint16_t) roundf( q_direction->coherence_band_data[j].spread_coherence[0] / ( 255.0f / (float) idx_ER ) ); + q_direction->coherence_band_data[j].spread_coherence[0] = (uint8_t) roundf( idx_sp_coh[j] * ( 255.0f / (float) idx_ER ) ); + } + else + { + idx_sp_coh[j] = 0; + q_direction->coherence_band_data[j].spread_coherence[0] = 0; + } + no_cv[j] = idx_ER + 1; + + no_cv_shift[idx_shift] = no_cv[j]; + idx_sp_coh_shift[idx_shift++] = idx_sp_coh[j]; + } + + if ( sum_s( no_cv, coding_subbands ) == coding_subbands ) + { + return 0; + } + + nbits_max = 0; + if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + { + j = maximum_s( (int16_t *) idx_sp_coh, coding_subbands, &max_val ); + for ( j = 0; j < coding_subbands; j++ ) + { + if ( no_cv[j] > max_val + 1 ) + { + no_cv[j] = max_val + 1; + } + } + nbits_max = MASA_MAX_NO_CV_SUR_COH - max_val + extra_cv; + } + + nbits = coherence_coding_length( idx_sp_coh_shift, idx_shift, coding_subbands, no_cv, + mr_idx_sp_coh, no_cv_shift, &min_idx, &GR_ord, &nbits_fr, &nbits_fr1 ); + half_coding_subbands = 0; + idx1 = 0; + + if ( nbits_fr + nbits_fr1 + nbits_max < nbits ) + { + /* write flag*/ + push_next_indice( hMasaMetaData, 0, 1 ); + + /* create combined index */ + nbits = nbits_fr + nbits_fr1 + 1; + + if ( coding_subbands > MASA_LIMIT_NO_BANDS_SUR_COH ) + { + /* write max value*/ + bits_GR = hMasaMetaData->nb_bits_tot; + ivas_qmetadata_encode_extended_gr( hMasaMetaData, MASA_MAX_NO_CV_SUR_COH - max_val - 1 + extra_cv, MASA_MAX_NO_CV_SUR_COH + extra_cv, 0 ); + nbits += hMasaMetaData->nb_bits_tot - bits_GR; + } + + if ( nbits_fr1 > 0 ) + { + half_coding_subbands = coding_subbands / 2; + idx = create_combined_index( idx_sp_coh, half_coding_subbands, no_cv ); + idx1 = create_combined_index( &idx_sp_coh[half_coding_subbands], half_coding_subbands, &no_cv[half_coding_subbands] ); + } + else { idx = create_combined_index( idx_sp_coh, coding_subbands, no_cv ); } @@ -6767,7 +7154,7 @@ static int16_t encode_spread_coherence_1sf( return nbits; } - +#endif /*-------------------------------------------------------------------* * encode_surround_coherence() @@ -6917,15 +7304,16 @@ static Word16 encode_surround_coherence_fx( idx = create_combined_index( idx_sur_coh, coding_subbands, no_cv ); } - /*if ( nbits_fr % 16 == 0 ) + // if ( nbits_fr % 16 == 0 ) + IF( s_and( nbits_fr, 15 ) == 0 ) { - no_idx16 = nbits_fr / 16; + no_idx16 = shr( nbits_fr, 4 ); } - else + ELSE { - no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); - }*/ - no_idx16 = shr_r( nbits_fr, 4 ); + // no_idx16 = (int16_t) round_f( ( nbits_fr / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits_fr, ONE_IN_Q3 ), 4 ); + } /* write combined index */ k = nbits_fr; @@ -6940,15 +7328,16 @@ static Word16 encode_surround_coherence_fx( IF( nbits_fr1 > 0 ) { - /*if ( nbits_fr1 % 16 == 0 ) + // if ( nbits_fr1 % 16 == 0 ) + IF( s_and( nbits_fr1, 15 ) == 0 ) { - no_idx16 = nbits_fr1 / 16; + no_idx16 = shr( nbits_fr1, 4 ); } - else + ELSE { - no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); - }*/ - no_idx16 = shr_r( nbits_fr1, 4 ); + // no_idx16 = (int16_t) round_f( ( nbits_fr1 / 16.0f + 0.5f ) ); + no_idx16 = shr_r( add( nbits_fr1, ONE_IN_Q3 ), 4 ); + } assert( no_idx16 <= 4 ); @@ -7405,7 +7794,58 @@ static int16_t encode_surround_coherence_hr( * * quanization of DCT component of order zero for transformed coherence vector *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: quantized value */ +static Word32 quantize_DCT_0_coh_fx( // o:Q21 + const Word16 x, /* i : input value Q14 */ + const int16_t j, /* i : subband index */ + const Word16 *coherence_cb, /* i : coherence codebook Q14 */ + const Word16 delta_var, /* i : azimuth variance threshold Q6 */ + const int16_t no_cb, /* i : maximum number of codewords */ + IVAS_QDIRECTION *q_direction, /* i : quantized metadata */ + UWord16 *idx_x, /* o : codewords index */ + Word16 *p_no_cb, /* o : actual number of codewords dependent on energy ratio value */ + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +) +{ + Word16 var_azi /*Q6*/, xhat; + Word16 idx_sub_cb, idx; + Word16 min_index; + Word16 azimuth_16[MAX_PARAM_SPATIAL_SUBFRAMES]; // Q6 + Copy_Scale_sig_32_16( q_direction->band_data[j].azimuth_fx, azimuth_16, MAX_PARAM_SPATIAL_SUBFRAMES, -16 ); // Q22->Q6 + /* quantize first DCT component */ + var_azi = var_fx( azimuth_16, Q6, q_direction->cfg.nblocks ); + IF( hrmasa_flag ) + { + minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); + min_index = shr( min_index, 1 ); + } + ELSE + { + min_index = q_direction->band_data[j].energy_ratio_index[0]; + move16(); + } + + IF( LT_16( var_azi, delta_var ) ) + { + idx_sub_cb = imult1616( no_cb, min_index ); + } + ELSE + { + idx_sub_cb = imult1616( no_cb, add( min_index, DIRAC_DIFFUSE_LEVELS ) ); + } + + idx = squant_fx( x, &xhat, &coherence_cb[idx_sub_cb], len_cb_dct0_masa[min_index] ); + + *p_no_cb = len_cb_dct0_masa[min_index]; + move16(); + *idx_x = idx; + move16(); + + return L_shl( xhat, 7 ); // Q21 +} +#else /*! r: quantized value */ static float quantize_DCT_0_coh( const float x, /* i : input value */ @@ -7451,14 +7891,44 @@ static float quantize_DCT_0_coh( return xhat; } - +#endif /*-------------------------------------------------------------------* * encode_coherence_indexesDCT1() * * Encoding DCT1 coeffs with joint index or EC *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +/*! r: number of bits written */ +static Word16 encode_coherence_indexesDCT1_fx( + UWord16 *idx_dct, /* i : data to be encoded */ + const Word16 len, /* i : number of data */ + BSTR_ENC_HANDLE hMetaData /* i : metadata handle */ +) +{ + Word16 i, nbits, GR_ord; + UWord16 av; + UWord16 mr_idx_dct[MASA_MAXIMUM_CODING_SUBBANDS]; + + GR_ord = 0; + move16(); + nbits = 0; + move16(); + + nbits = mean_removed_GR_new( idx_dct, MASA_NO_CV_COH1, len, 0, &GR_ord, &av, mr_idx_dct ); + + FOR( i = 0; i < len; i++ ) + { + ivas_qmetadata_encode_extended_gr( hMetaData, mr_idx_dct[i], 2 * MASA_NO_CV_COH1, GR_ord ); + } + + nbits = add( nbits, len_huf_masa[av] ); + + push_next_indice( hMetaData, huff_code_av_masa[av], len_huf_masa[av] ); + return nbits; +} +#else /*! r: number of bits written */ static int16_t encode_coherence_indexesDCT1( uint16_t *idx_dct, /* i : data to be encoded */ @@ -7486,14 +7956,38 @@ static int16_t encode_coherence_indexesDCT1( return nbits; } - +#endif /*-------------------------------------------------------------------* * dct4_transform() * * 4D implementation of DCT transform *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void dct4_transform_fx( + uint8_t *v, /* i : input 4D vector */ + Word32 *dct_v /* o : output transformed vector Q21 */ +) +{ + Word32 a, b, c, d; + + a = L_shl( L_add( v[0], v[3] ), Q12 ); //*0.5f / 256.0f; + b = L_shl( L_add( v[1], v[2] ), Q12 ); //*0.5f / 256.0f; + c = L_shl( L_sub( v[0], v[3] ), Q13 ); // / 256.0f; + d = L_shl( L_sub( v[1], v[2] ), Q13 ); // / 256.0f; + + dct_v[0] = L_add( a, b ); // 0.5f * (a + b); + move32(); + dct_v[1] = L_add( Mpy_32_32_r( 1402911301 /*0.653281482438188f*/, c ), Mpy_32_32_r( 581104888 /*0.270598050073099f*/, d ) ); + move32(); + dct_v[2] = L_sub( a, b ); // 0.5f * (a - b); + move32(); + dct_v[3] = L_sub( Mpy_32_32_r( 581104888 /*0.270598050073099f*/, c ), Mpy_32_32_r( 1402911301 /*0.653281482438188f*/, d ) ); + move32(); + return; +} +#else static void dct4_transform( uint8_t *v, /* i : input 4D vector */ float *dct_v /* o : output transformed vector */ @@ -7513,7 +8007,7 @@ static void dct4_transform( return; } - +#endif /*-------------------------------------------------------------------* * ivas_qmetadata_quantize_coherence_hr_512() @@ -7762,210 +8256,258 @@ static int16_t ivas_qmetadata_quantize_coherence_hr_512( /*! r: number of bits written */ #ifdef IVAS_FLOAT_FIXED -static int16_t ivas_qmetadata_quantize_coherence( - IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */ - const int16_t idx_d, /* i : current direction index */ - const int16_t all_coherence_zero, /* i : all coherence is zero - flag */ - BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */ - const int16_t write_flag, /* i : flag to actually write the data or not */ - int16_t *indice_coherence, - const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ +static Word16 ivas_qmetadata_quantize_coherence_fx( + IVAS_QMETADATA *hQMetaData, /* i/o: quantized metadata */ + const Word16 idx_d, /* i : current direction index */ + const Word16 all_coherence_zero, /* i : all coherence is zero - flag */ + BSTR_ENC_HANDLE hMetaData, /* i : metadata handle */ + const Word16 write_flag, /* i : flag to actually write the data or not */ + Word16 *indice_coherence, + const Word16 hrmasa_flag /* i : flag indicating high-rate MASA MD coding */ ) { - int16_t j, k; - float dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; -#ifdef IVAS_FLOAT_FIXED - Word32 dct_coh_fx[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; -#endif - uint16_t idx_dct[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t coding_subbands; - int16_t nbits; - uint64_t no_cb; - int16_t MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t nbits1; - int16_t coding_subbands_0, d; - int16_t two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; - int16_t no_cb_vec[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 j, k; + Word32 dct_coh[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; // Q21 + UWord16 idx_dct[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 coding_subbands; + Word16 nbits; + UWord64 no_cb; + Word16 MASA_grouping[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 nbits1; + Word16 coding_subbands_0, d; + Word16 two_dir_band[MASA_MAXIMUM_CODING_SUBBANDS]; + Word16 no_cb_vec[MASA_MAXIMUM_CODING_SUBBANDS]; IVAS_QDIRECTION *q_direction; - int16_t min_index; + Word16 min_index; + Word16 tmp16; min_index = 0; + move16(); q_direction = &( hQMetaData->q_direction[idx_d] ); coding_subbands = q_direction->cfg.nbands; + move16(); nbits = 0; + move16(); - if ( all_coherence_zero == 1 ) + IF( EQ_16( all_coherence_zero, 1 ) ) { return nbits; } - if ( hQMetaData->q_direction[idx_d].cfg.nblocks == 1 ) + IF( EQ_16( hQMetaData->q_direction[idx_d].cfg.nblocks, 1 ) ) { - nbits = encode_spread_coherence_1sf( hQMetaData, idx_d, hMetaData, hrmasa_flag ); + nbits = encode_spread_coherence_1sf_fx( hQMetaData, idx_d, hMetaData, hrmasa_flag ); return nbits; } - else + ELSE { k = 0; + move16(); no_cb = 1; + move64(); coding_subbands_0 = hQMetaData->q_direction[0].cfg.nbands; - if ( coding_subbands_0 <= 5 ) + move16(); + IF( LE_16( coding_subbands_0, 5 ) ) { - for ( j = 0; j < 5; j++ ) + FOR( j = 0; j < 5; j++ ) { MASA_grouping[j] = j; + move16(); } } - else + ELSE { - if ( coding_subbands_0 <= 8 ) + IF( LE_16( coding_subbands_0, 8 ) ) { - mvs2s( MASA_grouping_8_to_5, MASA_grouping, 8 ); + Copy( MASA_grouping_8_to_5, MASA_grouping, 8 ); } - else if ( coding_subbands_0 <= 12 ) + ELSE IF( LE_16( coding_subbands_0, 12 ) ) { - mvs2s( MASA_grouping_12_to_5, MASA_grouping, 12 ); + Copy( MASA_grouping_12_to_5, MASA_grouping, 12 ); } - else if ( coding_subbands_0 <= 18 ) + ELSE IF( LE_16( coding_subbands_0, 18 ) ) { - mvs2s( MASA_grouping_18_to_5, MASA_grouping, 18 ); + Copy( MASA_grouping_18_to_5, MASA_grouping, 18 ); } - else + ELSE { - if ( coding_subbands_0 <= 24 ) + IF( LE_16( coding_subbands_0, 24 ) ) { - mvs2s( MASA_grouping_24_to_5, MASA_grouping, 24 ); + Copy( MASA_grouping_24_to_5, MASA_grouping, 24 ); } } } - if ( coding_subbands < coding_subbands_0 ) + IF( LT_16( coding_subbands, coding_subbands_0 ) ) { d = 0; - for ( j = 0; j < coding_subbands_0; j++ ) + FOR( j = 0; j < coding_subbands_0; j++ ) { - if ( hQMetaData->twoDirBands[j] == 1 ) + if ( EQ_16( hQMetaData->twoDirBands[j], 1 ) ) { two_dir_band[d++] = j; + move16(); } } } - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { /* DCT transform */ - dct4_transform( hQMetaData->q_direction[idx_d].coherence_band_data[j].spread_coherence, dct_coh[j] ); + dct4_transform_fx( hQMetaData->q_direction[idx_d].coherence_band_data[j].spread_coherence, dct_coh[j] ); - if ( hrmasa_flag ) + IF( hrmasa_flag ) { - minimum_s( (int16_t *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); + minimum_s( (Word16 *) ( q_direction->band_data[j].energy_ratio_index ), q_direction->cfg.nblocks, &min_index ); no_cb_vec[j] = len_cb_dct0_masa[min_index >> 1]; + move16(); } - else + ELSE { no_cb_vec[j] = len_cb_dct0_masa[q_direction->band_data[j].energy_ratio_index[0]]; + move16(); } - if ( write_flag ) + IF( write_flag ) { /* quantize first DCT parameter */ - dct_coh[j][0] = quantize_DCT_0_coh( dct_coh[j][0], j, coherence_cb0_masa, MASA_DELTA_AZI_DCT0, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag ); + dct_coh[j][0] = quantize_DCT_0_coh_fx( extract_l( L_shr_r( dct_coh[j][0], 7 ) ), j, coherence_cb0_masa_Q14, MASA_DELTA_AZI_DCT0 << Q6, MASA_NO_CV_COH, q_direction, &idx_dct[k], &no_cb_vec[j], hrmasa_flag ); + move32(); } - if ( coding_subbands < coding_subbands_0 ) + IF( LT_16( coding_subbands, coding_subbands_0 ) ) { - idx_dct[k + coding_subbands] = squant( dct_coh[j][1], &dct_coh[j][1], &coherence_cb1_masa[MASA_grouping[two_dir_band[j]] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 ); + idx_dct[k + coding_subbands] = squant_fx( extract_l( L_shr_r( dct_coh[j][1], 6 ) ), &tmp16, &coherence_cb1_masa_Q15[MASA_grouping[two_dir_band[j]] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 ); + move16(); } - else + ELSE { - idx_dct[k + coding_subbands] = squant( dct_coh[j][1], &dct_coh[j][1], &coherence_cb1_masa[MASA_grouping[j] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 ); + idx_dct[k + coding_subbands] = squant_fx( extract_l( L_shr_r( dct_coh[j][1], 6 ) ), &tmp16, &coherence_cb1_masa_Q15[MASA_grouping[j] * MASA_NO_CV_COH1], MASA_NO_CV_COH1 ); + move16(); } - k++; + dct_coh[j][1] = L_shl( tmp16, 6 ); + k = add( k, 1 ); + move16(); - dct_coh[j][2] = 0.0f; - dct_coh[j][3] = 0.0f; + dct_coh[j][2] = 0; + move32(); + dct_coh[j][3] = 0; + move32(); } nbits1 = 0; - if ( sum_s( no_cb_vec, coding_subbands ) > MASA_COH_LIMIT_2IDX ) + move16(); + IF( GT_16( sum_s( no_cb_vec, coding_subbands ), MASA_COH_LIMIT_2IDX ) ) { /* make two indxes */ no_cb = 1; + move16(); - for ( j = 0; j < coding_subbands / 2; j++ ) + FOR( j = 0; j < coding_subbands / 2; j++ ) { - no_cb *= no_cb_vec[j]; + no_cb = no_cb * no_cb_vec[j]; } - nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + // nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + nbits = 0; + move16(); + } + ELSE + { + nbits = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); + } no_cb = 1; + move16(); - for ( j = coding_subbands / 2; j < coding_subbands; j++ ) + FOR( j = coding_subbands / 2; j < coding_subbands; j++ ) { - no_cb *= no_cb_vec[j]; + no_cb = no_cb * no_cb_vec[j]; + } + // nbits1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + nbits1 = 0; + move16(); + } + ELSE + { + nbits1 = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); } - nbits1 = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); } - else + ELSE { no_cb = 1; + move16(); - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { - no_cb *= no_cb_vec[j]; + no_cb = no_cb * no_cb_vec[j]; } - nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + // nbits = (int16_t) ceilf( logf( (float) no_cb ) * INV_LOG_2 ); + IF( LE_64( no_cb, 1 ) ) + { + nbits = 0; + move16(); + } + ELSE + { + nbits = sub( 63, W_norm( W_sub( no_cb, 1 ) ) ); + } } - if ( write_flag ) + IF( write_flag ) { - for ( j = 0; j < coding_subbands; j++ ) + FOR( j = 0; j < coding_subbands; j++ ) { /* inverse DCT transform */ #ifdef IVAS_FLOAT_FIXED /*================================flt-2-fix========================================*/ - floatToFixed_arrL( dct_coh[j], dct_coh_fx[j], Q21, MAX_PARAM_SPATIAL_SUBFRAMES ); // Q21 is used in decoder hence chosed otherwise function can work with variable Q + // floatToFixed_arrL( dct_coh[j], dct_coh_fx[j], Q21, MAX_PARAM_SPATIAL_SUBFRAMES ); // Q21 is used in decoder hence chosed otherwise function can work with variable Q /*================================fix-2-flt========================================*/ - invdct4_transform_fx( dct_coh_fx[j], q_direction->coherence_band_data[j].spread_coherence, Q21 ); + invdct4_transform_fx( dct_coh[j], q_direction->coherence_band_data[j].spread_coherence, Q21 ); #else invdct4_transform( dct_coh[j], q_direction->coherence_band_data[j].spread_coherence ); #endif } - nbits = encode_coherence_indexesDCT0( idx_dct, coding_subbands, no_cb_vec, hMetaData, *indice_coherence, nbits, nbits1 ); + nbits = encode_coherence_indexesDCT0_fx( idx_dct, coding_subbands, no_cb_vec, hMetaData, *indice_coherence, nbits, nbits1 ); } - else + ELSE { /* write dummy data now and save the position */ *indice_coherence = hMetaData->nb_ind_tot; + move16(); k = nbits; - while ( k > 0 ) + move16(); + WHILE( k > 0 ) { - push_next_indice( hMetaData, 0, min( 16, k ) ); - k -= 16; + push_next_indice( hMetaData, 0, s_min( 16, k ) ); + k = sub( k, 16 ); } - if ( nbits1 > 0 ) + IF( nbits1 > 0 ) { k = nbits1; - while ( k > 0 ) + move16(); + WHILE( k > 0 ) { push_next_indice( hMetaData, 0, min( 16, k ) ); - k -= 16; + k = sub( k, 16 ); } } - nbits += nbits1; - set_s( no_cb_vec, MASA_NO_CV_COH1, coding_subbands ); - nbits += encode_coherence_indexesDCT1( &idx_dct[coding_subbands], coding_subbands, hMetaData ); + nbits = add( nbits, nbits1 ); + set16_fx( no_cb_vec, MASA_NO_CV_COH1, coding_subbands ); + nbits = add( nbits, encode_coherence_indexesDCT1_fx( &idx_dct[coding_subbands], coding_subbands, hMetaData ) ); return nbits; } } - return nbits; } #else diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index 2f18205b0bf7e589f490786729f702750ef83772..7a83d7227b11944ef701d203fe7276a3258f59e1 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -1243,4 +1243,11 @@ const float param_mc_ild_diff_threshold[20] = { 8.0f, 8.0f, 10.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 20.0f }; +#ifdef IVAS_FLOAT_FIXED +//Q21 +const Word32 param_mc_ild_diff_threshold_fx[20] = { 16777216, 16777216, 20971520, 41943040, + 41943040, 41943040, 41943040, 41943040, + 41943040, 41943040, 41943040, 41943040 }; +#endif + /* clang-format on */ diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index e3164aa116a6c3562c27ed59e56caed4ce2d74ff..0a77df02ffb0570dbe77e103fa5722084b399551 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -187,6 +187,7 @@ extern const int16_t mc_paramupmix_fb_remix_order[4]; * ParamMC ROM tables *----------------------------------------------------------------------------------*/ extern const float param_mc_ild_diff_threshold[20]; +extern const Word32 param_mc_ild_diff_threshold_fx[20]; #endif diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 97c5a0d6e6de5d2b59194b941c7c78a650e00c63..8ea5eb8dca2329ab5f444a860137d7a77c924e5b 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -835,7 +835,11 @@ static ivas_error ivas_spar_cov_md_process( if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) { +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_spar_md_enc_process_fx( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, cov_real_fx, hSpar->hCovEnc->pCov_state->q_cov_real_per_band, cov_dtx_real_fx, hSpar->hCovEnc->pCov_dtx_state->q_cov_real_per_band, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer, *dyn_active_w_flag, hQMetaData->dirac_mono_flag ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer, *dyn_active_w_flag, hQMetaData->dirac_mono_flag ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -886,7 +890,11 @@ static ivas_error ivas_spar_cov_md_process( if ( hSpar->hMdEnc->spar_hoa_md_flag ) { +#ifdef IVAS_FLOAT_FIXED + error = ivas_spar_md_enc_process_fx( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, cov_real_fx, hSpar->hCovEnc->pCov_state->q_cov_real_per_band, cov_dtx_real_fx, hSpar->hCovEnc->pCov_dtx_state->q_cov_real_per_band, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer, *dyn_active_w_flag, hQMetaData->dirac_mono_flag ); +#else error = ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order, hSpar->hFbMixer->prior_mixer, *dyn_active_w_flag, hQMetaData->dirac_mono_flag ); +#endif } return error; diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 8b896e397a6d45f092ec17c7fe86dc26a9714ea6..3dfa3ba70624754669d699489d6dc7010e1ded15 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -33,6 +33,9 @@ #include #include "options.h" #include "prot.h" +#ifdef IVAS_FLOAT_FIXED +#include "prot_fx.h" +#endif #include "ivas_prot.h" #include "ivas_prot_fx.h" #include "math.h" @@ -63,9 +66,11 @@ typedef enum ivas_strats_t /*------------------------------------------------------------------------------------------* * Static functions declaration *------------------------------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static void ivas_band_mixer( float *cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t num_ch, int16_t *num_bands, int16_t red_band_fact ); - +#else +static void ivas_band_mixer_fx( Word32 *cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const Word16 num_ch, Word16 *num_bands, Word16 red_band_fact ); +#endif static int16_t ivas_get_huffman_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t nB, const int16_t qsi, const int16_t bands_bw ); static int16_t ivas_get_arith_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t *pDo_diff, const int16_t bands_bw, const int16_t nB, const int16_t qsi, const int16_t strat, const int32_t ivas_total_brate ); @@ -635,7 +640,444 @@ static void write_metadata_buffer( return; } +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_md_enc_process() + * + * SPAR FoA Meta Data generation process + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_spar_md_enc_process_fx( + ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *cov_dtx_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + const Word16 dtx_vad, + const Word16 nchan_inp, + const Word16 sba_order, /* i : Ambisonic (SBA) order */ + float *prior_mixer[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH], /* i : prior mixer_matrix */ + const Word16 dyn_active_w_flag, /* i : flag to indicate dynamic active W */ + const Word16 dirac_mono_flag /* i : flag to indicate mono only mode in SBA */ +) +{ + float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + Word16 i, j, b, qsi, ndm, ndec, num_ch, num_quant_strats; + float pred_coeffs_re_local[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + Word16 k, bwidth, num_bands, num_bands_full, num_bands_bw; + Word16 active_w, nchan_transport, dmx_switch, strat; + Word16 nB, bands_bw, packed_ok = 0; + ivas_strats_t cs[MAX_CODING_STRATS]; + Word16 code_strat; + Word16 bit_pos_start, next_ind_start; + BSTR_ENC_DATA hMetaData_tmp; + Indice *ind_list_tmp; + Word16 md_indices_allocated; + Word16 max_num_indices_tmp; + float Wscale[IVAS_MAX_NUM_BANDS]; + + /*extra 16 bits for arithmetic coder as overshoot check is after a symbol is written*/ + md_indices_allocated = add( hMdEnc->spar_md_cfg.max_bits_per_blk, IVAS_SPAR_ARITH_OVERSHOOT_BITS ); + IF( ( ind_list_tmp = (Indice *) malloc( sizeof( Indice ) * md_indices_allocated ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder indices" ); + } + + num_quant_strats = hMdEnc->spar_md_cfg.num_quant_strats; + move16(); + num_ch = ivas_sba_get_nchan_metadata_fx( sba_order, hEncoderConfig->ivas_total_brate ); + test(); + active_w = EQ_16( hMdEnc->spar_md_cfg.active_w, 1 ) || EQ_16( dyn_active_w_flag, 1 ); + nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; + move16(); + + bwidth = ivas_get_bw_idx_from_sample_rate_fx( hEncoderConfig->input_Fs ); + bwidth = s_min( bwidth, hEncoderConfig->max_bwidth ); + Word16 active_w_vlbr; + IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_24k4 ) ) + { + active_w_vlbr = 1; + move16(); + } + ELSE + { + active_w_vlbr = 0; + move16(); + } + num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); + IF( hMdEnc->spar_hoa_md_flag == 0 ) + { + num_bands = s_min( num_bands, SPAR_DIRAC_SPLIT_START_BAND ); + } + num_bands_full = num_bands; + move16(); + num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); + + IF( dtx_vad == 0 ) + { + FOR( i = 0; i < nchan_inp; i++ ) + { + FOR( j = 0; j < nchan_inp; j++ ) + { + cov_real_fx[i][j] = cov_dtx_real_fx[i][j]; + FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + cov_real_q[i][j][k] = cov_dtx_real_q[i][j][k]; + move16(); + } + } + } + } + + FOR( i = 0; i < nchan_inp; i++ ) + { + FOR( j = 0; j < nchan_inp; j++ ) + { + FOR( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) + { + cov_real_fx[i][j][k] = 0; + move32(); + } + } + } + + test(); + if ( EQ_32( hEncoderConfig->ivas_total_brate, BRATE_SPAR_Q_STRAT ) && EQ_16( sba_order, SBA_FOA_ORDER ) ) + { + /* make sure that qsi is always 0 (temporary bits are '00') */ + num_quant_strats = 1; + move16(); + } + + hMetaData_tmp.ind_list = ind_list_tmp; + hMetaData_tmp.nb_bits_tot = 0; + move16(); + max_num_indices_tmp = MAX_BITS_METADATA; + move16(); + hMetaData_tmp.ivas_max_num_indices = &max_num_indices_tmp; + hMetaData_tmp.ivas_ind_list_zero = (Indice **) ( &hMetaData_tmp.ind_list ); + hMetaData_tmp.st_ivas = NULL; + + /* Save state of metadata bitstream buffer */ + bit_pos_start = hMetaData->nb_bits_tot; + move16(); + next_ind_start = hMetaData->nb_ind_tot; + move16(); + dmx_switch = 0; + move16(); + + IF( dtx_vad == 0 ) + { + nB = SPAR_DTX_BANDS; + move16(); + bands_bw = idiv1616( num_bands, nB ); + + ivas_band_mixer_fx( cov_real_fx, cov_real_q, num_ch, &num_bands, bands_bw ); + } + ELSE IF( LT_32( hEncoderConfig->ivas_total_brate, IVAS_24k4 ) ) + { + bands_bw = 2; + move16(); + nB = idiv1616( num_bands, bands_bw ); + + ivas_band_mixer_fx( cov_real_fx, cov_real_q, num_ch, &num_bands, bands_bw ); + } + ELSE + { + nB = num_bands; + move16(); + bands_bw = 1; + move16(); + } + test(); + IF( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) + { + FOR( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) + { + FOR( i = 0; i < DIRAC_TO_SPAR_HBR_PRED_CHS; i++ ) + { + pred_coeffs_re_local[i][b] = hMdEnc->spar_md.band_coeffs[b].pred_re[i]; + } + } + } +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + FOR( i = 0; i < nchan_inp; i++ ) + { + FOR( j = 0; j < nchan_inp; j++ ) + { + FOR( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + cov_real[i][j][k] = me2f( cov_real_fx[i][j][k], sub( Q31, cov_real_q[i][j][k] ) ); + cov_dtx_real[i][j][k] = me2f( cov_dtx_real_fx[i][j][k], sub( Q31, cov_dtx_real_q[i][j][k] ) ); + } + } + } +#endif + + ivas_compute_spar_params( cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, bands_bw, active_w, active_w_vlbr, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0, dyn_active_w_flag ); + + if ( dirac_mono_flag ) + { + int16_t i_ts; + int16_t num_md_sub_frames = 1; + + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[0]; + + for ( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) + { + for ( b = 0; b < IVAS_MAX_NUM_BANDS; b++ ) + { + for ( j = 0; j < ndm + ndec - 1; j++ ) + { + hMdEnc->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j] = 0.0f; + } + for ( j = 0; j < ndec; j++ ) + { + for ( k = 0; k < ndm - 1; k++ ) + { + hMdEnc->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j][k] = 0.0f; + } + } + + for ( j = 0; j < ndec; j++ ) + { + hMdEnc->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[j] = 0.0f; + } + } + } + } + + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + hMdEnc->mixer_mat_local[i][j][b] = hMdEnc->mixer_mat[i][j][b]; + } + } + } + code_strat = 0; + for ( qsi = 0; qsi < num_quant_strats; qsi++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + + if ( dtx_vad == 1 ) + { + if ( ndm != num_ch ) + { + ivas_quant_p_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); + } + ivas_quant_pred_coeffs_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); + if ( active_w_vlbr ) + { + for ( i = 0; i < 3; i++ ) + { + int16_t i2; + i2 = 0; + switch ( i ) /* PRED (Y,Z,X) and DECD (Y,X,Z) coeffs are in different orders */ + { + case 0: + i2 = 0; + break; + case 1: + i2 = 2; + break; + case 2: + i2 = 1; + break; + } + if ( ( hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] == 0 ) && ( hMdEnc->spar_md.band_coeffs_idx[b].decd_index_re[i2] == 0 ) && ( hMdEnc->spar_md.band_coeffs[b].pred_re[i] != 0.0f ) && ( cov_real[i + 1][i + 1][b] != 0.0f ) ) + { + /* bump up the Pred coeff */ + float PR_uq, PR_step; + ivas_quant_strat_t qs; + qs = hMdEnc->spar_md_cfg.quant_strat[qsi]; + PR_uq = hMdEnc->spar_md.band_coeffs[b].pred_re[i]; + PR_step = ( qs.PR.max - qs.PR.min ) / ( qs.PR.q_levels[0] - 1 ); + + int16_t PR_sign; + PR_sign = ( PR_uq > 0 ) - ( PR_uq < 0 ); + hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] = PR_sign; + + /* deindex the modified coefficient */ + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = PR_sign * PR_step; + } + } + } + } + else + { + if ( ndm != num_ch ) + { + ivas_quant_p_per_band_dtx( hMdEnc->spar_md.band_coeffs[b].P_re, ndec, ndm, &hMdEnc->spar_md.band_coeffs_idx[b].decd_index_re[0], hMdEnc->spar_md.band_coeffs[b].P_quant_re, num_ch ); + } + + for ( i = 0; i < num_ch - 1; i++ ) + { + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = 0; + } + ivas_spar_quant_pred_coeffs_dtx( &hMdEnc->spar_md, hMdEnc->spar_md.band_coeffs[b].pred_re, ndm, hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re, num_ch - 1, hMdEnc->spar_md.band_coeffs[b].pred_quant_re ); + } + } + + for ( i = 0; i < num_ch - 1; i++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + pred_coeffs_re[i][b] = Wscale[b] * hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i]; + } + } + + if ( hMdEnc->spar_hoa_md_flag && hMdEnc->spar_hoa_dirac2spar_md_flag ) + { + for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) + { + for ( i = 0; i < DIRAC_TO_SPAR_HBR_PRED_CHS; i++ ) + { + /* Use the prediction coeffs computed based on DirAC MD to generate mixer matrix */ + pred_coeffs_re[i][b] = pred_coeffs_re_local[i][b]; + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = 0; + hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] = 0; + } + } + } + + ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, hMdEnc->mixer_mat, num_ch, 0, num_bands, active_w, &hMdEnc->spar_md_cfg ); + + for ( b = 0; b < num_bands; b++ ) + { + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + + for ( i = 0; i < num_ch; i++ ) + { + hMdEnc->mixer_mat[0][i][b] *= Wscale[b]; + } + + if ( ( ndm != num_ch ) && ( ndm != 1 ) ) + { + ivas_calc_c_p_coeffs( &hMdEnc->spar_md, cov_real, 0, hMdEnc->mixer_mat, num_ch, ndm, b, dtx_vad, 0, dyn_active_w_flag ); + + if ( dirac_mono_flag ) + { + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[0]; + for ( j = 0; j < ndec; j++ ) + { + for ( k = 0; k < ndm - 1; k++ ) + { + hMdEnc->spar_md.band_coeffs[b].C_re[j][k] = 0.0f; + } + } + } + + ivas_quant_c_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], + &hMdEnc->spar_md_cfg.quant_strat[qsi], ndec, ndm ); + } + } + + /* band limit downmix matrix */ + ivas_band_limit_dmx_matrix( hMdEnc, num_ch, num_bands, bands_bw ); + + /* band mixing */ + if ( bands_bw > 1 ) + { + ivas_band_mixing( hMdEnc, num_ch, num_bands, nchan_transport, num_bands_full ); + } + + if ( dtx_vad == 0 ) + { + ivas_write_parameter_bitstream_dtx( &hMdEnc->spar_md, hMetaData, hMdEnc->spar_md_cfg.num_dmx_chans_per_band, hMdEnc->spar_md_cfg.num_decorr_per_band, num_bands ); + break; + } + + ivas_select_next_strat( hMdEnc->spar_md_cfg.prior_strat, cs, dmx_switch, dtx_vad ); + + for ( i = 0; i < MAX_CODING_STRATS; i++ ) + { + strat = cs[i]; + if ( strat != NO_STRAT ) + { + reset_indices_enc( &hMetaData_tmp, md_indices_allocated ); + + ivas_write_spar_md_bitstream( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, strat, qsi ); + + /*write to main buffer if its a valid bitstream*/ + if ( hMetaData_tmp.nb_bits_tot > 0 ) + { + if ( hMetaData->nb_bits_tot == bit_pos_start || hMetaData_tmp.nb_bits_tot < ( hMetaData->nb_bits_tot - bit_pos_start ) ) + { + write_metadata_buffer( &hMetaData_tmp, hMetaData, bit_pos_start, next_ind_start ); + code_strat = strat; + } + + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == SBA_FOA_ORDER ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.tgt_bits_per_blk ) + { + packed_ok = 1; + break; + } + } + } + } + + if ( packed_ok == 1 ) + { + break; + } + + /*only if valid bitstream was written to main buffer*/ + if ( hMetaData->nb_bits_tot > bit_pos_start ) + { + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == SBA_FOA_ORDER ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.max_bits_per_blk ) + { + packed_ok = 1; + break; + } + } + } + + + /* Reuse mixer matrix values for unsent bands */ + if ( ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) && ( code_strat > 3 ) ) + { + for ( b = 0; b < num_bands * bands_bw; b += 2 * bands_bw ) + { + if ( ( b == 0 ) && ( code_strat % 2 == 0 ) ) + { + b += 2; + } + for ( i = 0; i < 1; i++ ) + { + for ( j = 0; j < 4; j++ ) + { + hMdEnc->mixer_mat[i][j][b] = prior_mixer[i][j][b]; + hMdEnc->mixer_mat[i][j][b + 1] = prior_mixer[i][j][b + 1]; + } + } + } + } + + ivas_store_prior_coeffs( hMdEnc, num_bands, code_strat, dtx_vad, qsi ); + + hMdEnc->spar_md.dtx_vad = dtx_vad; + hMdEnc->spar_md.num_bands = num_bands; + + free( ind_list_tmp ); + + return IVAS_ERR_OK; +} +#else /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_enc_process() * @@ -1033,8 +1475,70 @@ ivas_error ivas_spar_md_enc_process( return IVAS_ERR_OK; } +#endif +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_band_mixer() + * + * band mixer + *-----------------------------------------------------------------------------------------*/ + +static void ivas_band_mixer_fx( + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *cov_real_q[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + const Word16 num_ch, + Word16 *num_bands, + Word16 red_band_fact ) +{ + Word16 i, j, k, b, orig_band, rem_band; + Word32 avg_cov; + Word16 avg_cov_e; + + orig_band = *num_bands; + move16(); + *num_bands = idiv1616( *num_bands, red_band_fact ); + move16(); + rem_band = sub( orig_band, i_mult( *num_bands, red_band_fact ) ); + + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + FOR( k = 0; k < *num_bands - 1; k++ ) + { + avg_cov_e = 0; + move16(); + avg_cov = 0; + move32(); + FOR( b = 0; b < red_band_fact; b++ ) + { + avg_cov = BASOP_Util_Add_Mant32Exp( avg_cov, avg_cov_e, cov_real_fx[i][j][red_band_fact * k + b], sub( Q31, cov_real_q[i][j][red_band_fact * k + b] ), &avg_cov_e ); + } + cov_real_fx[i][j][k] = avg_cov; + move32(); + cov_real_q[i][j][k] = sub( Q31, avg_cov_e ); + move16(); + } + + avg_cov_e = 0; + move16(); + avg_cov = 0; + move32(); + FOR( b = 0; b < red_band_fact + rem_band; b++ ) + { + avg_cov = BASOP_Util_Add_Mant32Exp( avg_cov, avg_cov_e, cov_real_fx[i][j][red_band_fact * ( *num_bands - 1 ) + b], sub( Q31, cov_real_q[i][j][red_band_fact * ( *num_bands - 1 ) + b] ), &avg_cov_e ); + } + cov_real_fx[i][j][*num_bands - 1] = avg_cov; + move32(); + cov_real_q[i][j][*num_bands - 1] = sub( Q31, avg_cov_e ); + move16(); + } + } + return; +} +#else /*-----------------------------------------------------------------------------------------* * Function ivas_band_mixer() * @@ -1080,7 +1584,7 @@ static void ivas_band_mixer( return; } - +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_write_spar_md_bitstream() diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 2e167fe14c5d2a83e91f8f6641009daa05eb9b82..c4b1565a7a1f337834eda486b93d93cab521ec18 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -1096,6 +1096,8 @@ typedef struct ivas_param_mc_enc_data_structure int16_t max_param_band_abs_cov; float prev_ilds[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP]; + Word32 prev_ilds_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP]; /*Q21*/ + float ener_fac[PARAM_MC_MAX_PARAMETER_BANDS]; } PARAM_MC_ENC_DATA, *PARAM_MC_ENC_HANDLE; @@ -1109,19 +1111,18 @@ typedef struct ivas_mc_paramupmix_enc_data_structure ivas_trans_det_state_t *hTranDet[MC_PARAMUPMIX_COMBINATIONS * MC_PARAMUPMIX_NCH]; IVAS_FB_MIXER_HANDLE hFbMixer; ivas_enc_cov_handler_state_t *hCovEnc[MC_PARAMUPMIX_COMBINATIONS]; +#ifndef IVAS_FLOAT_FIXED float ***cov_real[MC_PARAMUPMIX_COMBINATIONS]; float ***cov_dtx_real[MC_PARAMUPMIX_COMBINATIONS]; -#ifdef IVAS_FLOAT_FIXED + float *midside[MC_PARAMUPMIX_COMBINATIONS][MC_PARAMUPMIX_NCH]; /* hold PCM of mid-side data */ +#else Word32 ***cov_real_fx[MC_PARAMUPMIX_COMBINATIONS]; Word32 ***cov_dtx_real_fx[MC_PARAMUPMIX_COMBINATIONS]; -#endif - float *midside[MC_PARAMUPMIX_COMBINATIONS][MC_PARAMUPMIX_NCH]; /* hold PCM of mid-side data */ -#ifdef IVAS_FLOAT_FIXED Word32 *midside_fx[MC_PARAMUPMIX_COMBINATIONS][MC_PARAMUPMIX_NCH]; /* hold PCM of mid-side data */ //(st_ivas->q_data_fx) #endif - int32_t alpha_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int32_t beta_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; - int16_t first_frame; + Word32 alpha_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word32 beta_quant_prev[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS]; + Word16 first_frame; } MC_PARAMUPMIX_ENC_DATA, *MC_PARAMUPMIX_ENC_HANDLE; @@ -1135,7 +1136,14 @@ 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 + Word32 chnlToFoaMtx_fx[DIRAC_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; /*q15*/ + Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ + Word16 **direction_vector_e[DIRAC_NUM_DIMS]; /* Average direction vector */ + Word32 *buffer_intensity_real_fx[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF]; + Word32 buffer_energy_fx[DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS]; + Word16 buffer_intensity_real_q[DIRAC_NO_COL_AVG_DIFF]; + Word16 buffer_energy_q[DIRAC_NO_COL_AVG_DIFF]; +#endif // IVAS_FLOAT_FIXED uint8_t nbands; uint8_t nCodingBands; uint8_t nSubframes; @@ -1176,6 +1184,8 @@ typedef struct ivas_omasa_encoder_one_data_struct float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; #ifdef IVAS_FLOAT_FIXED + Word32 energy_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; + Word16 energy_ism_e[MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 q_energy_ratio_ism_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS]; /* Q30 */ Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* Q30 */ #endif @@ -1265,7 +1275,7 @@ typedef struct ivas_mcmasa_enc_data_structure #ifndef IVAS_FLOAT_FIXED float *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ #else - Word32 *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ + Word32 *delay_buffer_lfe[2]; /* Delay buffer for LFE estimation */ #endif int16_t num_samples_delay_comp; @@ -1279,7 +1289,7 @@ typedef struct ivas_mcmasa_enc_data_structure #ifndef IVAS_FLOAT_FIXED float **direction_vector_m[DIRAC_NUM_DIMS]; /* Average direction vector */ #else - Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ + Word32 **direction_vector_m_fx[DIRAC_NUM_DIMS]; /* Average direction vector */ #endif Word16 **direction_vector_e[DIRAC_NUM_DIMS]; /* Average direction vector */ int16_t band_grouping[MASA_FREQUENCY_BANDS + 1]; diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 384ad20835c2db22ec02179df88cbd4d09fdcb34..c646d41f27263552015f81450e2a9e3b63090d32 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -480,7 +480,6 @@ void stereo_tcx_core_enc( st->mem_AR_fx[j] = (Word16) ( st->mem_AR[j] * 2.56f ); } - st->gamma = float_to_fix16( st->gamma_flt, Q15 ); floatToFixed_arr( st->lspold_enc, st->lspold_enc_fx, Q15, M ); st->hTcxEnc->spectrum_e[0] = 31 - ( Q_factor_arrL( st->hTcxEnc->spectrum[0], N_MAX ) - 4 ); diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index 9c277ca20b362398615028aa55196f992e204a35..d3433c41034cd8103566878c8ac290ba77bdc9d7 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -1347,6 +1347,8 @@ int16_t lsf_msvq_ma_encprm( return nbits_lpc; } + +#ifndef IVAS_FLOAT_FIXED /*--------------------------------------------------------------------------* * midlsf_enc() * @@ -1512,6 +1514,7 @@ int16_t Q_lsf_tcxlpc( return NumIndices; } +#endif /*--------------------------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 1e7315e652ed0afc634ae46d091570a12b78f934..7e32966289a88a8bd574e053a82a1f818dc0fd99 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1872,6 +1872,10 @@ AdjustFirstSID_fx( Word16 npart, Word16 *active_frame_counter, Encoder_State *stcod ); +void FdCng_encodeSID_ivas_fx( + Encoder_State *st /* i/o: encoder state structure */ +); + void resetFdCngEnc_fx( Encoder_State *st ); void encod_unvoiced_fx( diff --git a/lib_enc/qlpc_stoch.c b/lib_enc/qlpc_stoch.c index 517da127d1fbe0ce99fa8ca0bd0335f875318796..7f4b99d525dd770b9ae3fdd3d79d7a71048c8ffe 100644 --- a/lib_enc/qlpc_stoch.c +++ b/lib_enc/qlpc_stoch.c @@ -45,6 +45,7 @@ #include "basop_proto_func.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * lpc_quantization() * @@ -177,6 +178,7 @@ void lpc_quantization( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/sig_clas.c b/lib_enc/sig_clas.c index d089334b35c50982f8c5a2622caf61912cce0961..5c12978a702b1f4b0fb62d27ab123c749f7724b7 100644 --- a/lib_enc/sig_clas.c +++ b/lib_enc/sig_clas.c @@ -58,6 +58,7 @@ #define K_SNR_ENC 0.1111f #define C_SNR_ENC -0.3333f +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * signal_clas() * @@ -306,6 +307,7 @@ void select_TC( return; } +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/speech_music_classif.c b/lib_enc/speech_music_classif.c index 9fe43f12846962966bd49785423ec37c0cd2e413..b8c8f64a07bd1e34850ae3a856b701615cf1244e 100644 --- a/lib_enc/speech_music_classif.c +++ b/lib_enc/speech_music_classif.c @@ -112,42 +112,37 @@ void speech_music_clas_init( SP_MUS_CLAS_HANDLE hSpMusClas /* i/o: speech/music classifier handle */ ) { +#ifndef IVAS_FLOAT_FIXED int16_t i; +#endif +#ifndef IVAS_FLOAT_FIXED set_f( hSpMusClas->FV_st, 0.0f, N_SMC_FEATURES ); -#ifdef IVAS_FLOAT_FIXED - set_zero_fx( hSpMusClas->FV_st_fx, N_SMC_FEATURES ); #endif hSpMusClas->inact_cnt = 0; set_s( hSpMusClas->past_dec, 0, HANG_LEN - 1 ); +#ifndef IVAS_FLOAT_FIXED set_f( hSpMusClas->past_dlp, 0, HANG_LEN - 1 ); set_f( hSpMusClas->past_dlp_mean_ST, 0, HANG_LEN - 1 ); hSpMusClas->dlp_mean_ST = 0.0f; -#ifdef IVAS_FLOAT_FIXED - hSpMusClas->dlp_mean_ST_fx = 0; - hSpMusClas->dlp_var_LT_fx = 0; -#ifdef MSAN_FIX - hSpMusClas->dlp_mean_LT_fx = 0; - set16_fx( hSpMusClas->past_dlp_fx, 0, HANG_LEN - 1 ); -#endif // MSAN_FIX -#endif hSpMusClas->dlp_mean_LT = 0.0f; hSpMusClas->dlp_var_LT = 0.0f; +#endif +#ifndef IVAS_FLOAT_FIXED for ( i = 0; i < N_SMC_FEATURES; i++ ) { hSpMusClas->prev_FV[i] = 0.5f * hout_intervals[2 * i] + 0.5f * hout_intervals[2 * i + 1]; -#ifdef IVAS_FLOAT_FIXED - hSpMusClas->prev_FV_fx[i] = (Word32) ( hSpMusClas->prev_FV[i] * ONE_IN_Q20 ); -#endif } for ( i = 0; i < NB_BANDS_SPMUS; i++ ) { hSpMusClas->past_log_enr[i] = logf( E_MIN ); } +#endif hSpMusClas->sp_mus_state = -8; +#ifndef IVAS_FLOAT_FIXED hSpMusClas->wdrop = 0.0f; hSpMusClas->wrise = 0.0f; hSpMusClas->wdlp_0_95_sp = 0.0f; @@ -155,20 +150,25 @@ void speech_music_clas_init( set_f( hSpMusClas->last_lsp, 0.0f, M_LSP_SPMUS ); hSpMusClas->last_cor_map_sum = 0.0f; hSpMusClas->last_non_sta = 0.0f; +#endif set_f( hSpMusClas->past_PS, 0.0f, HIGHEST_FBIN - LOWEST_FBIN ); - hSpMusClas->past_ps_diff = 0; #ifndef IVAS_FLOAT_FIXED + hSpMusClas->past_ps_diff = 0; hSpMusClas->past_epsP2 = 01; hSpMusClas->past_epsP = 0; #endif hSpMusClas->flag_spitch_cnt = 0; +#ifndef IVAS_FLOAT_FIXED hSpMusClas->gsc_thres[0] = TH_0_MIN; hSpMusClas->gsc_thres[1] = TH_1_MIN; hSpMusClas->gsc_thres[2] = TH_2_MIN; hSpMusClas->gsc_thres[3] = TH_3_MIN; +#endif set_f( hSpMusClas->gsc_lt_diff_etot, 0.0f, MAX_LT ); +#ifndef IVAS_FLOAT_FIXED hSpMusClas->gsc_mem_etot = 0.0f; +#endif hSpMusClas->gsc_last_music_flag = 0; hSpMusClas->gsc_nb_thr_1 = 0; hSpMusClas->gsc_nb_thr_3 = 0; @@ -282,11 +282,9 @@ void speech_music_clas_init( hSpMusClas->high_stable_cor = 0; #ifndef IVAS_FLOAT_FIXED set_f( hSpMusClas->var_cor_t, 0.0f, VAR_COR_LEN ); -#endif hSpMusClas->lps = 0.0f; hSpMusClas->lpm = 0.0f; -#ifndef IVAS_FLOAT_FIXED hSpMusClas->lpn = 0.0f; #endif diff --git a/lib_enc/speech_music_classif_fx.c b/lib_enc/speech_music_classif_fx.c index ee1edb1b23634ff50a1ef076722a52fe05979d0b..56efcb4827e2774a4725b647cd54e94ca34cc714 100644 --- a/lib_enc/speech_music_classif_fx.c +++ b/lib_enc/speech_music_classif_fx.c @@ -291,7 +291,7 @@ void speech_music_clas_init_ivas_fx( { Word16 i; - set32_fx( hSpMusClas->FV_st_fx, 0, N_SMC_FEATURES ); //?? + set32_fx( hSpMusClas->FV_st_fx, 0, N_SMC_FEATURES ); hSpMusClas->inact_cnt = 0; move16(); @@ -326,6 +326,8 @@ void speech_music_clas_init_ivas_fx( move16(); hSpMusClas->wdlp_0_95_sp_fx = 0; move16(); + hSpMusClas->wdlp_0_95_sp_32fx = 0; + move32(); hSpMusClas->wdlp_xtalk_fx = 0; move16(); set16_fx( hSpMusClas->last_lsp_fx, 0, M_LSP_SPMUS ); @@ -2638,7 +2640,7 @@ Word16 ivas_smc_gmm_fx( * raw S/M decision based on smoothed GMM score *------------------------------------------------------------------*/ test(); - IF( dec == 0 || st->hSpMusClas->wdlp_0_95_sp_fx <= 0 ) + IF( dec == 0 || st->hSpMusClas->wdlp_0_95_sp_32fx <= 0 ) { st->sp_aud_decision0 = 0; st->sp_aud_decision1 = 0; @@ -2655,12 +2657,14 @@ Word16 ivas_smc_gmm_fx( *------------------------------------------------------------------*/ /* update buffer of past non-binary decisions */ - MVR2R_WORD16( &hSpMusClas->past_dlp_fx[0], &hSpMusClas->past_dlp_fx[1], HANG_LEN - 2 ); + Copy( &hSpMusClas->past_dlp_fx[0], &hSpMusClas->past_dlp_fx[1], HANG_LEN - 2 ); hSpMusClas->past_dlp_fx[0] = extract_l( L_shr( dlp_fx, 10 ) ); move16(); - mvr2r( &hSpMusClas->past_dlp_mean_ST[0], &hSpMusClas->past_dlp_mean_ST[1], HANG_LEN - 2 ); + + Copy32( &hSpMusClas->past_dlp_mean_ST_fx[0], &hSpMusClas->past_dlp_mean_ST_fx[1], HANG_LEN - 2 ); hSpMusClas->past_dlp_mean_ST_fx[0] = hSpMusClas->dlp_mean_ST_fx; move32(); + /* update buffer of past binary decisions */ mvs2s( &hSpMusClas->past_dec[0], &hSpMusClas->past_dec[1], HANG_LEN - 2 ); hSpMusClas->past_dec[0] = dec; @@ -3146,7 +3150,7 @@ void ivas_smc_mode_selection_fx( ELSE IF( flag_spitch ) { /* prevent GSC on signals with very short and stable high pitch period */ - IF( LT_16( hSpMusClas->wdlp_0_95_sp_fx, 640 /* 2.5f in Q8 */ ) ) + IF( LT_32( hSpMusClas->wdlp_0_95_sp_32fx, 41943040 /* 2.5f in Q24 */ ) ) { /* select ACELP instead */ st->sp_aud_decision1 = 0; @@ -3250,7 +3254,7 @@ void ivas_smc_mode_selection_fx( { st->GSC_IVAS_mode = 1; move16(); - IF( st->hSpMusClas->wdlp_0_95_sp_fx > 0 ) + IF( st->hSpMusClas->wdlp_0_95_sp_32fx > 0 ) { /* music-like content */ st->GSC_IVAS_mode = 3; diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index fdf3c8cc93328981efbc453c2c5222c7ae29600f..d6263872e39493d0a178aff399fb5a1c34a21e19 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -871,58 +871,73 @@ typedef struct noise_estimation_structure typedef struct sp_mus_clas_structure { - float FV_st[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ - Word32 FV_st_fx[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ +#ifndef IVAS_FLOAT_FIXED + float FV_st[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector */ +#else + Word32 FV_st_fx[N_SMC_FEATURES]; /* Speech/music classifier - short-term mean of the feature vector Q20 */ +#endif float past_PS[HIGHEST_FBIN - LOWEST_FBIN]; - float past_ps_diff; Word32 past_PS_fx[HIGHEST_FBIN - LOWEST_FBIN]; - Word16 past_ps_diff_fx; - float prev_FV[N_SMC_FEATURES]; - Word32 prev_FV_fx[N_SMC_FEATURES]; #ifndef IVAS_FLOAT_FIXED + float past_ps_diff; + float prev_FV[N_SMC_FEATURES]; float past_epsP; float past_epsP2; #else + Word16 past_ps_diff_fx; /* Q10 */ + Word32 prev_FV_fx[N_SMC_FEATURES]; /* Q20 */ Word16 past_epsP_fx; - Word16 past_epsP2_fx; /* Q10 */ + Word16 past_epsP2_fx; /* Q10 */ #endif int16_t inact_cnt; +#ifndef IVAS_FLOAT_FIXED float wdrop; - Word16 wdrop_fx; float wrise; - Word16 wrise_fx; float wdlp_0_95_sp; - Word16 wdlp_0_95_sp_fx; - Word32 wdlp_0_95_sp_32fx; float wdlp_xtalk; - Word32 wdlp_xtalk_fx; +#else + Word16 wdrop_fx; /* Q9 */ + Word16 wrise_fx; /* Q9 */ + Word16 wdlp_0_95_sp_fx; /* EVS - Q8 */ + Word32 wdlp_0_95_sp_32fx; /* IVAS - Q24 */ + Word32 wdlp_xtalk_fx; /* Q19 */ +#endif int16_t sp_mus_state; int16_t past_dec[HANG_LEN - 1]; /* Speech/music classifier - buffer of past binary decisions */ - float past_dlp[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions */ - Word16 past_dlp_fx[HANG_LEN - 1]; - float past_dlp_mean_ST[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ - Word32 past_dlp_mean_ST_fx[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ +#ifndef IVAS_FLOAT_FIXED + float past_dlp[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions */ + float past_dlp_mean_ST[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) */ float dlp_mean_ST; - Word32 dlp_mean_ST_fx; +#else + Word16 past_dlp_fx[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions Q9 */ + Word32 past_dlp_mean_ST_fx[HANG_LEN - 1]; /* Speech/music classifier - buffer of past non-binary decisions (with ST smoothing) Q19 */ + Word32 dlp_mean_ST_fx; /* Q19 */ +#endif int16_t flag_spitch_cnt; +#ifndef IVAS_FLOAT_FIXED float dlp_mean_LT; - Word32 dlp_mean_LT_fx; float dlp_var_LT; - Word32 dlp_var_LT_fx; float last_lsp[M_LSP_SPMUS]; float last_cor_map_sum; float last_non_sta; float past_log_enr[NB_BANDS_SPMUS]; /* Speech/music classifier - last average per-band log energy used for non_staX */ float gsc_thres[4]; /* Speech/music classifier - classification threshold */ +#else + Word32 dlp_mean_LT_fx; /* Q19 */ + Word32 dlp_var_LT_fx; /* Q19 */ + Word16 last_lsp_fx[M_LSP_SPMUS]; /* Q13 */ + Word16 last_cor_map_sum_fx; /* Q8 */ + Word16 last_non_sta_fx; /* Q8 */ + Word16 past_log_enr_fx[NB_BANDS_SPMUS]; /* Speech/music classifier - last average per-band log energy used for non_staX Q8 */ + Word16 gsc_thres_fx[4]; /* Speech/music classifier - classification threshold Q11 */ +#endif float gsc_lt_diff_etot[MAX_LT]; /* Speech/music classifier - long-term total energy variation */ - float gsc_mem_etot; /* Speech/music classifier - total energy memory */ - Word16 last_lsp_fx[M_LSP_SPMUS]; - Word16 last_cor_map_sum_fx; - Word16 last_non_sta_fx; - Word16 past_log_enr_fx[NB_BANDS_SPMUS]; /* Speech/music classifier - last average per-band log energy used for non_staX */ - Word16 gsc_thres_fx[4]; /* Speech/music classifier - classification threshold */ - Word16 gsc_lt_diff_etot_fx[MAX_LT]; /* Speech/music classifier - long-term total energy variation */ - Word16 gsc_mem_etot_fx; /* Speech/music classifier - total energy memory */ + Word16 gsc_lt_diff_etot_fx[MAX_LT]; /* Speech/music classifier - long-term total energy variation Q8 */ +#ifndef IVAS_FLOAT_FIXED + float gsc_mem_etot; /* Speech/music classifier - total energy memory */ +#else + Word16 gsc_mem_etot_fx; /* Speech/music classifier - total energy memory Q8 */ +#endif int16_t gsc_last_music_flag; /* Speech/music classifier - last music flag */ int16_t gsc_nb_thr_1; /* Speech/music classifier - number of consecutives frames of level 1 */ @@ -935,10 +950,10 @@ typedef struct sp_mus_clas_structure float lt_dec_thres; /* Speech/music classifier - Long term speech/music thresold values */ float ener_RAT; /* Speech/music classifier - LF/to total energy ratio */ #else - Word16 mean_avr_dyn_fx; /* Speech/music classifier - long term average dynamic Q7 */ - Word16 last_sw_dyn_fx; /* Speech/music classifier - last dynamic Q7 */ - Word16 lt_dec_thres_fx; /* Speech/music classifier - Long term speech/music thresold values Q9 */ - Word16 ener_RAT_fx; /* Speech/music classifier - LF/to total energy ratio Q15 */ + Word16 mean_avr_dyn_fx; /* Speech/music classifier - long term average dynamic Q7 */ + Word16 last_sw_dyn_fx; /* Speech/music classifier - last dynamic Q7 */ + Word16 lt_dec_thres_fx; /* Speech/music classifier - Long term speech/music thresold values Q9 */ + Word16 ener_RAT_fx; /* Speech/music classifier - LF/to total energy ratio Q15 */ #endif int16_t relE_attack_cnt; @@ -946,15 +961,15 @@ typedef struct sp_mus_clas_structure float prev_relE; float prev_Etot; #else - Word16 prev_relE_fx; /* Q8 */ - Word16 prev_Etot_fx; /* Q8 */ + Word16 prev_relE_fx; /* Q8 */ + Word16 prev_Etot_fx; /* Q8 */ #endif int16_t prev_vad; int16_t vad_0_1_cnt; #ifndef IVAS_FLOAT_FIXED float relE_attack_sum; #else - Word16 relE_attack_sum_fx; /* Q8 */ + Word16 relE_attack_sum_fx; /* Q8 */ #endif /* speech/music classifier improvement parameters */ @@ -969,22 +984,22 @@ typedef struct sp_mus_clas_structure float buf_Ntonal_lf[BUF_LEN]; float buf_dlp[10]; #else - Word16 old_Bin_E_fx[3 * N_OLD_BIN_E]; /* Q7 */ - Word16 buf_flux_fx[BUF_LEN]; /* Q7 */ - Word16 buf_pkh_fx[BUF_LEN]; /* Q1 */ - Word16 buf_epsP_tilt_fx[BUF_LEN]; /* Q15 */ - Word16 buf_cor_map_sum_fx[BUF_LEN]; /* Q8 */ - Word16 buf_Ntonal_fx[BUF_LEN]; /* Q0 */ - Word16 buf_Ntonal2_fx[BUF_LEN]; /* Q0 */ - Word16 buf_Ntonal_lf_fx[BUF_LEN]; /* Q0 */ - Word16 buf_dlp_fx[10]; /* Q9 */ + Word16 old_Bin_E_fx[3 * N_OLD_BIN_E]; /* Q7 */ + Word16 buf_flux_fx[BUF_LEN]; /* Q7 */ + Word16 buf_pkh_fx[BUF_LEN]; /* Q1 */ + Word16 buf_epsP_tilt_fx[BUF_LEN]; /* Q15 */ + Word16 buf_cor_map_sum_fx[BUF_LEN]; /* Q8 */ + Word16 buf_Ntonal_fx[BUF_LEN]; /* Q0 */ + Word16 buf_Ntonal2_fx[BUF_LEN]; /* Q0 */ + Word16 buf_Ntonal_lf_fx[BUF_LEN]; /* Q0 */ + Word16 buf_dlp_fx[10]; /* Q9 */ #endif int16_t onset_cnt; #ifndef IVAS_FLOAT_FIXED float buf_etot[4]; #else - Word16 buf_etot_fx[4]; /* Q8 */ + Word16 buf_etot_fx[4]; /* Q8 */ #endif int16_t attack_hangover; #ifndef IVAS_FLOAT_FIXED @@ -993,16 +1008,16 @@ typedef struct sp_mus_clas_structure float mov_log_max_spl; float old_lt_diff[2]; #else - Word16 dec_mov_fx; /* Q15 */ - Word16 dec_mov1_fx; /* Q15 */ - Word16 mov_log_max_spl_fx; /* Q7 */ - Word16 old_lt_diff_fx[2]; /* Q7 */ + Word16 dec_mov_fx; /* Q15 */ + Word16 dec_mov1_fx; /* Q15 */ + Word16 mov_log_max_spl_fx; /* Q7 */ + Word16 old_lt_diff_fx[2]; /* Q7 */ #endif int16_t UV_cnt1; #ifndef IVAS_FLOAT_FIXED float LT_UV_cnt1; #else - Word16 LT_UV_cnt1_fx; /* Q6 */ + Word16 LT_UV_cnt1_fx; /* Q6 */ #endif float finc_prev[ATT_NSEG]; /* strong attack detection - previous finc */ @@ -1019,11 +1034,11 @@ typedef struct sp_mus_clas_structure float tod_S_mass_prev; float tod_S_mass_lt; #else - Word32 tod_S_map_lt_fx[TOD_NSPEC]; /* tonal detector - long-term correlation map, Q22 */ - Word32 tod_thr_lt_fx; /* tonal detector - adaptive threshold, Q22 */ - Word16 tod_weight_fx; /* tonal detector - adaptive weight, Q15 */ - Word32 tod_S_mass_prev_fx; /* Q22 */ - Word32 tod_S_mass_lt_fx; /* Q22 */ + Word32 tod_S_map_lt_fx[TOD_NSPEC]; /* tonal detector - long-term correlation map, Q22 */ + Word32 tod_thr_lt_fx; /* tonal detector - adaptive threshold, Q22 */ + Word16 tod_weight_fx; /* tonal detector - adaptive weight, Q15 */ + Word32 tod_S_mass_prev_fx; /* Q22 */ + Word32 tod_S_mass_lt_fx; /* Q22 */ #endif int16_t lt_music_hangover; @@ -1032,9 +1047,9 @@ typedef struct sp_mus_clas_structure float tonality3_buf[HANG_LEN_INIT]; float LPCErr_buf[HANG_LEN_INIT]; #else - Word16 tonality2_buf_fx[HANG_LEN_INIT]; /* Q14 */ - Word16 tonality3_buf_fx[HANG_LEN_INIT]; /* Q14 */ - Word16 LPCErr_buf_fx[HANG_LEN_INIT]; /* Q10 */ + Word16 tonality2_buf_fx[HANG_LEN_INIT]; /* Q14 */ + Word16 tonality3_buf_fx[HANG_LEN_INIT]; /* Q14 */ + Word16 LPCErr_buf_fx[HANG_LEN_INIT]; /* Q10 */ #endif int16_t lt_music_state; int16_t lt_speech_state; @@ -1043,8 +1058,8 @@ typedef struct sp_mus_clas_structure float lpe_buf[HANG_LEN_INIT]; float voicing_buf[HANG_LEN_INIT]; #else - Word16 lpe_buf_fx[HANG_LEN_INIT]; /* Q10 */ - Word16 voicing_buf_fx[HANG_LEN_INIT]; /* Q13 */ + Word16 lpe_buf_fx[HANG_LEN_INIT]; /* Q10 */ + Word16 voicing_buf_fx[HANG_LEN_INIT]; /* Q13 */ #endif int16_t gsc_hangover; #ifndef IVAS_FLOAT_FIXED @@ -1083,13 +1098,13 @@ typedef struct sp_mus_clas_structure #endif int16_t high_stable_cor; +#ifndef IVAS_FLOAT_FIXED float lps; float lpm; - Word16 lps_fx; - Word16 lpm_fx; -#ifndef IVAS_FLOAT_FIXED float lpn; #else + Word16 lps_fx; /* Q7 */ + Word16 lpm_fx; /* Q7 */ Word16 lpn_fx; /* Q7 */ #endif @@ -1913,12 +1928,15 @@ typedef struct enc_core_structure * ACELP core parameters *----------------------------------------------------------------------------------*/ - int16_t clas; /* current frame clas */ - int16_t last_clas; /* previous frame signal classification */ + int16_t clas; /* current frame clas */ + int16_t last_clas; /* previous frame signal classification */ +#ifndef IVAS_FLOAT_FIXED float prev_fmerit_flt; /* previous signal classification score*/ float fmerit_dt_flt; /* signal classification score difference */ - Word16 prev_fmerit; - Word16 fmerit_dt; +#else + Word16 prev_fmerit; /* previous signal classification score Q15 */ + Word16 fmerit_dt; /* signal classification score difference Q15 */ +#endif int16_t Nb_ACELP_frames; int16_t pitch[3]; /* open-loop pitch values @12.8 kHz for three half-frames */ @@ -2330,12 +2348,13 @@ typedef struct enc_core_structure int16_t nb_bits_header_tcx; /* number of bits for the header */ float preemph_fac_flt; /* Preemphasis factor */ + Word16 preemph_fac; /*Preemphasis factor Q15*/ +#ifndef IVAS_FLOAT_FIXED float gamma_flt; - - Word16 preemph_fac; /*Preemphasis factor Q15*/ - - Word16 gamma; // Q15 - Word16 inv_gamma; +#else + Word16 gamma; /* Q15 */ + Word16 inv_gamma; /* Q14 */ +#endif TRAN_DET_HANDLE hTranDet; TransientDetection transientDetection; diff --git a/lib_enc/stat_noise_uv_enc.c b/lib_enc/stat_noise_uv_enc.c index 75324a3c11f4dd30426a424aa6a1a64290cbc3b0..94af0a56800ab9aa526ba8a08153afd2fa61d5be 100644 --- a/lib_enc/stat_noise_uv_enc.c +++ b/lib_enc/stat_noise_uv_enc.c @@ -40,6 +40,7 @@ #include "rom_com.h" #include "wmc_auto.h" +#ifndef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* * stat_noise_uv_enc() * @@ -102,3 +103,4 @@ void stat_noise_uv_enc( return; } +#endif diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index 61eec9e75d050923d892c027acfd8dee0f5a245a..2818df555262ed1ef5f6576f8cb7368c0ef62452 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -60,6 +60,7 @@ * Local function prototypes *-----------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED static void return_M_Least( const float *inp, const int16_t n_cols, const float *codebook, const int16_t num_grp, const float *weight, const int16_t interNum, int16_t *least ); static void singlevectortest_gain( const float *inp, const int16_t dimen, const int16_t cb_size, int16_t *index, const float *weight, float *recon, const float *codebook ); static void determine_gain_weights( const float *gain, float *weights, const int16_t dims ); @@ -78,6 +79,7 @@ static void Quant_BWE_LSF( BSTR_ENC_HANDLE hBstr, TD_BWE_ENC_HANDLE hBWE_TD, con static void Quant_shb_ener_sf( Encoder_State *st, float *shb_ener_sf ); static void Quant_shb_res_gshape( Encoder_State *st, float *shb_res_gshape ); static void LVQQuant_BWE_LSF( BSTR_ENC_HANDLE hBstr, const float lsf_shb[], float Q_lsfs[], int16_t nbits ); +#endif /*-------------------------------------------------------------------* * InitSWBencBuffer() @@ -230,6 +232,7 @@ void ResetSHBbuffer_Enc( } +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * wb_tbe_enc() * @@ -2690,6 +2693,7 @@ static void return_M_Least( return; } +#endif /*-------------------------------------------------------------------* * fb_tbe_reset_enc() @@ -2710,6 +2714,7 @@ void fb_tbe_reset_enc( return; } +#ifndef IVAS_FLOAT_FIXED /*-------------------------------------------------------------------* * fb_tbe_enc() * @@ -2865,6 +2870,7 @@ void tbe_write_bitstream( return; } +#endif /*---------------------------------------------------------------------* * TBEreset_enc() diff --git a/lib_enc/transition_enc.c b/lib_enc/transition_enc.c index c888269476595e5dc3aee07bad15b4a99f25a7c0..cd6e48fe239b1abd60ea5c0681c12eff2211ea75 100644 --- a/lib_enc/transition_enc.c +++ b/lib_enc/transition_enc.c @@ -970,6 +970,7 @@ static void gain_trans_enc( } +#ifndef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------* * tc_classif_enc() * @@ -1058,3 +1059,4 @@ void tc_classif_enc( return; } +#endif diff --git a/lib_enc/updt_enc.c b/lib_enc/updt_enc.c index ded37c0a8bc2fdb74b088dac64565eb227832943..b6178439a89398c13bdbd413d1bf3a895a6a742a 100644 --- a/lib_enc/updt_enc.c +++ b/lib_enc/updt_enc.c @@ -284,7 +284,6 @@ void updt_IO_switch_enc( return; } -#endif /*-------------------------------------------------------------------* * updt_enc_common() @@ -460,6 +459,7 @@ void updt_enc_common( return; } +#endif #ifdef IVAS_FLOAT_FIXED