From f11b964089b5fe0992a6ebb9d9d7ffb0672eed24 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Sun, 31 Mar 2024 13:25:52 +0530 Subject: [PATCH] Integration of spar decoder functions, crash fix and high MLD fix. [x] High MLD fix in CPE dec and stereo_switching dec. [x] spar decoder functions converted to fixed point. [x] ivas_bw_switching_pre_proc function crash fix. --- lib_com/cnst.h | 1 + lib_com/ivas_cnst.h | 3 + lib_com/ivas_prot.h | 50 +- lib_com/ivas_prot_fx.h | 24 + lib_com/ivas_rom_com.c | 205 ++ lib_com/ivas_rom_com.h | 5 +- lib_com/ivas_spar_com.c | 3619 +++++++++++++++++++++++++-- lib_com/ivas_spar_com_quant_util.c | 155 +- lib_com/ivas_stat_com.h | 18 +- lib_dec/core_switching_dec.c | 24 +- lib_dec/evs_dec.c | 7 +- lib_dec/ivas_core_dec.c | 13 +- lib_dec/ivas_cpe_dec_fx.c | 4 +- lib_dec/ivas_dirac_dec.c | 387 +-- lib_dec/ivas_jbm_dec.c | 14 + lib_dec/ivas_qmetadata_dec.c | 206 +- lib_dec/ivas_spar_decoder.c | 184 ++ lib_dec/ivas_spar_md_dec.c | 915 ++++++- lib_dec/ivas_stat_dec.h | 3 + lib_dec/ivas_stereo_switching_dec.c | 4 +- lib_dec/stat_dec.h | 4 +- 21 files changed, 5376 insertions(+), 469 deletions(-) diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e1da85ca6..2e99561e7 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -126,6 +126,7 @@ #define ONE_IN_Q29 536870912 #define ONE_IN_Q30 1073741824 #define ONE_IN_Q31 0x7fffffff +#define MINUS_ONE_IN_Q31 -2147483648 #define MAX_WORD16 32767 #define ONE_IN_Q62 (Word64)0x4000000000000000 diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 429695227..d5c44b42a 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1032,8 +1032,11 @@ typedef enum /* Common SPAR metadata constants */ #define IVAS_ACTIVEW_DM_F_SCALE 0.5f +#define IVAS_ACTIVEW_DM_F_SCALE_FX ONE_IN_Q30 #define IVAS_ACTIVEW_DM_F_SCALE_DTX 0.25f +#define IVAS_ACTIVEW_DM_F_SCALE_DTX_FX ONE_IN_Q29 #define IVAS_ACTIVEW_DM_F_SCALE_VLBR 0.25f +#define IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX ONE_IN_Q29 #define IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN 24000 #define IVAS_SPAR_DYN_ACTIVEW_THRESH (0.0039f) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 0f42b5251..92f1515ab 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3754,6 +3754,13 @@ int16_t masa_sq( const int16_t cb_sz /* i : codebook size */ ); +#ifdef IVAS_FLOAT_FIXED +Word16 masa_sq_fx( + const Word32 in, /* i : input value */ + const Word32 *threshold, /* i : partition */ + const Word16 cb_sz /* i : codebook size */ +); +#endif void ivas_qmetadata_azimuth_elevation_to_direction_vector( const float az, /* i : azimuth */ const float el, /* i : elevation */ @@ -4365,6 +4372,12 @@ void ivas_dirac_dec_get_response_fixed_Q( Word32 *response, const Word16 ambisonics_order, Word16 Q); + +void ivas_dirac_dec_get_response_fx( + const Word16 azimuth, + const Word16 elevation, + Word32 * response, + const Word16 ambisonics_order); #endif void calculate_hodirac_sector_parameters( @@ -5172,7 +5185,25 @@ void ivas_calc_c_p_coeffs( const int16_t compute_p_flag, const int16_t dyn_active_w_flag ); - +#ifdef IVAS_FLOAT_FIXED +void ivas_get_spar_md_from_dirac_fx( + float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + float diffuseness[IVAS_MAX_NUM_BANDS], + const int16_t n_ts, + float ***mixer_mat, + ivas_spar_md_t *hSpar_md, + ivas_spar_md_com_cfg *hSpar_md_cfg, + const int16_t start_band, + const int16_t end_band, + const int16_t order, + const int16_t dtx_vad, + float Wscale_d[IVAS_MAX_NUM_BANDS], + const uint8_t useLowerRes, + const int16_t active_w_vlbr, + const int16_t dyn_active_w_flag +); +#endif void ivas_get_spar_md_from_dirac( float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], @@ -5271,6 +5302,10 @@ int16_t ivas_spar_chk_zero_coefs( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ ); +Word16 ivas_spar_chk_zero_coefs_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +); + void ivas_spar_smooth_md_dtx( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const int16_t num_bands_out, /* i : number of output bands */ @@ -5664,6 +5699,14 @@ void ivas_quantise_real_values( float *quant, const int16_t dim ); +void ivas_quantise_real_values_fx( + const Word32 *values_fx, + const int16_t q_levels, + const Word32 min_value_fx, + const Word32 max_value_fx, + int16_t *index, + Word32 *quant_fx, + const int16_t dim); void ivas_spar_get_uniform_quant_strat( ivas_spar_md_com_cfg *pSpar_md_com_cfg, @@ -5684,6 +5727,11 @@ void ivas_spar_quant_dtx_init_fx( Word32 *min_max ); +void ivas_spar_quant_dtx_init_fx( + ivas_spar_md_t *spar_md, + Word32 *min_max +); + void ivas_map_prior_coeffs_quant( ivas_spar_md_prev_t *pSpar_md_prior, ivas_spar_md_com_cfg *pSpar_md_cfg, diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 1ff34c20e..7a3a430a7 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -660,6 +660,25 @@ Word16 masa_sq_fx( const Word16 cb_sz /* i : codebook size */ ); +void ivas_compute_spar_params_fx( + Word32 * pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + const int16_t i_ts, + float ***mixer_mat, + const int16_t start_band, + const int16_t end_band, + const int16_t dtx_vad, + const int16_t num_ch, + const int16_t bands_bw, + const int16_t active_w, + const int16_t active_w_vlbr, + ivas_spar_md_com_cfg * hSparCfg, + ivas_spar_md_t * hSparMd, + float *pWscale, + const int16_t from_dirac, + const int16_t dyn_active_w_flag +); + ivas_error ivas_ism_metadata_dec_fx( const Word32 ism_total_brate, /* i : ISM total bitrate */ const Word16 nchan_ism, /* i : number of ISM channels */ @@ -1883,4 +1902,9 @@ void ivas_qmetadata_close( IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */ ); #endif + +ivas_error ivas_spar_dec_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + Word16 *nb_bits_read /* o : number of MD bits read */ +); #endif diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index c1534f075..9bd5ee36e 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -1657,6 +1657,7 @@ const ivas_huff_models_t ivas_huff_decd_r_consts[TOTAL_DECD_QUANT_STRATS] = /* DTX quantization and bitstream constants */ const float dtx_pd_real_min_max[2] = { 0, 1.6f }; +const Word32 dtx_pd_real_min_max_fx[2] = { 0, 429496729 }; const int16_t dtx_pd_real_q_levels[3][3] = { { 7,7,7 },{ 7,7,0 },{ 3,0,0 } }; const int16_t dtx_pr_real_q_levels[3][3] = { { 9,9,9 },{ 9,7,9 },{ 9,5,7 } }; const int16_t pr_pr_idx_pairs[3][3][2] = { { { 0, 0 },{ 0, 0 },{ 0, 0 } },{ { 0, 0 },{ 0, 0 },{ 0, 0 } },{ { 0, 0 },{ 1, 3 },{ 0, 0 } } }; @@ -5462,6 +5463,11 @@ const Word32 dirac_gains_norm_term_int[9] = //Q30 1073741824, 759250176, 1073741824, 438353280, 219176688, 1073741824, 309962528, 98018768, 40015996 }; + +const Word32 dirac_gains_norm_term_fx[9] = //Q31 +{ + 2147483647, 1518500352, 2147483647, 876706560, 438353376, 2147483647, 619925056, 196037536, 80031992 +}; #endif const float dirac_gains_Pnm[91][9] = { @@ -6022,6 +6028,190 @@ const Word32 dirac_gains_trg_term_int[181][2] = //Q30 {1073578304, -18739382}, {1073741824, 0} }; + +const Word32 dirac_gains_trg_term_fx[181][2] = //Q31 +{ + {-2147483648,187}, + {-2147156608,-37478872}, + {-2146175360,-74946000}, + {-2144540544,-112390808}, + {-2142252544,-149800880}, + {-2139311872,-187165312}, + {-2135719552,-224473248}, + {-2131476480,-261712336}, + {-2126584576,-298872160}, + {-2121044736,-335940320}, + {-2114858496,-372906880}, + {-2108028416,-409759200}, + {-2100556032,-446486752}, + {-2092443904,-483078816}, + {-2083694208,-519523328}, + {-2074309888,-555809792}, + {-2064293760,-591926784}, + {-2053648896,-627863232}, + {-2042378240,-663608960}, + {-2030485760,-699152192}, + {-2017974528,-734482816}, + {-2004848896,-769589184}, + {-1991112320,-804461312}, + {-1976769280,-839088832}, + {-1961824000,-873460224}, + {-1946281216,-907565888}, + {-1930145664,-941394752}, + {-1913421952,-974937408}, + {-1896115584,-1008182592}, + {-1878231680,-1041120448}, + {-1859775360,-1073742080}, + {-1840752768,-1106035712}, + {-1821169152,-1137993088}, + {-1801031424,-1169603328}, + {-1780344960,-1200857344}, + {-1759115776,-1231746176}, + {-1737351040,-1262259072}, + {-1715056640,-1292388096}, + {-1692240256,-1322122752}, + {-1668908160,-1351455488}, + {-1645067776,-1380375808}, + {-1620726784,-1408876032}, + {-1595891328,-1436947072}, + {-1570570112,-1464580224}, + {-1544770304,-1491767808}, + {-1518500352,-1518500352}, + {-1491767808,-1544770304}, + {-1464580224,-1570570112}, + {-1436947200,-1595891328}, + {-1408876032,-1620726784}, + {-1380375808,-1645067776}, + {-1351455104,-1668908288}, + {-1322122752,-1692240256}, + {-1292388096,-1715056640}, + {-1262259072,-1737350784}, + {-1231746176,-1759115520}, + {-1200857344,-1780344704}, + {-1169603584,-1801031424}, + {-1137993088,-1821169152}, + {-1106035712,-1840752768}, + {-1073742080,-1859775360}, + {-1041120448,-1878231552}, + {-1008182592,-1896115584}, + {-974937408,-1913421952}, + {-941394752,-1930145664}, + {-907565888,-1946281216}, + {-873460416,-1961823872}, + {-839088832,-1976769280}, + {-804461568,-1991112320}, + {-769589184,-2004848896}, + {-734482560,-2017974528}, + {-699152192,-2030485760}, + {-663608960,-2042378240}, + {-627863424,-2053648768}, + {-591926784,-2064293760}, + {-555809600,-2074309888}, + {-519523328,-2083694208}, + {-483078592,-2092443904}, + {-446486976,-2100556032}, + {-409759200,-2108028416}, + {-372906656, -2114858496}, + { -335940320,-2121044736 }, + { -298871968,-2126584576 }, + { -261712336,-2131476480 }, + { -224473248,-2135719552 }, + { -187165584,-2139311872 }, + { -149800896,-2142252544 }, + { -112390576,-2144540544 }, + { -74946016,-2146175360 }, + { -37478636,-2147156608 }, + { -93,-2147483648 }, + { 37478700,-2147156608 }, + { 74946104,-2146175360 }, + { 112390640,-2144540544 }, + { 149800960,-2142252544 }, + { 187165648,-2139311872 }, + { 224473024,-2135719552 }, + { 261712336,-2131476480 }, + { 298871968,-2126584576 }, + { 335940544,-2121044736 }, + { 372906656,-2114858496 }, + { 409759008,-2108028416 }, + { 446486976,-2100556032 }, + { 483078592,-2092443904 }, + { 519523328,-2083694208 }, + { 555809792,-2074309888 }, + { 591926784,-2064293760 }, + { 627863424,-2053648896 }, + { 663608960,-2042378240 }, + { 699152192,-2030485760 }, + { 734482816,-2017974528 }, + { 769589440,-2004848640 }, + { 804461568,-1991112320 }, + { 839088640,-1976769280 }, + { 873460224,-1961824000 }, + { 907565696,-1946281216 }, + { 941395008,-1930145664 }, + { 974937152,-1913421952 }, + { 1008182592,-1896115584 }, + { 1041120704,-1878231552 }, + { 1073741824,-1859775360 }, + { 1106035840,-1840752768 }, + { 1137993088,-1821169408 }, + { 1169603328,-1801031424 }, + { 1200857600,-1780344448 }, + { 1231746176,-1759115776 }, + { 1262259072,-1737350784 }, + { 1292387840,-1715056640 }, + { 1322123008,-1692240128 }, + { 1351455232,-1668908288 }, + { 1380375808,-1645067776 }, + { 1408876032,-1620726272 }, + { 1436947072,-1595891584 }, + { 1464580352,-1570570112 }, + { 1491767552,-1544770432 }, + { 1518500352,-1518500352 }, + { 1544770432,-1491767552 }, + { 1570570112,-1464580224 }, + { 1595891328,-1436947072 }, + { 1620726528,-1408876032 }, + { 1645067776,-1380375808 }, + { 1668908288,-1351455232 }, + { 1692240256,-1322123008 }, + { 1715056640,-1292387840 }, + { 1737350784,-1262259072 }, + { 1759115776,-1231746176 }, + { 1780344704,-1200857600 }, + { 1801031424,-1169603584 }, + { 1821169408,-1137993088 }, + { 1840752768,-1106035840 }, + { 1859775360,-1073741824 }, + { 1878231552,-1041120704 }, + { 1896115584,-1008182592 }, + { 1913421952,-974937152 }, + { 1930145664,-941395008 }, + { 1946281216,-907565888 }, + { 1961823872,-873460224 }, + { 1976769280,-839088640 }, + { 1991112320,-804461568 }, + { 2004848640,-769589184 }, + { 2017974528,-734482560 }, + { 2030485760,-699152192 }, + { 2042378240,-663608960 }, + { 2053648896,-627863424 }, + { 2064293760,-591926784 }, + { 2074309888,-555809600 }, + { 2083694208,-519523328 }, + { 2092443904,-483078592 }, + { 2100556032,-446486976 }, + { 2108028416,-409759200 }, + { 2114858496,-372906656 }, + { 2121044736,-335940544 }, + { 2126584576,-298871968 }, + { 2131476480,-261712336 }, + { 2135719552,-224473248 }, + { 2139311872,-187165520 }, + { 2142252544,-149800880 }, + { 2144540544,-112390616 }, + { 2146175360,-74946104 }, + { 2147156608,-37478764 }, + { 2147483647,0 } }; #endif /*----------------------------------------------------------------------------------* * FB ROM tables @@ -8712,4 +8902,19 @@ const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9] = } }; +const Word32 one_by_q_level[64] = +{ 0, 2147483647, 1073741824, 715827904, 536870912, 429496736, +357913952, 306783392, 268435456, 238609296, 214748368, +195225792, 178956976, 165191056, 153391696, 143165584, +134217728, 126322568, 119304648, 113025456, 107374184, +102261128, 97612896, 93368856, 89478488, 85899344, +82595528, 79536432, 76695848, 74051160, 71582792, +69273664, 67108864, 65075264, 63161284, 61356676, +59652324, 58040100, 56512728, 55063684, 53687092, +52377648, 51130564, 49941480, 48806448, 47721860, +46684428, 45691140, 44739244, 43826196, 42949672, +42107524, 41297764, 40518560, 39768216, 39045156, +38347924, 37675152, 37025580, 36398028, 35791396, +35204648, 34636832, 34087044 }; + /* clang-format on */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index 48073c7d8..c271edabd 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -215,11 +215,12 @@ extern const int16_t HOA_keep_ind_spar[IVAS_SPAR_MAX_CH]; extern const int16_t HOA_keep_ind_spar512[IVAS_SPAR_MAX_CH]; extern const float dtx_pd_real_min_max[2]; +extern const Word32 dtx_pd_real_min_max_fx[2]; extern const int16_t dtx_pd_real_q_levels[3][3]; extern const int16_t dtx_pr_real_q_levels[3][3]; extern const int16_t pr_pr_idx_pairs[3][3][2]; extern const int16_t pr_pd_idx_pairs[3][3][2]; - +extern const Word32 one_by_q_level[64]; /*----------------------------------------------------------------------* * PCA ROM tables @@ -474,8 +475,10 @@ extern const float dirac_gains_Pnm[91][9]; extern const float dirac_gains_trg_term[181][2]; #ifdef IVAS_FLOAT_FIXED extern const Word32 dirac_gains_norm_term_int[9]; +extern const Word32 dirac_gains_norm_term_fx[9]; extern const Word32 dirac_gains_Pnm_int[91][9]; extern const Word32 dirac_gains_trg_term_int[181][2]; +extern const Word32 dirac_gains_trg_term_fx[181][2]; #endif /*------------------------------------------------------------------------------------------* * FB ROM tables diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 5fcfd9ed7..dc967e9fe 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -33,8 +33,11 @@ #include #include "math.h" #include "options.h" +#include "basop_util.h" #include "ivas_stat_com.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -50,14 +53,19 @@ *------------------------------------------------------------------------------------------*/ #define IVAS_FLT_EPS ( 1e-10F ) +#define IVAS_FIX_EPS ( 1 ) #define IVAS_DBL_EPS ( (double) 1e-20 ) #define IVAS_REMIX_MULT_FAC ( 0.5f ) #define IVAS_ACTIVEW_DM_F ( 1.0f ) +#define IVAS_ACTIVEW_DM_F_Q30 ( ONE_IN_Q30 ) #define IVAS_ACTIVEW_DM_F_DTX ( 0.25f ) +#define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) #define IVAS_ACTIVEW_DM_F_VLBR ( 0.25f ) +#define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) #define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH ( 3.0f ) +#define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29 ( 1610612736 ) #define IVAS_P_NORM_SCALING ( 1.0f ) #define IVAS_P_NORM_SCALING_DTX ( 0.75f ) @@ -73,7 +81,21 @@ static void ivas_get_pred_coeffs( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], const int16_t in_chans, const int16_t start_band, const int16_t end_band, const int16_t active_w, const int16_t active_w_vlbr, const int16_t dtx_vad, const int16_t from_dirac, const int16_t dyn_active_w_flag, const int16_t res_ind ); - +static void ivas_get_pred_coeffs_fx( + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + const Word16 in_chans, + const Word16 start_band, + const Word16 end_band, + const Word16 active_w, + const Word16 active_w_vlbr, + const Word16 dtx_vad, + const Word16 from_dirac, + const Word16 dyn_active_w_flag, + const Word16 res_ind, + Word16 *q_pred_coeffs, + Word16 *q_dm_fv_re ); static void ivas_reorder_array( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS], const int16_t in_chans, const int16_t order[IVAS_SPAR_MAX_CH], float ***mixer_mat, const int16_t start_band, const int16_t end_band ); static void ivas_get_Wscaling_factor( float *pppCov_mat_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], float ***mixer_mat, const int16_t start_band, const int16_t end_band, const int16_t dtx_vad, const int16_t num_ch, const int16_t *pNum_dmx, const int16_t bands_bw, const int16_t active_w, const int16_t active_w_vlbr, float *pWscale, const int16_t dyn_active_w_flag ); @@ -248,37 +270,37 @@ Word16 ivas_get_spar_table_idx_fx( Word16 table_idx = 0, ind1[IVAS_SPAR_BR_TABLE_LEN]; Word16 i, j = 0, ind2 = -1; - FOR (i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++) + FOR( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ ) { ind1[j] = 0; - IF ((EQ_32(ivas_spar_br_table_consts[i].ivas_total_brate , ivas_total_brate)) && - (EQ_16(ivas_spar_br_table_consts[i].sba_order , sba_order))) + IF( ( EQ_32( ivas_spar_br_table_consts[i].ivas_total_brate, ivas_total_brate ) ) && + ( EQ_16( ivas_spar_br_table_consts[i].sba_order, sba_order ) ) ) { ind1[j++] = i; } } - FOR (i = 0; i < j; i++) + FOR( i = 0; i < j; i++ ) { - IF (EQ_16(ivas_spar_br_table_consts[ind1[i]].bwidth , bwidth)) + IF( EQ_16( ivas_spar_br_table_consts[ind1[i]].bwidth, bwidth ) ) { ind2 = i; BREAK; } } - assert(j > 0); /* to check if bitrate entry is present */ - assert(ind2 >= 0); /* to check if bw entry is present */ + assert( j > 0 ); /* to check if bitrate entry is present */ + assert( ind2 >= 0 ); /* to check if bw entry is present */ table_idx = ind1[ind2]; - IF (ind != NULL) + IF( ind != NULL ) { *ind = ind2; } - IF (bitlen != NULL) + IF( bitlen != NULL ) { - *bitlen = ivas_get_bits_to_encode(j - 1); + *bitlen = ivas_get_bits_to_encode( j - 1 ); } return table_idx; @@ -313,7 +335,7 @@ Word16 ivas_get_sba_num_TCs_fx( { Word16 table_idx, nchan_transport; - table_idx = ivas_get_spar_table_idx_fx(ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL); + table_idx = ivas_get_spar_table_idx_fx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport; @@ -533,6 +555,396 @@ static void ivas_get_pred_coeffs( return; } +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_get_pred_coeffs_fx() + * + * Calculation of prediction coefficients + *-----------------------------------------------------------------------------------------*/ + +static void ivas_get_pred_coeffs_fx( + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + const Word16 in_chans, + const Word16 start_band, + const Word16 end_band, + const Word16 active_w, + const Word16 active_w_vlbr, + const Word16 dtx_vad, + const Word16 from_dirac, + const Word16 dyn_active_w_flag, + const Word16 res_ind, + Word16 *q_pred_coeffs, + Word16 *q_dm_fv_re ) +{ + Word16 i, j, k, b, p; + Word32 abs_value; + Word32 w_norm_fac; + Word32 one_in_q; + Word32 div_factor[IVAS_MAX_NUM_BANDS]; + Word16 pred_dim = sub( in_chans, 1 ); + Word16 tmp_shift, prev_tmp_shift, s_div, div_shift; + + w_norm_fac = EQ_16( from_dirac, 1 ) ? ONE_IN_Q29 : 3 * ONE_IN_Q29; // Q29 + tmp_shift = Q30; + IF( EQ_16( active_w, 0 ) ) + { + Word32 pPred_temp[IVAS_MAX_NUM_BANDS]; + Word16 q_pred_temp; + prev_tmp_shift = 31; + + set32_fx( pPred_temp, 0, IVAS_MAX_NUM_BANDS ); + FOR( k = start_band; k < end_band; k++ ) + { + div_factor[k] = L_max( 1, cov_real[0][0][k] ); + tmp_shift = Q30; + IF( NE_32( cov_real[0][0][k], ONE_IN_Q30 ) ) + { + div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, div_factor[k], &s_div ) ); + if ( LT_16( s_div, 0 ) ) + { + div_shift = 15 + ( s_div ); + tmp_shift = Q30; + } + else + { + div_shift = 15; + tmp_shift = Q30 - s_div; + } + div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift + + IF( LT_16( tmp_shift, prev_tmp_shift ) ) + { + FOR( p = start_band; p < k; p++ ) + { + div_factor[p] = L_shr( div_factor[p], prev_tmp_shift - tmp_shift ); + } + prev_tmp_shift = tmp_shift; + } + ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) ) + { + div_factor[k] = L_shr( div_factor[k], tmp_shift - prev_tmp_shift ); + tmp_shift = prev_tmp_shift; + } + } + } + + FOR( i = 0; i < pred_dim; i++ ) + { + FOR( k = start_band; k < end_band; k++ ) + { + ppPred_coeffs_re[i][k] = Mpy_32_32( cov_real[i + 1][0][k], div_factor[k] ); // Q30 + temp_shift - 31 => tmp_shift - 1 + + // IVAS_CALCULATE_SQ_ABS_N( ppPred_coeffs_re[i][k], abs_value ); + abs_value = Mpy_32_32( ppPred_coeffs_re[i][k], ppPred_coeffs_re[i][k] ); // Q = 2*tmp_shift - 2 - 31 + + pPred_temp[k] = L_add( pPred_temp[k], abs_value ); // Q= 2*tmp_shift - 2 - 31 + } + } + *q_pred_coeffs = tmp_shift - 1; + FOR( k = start_band; k < end_band; k++ ) + { + q_pred_temp = 31 - ( 2 * ( *q_pred_coeffs ) - 31 ); + pPred_temp[k] = Sqrt32( pPred_temp[k], &q_pred_temp ); + + IF( LT_16( q_pred_temp, 1 ) ) + { + pPred_temp[k] = L_shr( pPred_temp[k], abs_s( q_pred_temp ) + 1 ); // Q30 + q_pred_temp = 1; + } + ELSE IF( GT_16( q_pred_temp, 1 ) ) + { + pPred_temp[k] = L_shl( pPred_temp[k], abs_s( q_pred_temp ) - 1 ); // Q30 + q_pred_temp = 1; + } + + one_in_q = L_shl( 1, ( 31 - q_pred_temp ) ); + + IF( LT_32( one_in_q, pPred_temp[k] ) ) + { + div_factor[k] = pPred_temp[k]; + + div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( one_in_q, div_factor[k], &s_div ) ); + if ( LT_16( s_div, 0 ) ) + { + div_shift = 15 + ( s_div ); + tmp_shift = Q30; + } + else + { + div_shift = 15; + tmp_shift = Q30 - s_div; + } + div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift + } + ELSE + { + div_factor[k] = one_in_q; + tmp_shift = ( 31 - q_pred_temp ); + } + + IF( LT_16( tmp_shift, prev_tmp_shift ) ) + { + FOR( p = start_band; p < k; p++ ) + { + div_factor[p] = L_shr( div_factor[p], prev_tmp_shift - tmp_shift ); + } + prev_tmp_shift = tmp_shift; + } + ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) ) + { + div_factor[k] = L_shr( div_factor[k], tmp_shift - prev_tmp_shift ); + tmp_shift = prev_tmp_shift; + } + } + + FOR( i = 0; i < pred_dim; i++ ) + { + FOR( k = start_band; k < end_band; k++ ) + { + ppPred_coeffs_re[i][k] = Mpy_32_32( ppPred_coeffs_re[i][k], div_factor[k] ); // Q = q_pred_coeffs + tmp_shift -31 + ppDM_Fv_re[i][k] = 0; + } + } + *q_pred_coeffs = *q_pred_coeffs + tmp_shift - 31; + *q_dm_fv_re = 0; + } + ELSE + { + Word32 dm_alpha[IVAS_MAX_NUM_BANDS], dm_v_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + Word32 real[IVAS_SPAR_MAX_CH - 1], dm_beta_re = 0, dm_g[IVAS_MAX_NUM_BANDS]; + Word32 dm_f_local, dm_w, dm_y, DM_F[IVAS_MAX_NUM_BANDS]; + Word32 num_f, den_f, passive_g /*, inv_den_f*/; + Word32 activew_quad_thresh, g_th_sq; + Word32 L_tmp1, L_tmp2; + Word16 L_tmp2_q; + Word16 dm_alpha_e, den_f_e, s_dm_f; + prev_tmp_shift = 31; + dm_alpha_e = 0; + + IF( EQ_16( dyn_active_w_flag, 1 ) ) + { + activew_quad_thresh = ONE_IN_Q29; + } + ELSE + { + activew_quad_thresh = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29; + } + g_th_sq = Mpy_32_32( activew_quad_thresh, activew_quad_thresh ); // Q27 + + set32_fx( dm_alpha, 0, IVAS_MAX_NUM_BANDS ); + + FOR( i = 1; i < in_chans; i++ ) + { + FOR( k = start_band; k < end_band; k++ ) + { + // IVAS_CALCULATE_SQ_ABS_N( cov_real[i][0][k], abs_value ); + abs_value = Mpy_32_32( cov_real[i][0][k], cov_real[i][0][k] ); // Q29 + dm_alpha[k] = L_add( dm_alpha[k], abs_value ); // Q29 + } + } + + FOR( k = start_band; k < end_band; k++ ) + { + dm_alpha_e = 31 - Q29; + dm_alpha[k] = Sqrt32( dm_alpha[k], &dm_alpha_e ); + IF( LT_16( dm_alpha_e, 0 ) ) + { + dm_alpha[k] = L_shr( dm_alpha[k], abs_s( dm_alpha_e ) ); + dm_alpha_e = 0; + } + ELSE IF( GT_16( dm_alpha_e, 0 ) ) + { + dm_alpha[k] = L_shl( dm_alpha[k], abs_s( dm_alpha_e ) ); + dm_alpha_e = 0; + } + div_factor[k] = L_max( dm_alpha[k], 1 ); + + div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, div_factor[k], &s_div ) ); + if ( LT_16( s_div, 0 ) ) + { + div_shift = 15 + ( s_div ); + tmp_shift = Q30; + } + else + { + div_shift = 15; + tmp_shift = Q30 - s_div; + } + div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift + + IF( LT_16( tmp_shift, prev_tmp_shift ) ) + { + FOR( p = start_band; p < k; p++ ) + { + div_factor[p] = L_shr( div_factor[p], prev_tmp_shift - tmp_shift ); + } + prev_tmp_shift = tmp_shift; + } + ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) ) + { + div_factor[k] = L_shr( div_factor[k], tmp_shift - prev_tmp_shift ); + tmp_shift = prev_tmp_shift; + } + } + + FOR( i = 0; i < pred_dim; i++ ) + { + FOR( k = start_band; k < end_band; k++ ) + { + dm_v_re[i][k] = Mpy_32_32( cov_real[i + 1][0][k], div_factor[k] ); // Q30 + Qb - 31 = tmp_shift - 1 + } + } + + IF( EQ_16( dtx_vad, 0 ) ) + { + dm_f_local = IVAS_ACTIVEW_DM_F_DTX_Q30; + } + ELSE + { + dm_f_local = ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_VLBR_Q30 : IVAS_ACTIVEW_DM_F_Q30; + } + + FOR( b = start_band; b < end_band; b++ ) + { + set32_fx( real, 0, pred_dim ); + + FOR( j = 0; j < pred_dim; j++ ) + { + FOR( k = 1; k < in_chans; k++ ) + { + Word32 re; + + // IVAS_RMULT_FLOAT( cov_real[j + 1][k][b], dm_v_re[k - 1][b], re ); + re = Mpy_32_32( cov_real[j + 1][k][b], dm_v_re[k - 1][b] ); // Q30 + Q_div_factor - 1 - 31 + real[j] = L_add( real[j], re ); // tmp_shift - 2 + } + } + dm_beta_re = 0; + FOR( k = 0; k < pred_dim; k++ ) + { + Word32 re; + // IVAS_RMULT_FLOAT( real[k], dm_v_re[k][b], re ); + re = Mpy_32_32( real[k], dm_v_re[k][b] ); // Q = 2*tmp_shift - 3 - 31 + dm_beta_re = L_add( dm_beta_re, re ); // Q = 2*tmp_shift - 3 - 31 + } + + dm_w = cov_real[0][0][b]; // Q30 + den_f = L_max( dm_w, 1 ); + passive_g = L_deposit_l( BASOP_Util_Divide3232_Scale( dm_alpha[b], den_f, &s_div ) ); + + div_shift = 15 - ( 31 - dm_alpha_e - Q30 ) + s_div - 1; + passive_g = L_shl( passive_g, div_shift ); // Q = 29 + + IF( EQ_16( dyn_active_w_flag, 1 ) ) + { + dm_alpha[b] = 0; + dm_w = 0; + FOR( i = 0; i < pred_dim; i++ ) + { + dm_v_re[i][b] = 0; + } + IF( NE_16( sub( tmp_shift, 1 ), 31 ) ) + { + dm_v_re[res_ind - 1][b] = L_shl( 1, sub( tmp_shift, 1 ) ); + } + ELSE + { + dm_v_re[res_ind - 1][b] = MAX_32; + } + passive_g = activew_quad_thresh; + } + + IF( LT_32( passive_g, activew_quad_thresh ) ) + { + /*linear activeW*/ + dm_y = 0; + + FOR( k = 1; k < in_chans; k++ ) + { + dm_y = L_add( dm_y, L_shr( cov_real[k][k][b], 2 ) ); // Q28 + } + den_f = L_max( dm_y, 1 ); // Q28 + den_f = L_max( den_f, Mpy_32_32( w_norm_fac, dm_w ) ); // Q28 + + DM_F[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( Mpy_32_32( dm_f_local, dm_alpha[b] ), den_f, &s_div ) ); // Q30 + 31 - dm_alpha_e - 31 + den_f_e - 31 => den_f_e - dm_alpha_e - 1 + + div_shift = 15 - ( 30 - (dm_alpha_e) -28 ) + s_div; + + DM_F[b] = L_shl( DM_F[b], div_shift ); // Q30 + + DM_F[b] = L_min( ONE_IN_Q30, DM_F[b] ); + + L_tmp1 = L_add( L_shr( dm_w, 1 ), Mpy_32_32( dm_alpha[b], DM_F[b] ) ); /* Q 29*/ + L_tmp2 = Mpy_32_32( Mpy_32_32( DM_F[b], DM_F[b] ), dm_beta_re ); + L_tmp2_q = 29 + 2 * tmp_shift - 65; // simplified equation for calculating Q of L_tmp2 + L_tmp2 = L_shl( L_tmp2, ( 29 - L_tmp2_q ) ); + + den_f = L_add( L_tmp1, L_tmp2 ); // Q29 + den_f = L_max( den_f, 1 ); + + den_f_e = 29; + L_tmp2 = Mpy_32_32( DM_F[b], dm_beta_re ); + L_tmp2_q = 30 + 2 * tmp_shift - 34 - 31; + L_tmp2 = L_shl( L_tmp2, ( 30 - dm_alpha_e - L_tmp2_q ) ); + L_tmp1 = L_shr( dm_alpha[b], ( 31 - dm_alpha_e - 30 ) ); + L_tmp1 = L_add( L_tmp1, L_tmp2 ); // Q30 + + dm_g[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( L_tmp1, den_f, &s_div ) ); // Q30 + den_f_e - 31 + div_shift = 15 - ( 30 - ( den_f_e ) ) + s_div; + dm_g[b] = L_shl( dm_g[b], div_shift ); // Q30 + } + ELSE + { + Word32 sqrt_val; + Word16 val_e; + + /* quadratic activeW */ + + num_f = L_sub( dm_beta_re, L_shl( Mpy_32_32( dm_alpha[b], activew_quad_thresh ), 1 ) ); + + sqrt_val = L_shl( Mpy_32_32( Mpy_32_32( dm_alpha[b], dm_alpha[b] ), g_th_sq ), 2 ); + sqrt_val = L_add( sqrt_val, Mpy_32_32( dm_beta_re, dm_beta_re ) ); + sqrt_val = L_sub( sqrt_val, L_shl( Mpy_32_32( Mpy_32_32( dm_beta_re, g_th_sq ), dm_w ), 2 ) ); + val_e = norm_l( sqrt_val ); + sqrt_val = Sqrt32( sqrt_val, &val_e ); + IF( LT_16( val_e, 0 ) ) + { + sqrt_val = L_shr( sqrt_val, abs_s( val_e ) ); + } + ELSE IF( GT_16( val_e, 0 ) ) + { + sqrt_val = L_shl( sqrt_val, abs_s( val_e ) ); + val_e = 0; + } + num_f = L_add( num_f, sqrt_val ); + + den_f = L_shl( Mpy_32_32( dm_beta_re, g_th_sq ), 1 ); + den_f = L_max( den_f, 1 ); + dm_g[b] = activew_quad_thresh; // Q29 + DM_F[b] = BASOP_Util_Divide3232_Scale( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); + div_shift = 15 - ( 29 - ( 31 ) ) + s_dm_f; + DM_F[b] = L_shl( DM_F[b], div_shift ); // Q30 + } + } + + FOR( i = 0; i < pred_dim; i++ ) + { + FOR( b = start_band; b < end_band; b++ ) + { + ppPred_coeffs_re[i][b] = Mpy_32_32( dm_v_re[i][b], dm_g[b] ); // Q = tmp_shift - 1 + 30 - 31 + ppDM_Fv_re[i][b] = Mpy_32_32( dm_v_re[i][b], DM_F[b] ); + } + } + *q_pred_coeffs = tmp_shift - 2; + *q_dm_fv_re = tmp_shift - 2; + } + + return; +} +#endif // IVAS_FLOAT_FIXED + /*-----------------------------------------------------------------------------------------* * Function ivas_get_Wscaling_factor() @@ -850,6 +1262,7 @@ static void ivas_calc_p_coeffs_per_band( if ( num_dmx != num_ch ) { set_zero( pSparMd->band_coeffs[b_ts_idx].P_re, IVAS_SPAR_MAX_CH - 1 ); + set32_fx( pSparMd->band_coeffs[b_ts_idx].P_re_fx, 0, IVAS_SPAR_MAX_CH - 1 ); for ( i = 0; i < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; i++ ) { set_zero( recon_uu_re[i], IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ); @@ -1160,6 +1573,7 @@ void ivas_calc_c_p_coeffs( for ( i = num_dmx; i < num_ch; i++ ) { pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re[i - num_dmx] = 0; + pSparMd->band_coeffs[band_idx + i_ts * IVAS_MAX_NUM_BANDS].P_re_fx[i - num_dmx] = 0; } } } @@ -1452,14 +1866,106 @@ void ivas_compute_spar_params( return; } +#ifdef IVAS_FLOAT_FIXED +void ivas_compute_spar_params_fx( + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], + const int16_t i_ts, + float ***mixer_mat, + const int16_t start_band, + const int16_t end_band, + const int16_t dtx_vad, + const int16_t num_ch, + const int16_t bands_bw, + const int16_t active_w, + const int16_t active_w_vlbr, + ivas_spar_md_com_cfg *hSparCfg, + ivas_spar_md_t *hSparMd, + float *pWscale, + const int16_t from_dirac, + const int16_t dyn_active_w_flag ) +{ + Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + float pred_coeffs_re_flt[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + float dm_fv_re_flt[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + + int16_t b, i, ndm; + int16_t q_pred_coeffs; + int16_t q_dm_fv_re; + float cov_real_flt[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][12]; + float *p_cov_real_flt[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + for ( i = 0; i < num_ch; i++ ) + { + for ( int j = 0; j < num_ch; j++ ) + { + for ( int k = 0; k < 12; k++ ) + { + cov_real_flt[i][j][k] = (float) cov_real[i][j][k] / ONE_IN_Q30; + } + p_cov_real_flt[i][j] = cov_real_flt[i][j]; + } + } + + ivas_get_pred_coeffs_fx( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind, &q_pred_coeffs, &q_dm_fv_re ); + + for ( b = start_band; b < end_band; b++ ) + { + for ( i = 0; i < num_ch - 1; i++ ) + { + pred_coeffs_re_flt[i][b] = (float) pred_coeffs_re[i][b] / ( 1 << q_pred_coeffs ); + dm_fv_re_flt[i][b] = (float) dm_fv_re[i][b] / ( 1 << q_dm_fv_re ); + } + } + + ivas_create_fullr_dmx_mat( pred_coeffs_re_flt, dm_fv_re_flt, mixer_mat, num_ch, start_band, end_band, active_w, hSparCfg ); + + ivas_get_Wscaling_factor( p_cov_real_flt, pred_coeffs_re_flt, mixer_mat, start_band, end_band, dtx_vad, num_ch, hSparCfg->num_dmx_chans_per_band, bands_bw, active_w, active_w_vlbr, pWscale, dyn_active_w_flag ); + + for ( b = start_band; b < end_band; b++ ) + { + float onebyscale = 1.0f / pWscale[b]; + Word32 onebyscale_fx = (Word32) ( onebyscale * ( (UWord32) 1 << ( 53 - q_pred_coeffs ) ) ); + for ( i = 0; i < num_ch - 1; i++ ) + { + hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[i] = pred_coeffs_re_flt[i][b] * onebyscale; + hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re_fx[i] = Mpy_32_32( pred_coeffs_re[i][b], onebyscale_fx ); // q_pred_coeffs + (53 - q_pred_coeffs) - 31 = Q22 + } + + for ( i = 0; i < num_ch; i++ ) + { + mixer_mat[0][i][b] *= pWscale[b]; + } + } + + for ( b = start_band; b < end_band; b++ ) + { + ndm = hSparCfg->num_dmx_chans_per_band[b * bands_bw]; + + if ( ndm != num_ch ) + { + ivas_calc_c_p_coeffs( hSparMd, p_cov_real_flt, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1, dyn_active_w_flag ); + } + } + + return; +} +#endif // IVAS_FLOAT_FIXED + /*-----------------------------------------------------------------------------------------* - * Function ivas_get_spar_md_from_dirac() + * Function ivas_get_spar_md_from_dirac_fx() * * *-----------------------------------------------------------------------------------------*/ - -void ivas_get_spar_md_from_dirac( +#ifdef IVAS_FLOAT_FIXED +Word32 diff_norm_order1_table[4] = { 0, 805306368, 402653184, 268435456 }; +Word32 diff_norm_order2_table[6] = { 0, 1342177280, 671088640, 447392416, 335544320, 268435456 }; +Word32 diff_norm_order3_table[8] = { 0, 1879048192, 939524096, 626349376, 469762048, 375809632, 313174688, 268435456 }; +#define EPSILON_FX_THR 70 +#define ONE_BY_THREE_Q31 715827882 +#define ONE_BY_FIVE_Q31 429496729 +#define ONE_BY_SEVEN_Q31 306783378 +void ivas_get_spar_md_from_dirac_fx( float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float diffuseness[IVAS_MAX_NUM_BANDS], @@ -1476,22 +1982,49 @@ void ivas_get_spar_md_from_dirac( const int16_t active_w_vlbr, const int16_t dyn_active_w_flag ) { + + Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS]; + for ( int i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) + { + for ( int j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ ) + { + azi_dirac_fx[i][j] = azi_dirac[i][j] * ( 1 << 22 ); + ele_dirac_fx[i][j] = ele_dirac[i][j] * ( 1 << 22 ); + } + diffuseness_fx[i] = diffuseness[i] * ( 1 << 30 ); + } + int16_t num_ch, band, i, j; int16_t block, ch; - float response_avg[MAX_OUTPUT_CHANNELS]; - float response[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS]; - float cov_real_dirac[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - float *pCov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + + + //float response_avg[MAX_OUTPUT_CHANNELS]; + Word32 response_avg_fx[MAX_OUTPUT_CHANNELS]; + //float response[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS]; + Word32 response_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS]; + //float cov_real_dirac[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + Word32 cov_real_dirac_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + //float *pCov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word32 *pCov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + //float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + Word32 dm_fv_re_fx[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float Wscale[IVAS_MAX_NUM_BANDS]; + Word32 Wscale_fx[IVAS_MAX_NUM_BANDS]; float mixer_mat_local[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; + Word32 mixer_mat_local_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; float **ppMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH]; + Word32 **ppMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH]; float *pMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; - float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3; + Word32 *pMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; + //float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3; + Word32 en_ratio_fac_fx, diff_norm_order1_fx, diff_norm_order2_fx, diff_norm_order3_fx; int16_t active_w; int16_t ndm, foa_ch, hoa2_ch; float P_dir_fact[IVAS_SPAR_MAX_CH - 1]; + Word32 P_dir_fact_fx[IVAS_SPAR_MAX_CH - 1]; const int16_t *remix_order; remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order]; @@ -1499,65 +2032,117 @@ void ivas_get_spar_md_from_dirac( num_ch = ivas_sba_get_nchan_metadata( order, IVAS_256k /*dummy value as order is always 1 in this function*/ ); hoa2_ch = ivas_sba_get_nchan_metadata( SBA_HOA2_ORDER, IVAS_256k /*dummy value as order is always 1 in this function*/ ); - + // hoa2_ch max 6 foa_ch = FOA_CHANNELS; - diff_norm_order1 = 3.0f; - diff_norm_order2 = 5.0f; - diff_norm_order3 = 7.0f; + // foa_ch 4; + //diff_norm_order1 = 3.0f; + diff_norm_order1_fx = 3; + //diff_norm_order2 = 5.0f; + diff_norm_order2_fx = 5; + //diff_norm_order3 = 7.0f; + diff_norm_order3_fx = 7; for ( i = 0; i < IVAS_MAX_FB_MIXER_OUT_CH; i++ ) { for ( j = 0; j < IVAS_MAX_SPAR_FB_MIXER_IN_CH; j++ ) { pMixer_mat[i][j] = mixer_mat_local[i][j]; + pMixer_mat_fx[i][j] = mixer_mat_local_fx[i][j]; } ppMixer_mat[i] = pMixer_mat[i]; + ppMixer_mat_fx[i] = pMixer_mat_fx[i]; } if ( ( start_band >= 6 && hSpar_md_cfg->nchan_transport <= 2 && ( dtx_vad == 1 ) ) || ( useLowerRes && start_band >= 3 && hSpar_md_cfg->nchan_transport <= 2 && ( dtx_vad == 1 ) ) ) { float P_norm[3]; + Word32 P_norm_fx[3]; int16_t idx; ndm = hSpar_md_cfg->num_dmx_chans_per_band[start_band - 1]; + // ndm max value of 4 P_norm[0] = 0.0f; + P_norm_fx[0] = 0; for ( i = 0; i < max( 0, foa_ch - ndm ); i++ ) { + // use 64bit if low precission P_norm[0] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_norm_fx[0] = P_norm_fx[0] + Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); } - P_norm[0] *= diff_norm_order1 / min( diff_norm_order1, max( 0, foa_ch - ndm ) ); + //P_norm[0] *= diff_norm_order1 / min( diff_norm_order1, max( 0, foa_ch - ndm ) ); + // P_norm_fx[0] *= diff_norm_order1 / min( diff_norm_order1, max( 0, foa_ch - ndm ) ); + P_norm_fx[0] = Mpy_32_32( L_shl( P_norm_fx[0], 3 ), diff_norm_order1_table[min( diff_norm_order1_fx, max( 0, foa_ch - ndm ) )] ); P_norm[1] = 0.0f; + P_norm_fx[1] = 0; for ( ; i < max( 0, min( num_ch, hoa2_ch ) - ndm ); i++ ) { P_norm[1] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_norm_fx[1] = P_norm_fx[1] + Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); } - P_norm[1] *= diff_norm_order2 / min( diff_norm_order2, max( 0, min( num_ch, hoa2_ch ) - ndm ) ); + //P_norm[1] *= diff_norm_order2 / min( diff_norm_order2, max( 0, min( num_ch, hoa2_ch ) - ndm ) ); + // P_norm_fx[1] *= diff_norm_order2 / min( diff_norm_order2, max( 0, min( num_ch, hoa2_ch ) - ndm ) ); + P_norm_fx[1] = Mpy_32_32( L_shl( P_norm_fx[1], 3 ), diff_norm_order2_table[min( diff_norm_order2_fx, max( 0, min( num_ch, hoa2_ch ) - ndm ) )] ); + P_norm[2] = 0.0f; + P_norm_fx[2] = 0; for ( ; i < num_ch - ndm; i++ ) { P_norm[2] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_norm_fx[2] = P_norm_fx[2] + Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); } - P_norm[2] *= diff_norm_order3 / min( diff_norm_order3, max( 0, num_ch - ndm ) ); + //P_norm[2] *= diff_norm_order3 / min( diff_norm_order3, max( 0, num_ch - ndm ) ); + // P_norm_fx[2] *= diff_norm_order3 / min( diff_norm_order3, max( 0, num_ch - ndm ) ); + P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, num_ch - ndm ) )] ); for ( i = 0; i < max( 0, foa_ch - ndm ); i++ ) { idx = remix_order[i + ndm] - ndm; P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[0] ); + if ( P_dir_fact_fx[idx] == 0 ) + { + P_dir_fact_fx[idx] = 0; + } + else + { + P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], max( P_norm_fx[0], IVAS_FIX_EPS ) ); + P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); + } } for ( ; i < max( 0, min( num_ch, hoa2_ch ) - ndm ); i++ ) { idx = remix_order[i + ndm] - ndm; P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact_fx[idx] = ( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[1] ); + if ( P_dir_fact_fx[idx] == 0 ) + { + P_dir_fact_fx[idx] = 0; + } + else + { + P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], max( P_norm_fx[1], IVAS_FIX_EPS ) ); + P_dir_fact_fx[idx] = L_shl(P_dir_fact_fx[idx], 15); + } } for ( ; i < num_ch - ndm; i++ ) { idx = remix_order[i + ndm] - ndm; P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact_fx[idx] = ( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[2] ); + if ( P_dir_fact_fx[idx] == 0 ) + { + P_dir_fact_fx[idx] = 0; + } + else + { + P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], max( P_norm_fx[2], IVAS_FIX_EPS ) ); + P_dir_fact_fx[idx] = L_shl(P_dir_fact_fx[idx], 15); + } } } @@ -1568,26 +2153,44 @@ void ivas_get_spar_md_from_dirac( ndm = hSpar_md_cfg->num_dmx_chans_per_band[band]; /*SPAR from DirAC*/ - set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); + //set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); + set32_fx( response_avg_fx, 0, MAX_OUTPUT_CHANNELS ); if ( n_ts > 1 ) { - ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order ); + //ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order ); + ivas_dirac_dec_get_response_fx( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg_fx, order ); + /*for ( int l = 0; l < MAX_OUTPUT_CHANNELS; l++ ) + { + response_avg[l] = (float) response_avg_fx[l] / ( 1 << 30 ); + }*/ } else if ( useLowerRes ) { - ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][0], (int16_t) ele_dirac[band][0], response_avg, order ); + //ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][0], (int16_t) ele_dirac[band][0], response_avg, order ); + ivas_dirac_dec_get_response_fx( (int16_t) azi_dirac[band][0], (int16_t) ele_dirac[band][0], response_avg_fx, order ); + /*for ( int l = 0; l < MAX_OUTPUT_CHANNELS; l++ ) + { + response_avg[l] = (float) response_avg_fx[l] / ( 1 << 30 ); + }*/ } else { for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { - ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][block], (int16_t) ele_dirac[band][block], &( response[block][0] ), order ); + //ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][block], (int16_t) ele_dirac[band][block], &( response[block][0] ), order ); + ivas_dirac_dec_get_response_fx( (int16_t) azi_dirac[band][block], (int16_t) ele_dirac[band][block], &( response_fx[block][0] ), order ); + /*for ( int l = 0; l < MAX_OUTPUT_CHANNELS; l++ ) + { + response[block][l] = (float) response_fx[block][l] / ( 1 << 30 ); + }*/ } /* average responses in all subframes*/ { float norm; + Word32 norm_fx; + Word16 norm_q; int16_t num_ch_order, hoa2_ch_order; num_ch_order = ivas_sba_get_nchan( order, 0 ); @@ -1595,57 +2198,163 @@ void ivas_get_spar_md_from_dirac( for ( ch = 0; ch < num_ch_order; ch++ ) { + Word64 temp = 0; for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { - response_avg[ch] += response[block][ch]; + //response_avg[ch] += response[block][ch]; + temp = temp + response_fx[block][ch]; } - response_avg[ch] /= MAX_PARAM_SPATIAL_SUBFRAMES; + //response_avg[ch] /= MAX_PARAM_SPATIAL_SUBFRAMES; + response_avg_fx[ch] = W_shr( temp, 2 ); } /*normalize 1st order*/ norm = 0.0f; + norm_fx = 0; + norm_q = 0; for ( ch = 1; ch < foa_ch; ch++ ) { - norm += response_avg[ch] * response_avg[ch]; + //norm += response_avg[ch] * response_avg[ch]; + norm_fx = norm_fx + Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ); } + + norm_q = 31 - ( 30 + 30 - 31 ); norm = max( EPSILON, sqrtf( norm ) ); - for ( ch = 1; ch < foa_ch; ch++ ) + if ( norm_fx ) { - response_avg[ch] /= norm; + norm_fx = Sqrt32( norm_fx, &norm_q ); + } + else + { + norm_fx = EPSILON_FX; + } + if ( norm_q < 0 ) + { + norm_fx = L_shr( norm_fx, (-1 * norm_q) ); + norm_q = 0; + } + norm_fx = L_shr( norm_fx, 1 - norm_q ); + for ( ch = 1; ch < foa_ch; ch++ ) + { + //response_avg[ch] /= norm; + if ( norm_fx < EPSILON_FX_THR ) + { + if ( response_avg_fx[ch] != 0 ) + { + response_avg_fx[ch] = divide3232( response_avg_fx[ch], EPSILON_FX_THR ); + } + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + else if ( response_avg_fx[ch] > norm_fx ) + { + response_avg_fx[ch] = ONE_IN_Q30; + } + else + { + response_avg_fx[ch] = divide3232( response_avg_fx[ch], norm_fx ); + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + //response_avg[ch] = (float) response_avg_fx[ch] / ( 1 << 30 ); } /*normalize 2nd order*/ norm = 0.0f; + norm_fx = 0; for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) { - norm += response_avg[ch] * response_avg[ch]; + //norm += response_avg[ch] * response_avg[ch]; + norm_fx = norm_fx + Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ); } + norm_q = 31 - ( 29 + 29 - 31 ); norm = max( EPSILON, sqrtf( norm ) ); + if ( norm_fx ) + { + norm_fx = Sqrt32( norm_fx, &norm_q ); + } + else + { + norm_fx = EPSILON_FX; + } + if ( norm_q < 0 ) + { + norm_fx = L_shr( norm_fx, -1 * norm_q ); + norm_q = 0; + } + norm_fx = L_shr( norm_fx, 1 - norm_q ); for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) { - response_avg[ch] /= norm; + if ( norm_fx < EPSILON_FX_THR ) + { + response_avg_fx[ch] = response_avg_fx[ch]; + response_avg_fx[ch] = divide3232( response_avg_fx[ch], EPSILON_FX_THR ); + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + else if ( response_avg_fx[ch] > norm_fx ) + { + response_avg_fx[ch] = ONE_IN_Q30; + } + else + { + response_avg_fx[ch] = divide3232( response_avg_fx[ch], norm_fx ); + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + //response_avg[ch] = (float)response_avg_fx[ch] / (1 << 30); } /*normalize 3rd order*/ norm = 0.0f; for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ ) { - norm += response_avg[ch] * response_avg[ch]; + //norm += response_avg[ch] * response_avg[ch]; + norm_fx = norm_fx + Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ); } + norm_q = 31 - ( 29 + 29 - 31 ); norm = max( EPSILON, sqrtf( norm ) ); + if ( norm_fx ) + { + norm_fx = Sqrt32( norm_fx, &norm_q ); + } + else + { + norm_fx = EPSILON_FX; + } + if ( norm_q < 0 ) + { + norm_fx = L_shr( norm_fx, -1 * norm_q ); + norm_q = 0; + } + norm_fx = L_shr( norm_fx, 1 - norm_q ); for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ ) { - response_avg[ch] /= norm; + //response_avg[ch] /= norm; + if ( norm_fx < EPSILON_FX_THR ) + { + response_avg_fx[ch] = response_avg_fx[ch]; + response_avg_fx[ch] = divide3232( response_avg_fx[ch], EPSILON_FX_THR ); + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + else if ( response_avg_fx[ch] > norm_fx ) + { + response_avg_fx[ch] = ONE_IN_Q30; + } + else + { + response_avg_fx[ch] = divide3232( response_avg_fx[ch], norm_fx ); + response_avg_fx[ch] = L_shl( response_avg_fx[ch], 15 ); + } + //response_avg[ch] = (float) response_avg_fx[ch] / ( 1 << 30 ); } } } for ( i = FOA_CHANNELS + 1; i < num_ch; i++ ) { - response_avg[i] = response_avg[HOA_keep_ind[i]]; + //response_avg[i] = response_avg[HOA_keep_ind[i]]; + response_avg_fx[i] = response_avg_fx[HOA_keep_ind[i]]; } - en_ratio_fac = ( 1.0f - diffuseness[band] ); + //en_ratio_fac = ( 1.0f - diffuseness[band] ); + en_ratio_fac_fx = ( ONE_IN_Q31 - L_shl_sat(diffuseness_fx[band],1) );//assuming q of dissusion 30 for ( i = 0; i < num_ch; i++ ) { @@ -1655,33 +2364,49 @@ void ivas_get_spar_md_from_dirac( { if ( i == 0 ) { - cov_real_dirac[i][i][band] = 1.0f; + //cov_real_dirac[i][i][band] = 1.0f; + cov_real_dirac_fx[i][i][band] = ONE_IN_Q30; } else { - cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + Word32 en_ratio_fac_sq = 0; + //cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + cov_real_dirac_fx[i][j][band] = Mpy_32_32(L_shl_sat(Mpy_32_32(en_ratio_fac_fx, response_avg_fx[i]),1), response_avg_fx[j]); if ( hSpar_md_cfg->nchan_transport <= 2 ) { - cov_real_dirac[i][j][band] *= en_ratio_fac; + //cov_real_dirac[i][j][band] *= en_ratio_fac; + cov_real_dirac_fx[i][j][band] = Mpy_32_32(cov_real_dirac_fx[i][j][band],en_ratio_fac_fx); if ( ( i >= ndm ) && ( dtx_vad == 1 ) ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) * P_dir_fact[i - ndm]; + en_ratio_fac_sq = Mpy_32_32(en_ratio_fac_fx, en_ratio_fac_fx); + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_sq), P_dir_fact_fx[i - ndm]); + //cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) * P_dir_fact[i - ndm]; } else { if ( i < foa_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order1; + en_ratio_fac_sq = Mpy_32_32(en_ratio_fac_fx, en_ratio_fac_fx); + Word32 temp = Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_sq), ONE_BY_THREE_Q31); + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(temp, 1); + //cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order1; + } else if ( i < hoa2_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order2; + en_ratio_fac_sq = Mpy_32_32(en_ratio_fac_fx, en_ratio_fac_fx); + Word32 temp = Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_sq), ONE_BY_FIVE_Q31); + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(temp, 1); + //cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order2; } else { - cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order3; + en_ratio_fac_sq = Mpy_32_32(en_ratio_fac_fx, en_ratio_fac_fx); + Word32 temp = Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_sq), ONE_BY_SEVEN_Q31); + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(temp, 1); + //cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order3; } } } @@ -1689,22 +2414,26 @@ void ivas_get_spar_md_from_dirac( { if ( i < foa_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order1; + //cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order1; + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(Mpy_32_32(( ONE_IN_Q31 - en_ratio_fac_fx ), ONE_BY_THREE_Q31),1); } else if ( i < hoa2_ch ) { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order2; + //cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order2; + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_fx), ONE_BY_FIVE_Q31), 1); } else { - cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order3; + //cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order3; + cov_real_dirac_fx[i][j][band] = cov_real_dirac_fx[i][j][band] + L_shr(Mpy_32_32((ONE_IN_Q31 - en_ratio_fac_fx), ONE_BY_SEVEN_Q31), 1); } } } } else { - cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + //cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + cov_real_dirac_fx[i][j][band] = L_shl_sat(Mpy_32_32(Mpy_32_32(en_ratio_fac_fx, response_avg_fx[i]), response_avg_fx[j]), 1); } } } @@ -1714,14 +2443,35 @@ void ivas_get_spar_md_from_dirac( { for ( j = 0; j < num_ch; j++ ) { - pCov_real[i][j] = cov_real_dirac[i][j]; + //pCov_real[i][j] = cov_real_dirac[i][j]; + pCov_real_fx[i][j] = cov_real_dirac_fx[i][j]; } } - + static int frame_counter; + frame_counter++; + if (frame_counter > 500) + { + frame_counter = frame_counter; + } active_w = ( dyn_active_w_flag == 1 ) || ( hSpar_md_cfg->active_w == 1 ); +#ifdef IVAS_FLOAT_FIXED + ivas_compute_spar_params_fx( pCov_real_fx, dm_fv_re_fx, i_ts, ppMixer_mat, start_band, end_band, dtx_vad, num_ch, 1, active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale, 1, dyn_active_w_flag ); +#else + for (int i = 0; i < num_ch; i++) + { + for (int j = 0; j < num_ch; j++) + { + for (int k = start_band; k < end_band; k++) + { + cov_real_dirac[i][j][k] = (float)cov_real_dirac_fx[i][j][k] / (1 << 30); + } + } + } + ivas_compute_spar_params( pCov_real, dm_fv_re, i_ts, ppMixer_mat, start_band, end_band, dtx_vad, num_ch, 1, active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale, 1, dyn_active_w_flag ); +#endif // IVAS_FLOAT_FIXED if ( mixer_mat != NULL ) { @@ -1758,166 +2508,2611 @@ void ivas_get_spar_md_from_dirac( return; } - - -/*------------------------------------------------------------------------- - * ivas_dirac_dec_get_response() +#endif +/*-----------------------------------------------------------------------------------------* + * Function ivas_get_spar_md_from_dirac() * - * calculate reponse, 1 degree resolution - *------------------------------------------------------------------------*/ + * + *-----------------------------------------------------------------------------------------*/ -void ivas_dirac_dec_get_response( - const int16_t azimuth, - const int16_t elevation, - float *response, - const int16_t ambisonics_order ) +void ivas_get_spar_md_from_dirac( + float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + float diffuseness[IVAS_MAX_NUM_BANDS], + const int16_t n_ts, + float ***mixer_mat, + ivas_spar_md_t *hSpar_md, + ivas_spar_md_com_cfg *hSpar_md_cfg, + const int16_t start_band, + const int16_t end_band, + const int16_t order, + const int16_t dtx_vad, + float Wscale_d[IVAS_MAX_NUM_BANDS], + const uint8_t useLowerRes, + const int16_t active_w_vlbr, + const int16_t dyn_active_w_flag ) { - int16_t index_azimuth, index_elevation; - int16_t el, e, az; - float cos_1, cos_2, sin_1, cos_az[3]; - float sin_az[3]; - float f, c; - int16_t l, m; - int16_t b, b1, b_2, b1_2, a; - - index_azimuth = ( azimuth + 180 ) % 360; - index_elevation = elevation + 90; - e = index_elevation > 90 ? -1 : 1; - el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -1.0f : 1.0f; - - cos_1 = dirac_gains_trg_term[az][0]; - cos_2 = cos_1 * cos_1; - sin_1 = f * dirac_gains_trg_term[az][1]; - cos_az[0] = cos_1; - cos_az[1] = 2.0f * cos_2 - 1.0f; - cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; - sin_az[0] = sin_1; - sin_az[1] = sin_1 * 2.0f * cos_1; - sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); - - response[0] = 1.0f; - /* Un-optimized code - for reference */ - /* for( l = 1; l<= ambisonics_order; l++ ) */ - /* { */ - /* int16_t b, b1, a; */ - /* float c; */ - /* for( m = 0; m < l; m++ ) */ - /* { */ - /* b = l*l+m; */ - /* a = dirac_gains_P_idx[b]; */ - /* c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ - - /* if( m%2 == 1 ) */ - /* { */ - /* c = c*e; */ - /* } */ + int16_t num_ch, band, i, j; + int16_t block, ch; + float response_avg[MAX_OUTPUT_CHANNELS]; + float response[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS]; + float cov_real_dirac[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + float *pCov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; + float Wscale[IVAS_MAX_NUM_BANDS]; + float mixer_mat_local[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS]; + float **ppMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH]; + float *pMixer_mat[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; + float en_ratio_fac, diff_norm_order1, diff_norm_order2, diff_norm_order3; + int16_t active_w; - /* response[b] = c * sin_az[l-m-1]; */ + int16_t ndm, foa_ch, hoa2_ch; + float P_dir_fact[IVAS_SPAR_MAX_CH - 1]; + const int16_t *remix_order; - /* b1 = l*l+2*l-m; */ - /* response[b1] = c * cos_az[l-m-1]; */ + remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order]; - /* } */ + num_ch = ivas_sba_get_nchan_metadata( order, IVAS_256k /*dummy value as order is always 1 in this function*/ ); - /* b = l*l+l; */ - /* a = dirac_gains_P_idx[b]; */ - /* c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ - /* if( l%2 == 1) */ - /* { */ - /* c = c*e; */ - /* } */ + hoa2_ch = ivas_sba_get_nchan_metadata( SBA_HOA2_ORDER, IVAS_256k /*dummy value as order is always 1 in this function*/ ); - /* response[b] = c; */ - /* } */ + foa_ch = FOA_CHANNELS; + diff_norm_order1 = 3.0f; + diff_norm_order2 = 5.0f; + diff_norm_order3 = 7.0f; - for ( l = 1; l <= ambisonics_order; l++ ) + for ( i = 0; i < IVAS_MAX_FB_MIXER_OUT_CH; i++ ) { - b_2 = l * l; - b1_2 = l * l + 2 * l; - for ( m = 0; m < l; m += 2 ) + for ( j = 0; j < IVAS_MAX_SPAR_FB_MIXER_IN_CH; j++ ) { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + pMixer_mat[i][j] = mixer_mat_local[i][j]; + } + ppMixer_mat[i] = pMixer_mat[i]; + } - response[b] = c * sin_az[l - m - 1]; + if ( ( start_band >= 6 && hSpar_md_cfg->nchan_transport <= 2 && ( dtx_vad == 1 ) ) || ( useLowerRes && start_band >= 3 && hSpar_md_cfg->nchan_transport <= 2 && ( dtx_vad == 1 ) ) ) + { + float P_norm[3]; + int16_t idx; - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; + ndm = hSpar_md_cfg->num_dmx_chans_per_band[start_band - 1]; + P_norm[0] = 0.0f; + for ( i = 0; i < max( 0, foa_ch - ndm ); i++ ) + { + P_norm[0] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; } + P_norm[0] *= diff_norm_order1 / min( diff_norm_order1, max( 0, foa_ch - ndm ) ); - for ( m = 1; m < l; m += 2 ) + P_norm[1] = 0.0f; + for ( ; i < max( 0, min( num_ch, hoa2_ch ) - ndm ); i++ ) { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - c = c * e; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; + P_norm[1] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; } + P_norm[1] *= diff_norm_order2 / min( diff_norm_order2, max( 0, min( num_ch, hoa2_ch ) - ndm ) ); - b = b_2 + l; - a = dirac_gains_P_idx[b]; - c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - if ( l % 2 == 1 ) + P_norm[2] = 0.0f; + for ( ; i < num_ch - ndm; i++ ) + { + P_norm[2] += hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + } + P_norm[2] *= diff_norm_order3 / min( diff_norm_order3, max( 0, num_ch - ndm ) ); + + for ( i = 0; i < max( 0, foa_ch - ndm ); i++ ) + { + idx = remix_order[i + ndm] - ndm; + P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[0] ); + } + for ( ; i < max( 0, min( num_ch, hoa2_ch ) - ndm ); i++ ) + { + idx = remix_order[i + ndm] - ndm; + P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[1] ); + } + for ( ; i < num_ch - ndm; i++ ) + { + idx = remix_order[i + ndm] - ndm; + P_dir_fact[idx] = hSpar_md->band_coeffs[start_band - 1].P_re[i] * hSpar_md->band_coeffs[start_band - 1].P_re[i]; + P_dir_fact[idx] = P_dir_fact[idx] / max( IVAS_FLT_EPS, P_norm[2] ); + } + } + + for ( int16_t i_ts = 0; i_ts < n_ts; i_ts++ ) + { + for ( band = start_band; band < end_band; band++ ) + { + ndm = hSpar_md_cfg->num_dmx_chans_per_band[band]; + + /*SPAR from DirAC*/ + set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); + + if ( n_ts > 1 ) + { + ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order ); + } + else if ( useLowerRes ) + { + ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][0], (int16_t) ele_dirac[band][0], response_avg, order ); + } + else + { + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][block], (int16_t) ele_dirac[band][block], &( response[block][0] ), order ); + } + + /* average responses in all subframes*/ + { + float norm; + int16_t num_ch_order, hoa2_ch_order; + + num_ch_order = ivas_sba_get_nchan( order, 0 ); + hoa2_ch_order = ivas_sba_get_nchan( SBA_HOA2_ORDER, 0 ); + + for ( ch = 0; ch < num_ch_order; ch++ ) + { + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + response_avg[ch] += response[block][ch]; + } + response_avg[ch] /= MAX_PARAM_SPATIAL_SUBFRAMES; + } + + /*normalize 1st order*/ + norm = 0.0f; + for ( ch = 1; ch < foa_ch; ch++ ) + { + norm += response_avg[ch] * response_avg[ch]; + } + norm = max( EPSILON, sqrtf( norm ) ); + for ( ch = 1; ch < foa_ch; ch++ ) + { + response_avg[ch] /= norm; + } + + /*normalize 2nd order*/ + norm = 0.0f; + for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + { + norm += response_avg[ch] * response_avg[ch]; + } + norm = max( EPSILON, sqrtf( norm ) ); + for ( ch = foa_ch; ch < min( hoa2_ch_order, num_ch_order ); ch++ ) + { + response_avg[ch] /= norm; + } + + /*normalize 3rd order*/ + norm = 0.0f; + for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ ) + { + norm += response_avg[ch] * response_avg[ch]; + } + norm = max( EPSILON, sqrtf( norm ) ); + for ( ch = hoa2_ch_order; ch < num_ch_order; ch++ ) + { + response_avg[ch] /= norm; + } + } + } + + for ( i = FOA_CHANNELS + 1; i < num_ch; i++ ) + { + response_avg[i] = response_avg[HOA_keep_ind[i]]; + } + + en_ratio_fac = ( 1.0f - diffuseness[band] ); + + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + if ( i == j ) + { + if ( i == 0 ) + { + cov_real_dirac[i][i][band] = 1.0f; + } + else + { + cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + + if ( hSpar_md_cfg->nchan_transport <= 2 ) + { + + cov_real_dirac[i][j][band] *= en_ratio_fac; + if ( ( i >= ndm ) && ( dtx_vad == 1 ) ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) * P_dir_fact[i - ndm]; + } + else + { + if ( i < foa_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order1; + } + else if ( i < hoa2_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order2; + } + else + { + cov_real_dirac[i][j][band] += ( 1.0f - ( en_ratio_fac * en_ratio_fac ) ) / diff_norm_order3; + } + } + } + else + { + if ( i < foa_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order1; + } + else if ( i < hoa2_ch ) + { + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order2; + } + else + { + cov_real_dirac[i][j][band] += ( 1.0f - en_ratio_fac ) / diff_norm_order3; + } + } + } + } + else + { + cov_real_dirac[i][j][band] = en_ratio_fac * response_avg[i] * response_avg[j]; + } + } + } + } + + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + pCov_real[i][j] = cov_real_dirac[i][j]; + } + } + + + active_w = ( dyn_active_w_flag == 1 ) || ( hSpar_md_cfg->active_w == 1 ); + + ivas_compute_spar_params( pCov_real, dm_fv_re, i_ts, ppMixer_mat, start_band, end_band, dtx_vad, num_ch, 1, active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale, 1, dyn_active_w_flag ); + + if ( mixer_mat != NULL ) + { + for ( band = start_band; band < end_band; band++ ) + { + ndm = hSpar_md_cfg->num_dmx_chans_per_band[band]; + + for ( i = 0; i < ndm; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + mixer_mat[i][j][band + i_ts * IVAS_MAX_NUM_BANDS] = ppMixer_mat[i][j][band]; + } + } + + for ( i = ndm; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + mixer_mat[i][j][band + i_ts * IVAS_MAX_NUM_BANDS] = 0.0f; + } + } + + if ( ( ndm == 1 ) && ( Wscale_d != NULL ) ) + { + for ( j = 0; j < num_ch; j++ ) + { + mixer_mat[0][j][band + i_ts * IVAS_MAX_NUM_BANDS] *= Wscale_d[band]; + } + } + } + } + } + + return; +} + +/*------------------------------------------------------------------------- + * ivas_dirac_dec_get_response() + * + * calculate reponse, 1 degree resolution + *------------------------------------------------------------------------*/ + +void ivas_dirac_dec_get_response( + const int16_t azimuth, + const int16_t elevation, + float *response, + const int16_t ambisonics_order ) +{ + int16_t index_azimuth, index_elevation; + int16_t el, e, az; + float cos_1, cos_2, sin_1, cos_az[3]; + float sin_az[3]; + float f, c; + int16_t l, m; + int16_t b, b1, b_2, b1_2, a; + + index_azimuth = ( azimuth + 180 ) % 360; + index_elevation = elevation + 90; + e = index_elevation > 90 ? -1 : 1; + el = index_elevation > 90 ? 180 - index_elevation : index_elevation; + + az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; + f = index_azimuth > 180 ? -1.0f : 1.0f; + + cos_1 = dirac_gains_trg_term[az][0]; + cos_2 = cos_1 * cos_1; + sin_1 = f * dirac_gains_trg_term[az][1]; + cos_az[0] = cos_1; + cos_az[1] = 2.0f * cos_2 - 1.0f; + cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; + sin_az[0] = sin_1; + sin_az[1] = sin_1 * 2.0f * cos_1; + sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); + + response[0] = 1.0f; + /* Un-optimized code - for reference */ + /* for( l = 1; l<= ambisonics_order; l++ ) */ + /* { */ + /* int16_t b, b1, a; */ + /* float c; */ + /* for( m = 0; m < l; m++ ) */ + /* { */ + /* b = l*l+m; */ + /* a = dirac_gains_P_idx[b]; */ + /* c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ + + /* if( m%2 == 1 ) */ + /* { */ + /* c = c*e; */ + /* } */ + + /* response[b] = c * sin_az[l-m-1]; */ + + /* b1 = l*l+2*l-m; */ + /* response[b1] = c * cos_az[l-m-1]; */ + + /* } */ + + /* b = l*l+l; */ + /* a = dirac_gains_P_idx[b]; */ + /* c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ + /* if( l%2 == 1) */ + /* { */ + /* c = c*e; */ + /* } */ + + /* response[b] = c; */ + /* } */ + + for ( l = 1; l <= ambisonics_order; l++ ) + { + b_2 = l * l; + b1_2 = l * l + 2 * l; + for ( m = 0; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + for ( m = 1; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c = c * e; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + b = b_2 + l; + a = dirac_gains_P_idx[b]; + c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + if ( l % 2 == 1 ) + { + c = c * e; + } + + response[b] = c; + } + + return; +} + +#ifdef IVAS_FLOAT_FIXED +/*------------------------------------------------------------------------- + * ivas_dirac_dec_get_response_fixed() + * + * Block Q of 29 is maintained + * calculate reponse, 1 degree resolution + * Input azimuth and elevation are expected in Q0 + *------------------------------------------------------------------------*/ + +void ivas_dirac_dec_get_response_fixed( + const Word16 azimuth, + const Word16 elevation, + Word32 *response, + const Word16 ambisonics_order ) +{ + Word16 index_azimuth, index_elevation; + Word16 el, e, az; + Word32 cos_1, cos_2, sin_1, cos_az[3]; + Word32 sin_az[3]; + Word32 f, c; + Word16 l, m; + Word16 b, b1, b_2, b1_2, a; + + index_azimuth = ( azimuth + 180 ) % 360; + index_elevation = elevation + 90; + e = index_elevation > 90 ? -1 : 1; + el = index_elevation > 90 ? 180 - index_elevation : index_elevation; + + az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; + f = index_azimuth > 180 ? -( 1 << Q29 ) : ( 1 << Q29 ); + + cos_1 = dirac_gains_trg_term_int[az][0] >> 1; // Q29 + cos_2 = Mpy_32_32( cos_1, cos_1 ); // Q27 + sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] >> 1 ); // Q27 + cos_az[0] = cos_1; // Q29 + cos_az[1] = L_sub( Mpy_32_32( ( 1 << Q30 ), cos_2 ), ( 1 << Q25 ) ) << 4; // Q29 + cos_az[2] = L_sub( Mpy_32_32( Mpy_32_32( ( 1 << Q30 ), cos_1 ), cos_az[1] ) << 4, cos_az[0] ); // Q29 + sin_az[0] = sin_1 << 2; // Q29 + sin_az[1] = Mpy_32_32( Mpy_32_32( sin_1, ( 1 << Q30 ) ), cos_1 ) << 6; // Q29 + sin_az[2] = Mpy_32_32( sin_1, L_sub( L_shl_sat(Mpy_32_32( ( 1 << Q30 ), cos_2 ), 5), ( 1 << 29 ) ) ) << 4; + + response[0] = ( 1 << 29 ); + /* Un-optimized code - for reference */ + /* for( l = 1; l<= ambisonics_order; l++ ) */ + /* { */ + /* int16_t b, b1, a; */ + /* float c; */ + /* for( m = 0; m < l; m++ ) */ + /* { */ + /* b = l*l+m; */ + /* a = dirac_gains_P_idx[b]; */ + /* c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ + + /* if( m%2 == 1 ) */ + /* { */ + /* c = c*e; */ + /* } */ + + /* response[b] = c * sin_az[l-m-1]; */ + + /* b1 = l*l+2*l-m; */ + /* response[b1] = c * cos_az[l-m-1]; */ + + /* } */ + + /* b = l*l+l; */ + /* a = dirac_gains_P_idx[b]; */ + /* c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; */ + /* if( l%2 == 1) */ + /* { */ + /* c = c*e; */ + /* } */ + + /* response[b] = c; */ + /* } */ + + FOR( l = 1; l <= ambisonics_order; l++ ) + { + b_2 = l * l; + b1_2 = l * l + 2 * l; + FOR( m = 0; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25 + + response[b] = Mpy_32_32( c, sin_az[l - m - 1] ) << 6; // Q29 + + b1 = b1_2 - m; + response[b1] = Mpy_32_32( c, cos_az[l - m - 1] ) << 6; // Q29 + } + + FOR( m = 1; m < l; m += 2 ) { - c = c * e; + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25 + IF( e == -1 ) + { + c = -c; + } + + response[b] = Mpy_32_32( c, sin_az[l - m - 1] ) << 6; // Q29 + + b1 = b1_2 - m; + response[b1] = Mpy_32_32( c, cos_az[l - m - 1] ) << 6; // Q29 } - response[b] = c; + b = b_2 + l; + a = dirac_gains_P_idx[b]; + c = Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ); // Q26 + IF( l % 2 == 1 ) + { + IF( e == -1 ) + { + c = -c; + } + } + + response[b] = c << 3; // Q29 } return; } +Word32 local_result_table[91][9] = { + { + -1518500224, + 0, + 1518500224, + 0, + 0, + -1518500224, + 0, + 0, + 0, + }, + { + -1518268928, + 18739168, + 1517806336, + -32452256, + 283224, + -1517112832, + 45883920, + -633213, + 4512, + }, + { + -1517575296, + 37472840, + 1515726208, + -64865308, + 1132567, + -1512954368, + 91649576, + -2530954, + 36081, + }, + { + -1516419072, + 56195504, + 1512261120, + -97200048, + 2547029, + -1506034816, + 137178960, + -5687523, + 121687, + }, + { + -1514801280, + 74899824, + 1507416960, + -129414272, + 4524729, + -1496374144, + 182350416, + -10092950, + 288126, + }, + { + -1512721920, + 93582472, + 1501198336, + -161472816, + 7063499, + -1483994752, + 227052672, + -15734350, + 561983, + }, + { + -1510181888, + 112236512, + 1493612928, + -193334368, + 10160129, + -1468930304, + 271167360, + -22594280, + 969488, + }, + { + -1507181440, + 130856376, + 1484670848, + -224960416, + 13810849, + -1451219200, + 314580448, + -30651802, + 1536471, + }, + { + -1503722368, + 149436080, + 1474381824, + -256312016, + 18011172, + -1430907520, + 357179712, + -39882252, + 2288268, + }, + { + -1499805056, + 167970048, + 1462759808, + -287350848, + 22755934, + -1408048256, + 398855200, + -50257348, + 3249646, + }, + { + -1495430784, + 186453552, + 1449817472, + -318040608, + 28039610, + -1382698496, + 439501280, + -61745920, + 4444797, + }, + { + -1490601216, + 204879712, + 1435571584, + -348342304, + 33855484, + -1354926336, + 479011360, + -74312248, + 5897082, + }, + { + -1485317248, + 223243280, + 1420039296, + -378219040, + 40196448, + -1324801792, + 517284416, + -87917840, + 7629140, + }, + { + -1479581312, + 241539296, + 1403239552, + -407635936, + 47055084, + -1292403328, + 554224000, + -102521616, + 9662823, + }, + { + -1473394304, + 259761664, + 1385192192, + -436555904, + 54422836, + -1257814016, + 589734528, + -118078312, + 12018922, + }, + { + -1466758528, + 277904896, + 1365919872, + -464943936, + 62290712, + -1221123072, + 623725376, + -134540160, + 14717325, + }, + { + -1459675904, + 295963392, + 1345445888, + -492765408, + 70649128, + -1182425216, + 656109568, + -151856528, + 17776824, + }, + { + -1452148992, + 313931616, + 1323795328, + -519986432, + 79487904, + -1141820288, + 686806528, + -169973952, + 21215122, + }, + { + -1444179456, + 331804576, + 1300994176, + -546574464, + 88796448, + -1099412096, + 715738304, + -188836864, + 25048834, + }, + { + -1435770240, + 349576096, + 1277071104, + -572495872, + 98563056, + -1055310848, + 742831168, + -208386384, + 29293104, + }, + { + -1426923392, + 367241408, + 1252053888, + -597720320, + 108776240, + -1009627456, + 768018944, + -228562448, + 33962144, + }, + { + -1417641984, + 384794496, + 1225974400, + -622216320, + 119423168, + -962481536, + 791238528, + -249301712, + 39068520, + }, + { + -1407929088, + 402230560, + 1198863744, + -645953856, + 130491136, + -913992384, + 812432896, + -270540160, + 44623688, + }, + { + -1397786880, + 419544320, + 1170754432, + -668905408, + 141966720, + -864283712, + 831550336, + -292211648, + 50637684, + }, + { + -1387219200, + 436730112, + 1141681280, + -691041088, + 153835648, + -813483968, + 848545344, + -314247680, + 57118880, + }, + { + -1376228736, + 453783040, + 1111679744, + -712335552, + 166083808, + -761721216, + 863377472, + -336579712, + 64074440, + }, + { + -1364819072, + 470697504, + 1080786560, + -732761408, + 178695840, + -709128192, + 876011648, + -359136416, + 71509840, + }, + { + -1352993664, + 487468704, + 1049038720, + -752295232, + 191656864, + -655838272, + 886421184, + -381847712, + 79429264, + }, + { + -1340756224, + 504091296, + 1016475840, + -770911616, + 204950624, + -601987264, + 894582912, + -404640384, + 87835088, + }, + { + -1328110336, + 520560224, + 983137344, + -788589376, + 218561056, + -547711936, + 900480064, + -427441888, + 96728224, + }, + { + -1315059712, + 536870912, + 949062848, + -805306304, + 232471968, + -493147392, + 904103488, + -450179904, + 106108432, + }, + { + -1301608576, + 553017920, + 914294592, + -821041856, + 246665952, + -438433216, + 905449280, + -472780672, + 115973296, + }, + { + -1287761024, + 568996608, + 878874816, + -835777472, + 261126064, + -383705856, + 904519040, + -495171488, + 126319176, + }, + { + -1273521536, + 584801792, + 842847360, + -849494592, + 275834208, + -329104384, + 901322112, + -517278496, + 137140640, + }, + { + -1258893952, + 600428672, + 806255552, + -862177024, + 290772768, + -274764416, + 895873408, + -539030016, + 148430976, + }, + { + -1243882624, + 615873088, + 769143424, + -873808640, + 305923776, + -220820592, + 888192128, + -560354240, + 160182032, + }, + { + -1228492672, + 631129536, + 731557056, + -884375872, + 321268192, + -167408576, + 878306816, + -581179712, + 172383520, + }, + { + -1212728192, + 646193920, + 693541568, + -893865664, + 336788032, + -114659368, + 866249088, + -601437056, + 185024416, + }, + { + -1196594560, + 661061376, + 655143872, + -902266304, + 352463776, + -62704428, + 852058240, + -621057088, + 198091488, + }, + { + -1180096256, + 675727744, + 616410112, + -909567168, + 368276832, + -11670283, + 835778240, + -639973248, + 211570704, + }, + { + -1163238528, + 690187904, + 577388480, + -915760192, + 384207328, + 38316972, + 817459904, + -658119040, + 225445952, + }, + { + -1146026752, + 704437888, + 538126144, + -920838016, + 400236128, + 87136208, + 797158016, + -675430976, + 239700208, + }, + { + -1128465792, + 718473536, + 498670016, + -924793792, + 416343968, + 134670400, + 774934400, + -691848064, + 254315376, + }, + { + -1110560896, + 732290176, + 459069056, + -927622464, + 432511008, + 180804176, + 750854336, + -707309760, + 269271168, + }, + { + -1092317568, + 745883904, + 419370880, + -929321088, + 448717696, + 225428032, + 724989312, + -721759040, + 284546880, + }, + { + -1073741824, + 759250176, + 379625056, + -929887680, + 464943936, + 268435456, + 697415552, + -735140736, + 300119968, + }, + { + -1054839104, + 772385152, + 339879232, + -929321088, + 481170176, + 309726208, + 668213824, + -747403200, + 315967200, + }, + { + -1035614656, + 785285184, + 300180928, + -927622464, + 497376864, + 349204928, + 637467712, + -758496960, + 332064416, + }, + { + -1016075072, + 797945664, + 260580400, + -924793792, + 513543616, + 386779488, + 605268032, + -768375104, + 348385536, + }, + { + -996225600, + 810363264, + 221124000, + -920838016, + 529651744, + 422366560, + 571706432, + -776995008, + 364904864, + }, + { + -976073088, + 822533888, + 181861520, + -915760768, + 545680512, + 455884896, + 536880512, + -784315776, + 381594208, + }, + { + -955623040, + 834454272, + 142839376, + -909567168, + 561611328, + 487262400, + 500889568, + -790300992, + 398426144, + }, + { + -934881920, + 846120128, + 104106176, + -902266304, + 577424064, + 516431136, + 463836896, + -794917120, + 415371168, + }, + { + -913856384, + 857528256, + 65708784, + -893865664, + 593099520, + 543330048, + 425828896, + -798133760, + 432399904, + }, + { + -892551936, + 868675520, + 27693010, + -884375872, + 608619648, + 567905408, + 386972736, + -799925440, + 449482624, + }, + { + -870975872, + 879557760, + -9893141, + -873808640, + 623964096, + 590108032, + 347380800, + -800268608, + 466587840, + }, + { + -849134336, + 890172352, + -47005296, + -862177024, + 639115008, + 609897856, + 307164128, + -799144896, + 483684960, + }, + { + -827034624, + 900515712, + -83597168, + -849494592, + 654053696, + 627240256, + 266438224, + -796539136, + 500742080, + }, + { + -804682624, + 910584576, + -119624760, + -835777472, + 668762048, + 642107520, + 225317632, + -792439552, + 517727488, + }, + { + -782085312, + 920376512, + -155044640, + -821041856, + 683222080, + 654480128, + 183918624, + -786839296, + 534609632, + }, + { + -759250304, + 929887616, + -189812384, + -805306304, + 697415936, + 664343872, + 142359552, + -779734528, + 551355584, + }, + { + -736183296, + 939115776, + -223886912, + -788589376, + 711326720, + 671693120, + 100756408, + -771125696, + 567933632, + }, + { + -712892608, + 948057792, + -257225888, + -770911616, + 724937152, + 676528896, + 59227880, + -761017408, + 584311680, + }, + { + -689384832, + 956710976, + -289788768, + -752295232, + 738231168, + 678858752, + 17890716, + -749417856, + 600457728, + }, + { + -665666624, + 965072704, + -321536480, + -732761408, + 751191936, + 678698240, + -23139272, + -736339008, + 616340032, + }, + { + -641745984, + 973140608, + -352429632, + -712335552, + 763803968, + 676069440, + -63745280, + -721797248, + 631926912, + }, + { + -617629760, + 980911936, + -382431072, + -691041088, + 776052160, + 671001088, + -103813880, + -705812224, + 647187904, + }, + { + -593325248, + 988384512, + -411504000, + -668905408, + 787920960, + 663529280, + -143232048, + -688407552, + 662091712, + }, + { + -568840192, + 995556160, + -439613248, + -645954560, + 799396736, + 653696896, + -181889024, + -669611072, + 676608512, + }, + { + -544181696, + 1002424320, + -466724288, + -622216320, + 810464576, + 641552832, + -219676144, + -649453696, + 690709312, + }, + { + -519357600, + 1008987328, + -492803904, + -597720256, + 821111744, + 627153216, + -256487184, + -627969792, + 704364160, + }, + { + -494375232, + 1015242880, + -517820864, + -572495872, + 831324672, + 610560128, + -292219008, + -605198016, + 717546496, + }, + { + -469242400, + 1021189056, + -541744064, + -546574272, + 841091328, + 591841984, + -326770816, + -581179840, + 730228608, + }, + { + -443966464, + 1026824384, + -564545152, + -519986624, + 850399808, + 571072896, + -360046304, + -555960000, + 742384384, + }, + { + -418555424, + 1032146880, + -586195904, + -492765472, + 859238720, + 548332736, + -391952064, + -529586400, + 753988416, + }, + { + -393016736, + 1037154944, + -606669696, + -464943776, + 867597120, + 523707360, + -422398496, + -502110496, + 765017472, + }, + { + -367358464, + 1041847104, + -625942016, + -436555712, + 875464896, + 497287264, + -451300416, + -473585952, + 775447168, + }, + { + -341588128, + 1046221952, + -643989248, + -407635840, + 882832768, + 469168768, + -478576512, + -444069824, + 785256768, + }, + { + -315714112, + 1050278016, + -660789184, + -378219488, + 889691264, + 439452448, + -504150464, + -413621792, + 794425024, + }, + { + -289743520, + 1054014208, + -676321600, + -348342080, + 896032512, + 408242848, + -527951296, + -382302944, + 802933568, + }, + { + -263684816, + 1057429248, + -690567552, + -318040352, + 901848320, + 375649632, + -549911936, + -350177888, + 810763520, + }, + { + -237545680, + 1060522240, + -703509440, + -287351040, + 907131648, + 341785696, + -569970496, + -317312864, + 817899072, + }, + { + -211334384, + 1063292288, + -715132096, + -256311760, + 911876928, + 306768160, + -588071424, + -283776384, + 824324416, + }, + { + -185058560, + 1065738240, + -725420672, + -224960096, + 916077184, + 270716544, + -604163840, + -249638288, + 830026560, + }, + { + -158726560, + 1067859776, + -734362944, + -193334624, + 919727616, + 233754128, + -618202944, + -214970528, + 834993024, + }, + { + -132346048, + 1069655936, + -741948032, + -161473376, + 922824448, + 196005872, + -630149440, + -179845728, + 839213568, + }, + { + -105925224, + 1071126272, + -748166720, + -129415376, + 925363072, + 157599216, + -639969344, + -144338352, + 842679232, + }, + { + -79472136, + 1072270272, + -753011392, + -97199672, + 927340864, + 118664000, + -647635776, + -108523640, + 845382016, + }, + { + -52994836, + 1073087808, + -756475840, + -64865616, + 928755264, + 79330888, + -653127424, + -72477792, + 847316864, + }, + { + -26501398, + 1073578432, + -758556288, + -32452510, + 929604544, + 39731924, + -656428672, + -36277476, + 848479808, + }, + { + -66, + 1073741824, + -759250112, + -81, + 929887872, + 99, + -657529856, + -90, + 848867456, + } +}; -#ifdef IVAS_FLOAT_FIXED -/*------------------------------------------------------------------------- - * ivas_dirac_dec_get_response_fixed() - * - * Block Q of 29 is maintained - * calculate reponse, 1 degree resolution - * Input azimuth and elevation are expected in Q0 - *------------------------------------------------------------------------*/ - -void ivas_dirac_dec_get_response_fixed( +Word32 local_result_table_2[91][9] = { + { + -1073741824, + 0, + 1073741824, + 0, + 0, + -1073741824, + 0, + 0, + 0, + }, + { + -1073578304, + 13250594, + 1073251200, + -22947212, + 200270, + -1072760832, + 32444832, + -447749, + 3190, + }, + { + -1073087808, + 26497302, + 1071780288, + -45866700, + 800846, + -1069820288, + 64806036, + -1789655, + 25513, + }, + { + -1072270272, + 39736224, + 1069330112, + -68730816, + 1801021, + -1064927488, + 97000176, + -4021686, + 86045, + }, + { + -1071126272, + 52962176, + 1065904768, + -91509712, + 3199466, + -1058096320, + 128941216, + -7136793, + 203735, + }, + { + -1069655936, + 66172804, + 1061507520, + -114178536, + 4994649, + -1049342784, + 160550480, + -11125865, + 397382, + }, + { + -1067859840, + 79363208, + 1056143808, + -136708048, + 7184296, + -1038690624, + 191744288, + -15976569, + 685532, + }, + { + -1065738240, + 92529440, + 1049820800, + -159071040, + 9765746, + -1026166912, + 222441968, + -21674096, + 1086449, + }, + { + -1063292288, + 105667272, + 1042545408, + -181239968, + 12735822, + -1011804416, + 252564208, + -28201010, + 1618050, + }, + { + -1060522368, + 118772768, + 1034327424, + -203187744, + 16090877, + -995640448, + 282033216, + -35537312, + 2297847, + }, + { + -1057429248, + 131842576, + 1025175744, + -224888688, + 19827000, + -977715456, + 310774336, + -43660960, + 3142946, + }, + { + -1054014208, + 144871840, + 1015102400, + -246315216, + 23939442, + -958077632, + 338712160, + -52546696, + 4169866, + }, + { + -1050277888, + 157856848, + 1004119424, + -267441264, + 28423184, + -936776384, + 365775328, + -62167296, + 5394616, + }, + { + -1046221952, + 170794080, + 992240192, + -288242144, + 33272972, + -913867136, + 391895552, + -72493728, + 6832647, + }, + { + -1041847104, + 183679248, + 979478784, + -308691648, + 38482756, + -889408832, + 417005280, + -83493976, + 8498661, + }, + { + -1037154944, + 196508448, + 965851264, + -328765024, + 44046188, + -863464384, + 441040416, + -95134256, + 10406720, + }, + { + -1032146752, + 209277728, + 951373888, + -348437760, + 49956480, + -836100864, + 463939520, + -107378776, + 12570113, + }, + { + -1026824448, + 221983184, + 936064704, + -367685952, + 56206436, + -807388864, + 485645568, + -120189736, + 15001357, + }, + { + -1021189120, + 234621280, + 919941824, + -386486528, + 62788576, + -777401728, + 506103424, + -133527832, + 17712200, + }, + { + -1015242880, + 247187648, + 903025664, + -404815744, + 69694608, + -746217472, + 525260928, + -147351424, + 20713352, + }, + { + -1008987264, + 259678912, + 885335808, + -422652128, + 76916424, + -713914432, + 543071424, + -161618048, + 24014862, + }, + { + -1002424320, + 272090816, + 866894784, + -439973408, + 84444936, + -680577216, + 559490112, + -176282928, + 27625616, + }, + { + -995556224, + 284419968, + 847724672, + -456758400, + 92271176, + -646290240, + 574476800, + -191300784, + 31553712, + }, + { + -988384640, + 296662656, + 827848384, + -472987584, + 100385640, + -611140864, + 587994880, + -206624832, + 35806248, + }, + { + -980912128, + 308814848, + 807290624, + -488639872, + 108778240, + -575220032, + 600012160, + -222206672, + 40389148, + }, + { + -973140672, + 320873088, + 786076288, + -503697312, + 117438992, + -538618240, + 610500032, + -237997792, + 45307472, + }, + { + -965072832, + 332833408, + 764231552, + -518140608, + 126357048, + -501429376, + 619433792, + -253947792, + 50565096, + }, + { + -956710976, + 344692448, + 741782400, + -531953120, + 135521872, + -463747712, + 626794432, + -270007104, + 56164972, + }, + { + -948057792, + 356446400, + 718756992, + -545116864, + 144921984, + -425669280, + 632565632, + -286123936, + 62108788, + }, + { + -939115840, + 368091680, + 695183104, + -557616896, + 154546016, + -387290848, + 636735552, + -302247040, + 68397184, + }, + { + -929887616, + 379625088, + 671088768, + -569437568, + 164382512, + -348707872, + 639297728, + -318325280, + 75029992, + }, + { + -920376256, + 391042752, + 646503936, + -580564288, + 174419184, + -310019104, + 640249344, + -334306432, + 82005504, + }, + { + -910584576, + 402341376, + 621458368, + -590983936, + 184644016, + -271321024, + 639591552, + -350139136, + 89321144, + }, + { + -900515712, + 413517344, + 595983104, + -600683392, + 195044256, + -232711952, + 637331008, + -365771136, + 96973080, + }, + { + -890172480, + 424567200, + 570108800, + -609651264, + 205607392, + -194287792, + 633478144, + -381151776, + 104956552, + }, + { + -879557888, + 435488064, + 543866560, + -617876032, + 216320784, + -156143744, + 628046656, + -396230272, + 113265800, + }, + { + -868675520, + 446276000, + 517288960, + -625348224, + 227170944, + -118375744, + 621056704, + -410956128, + 121893560, + }, + { + -857528320, + 456928128, + 490407968, + -632058496, + 238145120, + -81076416, + 612530560, + -425280224, + 130832024, + }, + { + -846120128, + 467441024, + 463256672, + -637998656, + 249229552, + -44338728, + 602496192, + -439153664, + 140071840, + }, + { + -834454080, + 477811712, + 435867776, + -643161152, + 260411056, + -8252136, + 590984448, + -452529440, + 149603072, + }, + { + -822533888, + 488036576, + 408275296, + -647540288, + 271675616, + 27094190, + 578031424, + -465360448, + 159414368, + }, + { + -810363264, + 498112832, + 380512640, + -651130816, + 283009696, + 61614604, + 563675840, + -477601824, + 169493648, + }, + { + -797945792, + 508037536, + 352612960, + -653928000, + 294399648, + 95226360, + 547961344, + -489210464, + 179828128, + }, + { + -785285184, + 517807392, + 324610848, + -655928192, + 305831488, + 127847864, + 530934208, + -500143520, + 190403472, + }, + { + -772385152, + 527419616, + 296540000, + -657129280, + 317291360, + 159401696, + 512644864, + -510360704, + 201205024, + }, + { + -759250176, + 536870976, + 268435456, + -657529920, + 328765024, + 189812544, + 493147264, + -519823008, + 212216864, + }, + { + -745883904, + 546158784, + 240330912, + -657129280, + 340238720, + 219009504, + 472498528, + -528493856, + 223422560, + }, + { + -732290176, + 555280512, + 212259968, + -655928192, + 351698592, + 246925184, + 450757760, + -536338336, + 234805008, + }, + { + -718473600, + 564232832, + 184258176, + -653928000, + 363130208, + 273494400, + 427989120, + -543323264, + 246345792, + }, + { + -704437888, + 573013376, + 156358288, + -651130816, + 374520352, + 298658272, + 404257472, + -549418432, + 258026704, + }, + { + -690187904, + 581619328, + 128595512, + -647540736, + 385854432, + 322359296, + 379631872, + -554595008, + 269827872, + }, + { + -675727552, + 590048320, + 101002688, + -643161152, + 397119232, + 344546560, + 354182432, + -558827200, + 281729824, + }, + { + -661061376, + 598297344, + 73614184, + -637998656, + 408300512, + 365171968, + 327982208, + -562091264, + 293711776, + }, + { + -646194048, + 606364096, + 46463128, + -632058496, + 419384736, + 384192352, + 301106496, + -564365760, + 305752896, + }, + { + -631129536, + 614246400, + 19581916, + -625348224, + 430359136, + 401569792, + 273631040, + -565632704, + 317832192, + }, + { + -615872960, + 621941312, + -6995507, + -617876032, + 441209248, + 417269376, + 245635312, + -565875392, + 329927424, + }, + { + -600428672, + 629446976, + -33237764, + -609651264, + 451922592, + 431262912, + 217197840, + -565080768, + 342016896, + }, + { + -584801792, + 636760832, + -59112128, + -600683392, + 462485824, + 443525824, + 188400272, + -563238208, + 354078112, + }, + { + -568996544, + 643880576, + -84587480, + -590983936, + 472886208, + 454038592, + 159323616, + -560339392, + 366088608, + }, + { + -553017856, + 650804544, + -109633120, + -580564288, + 483110976, + 462787328, + 130050112, + -556379392, + 378026112, + }, + { + -536871040, + 657529856, + -134217624, + -569437568, + 493147552, + 469762048, + 100663400, + -551355584, + 389867264, + }, + { + -520560224, + 664055168, + -158311952, + -557616896, + 502983968, + 474958752, + 71245536, + -545268160, + 401589760, + }, + { + -504091200, + 670378112, + -181886176, + -545116864, + 512608032, + 478378176, + 41880432, + -538120576, + 413170752, + }, + { + -487468704, + 676496896, + -204911600, + -531953120, + 522008320, + 480025632, + 12650646, + -529918464, + 424587712, + }, + { + -470697376, + 682409472, + -227360640, + -518140608, + 531172928, + 479912128, + -16361936, + -520670304, + 435818208, + }, + { + -453782944, + 688114368, + -249205392, + -503697312, + 540091008, + 478053280, + -45074720, + -510387712, + 446839808, + }, + { + -436730208, + 693609536, + -270419616, + -488639872, + 548751808, + 474469440, + -73407496, + -499084608, + 457630944, + }, + { + -419544320, + 698893440, + -290977280, + -472987584, + 557144256, + 469186080, + -101280352, + -486777664, + 468169568, + }, + { + -402230784, + 703964544, + -310853504, + -456758880, + 565258880, + 462233504, + -128614952, + -473486528, + 478434464, + }, + { + -384794592, + 708821056, + -330023904, + -439973408, + 573084992, + 453646368, + -155334496, + -459233120, + 488405216, + }, + { + -367241280, + 713461824, + -348464992, + -422652096, + 580613696, + 443464288, + -181363824, + -444041664, + 498060704, + }, + { + -349576096, + 717885184, + -366154656, + -404815744, + 587835392, + 431731200, + -206630032, + -427939616, + 507382016, + }, + { + -331804480, + 722089728, + -383070912, + -386486400, + 594741440, + 418495488, + -231061856, + -410956224, + 516349600, + }, + { + -313931712, + 726074560, + -399193696, + -367686080, + 601323520, + 403809504, + -254591184, + -393123104, + 524945024, + }, + { + -295963392, + 729838080, + -414503104, + -348437824, + 607573568, + 387729792, + -277151968, + -374474112, + 533150336, + }, + { + -277904800, + 733379328, + -428980256, + -328764896, + 613483840, + 370317024, + -298680832, + -355045728, + 540949056, + }, + { + -259761664, + 736697216, + -442607872, + -308691520, + 619047232, + 351635200, + -319117568, + -334875840, + 548323968, + }, + { + -241539296, + 739790656, + -455369184, + -288242080, + 624257088, + 331752416, + -338404704, + -314004800, + 555260352, + }, + { + -223243600, + 742658752, + -467248512, + -267441568, + 629106752, + 310739808, + -356488192, + -292474784, + 561743360, + }, + { + -204879600, + 745300672, + -478231616, + -246315056, + 633590720, + 288671296, + -373317920, + -270328992, + 567759744, + }, + { + -186453328, + 747715456, + -488305024, + -224888512, + 637703104, + 265624400, + -388846464, + -247613152, + 573296384, + }, + { + -167970160, + 749902528, + -497456320, + -203187888, + 641438976, + 241678992, + -403030016, + -224374080, + 578342016, + }, + { + -149435984, + 751861248, + -505674752, + -181239792, + 644794368, + 216917856, + -415829312, + -200660208, + 582885376, + }, + { + -130856168, + 753590784, + -512949888, + -159070816, + 647764480, + 191425504, + -427208320, + -176520928, + 586917440, + }, + { + -112236624, + 755090944, + -519273024, + -136708240, + 650345664, + 165289136, + -437135488, + -152007120, + 590429248, + }, + { + -93582792, + 756361024, + -524636480, + -114178928, + 652535424, + 138597088, + -445582912, + -127170136, + 593413568, + }, + { + -74900448, + 757400704, + -529033792, + -91510496, + 654330560, + 111439480, + -452526688, + -102062624, + 595864192, + }, + { + -56195288, + 758209600, + -532459456, + -68730552, + 655729088, + 83908120, + -457947648, + -76737800, + 597775360, + }, + { + -37473008, + 758787712, + -534909184, + -45866920, + 656729216, + 56095408, + -461830816, + -51249536, + 599143488, + }, + { + -18739318, + 759134656, + -536380320, + -22947390, + 657329728, + 28094712, + -464165184, + -25652050, + 599965824, + }, + { + -46, + 759250176, + -536870912, + -57, + 657530048, + 70, + -464943808, + -64, + 600239936, + } +}; +void ivas_dirac_dec_get_response_fx( const Word16 azimuth, const Word16 elevation, - Word32 *response, + Word32 *response_fx, const Word16 ambisonics_order ) { - Word16 index_azimuth, index_elevation; - Word16 el, e, az; - Word32 cos_1, cos_2, sin_1, cos_az[3]; - Word32 sin_az[3]; - Word32 f, c; - Word16 l, m; - Word16 b, b1, b_2, b1_2, a; + //float response[MAX_OUTPUT_CHANNELS]; + int16_t index_azimuth, index_elevation; + int16_t el, e, az; + //float cos_1, cos_2, sin_1, cos_az[3]; + Word32 cos_1_fx, cos_2_fx, sin_1_fx, cos_az_fx[3]; + //float sin_az[3]; + Word32 sin_az_fx[3]; + //float f, c; + Word32 f_fx, c_fx; + Word32 c_fx_better; + int16_t l, m; + int16_t b, b1, b_2, b1_2, a; index_azimuth = ( azimuth + 180 ) % 360; index_elevation = elevation + 90; e = index_elevation > 90 ? -1 : 1; el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -( 1 << Q29 ) : ( 1 << Q29 ); - - cos_1 = dirac_gains_trg_term_int[az][0] >> 1; // Q29 - cos_2 = Mpy_32_32( cos_1, cos_1 ); // Q27 - sin_1 = Mpy_32_32( f, dirac_gains_trg_term_int[az][1] >> 1 ); // Q27 - cos_az[0] = cos_1; // Q29 - cos_az[1] = L_sub( Mpy_32_32( ( 1 << Q30 ), cos_2 ), ( 1 << Q25 ) ) << 4; // Q29 - cos_az[2] = L_sub( Mpy_32_32( Mpy_32_32( ( 1 << Q30 ), cos_1 ), cos_az[1] ) << 4, cos_az[0] ); // Q29 - sin_az[0] = sin_1 << 2; // Q29 - sin_az[1] = Mpy_32_32( Mpy_32_32( sin_1, ( 1 << Q30 ) ), cos_1 ) << 6; // Q29 - sin_az[2] = Mpy_32_32( sin_1, L_sub( L_shl_sat(Mpy_32_32( ( 1 << Q30 ), cos_2 ), 5), ( 1 << 29 ) ) ) << 4; - - response[0] = ( 1 << 29 ); + //f = index_azimuth > 180 ? -1.0f : 1.0f; + f_fx = index_azimuth > 180 ? -1 : 1; + //cos_1 = dirac_gains_trg_term[az][0]; + cos_1_fx = dirac_gains_trg_term_fx[az][0]; + //cos_2 = cos_1 * cos_1; + cos_2_fx = Mpy_32_32( cos_1_fx, cos_1_fx ); + //sin_1 = f * dirac_gains_trg_term[az][1]; + sin_1_fx = dirac_gains_trg_term_fx[az][1]; + if ( f_fx == -1 ) + { + sin_1_fx = L_negate( sin_1_fx ); + } + //cos_az[0] = cos_1; + cos_az_fx[0] = cos_1_fx; + //cos_az[1] = 2.0f * cos_2 - 1.0f; + cos_az_fx[1] = L_shl_sat( ( cos_2_fx - ONE_IN_Q30 ), 1 ); + //cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; + cos_az_fx[2] = L_shl_sat( ( Mpy_32_32( cos_1_fx, cos_az_fx[1] ) - L_shr( cos_az_fx[0], 1 ) ), 1 ); + //sin_az[0] = sin_1; + sin_az_fx[0] = sin_1_fx; + //sin_az[1] = sin_1 * 2.0f * cos_1; + sin_az_fx[1] = L_shl_sat( Mpy_32_32( sin_1_fx, cos_1_fx ), 1 ); + //sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); + sin_az_fx[2] = L_shl_sat( Mpy_32_32( sin_1_fx, ( cos_2_fx - ONE_IN_Q29 ) ), 2 ); + + //response[0] = 1.0f; + response_fx[0] = ONE_IN_Q30; /* Un-optimized code - for reference */ /* for( l = 1; l<= ambisonics_order; l++ ) */ /* { */ @@ -1952,50 +5147,68 @@ void ivas_dirac_dec_get_response_fixed( /* response[b] = c; */ /* } */ - FOR ( l = 1; l <= ambisonics_order; l++ ) + for ( l = 1; l <= ambisonics_order; l++ ) { b_2 = l * l; b1_2 = l * l + 2 * l; - FOR ( m = 0; m < l; m += 2 ) + for ( m = 0; m < l; m += 2 ) { b = b_2 + m; a = dirac_gains_P_idx[b]; - c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25 - - response[b] = Mpy_32_32( c, sin_az[l - m - 1] ) << 6; // Q29 + //c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c_fx = Mpy_32_32( SQRT2_FIXED, Mpy_32_32( dirac_gains_norm_term_fx[a], dirac_gains_Pnm_int[el][a] ) ); + c_fx_better = local_result_table[el][a]; + //response[b] = c * sin_az[l - m - 1]; + response_fx[b] = Mpy_32_32( L_shl( c_fx, 3 ), sin_az_fx[l - m - 1] ); + response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); b1 = b1_2 - m; - response[b1] = Mpy_32_32( c, cos_az[l - m - 1] ) << 6; // Q29 + //response[b1] = c * cos_az[l - m - 1]; + response_fx[b1] = Mpy_32_32( L_shl( c_fx, 3 ), cos_az_fx[l - m - 1] ); + response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); } - FOR( m = 1; m < l; m += 2 ) + for ( m = 1; m < l; m += 2 ) { b = b_2 + m; a = dirac_gains_P_idx[b]; - c = Mpy_32_32( Mpy_32_32( SQRT2_FIXED, dirac_gains_norm_term_int[a] ), dirac_gains_Pnm_int[el][a] ); // Q25 - IF ( e == -1 ) + //c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c_fx = Mpy_32_32( SQRT2_FIXED, Mpy_32_32( dirac_gains_norm_term_fx[a], dirac_gains_Pnm_int[el][a] ) ); + c_fx_better = local_result_table[el][a]; + if ( e == -1 ) { - c = -c; + c_fx = L_negate( c_fx ); + c_fx_better = L_negate( c_fx_better ); } + //c = c * e; - response[b] = Mpy_32_32( c, sin_az[l - m - 1] ) << 6; //Q29 - + //response[b] = c * sin_az[l - m - 1]; + response_fx[b] = Mpy_32_32( L_shl( c_fx, 3 ), sin_az_fx[l - m - 1] ); + response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); b1 = b1_2 - m; - response[b1] = Mpy_32_32( c, cos_az[l - m - 1] ) << 6; //Q29 + //response[b1] = c * cos_az[l - m - 1]; + response_fx[b1] = Mpy_32_32( L_shl( c_fx, 3 ), cos_az_fx[l - m - 1] ); + response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); } b = b_2 + l; a = dirac_gains_P_idx[b]; - c = Mpy_32_32( dirac_gains_norm_term_int[a], dirac_gains_Pnm_int[el][a] ); //Q26 - IF ( l % 2 == 1 ) + //c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c_fx = Mpy_32_32( dirac_gains_norm_term_fx[a], dirac_gains_Pnm_int[el][a] ); + c_fx_better = local_result_table_2[el][a]; + if ( l % 2 == 1 ) { - IF( e == -1 ) + //c = c * e; + if ( e == -1 ) { - c = -c; + c_fx = L_negate( c_fx ); + c_fx_better = L_negate( c_fx_better ); } } - response[b] = c << 3; //Q29 + //response[b] = c; + response_fx[b] = L_shl( c_fx, 2 ); + response_fx[b] = c_fx_better; } return; @@ -2143,16 +5356,16 @@ int16_t ivas_get_bits_to_encode( #ifdef IVAS_FLOAT_FIXED Word16 ivas_get_bits_to_encode_fx( - Word32 val) + Word32 val ) { Word16 bits_req = 0; - assert(GE_32(val , 0)); + assert( GE_32( val, 0 ) ); - WHILE (val) + WHILE( val ) { - bits_req = add(bits_req, 1); - val = L_shr(val,1); + bits_req = add( bits_req, 1 ); + val = L_shr( val, 1 ); } return bits_req; diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util.c index 40f4dafcc..11c90abac 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util.c @@ -34,6 +34,8 @@ #include "options.h" #include "math.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include @@ -85,6 +87,51 @@ void ivas_quantise_real_values( return; } +void ivas_quantise_real_values_fx( + const Word32 *values_fx, + const int16_t q_levels, + const Word32 min_value_fx, + const Word32 max_value_fx, + int16_t *index, + Word32 *quant_fx, + const int16_t dim ) +{ + int16_t i; + Word32 q_step_fx, one_by_q_step_fx; + if ( q_levels == 1 ) + { + for ( i = 0; i < dim; i++ ) + { + quant_fx[i] = 0; + index[i] = 0; + } + } + else if ( q_levels && max_value_fx != min_value_fx) + { + Word32 nor_q_level = norm_l(q_levels - 1); + Word32 one_by_q_level = divide3232(L_shl(1, (nor_q_level)), L_shl((q_levels - 1), (nor_q_level))); + one_by_q_level = L_shl(one_by_q_level, 16); + q_step_fx = Mpy_32_32((max_value_fx - min_value_fx), one_by_q_level); + Word32 one_by_max_min = divide3232(ONE_IN_Q28,L_sub(max_value_fx, min_value_fx)); + one_by_q_step_fx = (q_levels - 1)*one_by_max_min; + Word32 val_fx; + for ( i = 0; i < dim; i++ ) + { + val_fx = max( min_value_fx, min( values_fx[i], max_value_fx ) ); + index[i] = (int16_t)L_shr(Mpy_32_32(one_by_q_step_fx, val_fx),12); + quant_fx[i] = index[i] * q_step_fx; + } + } + else + { + for ( i = 0; i < dim; i++ ) + { + quant_fx[i] = values_fx[i]; + } + } + return; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_get_uniform_quant_strat() @@ -113,44 +160,60 @@ void ivas_spar_get_uniform_quant_strat( pSpar_md_com_cfg->quant_strat[i].PR.q_levels[0] = PQ_q_lvl; pSpar_md_com_cfg->quant_strat[i].PR.q_levels[1] = PQ_q_lvl; pSpar_md_com_cfg->quant_strat[i].PR.min = -1.2f; + pSpar_md_com_cfg->quant_strat[i].PR.min_fx = -644245094/2; pSpar_md_com_cfg->quant_strat[i].PR.max = 1.2f; + pSpar_md_com_cfg->quant_strat[i].PR.max_fx = 644245094/2; pSpar_md_com_cfg->quant_strat[i].C.q_levels[0] = C_q_lvl; pSpar_md_com_cfg->quant_strat[i].C.q_levels[1] = C_q_lvl; pSpar_md_com_cfg->quant_strat[i].C.min = -0.8f; + pSpar_md_com_cfg->quant_strat[i].C.min_fx = -429496729/2; pSpar_md_com_cfg->quant_strat[i].C.max = 0.8f; + pSpar_md_com_cfg->quant_strat[i].C.max_fx = 429496729/2; pSpar_md_com_cfg->quant_strat[i].P_r.q_levels[0] = Pr_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_r.q_levels[1] = Pr_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_r.min = 0; + pSpar_md_com_cfg->quant_strat[i].P_r.min_fx = 0; pSpar_md_com_cfg->quant_strat[i].P_r.max = 0.8f; + pSpar_md_com_cfg->quant_strat[i].P_r.max_fx = 429496729/2; pSpar_md_com_cfg->quant_strat[i].P_c.q_levels[0] = Pc_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_c.q_levels[1] = Pc_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_c.min = -0.8f; + pSpar_md_com_cfg->quant_strat[i].P_c.min_fx = -429496729/2; pSpar_md_com_cfg->quant_strat[i].P_c.max = 0.8f; + pSpar_md_com_cfg->quant_strat[i].P_c.max_fx = 429496729/2; } else { pSpar_md_com_cfg->quant_strat[i].PR.q_levels[0] = PQ_q_lvl; pSpar_md_com_cfg->quant_strat[i].PR.q_levels[1] = PQ_q_lvl; pSpar_md_com_cfg->quant_strat[i].PR.max = 1; + pSpar_md_com_cfg->quant_strat[i].PR.max_fx = 536870912/2; pSpar_md_com_cfg->quant_strat[i].PR.min = -1; + pSpar_md_com_cfg->quant_strat[i].PR.min_fx = -536870912/2; pSpar_md_com_cfg->quant_strat[i].C.q_levels[0] = C_q_lvl; pSpar_md_com_cfg->quant_strat[i].C.q_levels[1] = C_q_lvl; pSpar_md_com_cfg->quant_strat[i].C.max = 2; + pSpar_md_com_cfg->quant_strat[i].C.max_fx = 1073741824/2; pSpar_md_com_cfg->quant_strat[i].C.min = -2; + pSpar_md_com_cfg->quant_strat[i].C.min_fx = -1073741824/2; pSpar_md_com_cfg->quant_strat[i].P_r.q_levels[0] = Pr_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_r.q_levels[1] = Pr_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_r.max = 1.0f; + pSpar_md_com_cfg->quant_strat[i].P_r.max_fx = 536870912/2; pSpar_md_com_cfg->quant_strat[i].P_r.min = 0; + pSpar_md_com_cfg->quant_strat[i].P_r.min_fx = 0; pSpar_md_com_cfg->quant_strat[i].P_c.q_levels[0] = Pc_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_c.q_levels[1] = Pc_q_lvl; pSpar_md_com_cfg->quant_strat[i].P_c.max = 0.5; + pSpar_md_com_cfg->quant_strat[i].P_c.max_fx = 268435456/2; pSpar_md_com_cfg->quant_strat[i].P_c.min = -0.5; + pSpar_md_com_cfg->quant_strat[i].P_c.min_fx = -268435456/2; } } @@ -228,7 +291,7 @@ void ivas_spar_get_uniform_quant_strat_fx( * * Map prior coeffs *-----------------------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED void ivas_map_prior_coeffs_quant( ivas_spar_md_prev_t *pSpar_md_prior, ivas_spar_md_com_cfg *pSpar_md_cfg, @@ -241,19 +304,34 @@ void ivas_map_prior_coeffs_quant( { ivas_quant_strat_t qs = pSpar_md_cfg->quant_strat[qsi]; ivas_quant_strat_t prev_qs = pSpar_md_cfg->quant_strat[pSpar_md_cfg->prev_quant_idx]; - float one_by_q_lvl_PR = 1.0f / max( prev_qs.PR.q_levels[0] - 1, 1 ); - float one_by_q_lvl_C = 1.0f / max( prev_qs.C.q_levels[0] - 1, 1 ); - float one_by_q_lvl_P_r = 1.0f / max( prev_qs.P_r.q_levels[0] - 1, 1 ); + //float one_by_q_lvl_PR = 1.0f / max( prev_qs.PR.q_levels[0] - 1, 1 ); + Word32 one_by_q_lvl_PR_fx = one_by_q_level[max(prev_qs.PR.q_levels[0] - 1, 1) ]; + //float one_by_q_lvl_C = 1.0f / max( prev_qs.C.q_levels[0] - 1, 1 ); + Word32 one_by_q_lvl_C_fx = one_by_q_level[max(prev_qs.C.q_levels[0] - 1, 1) ]; + //float one_by_q_lvl_P_r = 1.0f / max( prev_qs.P_r.q_levels[0] - 1, 1 ); + Word32 one_by_q_lvl_P_r_fx = one_by_q_level[max(prev_qs.P_r.q_levels[0] - 1, 1) ]; for ( i = 0; i < nB; i++ ) { for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { - pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = (int16_t) round( ( qs.PR.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j] * one_by_q_lvl_PR ); - pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = (int16_t) round( ( qs.P_r.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j] * one_by_q_lvl_P_r ); + Word32 trial1 = (qs.PR.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j]; + trial1 = trial1 << 16; + trial1 = round_fx(Mpy_32_32(trial1, one_by_q_lvl_PR_fx)); + //pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = (int16_t) round( ( qs.PR.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j] * one_by_q_lvl_PR ); + pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = trial1; + Word32 trial2 = (qs.P_r.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j]; + trial2 = trial2 << 16; + trial2 = round_fx(Mpy_32_32(trial2, one_by_q_lvl_P_r_fx)); + //pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = (int16_t) round( ( qs.P_r.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j] * one_by_q_lvl_P_r ); + pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = trial2; } for ( j = 0; j < IVAS_SPAR_MAX_C_COEFF; j++ ) { - pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = (int16_t) round( ( qs.C.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j] * one_by_q_lvl_C ); + Word32 trial1 = (qs.C.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j]; + trial1 = trial1 << 16; + trial1 = round_fx(Mpy_32_32(trial1, one_by_q_lvl_C_fx)); + //pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = (int16_t) round( ( qs.C.q_levels[0] - 1 ) * pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j] * one_by_q_lvl_C ); + pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = trial1; } } } @@ -275,7 +353,64 @@ void ivas_map_prior_coeffs_quant( return; } +#else +void ivas_map_prior_coeffs_quant( + ivas_spar_md_prev_t *pSpar_md_prior, + ivas_spar_md_com_cfg *pSpar_md_cfg, + const int16_t qsi, + const int16_t nB) +{ + int16_t i, j; + + if (qsi != pSpar_md_cfg->prev_quant_idx) + { + ivas_quant_strat_t qs = pSpar_md_cfg->quant_strat[qsi]; + ivas_quant_strat_t prev_qs = pSpar_md_cfg->quant_strat[pSpar_md_cfg->prev_quant_idx]; + float one_by_q_lvl_PR = 1.0f / max(prev_qs.PR.q_levels[0] - 1, 1); + float one_by_q_lvl_C = 1.0f / max(prev_qs.C.q_levels[0] - 1, 1); + float one_by_q_lvl_P_r = 1.0f / max(prev_qs.P_r.q_levels[0] - 1, 1); + for (i = 0; i < nB; i++) + { + for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) + { + pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = (int16_t)round((qs.PR.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j] * one_by_q_lvl_PR); + pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = (int16_t)round((qs.P_r.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j] * one_by_q_lvl_P_r); + } + for (j = 0; j < IVAS_SPAR_MAX_C_COEFF; j++) + { + pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = (int16_t)round((qs.C.q_levels[0] - 1) * pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j] * one_by_q_lvl_C); + } + } + } + else + { + for (i = 0; i < nB; i++) + { + for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) + { + pSpar_md_prior->band_coeffs_idx_mapped[i].pred_index_re[j] = pSpar_md_prior->band_coeffs_idx[i].pred_index_re[j]; + pSpar_md_prior->band_coeffs_idx_mapped[i].decd_index_re[j] = pSpar_md_prior->band_coeffs_idx[i].decd_index_re[j]; + } + for (j = 0; j < IVAS_SPAR_MAX_C_COEFF; j++) + { + pSpar_md_prior->band_coeffs_idx_mapped[i].drct_index_re[j] = pSpar_md_prior->band_coeffs_idx[i].drct_index_re[j]; + } + } + } + + return; +} +#endif +void ivas_spar_quant_dtx_init_fx( + ivas_spar_md_t *spar_md, + Word32 *min_max) +{ + spar_md->min_max_fx[0] = min_max[0]; + spar_md->min_max_fx[1] = min_max[1]; + + return; +} /*-----------------------------------------------------------------------------------------* * Function ivas_spar_quant_dtx_init() @@ -371,11 +506,17 @@ void ivas_clear_band_coeffs( for ( i = 0; i < num_bands; i++ ) { set_zero( (float *) pband_coeffs[i].C_re, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); + set32_fx( (Word32 *) pband_coeffs[i].C_re_fx, 0, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); set_zero( (float *) pband_coeffs[i].P_re, ( IVAS_SPAR_MAX_CH - 1 ) ); + set32_fx( (Word32 *) pband_coeffs[i].P_re_fx, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); set_zero( (float *) pband_coeffs[i].C_quant_re, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); + set32_fx( (Word32 *) pband_coeffs[i].C_quant_re_fx, 0, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); set_zero( (float *) pband_coeffs[i].P_quant_re, ( IVAS_SPAR_MAX_CH - 1 ) ); + set32_fx( (Word32 *) pband_coeffs[i].P_quant_re_fx, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); set_zero( pband_coeffs[i].pred_re, ( IVAS_SPAR_MAX_CH - 1 ) ); + set32_fx( pband_coeffs[i].pred_re_fx, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); set_zero( pband_coeffs[i].pred_quant_re, ( IVAS_SPAR_MAX_CH - 1 ) ); + set32_fx( pband_coeffs[i].pred_quant_re_fx, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); } return; diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index af6923849..86a9bc830 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -180,12 +180,19 @@ typedef struct ivas_dirac_config_data_struct /* SPAR MD structures */ typedef struct ivas_band_coeffs_t { - float pred_re[IVAS_SPAR_MAX_CH - 1]; - float C_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1]; - float P_re[IVAS_SPAR_MAX_CH - 1]; + float pred_re[IVAS_SPAR_MAX_CH - 1];//22 + float C_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1];//22 + float P_re[IVAS_SPAR_MAX_CH - 1];//22 float pred_quant_re[IVAS_SPAR_MAX_CH - 1]; float C_quant_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1]; float P_quant_re[IVAS_SPAR_MAX_CH - 1]; + + Word32 pred_re_fx[IVAS_SPAR_MAX_CH - 1]; + Word32 C_re_fx[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1]; + Word32 P_re_fx[IVAS_SPAR_MAX_CH - 1]; + Word32 pred_quant_re_fx[IVAS_SPAR_MAX_CH - 1]; + Word32 C_quant_re_fx[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1]; + Word32 P_quant_re_fx[IVAS_SPAR_MAX_CH - 1]; } ivas_band_coeffs_t; typedef struct ivas_band_coeffs_ind_t @@ -202,9 +209,12 @@ typedef struct ivas_spar_md_t ivas_band_coeffs_ind_t band_coeffs_idx[IVAS_MAX_NUM_BANDS]; int16_t num_bands; float min_max[2]; + Word32 min_max_fx[2]; int16_t dtx_vad; float en_ratio_slow[IVAS_MAX_NUM_BANDS]; + Word32 en_ratio_slow_fx[IVAS_MAX_NUM_BANDS]; float ref_pow_slow[IVAS_MAX_NUM_BANDS]; + Word32 ref_pow_slow_fx[IVAS_MAX_NUM_BANDS]; int16_t res_ind; int16_t prior_dyn_active_w_flag; } ivas_spar_md_t; @@ -219,7 +229,9 @@ typedef struct ivas_spar_md_prev_t typedef struct ivas_quant_coeffs_t { float min; + Word32 min_fx; float max; + Word32 max_fx; int16_t q_levels[2]; } ivas_quant_coeffs_t; diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index de7ab4114..dbfb6699c 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -1944,7 +1944,6 @@ void bw_switching_pre_proc( { if ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) && st->hBWE_FD != NULL && !( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) && !( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_5k2 ) ) { - /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ calc_tilt_bwe( old_syn_12k8_16k, &st->tilt_wb, st->L_frame ); } @@ -2059,7 +2058,6 @@ void ivas_bw_switching_pre_proc_fx( { /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q , st->L_frame ); - st->tilt_wb = fix16_to_float(st->tilt_wb_fx, 11); } return; @@ -2072,13 +2070,11 @@ void ivas_bw_switching_pre_proc_fx( *----------------------------------------------------------------------*/ st->tilt_wb_fx = ivas_calc_tilt_bwe_fx( old_syn_12k8_16k_fx, Q, st->L_frame ); - st->tilt_wb = fix16_to_float(st->tilt_wb_fx, 11); /*-------------------------------------------------------------------------------* * Calculate frequency energy of 0~3.2kHz and 3.2~6.4kHz the ACELP core synthesis *-------------------------------------------------------------------------------*/ edct_fx(old_syn_12k8_16k_fx, syn_dct_fx, L_FRAME, &Q); - st->enerLL = EPSILON; Word64 W_tmp = 0; Word32 tmp; Word16 shift; @@ -2092,10 +2088,9 @@ void ivas_bw_switching_pre_proc_fx( tmp = L_shr(tmp, 8); tmp = getSqrtWord32(tmp); - st->enerLL = fixedToFloat(tmp, (Q + shift - 32) / 2); // Q / 2 st->enerLL_fx = tmp; + st->enerLL_fx_Q = (Q + shift - 32) / 2; - st->enerLH = EPSILON; W_tmp = 0; FOR ( ; i < L_FRAME; i++ ) { @@ -2106,8 +2101,8 @@ void ivas_bw_switching_pre_proc_fx( tmp = W_extract_h(W_tmp); // Q = Q + shift - 32 tmp = L_shr(tmp, 7); // divide by 128 tmp = getSqrtWord32(tmp); - st->enerLH = fixedToFloat(tmp, (Q + shift - 32) / 2); // Q / 2 st->enerLH_fx = tmp; + st->enerLH_fx_Q = ( Q + shift - 32 ) / 2; } ELSE @@ -2123,10 +2118,9 @@ void ivas_bw_switching_pre_proc_fx( } tmp = L_shr(L_tmp, 5); // divide by 32 tmp = getSqrtWord32(tmp); - st->enerLL = fixedToFloat(tmp, Q_audio); // Q / 2 st->enerLL_fx = tmp; + st->enerLL_fx_Q = Q_audio; - st->enerLH = EPSILON; L_tmp = 0; FOR ( ; i < 64; i++ ) { @@ -2135,12 +2129,11 @@ void ivas_bw_switching_pre_proc_fx( tmp = L_shr(L_tmp, 5); // divide by 32 tmp = getSqrtWord32(tmp); - st->enerLH = fixedToFloat(tmp, Q_audio); // Q / 2 st->enerLH_fx = tmp; + st->enerLH_fx_Q = Q_audio; } ELSE { - st->enerLL = EPSILON; Word32 tmp, L_tmp = 0; Word16 shift; L_tmp = 0; @@ -2150,8 +2143,8 @@ void ivas_bw_switching_pre_proc_fx( } tmp = L_shr(L_tmp, 5); // divide by 32 tmp = getSqrtWord32(tmp); - st->enerLL = fixedToFloat(tmp, Q_audio); // Q / 2 - st->enerLL_fx = tmp; + st->enerLL_fx = tmp; + st->enerLL_fx_Q = Q_audio; L_tmp = 0; FOR ( ; i < L_FRAME; i++ ) @@ -2160,14 +2153,15 @@ void ivas_bw_switching_pre_proc_fx( } tmp = L_shr(L_tmp, 5); // divide by 32 tmp = getSqrtWord32(tmp); - st->enerLL = fixedToFloat(tmp, Q_audio); // Q / 2 - st->enerLL_fx = tmp; + st->enerLL_fx = tmp; + st->enerLL_fx_Q = Q_audio; } } IF ( EQ_16( st->last_bwidth, 0 ) && LE_16( st->extl, SWB_CNG ) ) { st->prev_ener_shb = 0.0f; + st->prev_ener_shb_fx = 0; IF ( st->hBWE_FD != NULL ) { diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index 0c57c5b36..815d398a6 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -552,13 +552,16 @@ ivas_error evs_dec_flt( Word32 old_syn_12k8_16k_fx[L_FRAME16k]; Word16 norm = norm_arr_l(old_syn_12k8_16k, L_FRAME), q_old_syn, q_audio; Word16 gb = find_guarded_bits_fx(L_FRAME16k); - floatToFixed_arrL(old_syn_12k8_16k, old_syn_12k8_16k_fx, norm - gb, L_FRAME16k); + floatToFixed_arrL(old_syn_12k8_16k, old_syn_12k8_16k_fx, 11, L_FRAME16k); q_old_syn = norm - gb; norm = norm_arr_s(st->t_audio_q, L_FRAME); gb = find_guarded_bits_fx(L_FRAME); floatToFixed_arr(st->t_audio_q, st->t_audio_q_fx, norm - gb, L_FRAME); q_audio = norm - gb; - ivas_bw_switching_pre_proc_fx(st, -1, 1, old_syn_12k8_16k_fx, q_old_syn, q_audio); + ivas_bw_switching_pre_proc_fx(st, -1, 1, old_syn_12k8_16k_fx, 11, q_audio); + st->enerLH = fixedToFloat(st->enerLH_fx, st->enerLH_fx_Q); // Q / 2 + st->tilt_wb = fix16_to_float(st->tilt_wb_fx, 11); + st->enerLL = fixedToFloat(st->enerLL_fx, st->enerLL_fx_Q ); #else bw_switching_pre_proc( st, old_syn_12k8_16k, -1, 1 ); #endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 95cb9a086..c6bdc167a 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1781,16 +1781,19 @@ ivas_error ivas_core_dec( #ifdef IVAS_FLOAT_FIXED Word32 old_syn_12k8_16k_fx[L_FRAME16k]; - Word16 norm = norm_arr_l(old_syn_12k8_16k[n], L_FRAME), q_old_syn, q_audio; - Word16 gb = find_guarded_bits_fx(L_FRAME16k); - floatToFixed_arrL(old_syn_12k8_16k[n], old_syn_12k8_16k_fx, norm - gb, L_FRAME16k); - q_old_syn = norm - gb; + Word16 gb, norm, q_audio, old_syn_fx; + old_syn_fx = Q11; + floatToFixed_arrL(old_syn_12k8_16k[n], old_syn_12k8_16k_fx, old_syn_fx, L_FRAME16k); norm = norm_arr_s(st->t_audio_q, L_FRAME); gb = find_guarded_bits_fx(L_FRAME); floatToFixed_arr(st->t_audio_q, st->t_audio_q_fx, norm - gb, L_FRAME); q_audio = norm - gb; - ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx, q_old_syn, q_audio ); + ivas_bw_switching_pre_proc_fx( st, last_element_brate, nchan_out, old_syn_12k8_16k_fx, old_syn_fx, q_audio ); + st->enerLH = fixedToFloat(st->enerLH_fx, st->enerLH_fx_Q); // Q / 2 + st->tilt_wb = fix16_to_float(st->tilt_wb_fx, 11); + st->enerLL = fixedToFloat(st->enerLL_fx, st->enerLL_fx_Q); + #else bw_switching_pre_proc( st, old_syn_12k8_16k, last_element_brate, nchan_out ); #endif diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 2bae89389..5ad42bd4c 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -335,7 +335,7 @@ ivas_error ivas_cpe_dec_fx( * Resets/updates in case of stereo switching *----------------------------------------------------------------*/ Word16 q_temp = 11;//any q works - FOR(n = 0; n < hCPE->nchan_out; n++) + FOR(n = 0; n < CPE_CHANNELS; n++) { if (hCPE->output_mem[n] != NULL) { @@ -363,7 +363,7 @@ ivas_error ivas_cpe_dec_fx( stereo_switching_dec( hCPE, ivas_total_brate ); - FOR(n = 0; n < hCPE->nchan_out; n++) + FOR(n = 0; n < CPE_CHANNELS; n++) { if (hCPE->output_mem[n] != NULL) { diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 7803d68d2..cd7f29bee 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2042,26 +2042,33 @@ void ivas_dirac_dec_read_BS( Word16 i, j, b, dir, orig_dirac_bands; Word16 next_bit_pos_orig; - IF( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) + test(); + test(); + IF( !st->bfi && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) { next_bit_pos_orig = st->next_bit_pos; - st->next_bit_pos = (Word16) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); - IF( last_bit_pos > 0 ) + move16(); + st->next_bit_pos = extract_l( L_sub( ivas_total_brate / FRAMES_PER_SEC, 1 ) ); + IF( GT_16( last_bit_pos, 0 ) ) { st->next_bit_pos = last_bit_pos; + move16(); } /* 1 bit flag for signaling metadata to read */ b = st->bit_stream[( st->next_bit_pos )--]; + move16(); ( *nb_bits )++; - IF( b == 1 ) /* WB 4TCs condition, no other metadata to read*/ + IF( EQ_16( b, 1 ) ) /* WB 4TCs condition, no other metadata to read*/ { orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; + move16(); hQMetaData->sba_inactive_mode = 1; + move16(); /* if we start with a SID frame, we need to init the azi/ele arrays.*/ - IF( st->ini_frame == 0 ) + IF( EQ_16( st->ini_frame, 0 ) ) { FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { @@ -2069,60 +2076,77 @@ void ivas_dirac_dec_read_BS( set32_fx( hQMetaData->q_direction[0].band_data[b].elevation_fx, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); } } - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); + *nb_bits = add( *nb_bits, ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ) ); FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[1].azimuth_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[1].elevation_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_index[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_index[0]; + move16(); } FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - FOR( j = orig_dirac_bands - 2; j >= 0; j-- ) + FOR( j = sub( orig_dirac_bands, 2 ); j >= 0; j-- ) { hQMetaData->q_direction[0].band_data[j].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].elevation_fx[i] = hQMetaData->q_direction[0].band_data[0].elevation_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].energy_ratio_index[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_index[0]; + move16(); } } hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; + move16(); } ELSE { hQMetaData->sba_inactive_mode = 0; + move16(); hQMetaData->is_masa_ivas_format = 0; IF( hQMetaData->useLowerRes ) { hQMetaData->q_direction[0].cfg.nblocks = 1; + move16(); } ELSE { hQMetaData->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES; + move16(); } - *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), hodirac_flag ); + *nb_bits = add( *nb_bits, ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), hodirac_flag ) ); } - st->next_bit_pos = next_bit_pos_orig; + move16(); } - ELSE IF( !st->bfi && ivas_total_brate == IVAS_SID_5k2 ) + ELSE IF( !st->bfi && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) ) { next_bit_pos_orig = st->next_bit_pos; + move16(); /* subtract mode signaling bits, since bitstream was moved after mode reading */ - st->next_bit_pos = (Word16) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS ); + st->next_bit_pos = extract_l( L_sub( L_sub( ivas_total_brate / FRAMES_PER_SEC, 1 ), SID_FORMAT_NBITS ) ); + move16(); /* 1 bit flag for signaling metadata to read */ b = st->bit_stream[( st->next_bit_pos )--]; + move16(); ( *nb_bits )++; hQMetaData->sba_inactive_mode = 1; + move16(); orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; + move16(); /* if we start with a SID frame, we need to init the azi/ele arrays.*/ - IF( st->ini_frame == 0 ) + IF( EQ_16( st->ini_frame, 0 ) ) { FOR( dir = 0; dir < hQMetaData->no_directions; dir++ ) { @@ -2133,59 +2157,45 @@ void ivas_dirac_dec_read_BS( } } } - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ); + *nb_bits = add( *nb_bits, ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT ) ); FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[1].azimuth_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation_fx[i] = hQMetaData->q_direction[0].band_data[1].elevation_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio_index[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio_index[0]; + move16(); } FOR( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - FOR( j = orig_dirac_bands - 2; j >= 0; j-- ) + FOR( j = sub( orig_dirac_bands, 2 ); j >= 0; j-- ) { hQMetaData->q_direction[0].band_data[j].azimuth_fx[i] = hQMetaData->q_direction[0].band_data[0].azimuth_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].elevation_fx[i] = hQMetaData->q_direction[0].band_data[0].elevation_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].energy_ratio_fx[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[j].energy_ratio_index[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio_index[0]; + move16(); } } hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; + move16(); st->next_bit_pos = next_bit_pos_orig; + move16(); } - + IF( hDirAC != NULL && hSpatParamRendCom != NULL ) { - for (i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++) { - for ( j = 0; j < hSpatParamRendCom->num_freq_bands; j++) { - hSpatParamRendCom->diffuseness_vector_fx[i][j] = float_to_fix(hSpatParamRendCom->diffuseness_vector[i][j], 30); - hSpatParamRendCom->energy_ratio1_fx[i][j] = float_to_fix(hSpatParamRendCom->energy_ratio1[i][j], 30); - IF(hodirac_flag) - { - hSpatParamRendCom->energy_ratio2_fx[i][j] = float_to_fix(hSpatParamRendCom->energy_ratio2[i][j], 30); - } - hSpatParamRendCom->surroundingCoherence_fx[i][j] = float_to_fix16(hSpatParamRendCom->surroundingCoherence[i][j], 15); - hSpatParamRendCom->spreadCoherence_fx[i][j] = float_to_fix16(hSpatParamRendCom->spreadCoherence[i][j], 15); - } - } ivas_qmetadata_to_dirac_fx( hQMetaData, hDirAC, NULL, hSpatParamRendCom, ivas_total_brate, SBA_FORMAT, hodirac_flag, dirac_to_spar_md_bands ); - - for (i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++) { - for ( j = 0; j < hSpatParamRendCom->num_freq_bands; j++) { - hSpatParamRendCom->diffuseness_vector[i][j] = fix_to_float(hSpatParamRendCom->diffuseness_vector_fx[i][j], 30); - hSpatParamRendCom->energy_ratio1[i][j] = fix_to_float(hSpatParamRendCom->energy_ratio1_fx[i][j], 30); - IF(hodirac_flag) - { - hSpatParamRendCom->energy_ratio2[i][j] = fix_to_float(hSpatParamRendCom->energy_ratio2_fx[i][j], 30); - } - hSpatParamRendCom->surroundingCoherence[i][j] = fix_to_float(hSpatParamRendCom->surroundingCoherence_fx[i][j], 15); - hSpatParamRendCom->spreadCoherence[i][j] = fix_to_float(hSpatParamRendCom->spreadCoherence_fx[i][j], 15); - } - } } + return; } #else @@ -2339,10 +2349,10 @@ void ivas_qmetadata_to_dirac_fx( DIRAC_DEC_HANDLE hDirAC, /* i : DirAC decoder structure */ MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */ SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ - const Word32 ivas_total_brate, /* i : IVAS total bitrate */ + const Word32 ivas_total_brate, /* i : IVAS total bitrate */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */ - Word16 *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ + const Word16 hodirac_flag, /* i : flag to indicate HO-DirAC mode */ + Word16 *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */ ) { Word16 block, band; @@ -2360,95 +2370,115 @@ void ivas_qmetadata_to_dirac_fx( Word16 qBand_idx; Word16 idx_sec = 0; Word16 no_secs = 1; - q_direction = &(hQMetaData->q_direction[0]); + q_direction = &( hQMetaData->q_direction[0] ); hSpatParamRendCom->numParametricDirections = hQMetaData->no_directions; - hSpatParamRendCom->numSimultaneousDirections = add(hSpatParamRendCom->numParametricDirections , hSpatParamRendCom->numIsmDirections); - - IF (hMasa != NULL && ivas_total_brate > IVAS_SID_5k2) + hSpatParamRendCom->numSimultaneousDirections = add( hSpatParamRendCom->numParametricDirections, hSpatParamRendCom->numIsmDirections ); + + test(); + IF( hMasa != NULL && GT_32( ivas_total_brate, IVAS_SID_5k2 ) ) { Word16 meta_write_index; band_mapping = hMasa->data.band_mapping; + move16(); - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) { - meta_write_index = (hSpatParamRendCom->dirac_bs_md_write_idx + block) % hSpatParamRendCom->dirac_md_buffer_length; + meta_write_index = add( hSpatParamRendCom->dirac_bs_md_write_idx, block ) % hSpatParamRendCom->dirac_md_buffer_length; - FOR (band = 0; band < hMasa->config.numCodingBands; ++band) + FOR( band = 0; band < hMasa->config.numCodingBands; ++band ) { - FOR (b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b) + FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { - hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h(L_shr(q_direction->band_data[band].azimuth_fx[block], 6)); - hSpatParamRendCom->elevation[meta_write_index][b] = extract_h(L_shr(q_direction->band_data[band].elevation_fx[block], 6)); + hSpatParamRendCom->azimuth[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + move16(); + hSpatParamRendCom->elevation[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + move16(); hSpatParamRendCom->energy_ratio1_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; - hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub(ONE_IN_Q30, q_direction->band_data[band].energy_ratio_fx[block]); + move32(); + hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( ONE_IN_Q30, q_direction->band_data[band].energy_ratio_fx[block] ); + move32(); - IF (q_direction->coherence_band_data != NULL) + IF( q_direction->coherence_band_data != NULL ) { hSpatParamRendCom->spreadCoherence_fx[meta_write_index][b] = ivas_divde_255[q_direction->coherence_band_data[band].spread_coherence[block]]; + move16(); } ELSE { hSpatParamRendCom->spreadCoherence_fx[meta_write_index][b] = 0; + move16(); } - IF (hQMetaData->surcoh_band_data != NULL) + IF( hQMetaData->surcoh_band_data != NULL ) { - hSpatParamRendCom->surroundingCoherence_fx[meta_write_index][b] = ivas_divde_255[hQMetaData->surcoh_band_data[band].surround_coherence[block]];/*q15*/ + hSpatParamRendCom->surroundingCoherence_fx[meta_write_index][b] = ivas_divde_255[hQMetaData->surcoh_band_data[band].surround_coherence[block]]; /*q15*/ + move16(); } ELSE { hSpatParamRendCom->surroundingCoherence_fx[meta_write_index][b] = 0; + move16(); } } } } - IF (hQMetaData->no_directions == 2) + test(); + test(); + test(); + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { - q_direction = &(hQMetaData->q_direction[1]); - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block) + q_direction = &( hQMetaData->q_direction[1] ); + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) { - meta_write_index = (add(hSpatParamRendCom->dirac_bs_md_write_idx , block)) % hSpatParamRendCom->dirac_md_buffer_length; + meta_write_index = ( add( hSpatParamRendCom->dirac_bs_md_write_idx, block ) ) % hSpatParamRendCom->dirac_md_buffer_length; - FOR (band = 0; band < hMasa->config.numCodingBands; ++band) + FOR( band = 0; band < hMasa->config.numCodingBands; ++band ) { - FOR (b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b) + FOR( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b ) { - hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h(L_shr(q_direction->band_data[band].azimuth_fx[block], 6)); - hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h(L_shr(q_direction->band_data[band].elevation_fx[block], 6)); + hSpatParamRendCom->azimuth2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].azimuth_fx[block], 6 ) ); + move16(); + hSpatParamRendCom->elevation2[meta_write_index][b] = extract_h( L_shr( q_direction->band_data[band].elevation_fx[block], 6 ) ); + move16(); hSpatParamRendCom->energy_ratio2_fx[meta_write_index][b] = q_direction->band_data[band].energy_ratio_fx[block]; - hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub(hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], q_direction->band_data[band].energy_ratio_fx[block]); + move32(); + hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = L_sub( hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], q_direction->band_data[band].energy_ratio_fx[block] ); + move32(); /* Sanitize diffuseness for rare cases where floating point inaccuracy could result in negative diffuseness. */ - IF(hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] < 0) + IF( LT_32( hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b], 0 ) ) { hSpatParamRendCom->diffuseness_vector_fx[meta_write_index][b] = 0; + move32(); } - IF (q_direction->coherence_band_data != NULL) + IF( q_direction->coherence_band_data != NULL ) { hSpatParamRendCom->spreadCoherence2_fx[meta_write_index][b] = ivas_divde_255[q_direction->coherence_band_data[band].spread_coherence[block]]; + move16(); } ELSE { hSpatParamRendCom->spreadCoherence2_fx[meta_write_index][b] = 0; + move16(); } } } } } - ELSE IF (hSpatParamRendCom->azimuth2 != NULL && hSpatParamRendCom->elevation2 != NULL && hSpatParamRendCom->energy_ratio2_fx != NULL && hSpatParamRendCom->spreadCoherence2_fx != NULL) + ELSE IF( hSpatParamRendCom->azimuth2 != NULL && hSpatParamRendCom->elevation2 != NULL && hSpatParamRendCom->energy_ratio2_fx != NULL && hSpatParamRendCom->spreadCoherence2_fx != NULL ) { /* zero out old dir2 data */ - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) { - meta_write_index = add(hSpatParamRendCom->dirac_bs_md_write_idx , block) % hSpatParamRendCom->dirac_md_buffer_length; - set16_fx(hSpatParamRendCom->azimuth2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands); - set16_fx(hSpatParamRendCom->elevation2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands); - - set32_fx(hSpatParamRendCom->energy_ratio2_fx[meta_write_index], 0, hSpatParamRendCom->num_freq_bands); - set16_fx(hSpatParamRendCom->spreadCoherence2_fx[meta_write_index], 0, hSpatParamRendCom->num_freq_bands); + meta_write_index = add( hSpatParamRendCom->dirac_bs_md_write_idx, block ) % hSpatParamRendCom->dirac_md_buffer_length; + set16_fx( hSpatParamRendCom->azimuth2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands ); + set16_fx( hSpatParamRendCom->elevation2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands ); + + set32_fx( hSpatParamRendCom->energy_ratio2_fx[meta_write_index], 0, hSpatParamRendCom->num_freq_bands ); + set16_fx( hSpatParamRendCom->spreadCoherence2_fx[meta_write_index], 0, hSpatParamRendCom->num_freq_bands ); } } } @@ -2456,138 +2486,181 @@ void ivas_qmetadata_to_dirac_fx( { Word16 tmp_write_idx_param_band; Word16 tmp_write_idx_band; - + Word32 diffuseness_sec_fx = 0; + move32(); /* ungroup */ seed_ptr = &hDirAC->dithering_seed; nblocks = q_direction->cfg.nblocks; + move16(); nbands = hDirAC->band_grouping[hDirAC->hConfig->nbands]; + move16(); band_grouping = hDirAC->band_grouping; - IF (ivas_total_brate <= IVAS_SID_5k2 && ivas_format != SBA_FORMAT) + test(); + IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) && NE_32( ivas_format, SBA_FORMAT ) ) { /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/ start_band = 0; + move16(); hDirAC->hConfig->nbands = 5; - ivas_dirac_config_bands_fx(hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, NULL, 0, 0, NULL); + move16(); + ivas_dirac_config_bands_fx( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, NULL, 0, 0, NULL ); nbands = 5; + move16(); } ELSE { start_band = hDirAC->hConfig->enc_param_start_band; - IF (ivas_format == SBA_FORMAT) + move16(); + IF( EQ_32( ivas_format, SBA_FORMAT ) ) { hDirAC->hConfig->nbands = IVAS_MAX_NUM_BANDS; + move16(); } ELSE { hDirAC->hConfig->nbands = q_direction->cfg.nbands; + move16(); } - ivas_dirac_config_bands_fx(hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hDirAC->hConfig->enc_param_start_band, hDirAC->hFbMdft); + ivas_dirac_config_bands_fx( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hDirAC->hConfig->enc_param_start_band, hDirAC->hFbMdft ); nbands = hDirAC->hConfig->nbands; - IF (hQMetaData->q_direction[0].cfg.nblocks == 0) + move16(); + IF( EQ_16( hQMetaData->q_direction[0].cfg.nblocks, 0 ) ) { /* No transmission -> no copy from qmetadata buffers*/ nbands = start_band; + move16(); } } /* Low-Bands with no spatial data transmitted, analysis at decoder side */ - FOR (band = 0; band < start_band; band++) + FOR( band = 0; band < start_band; band++ ) { band_start = band_grouping[band]; + move16(); band_end = band_grouping[band + 1]; + move16(); tmp_write_idx_param_band = hSpatParamRendCom->dirac_bs_md_write_idx; + move16(); - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { - FOR (b = band_start; b < band_end; b++) + FOR( b = band_start; b < band_end; b++ ) { tmp_write_idx_band = tmp_write_idx_param_band; - + move16(); + hSpatParamRendCom->spreadCoherence_fx[block][b] = 0; + move16(); hSpatParamRendCom->surroundingCoherence_fx[block][b] = 0; + move16(); hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = 0; + move32(); hSpatParamRendCom->spreadCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->surroundingCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->energy_ratio1_fx[tmp_write_idx_band][b] = 0; + move32(); hSpatParamRendCom->elevation[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = 0; + move16(); - tmp_write_idx_band = (tmp_write_idx_band + 1) % hSpatParamRendCom->dirac_md_buffer_length; + tmp_write_idx_band = add( tmp_write_idx_band, 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + move16(); } } } /* Bands with spatial data transmitted */ - IF (hodirac_flag) + IF( hodirac_flag ) { no_secs = DIRAC_HO_NUMSECTORS; + move16(); } - FOR (idx_sec = 0; idx_sec < no_secs; idx_sec++) + FOR( idx_sec = 0; idx_sec < no_secs; idx_sec++ ) { - FOR (band = start_band; band < nbands; band++) + FOR( band = start_band; band < nbands; band++ ) { band_start = band_grouping[band]; + move16(); band_end = band_grouping[band + 1]; + move16(); tmp_write_idx_param_band = hSpatParamRendCom->dirac_bs_md_write_idx; + move16(); - IF (ivas_format == SBA_FORMAT) + IF( EQ_32( ivas_format, SBA_FORMAT ) ) { - qBand_idx = dirac_to_spar_md_bands[band] - start_band; + qBand_idx = sub( dirac_to_spar_md_bands[band], start_band ); + move16(); } ELSE { qBand_idx = band; + move16(); } diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0]; + move16(); - diffuseness_fx = L_sub(ONE_IN_Q30 , q_direction->band_data[qBand_idx].energy_ratio_fx[0]); + diffuseness_fx = L_sub( ONE_IN_Q30, q_direction->band_data[qBand_idx].energy_ratio_fx[0] ); + move32(); - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { Word16 block_qmetadata; - block_qmetadata = min(block, nblocks - 1); - block_qmetadata = max(block_qmetadata, 0); + block_qmetadata = s_min( block, sub( nblocks, 1 ) ); + block_qmetadata = s_max( block_qmetadata, 0 ); + - - IF(q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata] < 0) + IF( LT_32( q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata], 0 ) ) { - q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata] = L_add(q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata], 1509949440/*360.0F in Q22*/); + q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata] = L_add( q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata], 1509949440 /*360.0F in Q22*/ ); + move32(); } - - IF (hMasa == NULL && hodirac_flag) + + test(); + IF( hMasa == NULL && hodirac_flag ) { azimuth_fx = q_direction[idx_sec].band_data[qBand_idx].azimuth_fx[block_qmetadata]; + move32(); elevation_fx = q_direction[idx_sec].band_data[qBand_idx].elevation_fx[block_qmetadata]; - diffuseness_fx = L_sub(ONE_IN_Q30, q_direction[0].band_data[qBand_idx].energy_ratio_fx[block_qmetadata]); + move32(); + diffuseness_fx = L_sub( ONE_IN_Q30, q_direction[0].band_data[qBand_idx].energy_ratio_fx[block_qmetadata] ); diffuseness_sec_fx = q_direction[1].band_data[qBand_idx].energy_ratio_fx[block_qmetadata]; - assert(diffuseness_sec_fx < 1073849216/*1.0001f in Q30*/ && diffuseness_sec_fx > -107374/*-0.0001f in Q30*/); + move32(); + assert( diffuseness_sec_fx < 1073849216 /*1.0001f in Q30*/ && diffuseness_sec_fx > -107374 /*-0.0001f in Q30*/ ); } ELSE { azimuth_fx = q_direction->band_data[qBand_idx].azimuth_fx[block_qmetadata]; + move32(); elevation_fx = q_direction->band_data[qBand_idx].elevation_fx[block_qmetadata]; + move32(); } - FOR (b = band_start; b < band_end; b++) + FOR( b = band_start; b < band_end; b++ ) { tmp_write_idx_band = tmp_write_idx_param_band; + move16(); - IF (hodirac_flag) + IF( hodirac_flag ) { - azi = extract_h(L_shr((L_add(azimuth_fx, ONE_IN_Q21)), 6)); - ele = extract_h(L_shr((L_add(elevation_fx, ONE_IN_Q21)), 6)); + azi = extract_h( L_shr( ( L_add( azimuth_fx, ONE_IN_Q21 ) ), 6 ) ); + ele = extract_h( L_shr( ( L_add( elevation_fx, ONE_IN_Q21 ) ), 6 ) ); /*addition of one to compensate precision loss*/ - IF (azi < 0) { - azi += 1; + IF( LT_16( azi, 0 ) ) + { + azi = add( azi, 1 ); } - IF (ele < 0) { - ele += 1; + IF( LT_16( ele, 0 ) ) + { + ele = add( ele, 1 ); } } ELSE @@ -2596,111 +2669,143 @@ void ivas_qmetadata_to_dirac_fx( Word16 a, b_tmp; Word16 exp_factor = 0; - a = rand_triangular_signed_fx(seed_ptr, &exp_factor);//q = exp_factor - tmp1 = mult(a, dirac_dithering_azi_scale_fx[diff_idx]); // exp_factor + 5 + move16(); + a = rand_triangular_signed_fx( seed_ptr, &exp_factor ); // q = exp_factor + move16(); + tmp1 = mult( a, dirac_dithering_azi_scale_fx[diff_idx] ); // exp_factor + 5 - Word32 tmp1_32 = L_deposit_h(tmp1); + Word32 tmp1_32 = L_deposit_h( tmp1 ); Word16 final_1_exp; - Word32 final_1_32 = BASOP_Util_Add_Mant32Exp(azimuth_fx, 9, tmp1_32, exp_factor + 5, &final_1_exp); - b_tmp = rand_triangular_signed_fx(seed_ptr, &exp_factor);//q = exp_factor - tmp4 = mult(b_tmp, dirac_dithering_ele_scale_fx[diff_idx]);//exp_factor + 4 + Word32 final_1_32 = BASOP_Util_Add_Mant32Exp( azimuth_fx, 9, tmp1_32, exp_factor + 5, &final_1_exp ); + b_tmp = rand_triangular_signed_fx( seed_ptr, &exp_factor ); // q = exp_factor + move16(); + tmp4 = mult( b_tmp, dirac_dithering_ele_scale_fx[diff_idx] ); // exp_factor + 4 - Word32 tmp4_32 = L_deposit_h(tmp4); + Word32 tmp4_32 = L_deposit_h( tmp4 ); Word16 final_2_exp; - Word32 final_2_32 = BASOP_Util_Add_Mant32Exp(elevation_fx, 9, tmp4_32, exp_factor + 4, &final_2_exp); + Word32 final_2_32 = BASOP_Util_Add_Mant32Exp( elevation_fx, 9, tmp4_32, exp_factor + 4, &final_2_exp ); - final_1_32 = BASOP_Util_Add_Mant32Exp(final_1_32, final_1_exp, ONE_IN_Q30, 0, &final_1_exp);/*0.5 in q31*/ - final_2_32 = BASOP_Util_Add_Mant32Exp(final_2_32, final_2_exp, ONE_IN_Q30, 0, &final_2_exp); + final_1_32 = BASOP_Util_Add_Mant32Exp( final_1_32, final_1_exp, ONE_IN_Q30, 0, &final_1_exp ); /*0.5 in q31*/ + final_2_32 = BASOP_Util_Add_Mant32Exp( final_2_32, final_2_exp, ONE_IN_Q30, 0, &final_2_exp ); - azi = extract_h(L_shr(final_1_32, 31 - final_1_exp - 16)); - ele = extract_h(L_shr(final_2_32, 31 - final_2_exp - 16)); + azi = extract_h( L_shr( final_1_32, 31 - final_1_exp - 16 ) ); + ele = extract_h( L_shr( final_2_32, 31 - final_2_exp - 16 ) ); /*addition of one to compensate precision loss*/ - IF (azi < 0) { - azi += 1; + IF( LT_16( azi, 0 ) ) + { + azi = add( azi, 1 ); } - IF (ele < 0) { - ele += 1; + IF( LT_16( ele, 0 ) ) + { + ele = add( ele, 1 ); } /* limit the elevation to [-90, 90] */ - ele = min(90, ele); - ele = max(-90, ele); + ele = s_min( 90, ele ); + ele = s_max( -90, ele ); } - IF (ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL) + test(); + IF( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && q_direction->coherence_band_data != NULL ) { hSpatParamRendCom->spreadCoherence_fx[tmp_write_idx_band][b] = ivas_divde_255[q_direction->coherence_band_data[qBand_idx].spread_coherence[block]]; + move16(); } ELSE { hSpatParamRendCom->spreadCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); } - IF (ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL) + test(); + IF( GT_32( ivas_total_brate, IVAS_SID_5k2 ) && q_direction->coherence_band_data != NULL ) { hSpatParamRendCom->surroundingCoherence_fx[tmp_write_idx_band][b] = ivas_divde_255[hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0]]; + move16(); } ELSE { hSpatParamRendCom->surroundingCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); } - + hSpatParamRendCom->energy_ratio1_fx[tmp_write_idx_band][b] = q_direction->band_data[qBand_idx].energy_ratio_fx[0]; + move32(); hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = diffuseness_fx; + move32(); - IF (hodirac_flag) + IF( hodirac_flag ) { - IF (idx_sec == 0) + IF( EQ_16( idx_sec, 0 ) ) { hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele; + move16(); hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi; + move16(); hSpatParamRendCom->energy_ratio1_fx[tmp_write_idx_band][b] = 0; + move32(); } ELSE { - assert(idx_sec == 1); + assert( idx_sec == 1 ); hSpatParamRendCom->elevation2[tmp_write_idx_band][b] = ele; + move16(); hSpatParamRendCom->azimuth2[tmp_write_idx_band][b] = azi; - hSpatParamRendCom->energy_ratio2_fx[tmp_write_idx_band][b] = L_sub(ONE_IN_Q30 , diffuseness_sec_fx); + move16(); + hSpatParamRendCom->energy_ratio2_fx[tmp_write_idx_band][b] = L_sub( ONE_IN_Q30, diffuseness_sec_fx ); + move32(); } } ELSE { hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele; + move16(); hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi; + move16(); } } - tmp_write_idx_param_band = (tmp_write_idx_param_band + 1) % hSpatParamRendCom->dirac_md_buffer_length; + tmp_write_idx_param_band = add( tmp_write_idx_param_band, 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + move16(); } /* for ( block =...) */ } /* for ( band = ...) */ } /* for ( idx_sec = ...)*/ /* Bands not transmitted -> zeroed*/ - FOR (b = band_grouping[band]; b < hSpatParamRendCom->num_freq_bands; b++) + FOR( b = band_grouping[band]; b < hSpatParamRendCom->num_freq_bands; b++ ) { tmp_write_idx_band = hSpatParamRendCom->dirac_bs_md_write_idx; + move16(); - FOR (block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) { hSpatParamRendCom->spreadCoherence_fx[block][b] = 0; + move16(); hSpatParamRendCom->surroundingCoherence_fx[block][b] = 0; + move16(); hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = 0; + move32(); hSpatParamRendCom->spreadCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->surroundingCoherence_fx[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->energy_ratio1_fx[block][b] = 0; + move32(); hSpatParamRendCom->energy_ratio1_fx[tmp_write_idx_band][b] = 0; + move32(); hSpatParamRendCom->elevation[tmp_write_idx_band][b] = 0; + move16(); hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = 0; + move16(); - tmp_write_idx_band = add(tmp_write_idx_band , 1) % hSpatParamRendCom->dirac_md_buffer_length; + tmp_write_idx_band = add( tmp_write_idx_band, 1 ) % hSpatParamRendCom->dirac_md_buffer_length; } } } /* update buffer write index */ - hSpatParamRendCom->dirac_bs_md_write_idx = (hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES) % hSpatParamRendCom->dirac_md_buffer_length; + hSpatParamRendCom->dirac_bs_md_write_idx = add( hSpatParamRendCom->dirac_bs_md_write_idx, MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length; return; } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index af681b941..1335b4aa1 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -708,10 +708,17 @@ ivas_error ivas_jbm_dec_tc( } else if ( st_ivas->ivas_format == SBA_FORMAT ) { +#ifdef IVAS_FLOAT_FIXED + IF( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) { return error; } +#endif } if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) @@ -1534,10 +1541,17 @@ ivas_error ivas_jbm_dec_tc( } /* SBA metadata decoding */ +#ifdef IVAS_FLOAT_FIXED + IF( ( error = ivas_spar_dec_fx( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) { return error; } +#endif if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) { diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index c0a73c12d..369ca37b0 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -152,96 +152,114 @@ Word16 ivas_qmetadata_dec_decode( Word16 bits_dir_used; Word16 reduce_bits; Word16 ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; + Word32 tmp32; ec_flag = 0; + move16(); start_index_0 = *index; + move16(); /*Coherence flag decoding*/ bits_no_dirs_coh = 0; + move16(); all_coherence_zero = 1; + move16(); IF( hQMetaData->coherence_flag ) { /* read if coherence is zero */ all_coherence_zero = bitstream[( *index )--]; - bits_no_dirs_coh += 1; + move16(); + bits_no_dirs_coh = add( bits_no_dirs_coh, 1 ); } hQMetaData->all_coherence_zero = (UWord8) all_coherence_zero; - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { /* Read which bands have 2 directions */ hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; + move16(); set_c( (Word8 *) hQMetaData->twoDirBands, 0, hQMetaData->q_direction[0].cfg.nbands ); d = *index; + move16(); dif_p[0] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); + move16(); p[0] = dif_p[0]; + move16(); hQMetaData->twoDirBands[p[0]] = 1; FOR( b = 1; b < hQMetaData->numTwoDirBands; b++ ) { dif_p[b] = ivas_qmetadata_DecodeExtendedGR( bitstream, index, MASA_MAXIMUM_CODING_SUBBANDS, 0 ); - p[b] = p[b - 1] + dif_p[b] + 1; + move16(); + p[b] = add( add( p[b - 1], dif_p[b] ), 1 ); hQMetaData->twoDirBands[p[b]] = 1; } - bits_no_dirs_coh += ( d - *index ); + bits_no_dirs_coh = add( bits_no_dirs_coh, sub( d, *index ) ); } bits_diff_sum = 0; - bits_diff_sum += ivas_qmetadata_entropy_decode_diffuseness( bitstream, index, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ); + move16(); + bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_diffuseness( bitstream, index, &( hQMetaData->q_direction[0] ), &diffuseness_index_max_ec_frame_pre[0] ) ); IF( hodirac_flag ) { - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { /* Calculate bits for dfRatio */ dir2band = 0; + move16(); FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { - IF( hQMetaData->twoDirBands[b] == 1 ) + IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { dfRatio_bits[dir2band] = ivas_get_df_ratio_bits_hodirac( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); + move16(); dir2band++; } } - bits_diff_sum += ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ); + bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) ); } } ELSE { - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { /* Calculate bits for dfRatio */ dir2band = 0; + move16(); FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { - IF( hQMetaData->twoDirBands[b] == 1 ) + IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { dfRatio_bits[dir2band] = ivas_get_df_ratio_bits( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] ); + move16(); dir2band++; } } - bits_diff_sum += ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ); + bits_diff_sum = add( bits_diff_sum, ivas_qmetadata_entropy_decode_df_ratio( bitstream, index, &( hQMetaData->q_direction[1] ), dfRatio_bits ) ); } } /* Calculate direct-to-total energy ratios for both directions from diffuse-to-total ratio and distribution factor of direct-to-total ratios */ - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { dir2band = 0; + move16(); FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { - IF( hQMetaData->twoDirBands[b] == 1 ) + IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { Word32 diffRatio_fx, dir1ratio_fx, dir2ratio_fx; Word16 dfRatio_fx; Word16 dfRatio_qsteps; diffRatio_fx = diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; // Q30 + move32(); - dfRatio_qsteps = 1 << dfRatio_bits[dir2band]; + dfRatio_qsteps = shl( 1, dfRatio_bits[dir2band] ); /* already encoded as total and ratios in HO-DirAC */ IF( hodirac_flag ) { @@ -261,26 +279,33 @@ Word16 ivas_qmetadata_dec_decode( /* Requantize the 1 - dirRatio separately for each direction to obtain inverted dirRatio index. These are used in further decoding. */ hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir1ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); + move16(); IF( hodirac_flag ) { Word16 tmp_fx; hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = usquant_fx( extract_h( dir2ratio_fx ), &tmp_fx, 0, INV_DIRAC_DIFFUSE_LEVELS_Q13, DIRAC_DIFFUSE_LEVELS ); + move16(); } ELSE { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0] = masa_sq_fx( L_sub( ONE_IN_Q30, dir2ratio_fx ), diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); + move16(); } FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = dir1ratio_fx; // Q30 + move32(); hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; + move16(); } FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_fx[m] = dir2ratio_fx; + move32(); hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[m] = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; + move16(); } dir2band++; @@ -289,10 +314,13 @@ Word16 ivas_qmetadata_dec_decode( { /* 1dir band */ hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); + move32(); FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; + move16(); } } } @@ -303,10 +331,13 @@ Word16 ivas_qmetadata_dec_decode( FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0] = L_sub( ONE_IN_Q30, diffuseness_reconstructions_fx[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]] ); + move32(); FOR( m = 1; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_fx[0]; + move32(); hQMetaData->q_direction[0].band_data[b].energy_ratio_index[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; + move16(); } } } @@ -314,31 +345,42 @@ Word16 ivas_qmetadata_dec_decode( /* To decode directions correctly for 2dir bands, we need to obtain the compensated direct-to-total ratios and their * corresponding inverted indices. */ bits_dir_raw_pre[0] = 0; + move16(); bits_dir_raw_pre[1] = 0; + move16(); dir2band = 0; FOR( b = hQMetaData->q_direction[0].cfg.start_band; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { - IF( hQMetaData->no_directions == 2 && hQMetaData->twoDirBands[b] == 1 ) + test(); + IF( EQ_32( hQMetaData->no_directions, 2 ) && EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { Word16 index_dirRatio1Inv, index_dirRatio2Inv, index_dirRatio1Inv_mod, index_dirRatio2Inv_mod; index_dirRatio1Inv = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; + move16(); index_dirRatio2Inv = hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index[0]; + move16(); masa_compensate_two_dir_energy_ratio_index_fx( index_dirRatio1Inv, index_dirRatio2Inv, &index_dirRatio1Inv_mod, &index_dirRatio2Inv_mod, hodirac_flag ); FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = index_dirRatio1Inv_mod; + move16(); hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[index_dirRatio1Inv_mod]; - bits_dir_raw_pre[0] += hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m]; + move16(); + bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] ); + move16(); } FOR( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ ) { hQMetaData->q_direction[1].band_data[dir2band].energy_ratio_index_mod[m] = index_dirRatio2Inv_mod; + move16(); hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] = bits_direction_masa[index_dirRatio2Inv_mod]; - bits_dir_raw_pre[1] += hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m]; + move16(); + bits_dir_raw_pre[1] = add( bits_dir_raw_pre[1], hQMetaData->q_direction[1].band_data[dir2band].bits_sph_idx[m] ); + move16(); } dir2band++; @@ -348,22 +390,28 @@ Word16 ivas_qmetadata_dec_decode( FOR( m = 0; m < hQMetaData->q_direction[0].cfg.nblocks; m++ ) { hQMetaData->q_direction[0].band_data[b].energy_ratio_index_mod[m] = hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]; + move16(); hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] = bits_direction_masa[hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0]]; - bits_dir_raw_pre[0] += hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m]; + move16(); + bits_dir_raw_pre[0] = add( bits_dir_raw_pre[0], hQMetaData->q_direction[0].band_data[b].bits_sph_idx[m] ); + move16(); } } } - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { - no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks + hQMetaData->q_direction[1].cfg.nbands * hQMetaData->q_direction[1].cfg.nblocks; - IF( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - bits_diff_sum >= MASA_MIN_BITS_SURR_COH ) ) + no_TF = add( i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ), i_mult2( hQMetaData->q_direction[1].cfg.nbands, hQMetaData->q_direction[1].cfg.nblocks ) ); + tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) ); + test(); + IF( EQ_32( all_coherence_zero, 0 ) && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) ) { bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); } ELSE { bits_sur_coherence = 0; + move16(); /*Surround coherence*/ FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { @@ -373,19 +421,22 @@ Word16 ivas_qmetadata_dec_decode( } } } - bits_no_dirs_coh += bits_sur_coherence; - total_bits_1dir = ( ( hQMetaData->metadata_max_bits - bits_no_dirs_coh ) * hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks ) / no_TF; + bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence ); + total_bits_1dir = extract_l( L_mult0( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ) ) / no_TF ); } ELSE { - no_TF = hQMetaData->q_direction[0].cfg.nbands * hQMetaData->q_direction[0].cfg.nblocks; - IF( ( all_coherence_zero == 0 ) && ( hQMetaData->metadata_max_bits - bits_no_dirs_coh - 4.3f * no_TF - bits_diff_sum >= MASA_MIN_BITS_SURR_COH ) ) + no_TF = i_mult2( hQMetaData->q_direction[0].cfg.nbands, hQMetaData->q_direction[0].cfg.nblocks ); + tmp32 = L_sub( L_deposit_h( sub( sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ), bits_diff_sum ) ), L_mult0( 17612 /* 4.2998046875f in Q12 */, shl( no_TF, 4 ) ) ); + test(); + IF( EQ_32( all_coherence_zero, 0 ) && GE_32( tmp32, L_deposit_h( MASA_MIN_BITS_SURR_COH ) ) ) { bits_sur_coherence = read_surround_coherence( bitstream, index, hQMetaData ); } ELSE { bits_sur_coherence = 0; + move16(); /*Surround coherence*/ FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { @@ -395,36 +446,46 @@ Word16 ivas_qmetadata_dec_decode( } } } - bits_no_dirs_coh += bits_sur_coherence; + bits_no_dirs_coh = add( bits_no_dirs_coh, bits_sur_coherence ); - total_bits_1dir = hQMetaData->metadata_max_bits - bits_no_dirs_coh; + total_bits_1dir = sub( hQMetaData->metadata_max_bits, bits_no_dirs_coh ); } bits_dir_target = 0; + move16(); bits_dir_used = 0; + move16(); FOR( d = 0; d < hQMetaData->no_directions; d++ ) { q_direction = &hQMetaData->q_direction[d]; nbands = q_direction->cfg.nbands; + move16(); nblocks = q_direction->cfg.nblocks; + move16(); start_band = q_direction->cfg.start_band; + move16(); diffuseness_index_max_ec_frame = diffuseness_index_max_ec_frame_pre[0]; - IF( d == 0 ) + move16(); + IF( EQ_16( d, 0 ) ) { bits_diff = bits_diff_sum; + move16(); } ELSE { bits_diff = 0; + move16(); } bits_dir_raw = bits_dir_raw_pre[d]; + move16(); /* Read coherence, if any */ bits_coherence = 0; + move16(); - IF( all_coherence_zero == 0 ) + IF( EQ_32( all_coherence_zero, 0 ) ) { bits_coherence = read_coherence_data_fx( bitstream, index, hQMetaData, d, 0 ); } @@ -447,68 +508,77 @@ Word16 ivas_qmetadata_dec_decode( /* Read 2D signaling*/ q_direction->not_in_2D = bitstream[( *index )--]; + move16(); signal_bits = 1; + move16(); /* Read EC signaling */ ec_flag = 0; - IF( total_bits_1dir + bits_sur_coherence <= hQMetaData->qmetadata_max_bit_req ) + move16(); + IF( LE_16( add( total_bits_1dir, bits_sur_coherence ), hQMetaData->qmetadata_max_bit_req ) ) { ec_flag = bitstream[( *index )--]; + move16(); signal_bits++; - IF( nblocks > 1 ) + IF( GT_16( nblocks, 1 ) ) { IF( ec_flag ) { - ec_flag += bitstream[( *index )--]; + ec_flag = add( ec_flag, (Word16) bitstream[( *index )--] ); signal_bits++; } } } /* Decode quantized directions frame-wise */ - IF( ec_flag == 0 ) /* EC 1*/ + test(); + IF( EQ_16( ec_flag, 0 ) ) /* EC 1*/ { bits_dir = 0; + move16(); raw_flag[0] = bitstream[( *index )--]; + move16(); bits_dir++; - IF( raw_flag[0] == 0 ) + IF( EQ_16( raw_flag[0], 0 ) ) { - bits_dir += ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, nbands, start_band, 0 ); + bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, nbands, start_band, 0 ) ); } ELSE { - bits_dir += ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, nbands, start_band, 0 ); + bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, nbands, start_band, 0 ) ); } } /* Decode quantized directions band-wise */ - ELSE IF( ec_flag == 1 && ( nblocks > 1 ) ) /* EC2 */ + ELSE IF( EQ_16( ec_flag, 1 ) && GT_16( nblocks, 1 ) ) /* EC2 */ { bits_dir = 0; + move16(); FOR( b = start_band; b < nbands; b++ ) { raw_flag[b] = bitstream[( *index )--]; + move16(); bits_dir++; } /* Read EC bits*/ - diff_bits = bits_diff + bits_coherence + signal_bits - total_bits_1dir; + diff_bits = add( bits_diff, add( bits_coherence, sub( signal_bits, total_bits_1dir ) ) ); FOR( b = start_band; b < nbands; b++ ) { - IF( raw_flag[b] == 0 ) + IF( EQ_16( raw_flag[b], 0 ) ) { - bits_dir += ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, b + 1, b, 0 ); + bits_dir = add( bits_dir, ivas_qmetadata_entropy_decode_dir_fx( q_direction, bitstream, index, diffuseness_index_max_ec_frame, b + 1, b, 0 ) ); } ELSE { - diff_bits += q_direction->band_data[b].bits_sph_idx[0] * q_direction->cfg.nblocks; + diff_bits = add( diff_bits, q_direction->band_data[b].bits_sph_idx[0] * q_direction->cfg.nblocks ); } } - diff_bits += bits_dir; + diff_bits = add( diff_bits, bits_dir ); /* Small requantization?*/ - IF( q_direction->not_in_2D > 0 ) + IF( GT_16( q_direction->not_in_2D, 0 ) ) { /* This is not an ideal solution but mirrors better encoder */ Word16 i, j; @@ -519,6 +589,7 @@ Word16 ivas_qmetadata_dec_decode( FOR( j = 0; j < q_direction->cfg.nblocks; j++ ) { bits_temp[i][j] = q_direction->band_data[i].bits_sph_idx[j]; + move16(); } } @@ -529,6 +600,7 @@ Word16 ivas_qmetadata_dec_decode( FOR( j = 0; j < q_direction->cfg.nblocks; j++ ) { q_direction->band_data[i].bits_sph_idx[j] = bits_temp[i][j]; + move16(); } } } @@ -538,7 +610,7 @@ Word16 ivas_qmetadata_dec_decode( { IF( raw_flag[b] ) { - bits_dir += ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, b + 1, b, 0 ); + bits_dir = add( bits_dir, ivas_qmetadata_raw_decode_dir_fx( q_direction, bitstream, index, b + 1, b, 0 ) ); } } } @@ -547,19 +619,22 @@ Word16 ivas_qmetadata_dec_decode( { Word16 dummy; ec_flag = 2; + move16(); - IF( hQMetaData->is_masa_ivas_format == 0 ) + IF( EQ_16( hQMetaData->is_masa_ivas_format, 0 ) ) { - reduce_bits = bits_dir_raw - ( total_bits_1dir - bits_diff - bits_coherence - signal_bits ); + reduce_bits = sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ); ind_order[0] = -1; + move16(); } ELSE { ind_order[0] = 0; - reduce_bits = min( nbands * nblocks + MASA_BIT_REDUCT_PARAM, bits_dir_raw - ( total_bits_1dir - bits_diff - bits_coherence - signal_bits ) ); - IF( reduce_bits > bits_dir_raw - nbands * nblocks ) + move16(); + reduce_bits = s_min( add( i_mult2( nbands, nblocks ), MASA_BIT_REDUCT_PARAM ), sub( bits_dir_raw, sub( sub( sub( total_bits_1dir, bits_diff ), bits_coherence ), signal_bits ) ) ); + IF( GT_16( reduce_bits, sub( bits_dir_raw, i_mult2( nbands, nblocks ) ) ) ) { - reduce_bits = bits_dir_raw - nbands * nblocks; + reduce_bits = sub( bits_dir_raw, i_mult2( nbands, nblocks ) ); } } only_reduce_bits_direction_fx( &dummy, q_direction, reduce_bits, nbands, nblocks, ind_order ); @@ -568,9 +643,9 @@ Word16 ivas_qmetadata_dec_decode( bits_dir = read_directions_fx( q_direction, (UWord8) nbands, (UWord8) nblocks, bitstream, index, ind_order ); } - IF( bits_coherence > 0 ) + IF( GT_16( bits_coherence, 0 ) ) { - IF( nblocks > 1 ) + IF( GT_16( nblocks, 1 ) ) { decode_spread_coherence_fx( hQMetaData, d, nblocks, 0 ); } @@ -585,48 +660,51 @@ Word16 ivas_qmetadata_dec_decode( } } } - IF( d == 0 ) + IF( EQ_16( d, 0 ) ) { - total_bits_1dir = hQMetaData->metadata_max_bits - ( start_index_0 - *index ); + total_bits_1dir = sub( hQMetaData->metadata_max_bits, sub( start_index_0, *index ) ); } - bits_dir_target += bits_dir_raw; - bits_dir_used += bits_dir; + bits_dir_target = add( bits_dir_target, bits_dir_raw ); + bits_dir_used = add( bits_dir_used, bits_dir ); } /* move 2 dir data to its correct subband */ - IF( hQMetaData->no_directions == 2 ) + IF( EQ_32( hQMetaData->no_directions, 2 ) ) { - d = hQMetaData->q_direction[1].cfg.nbands - 1; + d = sub( hQMetaData->q_direction[1].cfg.nbands, 1 ); nblocks = hQMetaData->q_direction[0].cfg.nblocks; FOR( b = hQMetaData->q_direction[0].cfg.nbands - 1; b >= 0; b-- ) { - IF( hQMetaData->twoDirBands[b] == 1 ) + IF( EQ_16( hQMetaData->twoDirBands[b], 1 ) ) { Copy32( hQMetaData->q_direction[1].band_data[d].azimuth_fx, hQMetaData->q_direction[1].band_data[b].azimuth_fx, nblocks ); Copy32( hQMetaData->q_direction[1].band_data[d].elevation_fx, hQMetaData->q_direction[1].band_data[b].elevation_fx, nblocks ); Copy32( hQMetaData->q_direction[1].band_data[d].energy_ratio_fx, hQMetaData->q_direction[1].band_data[b].energy_ratio_fx, nblocks ); - IF( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0] < 7 ) + IF( LT_32( hQMetaData->q_direction[0].band_data[b].energy_ratio_index[0], 7 ) ) { FOR( m = 0; m < nblocks; m++ ) { Word32 a1 = hQMetaData->q_direction[1].band_data[b].azimuth_fx[m]; + move32(); a1 = L_shr( hQMetaData->q_direction[1].band_data[b].azimuth_fx[m], 1 ); Word32 b1 = hQMetaData->q_direction[0].band_data[b].azimuth_fx[m]; + move32(); b1 = L_shr( hQMetaData->q_direction[0].band_data[b].azimuth_fx[m], 1 ); Word32 c = L_shr( DEGREE_180_Q_22, 1 ); a1 = L_add( a1, L_sub( b1, c ) ); - IF( a1 >= L_shr( DEGREE_180_Q_22, 1 ) ) + IF( GE_32( a1, L_shr( DEGREE_180_Q_22, 1 ) ) ) { a1 = L_sub( a1, L_shr( DEGREE_360_Q_22, 1 ) ); } - IF( a1 < L_shr( -DEGREE_180_Q_22, 1 ) ) + IF( LT_32( a1, L_shr( -DEGREE_180_Q_22, 1 ) ) ) { a1 = L_add( a1, L_shr( DEGREE_360_Q_22, 1 ) ); } hQMetaData->q_direction[1].band_data[b].azimuth_fx[m] = L_shl( a1, 1 ); + move32(); } } @@ -669,16 +747,18 @@ Word16 ivas_qmetadata_dec_decode( /* Store status information for renderer use */ hQMetaData->ec_flag = ec_flag; + move16(); - IF( bits_dir_used > bits_dir_target ) + IF( GT_16( bits_dir_used, bits_dir_target ) ) { hQMetaData->dir_comp_ratio_fx = MAX_WORD16; + move16(); } ELSE { hQMetaData->dir_comp_ratio_fx = divide3232( bits_dir_used, bits_dir_target ); } - return ( start_index_0 - *index ); + return sub( start_index_0, *index ); } #else int16_t ivas_qmetadata_dec_decode( diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index c1818b09f..a2fbfb68e 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -342,6 +342,190 @@ void ivas_spar_dec_close( * Principal IVAS SPAR decoder routine *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_spar_dec_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + Word16 *nb_bits_read /* o : number of MD bits read */ +) +{ + DECODER_CONFIG_HANDLE hDecoderConfig; + Word16 i, nb_bits_read_orig; + Decoder_State *st0; + Word16 next_bit_pos_orig, last_bit_pos; + UWord16 bstr_meta[MAX_BITS_METADATA], *bit_stream_orig; + ivas_error error; + + push_wmops( "ivas_spar_decode" ); + error = IVAS_ERR_OK; + hDecoderConfig = st_ivas->hDecoderConfig; + +#ifndef IVAS_FLOAT_FIXED_TO_BE_REMOVED + Word16 hodirac_flag = ivas_get_hodirac_flag_fx( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); + Word16 j, k, d; + IF( st_ivas->hQMetaData != NULL ) + { + // To do remove this code once ivas_spar_dec_MD is done + FOR( d = 0; d < st_ivas->hQMetaData->no_directions; d++ ) + { + IVAS_QDIRECTION *q_direction; + q_direction = &st_ivas->hQMetaData->q_direction[d]; + int nbands = q_direction->cfg.nbands; + FOR( j = 0; j < nbands; j++ ) + { + FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + q_direction->band_data[j].elevation_fx[k] = (Word32) ( q_direction->band_data[j].elevation[k] * ( 1 << 22 ) ); + q_direction->band_data[j].azimuth_fx[k] = (Word32) ( q_direction->band_data[j].azimuth[k] * ( 1 << 22 ) ); + q_direction->band_data[j].energy_ratio_fx[k] = (Word32) ( q_direction->band_data[j].energy_ratio[k] * ( 1 << 30 ) ); + } + } + } + IF( st_ivas->hDirAC != NULL && st_ivas->hSpatParamRendCom != NULL ) + { + for ( i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + for ( j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->diffuseness_vector[i][j], 30 ); + st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio1[i][j], 30 ); + IF( hodirac_flag ) + { + st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j] = float_to_fix( st_ivas->hSpatParamRendCom->energy_ratio2[i][j], 30 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->surroundingCoherence[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j] = float_to_fix16( st_ivas->hSpatParamRendCom->spreadCoherence[i][j], 15 ); + } + } + } + } +#endif + + st0 = GT_16( st_ivas->nSCE, 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + bit_stream_orig = st0->bit_stream; + move16(); + next_bit_pos_orig = st0->next_bit_pos; + move16(); + + IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) + { + last_bit_pos = sub( extract_l( L_sub( ( hDecoderConfig->ivas_total_brate / FRAMES_PER_SEC ), 1 ) ), nb_bits_read[1] ); + } + ELSE + { + *nb_bits_read = 0; + move16(); + last_bit_pos = 0; + move16(); + } + + /* read DirAC bitstream */ + IF( st_ivas->hQMetaData != NULL ) + { + ivas_dirac_dec_read_BS( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hSpatParamRendCom, st_ivas->hQMetaData, nb_bits_read, last_bit_pos, ivas_get_hodirac_flag_fx( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ), st_ivas->hSpar->dirac_to_spar_md_bands ); + } + + IF( EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) ) + { + last_bit_pos = sub( extract_l( L_sub( ( hDecoderConfig->ivas_total_brate / FRAMES_PER_SEC ), 1 ) ), nb_bits_read[1] ); + } + ELSE + { + last_bit_pos = extract_l( L_sub( ( hDecoderConfig->ivas_total_brate / FRAMES_PER_SEC ), 1 ) ); + } + + test(); + IF( !st0->bfi && EQ_32( hDecoderConfig->ivas_total_brate, IVAS_SID_5k2 ) ) + { + last_bit_pos = sub( last_bit_pos, SID_FORMAT_NBITS ); + } + nb_bits_read_orig = *nb_bits_read; + move16(); + last_bit_pos = sub( last_bit_pos, nb_bits_read_orig ); + + /* reverse the bitstream for easier reading of indices */ + FOR( i = 0; i < s_min( MAX_BITS_METADATA, last_bit_pos ); i++ ) + { + bstr_meta[i] = st_ivas->bit_stream[last_bit_pos - i]; + move16(); + } + st0->bit_stream = bstr_meta; + move16(); + st0->next_bit_pos = 0; + move16(); + st0->bits_frame = s_min( MAX_BITS_METADATA, add( last_bit_pos, 1 ) ); + + IF( !st0->bfi ) + { + st0->total_brate = hDecoderConfig->ivas_total_brate; /* to avoid BER detect */ + move32(); + } + +#ifndef IVAS_FLOAT_FIXED_TO_BE_REMOVED + IF( st_ivas->hQMetaData != NULL ) + { + // To do remove this code once ivas_spar_dec_MD is done + FOR( d = 0; d < st_ivas->hQMetaData->no_directions; d++ ) + { + IVAS_QDIRECTION *q_direction; + q_direction = &st_ivas->hQMetaData->q_direction[d]; + int nbands = q_direction->cfg.nbands; + FOR( j = 0; j < nbands; j++ ) + { + FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ ) + { + q_direction->band_data[j].elevation[k] = ( (float) q_direction->band_data[j].elevation_fx[k] / ( 1 << 22 ) ); + q_direction->band_data[j].azimuth[k] = ( (float) q_direction->band_data[j].azimuth_fx[k] / ( 1 << 22 ) ); + q_direction->band_data[j].energy_ratio[k] = ( (float) q_direction->band_data[j].energy_ratio_fx[k] / ( 1 << 30 ) ); + } + } + } + IF( st_ivas->hDirAC != NULL && st_ivas->hSpatParamRendCom != NULL ) + { + for ( i = 0; i < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; i++ ) + { + for ( j = 0; j < st_ivas->hSpatParamRendCom->num_freq_bands; j++ ) + { + st_ivas->hSpatParamRendCom->diffuseness_vector[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[i][j], 30 ); + st_ivas->hSpatParamRendCom->energy_ratio1[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio1_fx[i][j], 30 ); + IF( hodirac_flag ) + { + st_ivas->hSpatParamRendCom->energy_ratio2[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->energy_ratio2_fx[i][j], 30 ); + } + st_ivas->hSpatParamRendCom->surroundingCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->surroundingCoherence_fx[i][j], 15 ); + st_ivas->hSpatParamRendCom->spreadCoherence[i][j] = fix_to_float( st_ivas->hSpatParamRendCom->spreadCoherence_fx[i][j], 15 ); + } + } + } + } +#endif + + /*---------------------------------------------------------------------* + * Decode SPAR metadata + *---------------------------------------------------------------------*/ + + IF( ( error = ivas_spar_dec_MD( st_ivas, st0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + *nb_bits_read = st0->next_bit_pos + nb_bits_read_orig; + st0->bit_stream = bit_stream_orig; + st0->next_bit_pos = next_bit_pos_orig; + + IF( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) + { + Word16 zero_pad_bits; + *nb_bits_read += SID_FORMAT_NBITS; + zero_pad_bits = (Word16) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - *nb_bits_read; + assert( zero_pad_bits <= 1 ); + *nb_bits_read += zero_pad_bits; + } + + pop_wmops(); + + return error; +} +#endif ivas_error ivas_spar_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ int16_t *nb_bits_read /* o : number of MD bits read */ diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 9f33c23b4..22943ea60 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -34,6 +34,8 @@ #include "options.h" #include "math.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include @@ -81,11 +83,16 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix_fx(ivas_spar_md_dec_stat static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t numch_out, const int16_t num_md_sub_frames ); static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, int16_t *first_valid_frame, const int16_t num_bands ); +#ifdef IVAS_FLOAT_FIXED +static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, Word32 *pFC ); +#else static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); +#endif static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st, const int16_t bw, const int16_t num_bands, int16_t *num_dmx_per_band, int16_t *num_dec_per_band ); static ivas_error ivas_deindex_real_index( const int16_t *index, const int16_t q_levels, const float min_value, const float max_value, float *quant, const int16_t num_ch_dim2 ); +static ivas_error ivas_deindex_real_index_fx( const int16_t *index, const int16_t q_levels, const Word32 min_value, const Word32 max_value, Word32 *quant, const int16_t num_ch_dim2 ); static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, int16_t *nB, int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode ); @@ -211,6 +218,26 @@ ivas_error ivas_spar_md_dec_matrix_open( } } } + //Fix_memory + /*if ((hMdDec->spar_coeffs.C_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs.C_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs.C_re_fx[i][j] = (Word32 *)malloc(num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + }*/ + if ( ( hMdDec->spar_coeffs.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { @@ -230,6 +257,25 @@ ivas_error ivas_spar_md_dec_matrix_open( } } } + //Fix memory + /*if ((hMdDec->spar_coeffs.P_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs.P_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs.P_re_fx[i][j] = (Word32 *)malloc(num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + }*/ if ( ( hMdDec->spar_coeffs_prev.C_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { @@ -249,7 +295,28 @@ ivas_error ivas_spar_md_dec_matrix_open( } } } - + + //Fix Memory +#ifdef IVAS_FLOAT_FIXED + if ((hMdDec->spar_coeffs_prev.C_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs_prev.C_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs_prev.C_re_fx[i][j] = (Word32 *)malloc(IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + } +#endif if ( ( hMdDec->spar_coeffs_prev.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -269,6 +336,28 @@ ivas_error ivas_spar_md_dec_matrix_open( } } +#ifdef IVAS_FLOAT_FIXED + //Fix Memory + if ((hMdDec->spar_coeffs_prev.P_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs_prev.P_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs_prev.P_re_fx[i][j] = (Word32 *)malloc(IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + } +#endif + if ( ( hMdDec->spar_coeffs_tar.C_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -288,6 +377,28 @@ ivas_error ivas_spar_md_dec_matrix_open( } } +#ifdef IVAS_FLOAT_FIXED + //Fix Memory + if ((hMdDec->spar_coeffs_tar.C_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs_tar.C_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs_tar.C_re_fx[i][j] = (Word32 *)malloc(IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + } +#endif + if ( ( hMdDec->spar_coeffs_tar.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -306,6 +417,29 @@ ivas_error ivas_spar_md_dec_matrix_open( } } } + +#ifdef IVAS_FLOAT_FIXED + //Fix Memory + if ((hMdDec->spar_coeffs_tar.P_re_fx = (Word32 ***)malloc(num_channels * sizeof(Word32 **))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (i = 0; i < num_channels; i++) + { + if ((hMdDec->spar_coeffs_tar.P_re_fx[i] = (Word32 **)malloc(num_channels * sizeof(Word32 *))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + for (j = 0; j < num_channels; j++) + { + if ((hMdDec->spar_coeffs_tar.P_re_fx[i][j] = (Word32 *)malloc(IVAS_MAX_NUM_BANDS * sizeof(Word32))) == NULL) + { + return IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix"); + } + } + } +#endif + for ( i = 0; i < num_channels; i++ ) { for ( j = 0; j < num_channels; j++ ) @@ -316,6 +450,12 @@ ivas_error ivas_spar_md_dec_matrix_open( hMdDec->spar_coeffs_prev.P_re[i][j][k] = 0.0f; hMdDec->spar_coeffs_tar.C_re[i][j][k] = 0.0f; hMdDec->spar_coeffs_tar.P_re[i][j][k] = 0.0f; +#ifdef IVAS_FLOAT_FIXED + hMdDec->spar_coeffs_prev.C_re_fx[i][j][k] = 0; + hMdDec->spar_coeffs_prev.P_re_fx[i][j][k] = 0; + hMdDec->spar_coeffs_tar.C_re_fx[i][j][k] = 0; + hMdDec->spar_coeffs_tar.P_re_fx[i][j][k] = 0; +#endif } } } @@ -536,6 +676,18 @@ void ivas_spar_md_dec_matrix_close( } free( hMdDecoder->spar_coeffs.C_re ); } + /*if (hMdDecoder->spar_coeffs.C_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs.C_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs.C_re_fx[i]); + } + free(hMdDecoder->spar_coeffs.C_re_fx); + }*/ if ( hMdDecoder->spar_coeffs.P_re != NULL ) { @@ -550,6 +702,19 @@ void ivas_spar_md_dec_matrix_close( free( hMdDecoder->spar_coeffs.P_re ); } + /*if (hMdDecoder->spar_coeffs.P_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs.P_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs.P_re_fx[i]); + } + free(hMdDecoder->spar_coeffs.P_re_fx); + }*/ + if ( hMdDecoder->spar_coeffs_prev.C_re != NULL ) { for ( i = 0; i < num_channels; i++ ) @@ -562,6 +727,20 @@ void ivas_spar_md_dec_matrix_close( } free( hMdDecoder->spar_coeffs_prev.C_re ); } +#ifdef IVAS_FLOAT_FIXED + if (hMdDecoder->spar_coeffs_prev.C_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs_prev.C_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs_prev.C_re_fx[i]); + } + free(hMdDecoder->spar_coeffs_prev.C_re_fx); + } +#endif if ( hMdDecoder->spar_coeffs_prev.P_re != NULL ) { @@ -576,6 +755,21 @@ void ivas_spar_md_dec_matrix_close( free( hMdDecoder->spar_coeffs_prev.P_re ); } +#ifdef IVAS_FLOAT_FIXED + if (hMdDecoder->spar_coeffs_prev.P_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs_prev.P_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs_prev.P_re_fx[i]); + } + free(hMdDecoder->spar_coeffs_prev.P_re_fx); + } +#endif + if ( hMdDecoder->spar_coeffs_tar.C_re != NULL ) { for ( i = 0; i < num_channels; i++ ) @@ -589,6 +783,21 @@ void ivas_spar_md_dec_matrix_close( free( hMdDecoder->spar_coeffs_tar.C_re ); } +#ifdef IVAS_FLOAT_FIXED + if (hMdDecoder->spar_coeffs_tar.C_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs_tar.C_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs_tar.C_re_fx[i]); + } + free(hMdDecoder->spar_coeffs_tar.C_re_fx); + } +#endif + if ( hMdDecoder->spar_coeffs_tar.P_re != NULL ) { for ( i = 0; i < num_channels; i++ ) @@ -601,6 +810,20 @@ void ivas_spar_md_dec_matrix_close( } free( hMdDecoder->spar_coeffs_tar.P_re ); } +#ifdef IVAS_FLOAT_FIXED + if (hMdDecoder->spar_coeffs_tar.P_re_fx != NULL) + { + for (i = 0; i < num_channels; i++) + { + for (j = 0; j < num_channels; j++) + { + free(hMdDecoder->spar_coeffs_tar.P_re_fx[i][j]); + } + free(hMdDecoder->spar_coeffs_tar.P_re_fx[i]); + } + free(hMdDecoder->spar_coeffs_tar.P_re_fx); + } +#endif return; } @@ -630,6 +853,11 @@ void ivas_spar_md_dec_close( return; } +Word32 pFC_8k[IVAS_MAX_NUM_BANDS] = { 33, 100, 166, 233, 300, 366, 433, 566, 866, 1333, 2033, 3233 }; +Word32 pFC_12k[IVAS_MAX_NUM_BANDS] = { 53, 160, 266, 373, 480, 586, 693, 906, 1386, 2133, 3253, 5173 }; +Word32 pFC_16k[IVAS_MAX_NUM_BANDS] = { 66, 200, 333, 466, 600, 733, 866, 1133, 1733, 2666, 4066, 6466 }; +Word32 pFC_32k[IVAS_MAX_NUM_BANDS] = { 133, 400, 666, 933, 1200, 1466, 1733, 2266, 3466, 5333, 8133, 12933 }; +Word32 pFC_48k[IVAS_MAX_NUM_BANDS] = { 199, 600, 1000, 1400, 1800, 2200, 2600, 3400, 5200, 8000, 12200, 19400 }; /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_dec_init() @@ -647,6 +875,7 @@ ivas_error ivas_spar_md_dec_init( int16_t i, j; int16_t nchan_transport; float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; + Word32 *pFC_fx, PR_minmax_fx[2]; ivas_error error; ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate, &hMdDec->spar_hoa_md_flag, &hMdDec->spar_hoa_dirac2spar_md_flag ); @@ -664,8 +893,37 @@ ivas_error ivas_spar_md_dec_init( { pFC[i] = ivas_fb_fcs_12band_1ms[i] * hDecoderConfig->output_Fs * 0.5f; } + + if (hDecoderConfig->output_Fs == 8000) + { + pFC_fx = pFC_8k; + } + else if (hDecoderConfig->output_Fs == 12800) + { + pFC_fx = pFC_12k; + } + else if (hDecoderConfig->output_Fs == 16000) + { + pFC_fx = pFC_16k; + } + else if (hDecoderConfig->output_Fs == 32000) + { + pFC_fx = pFC_32k; + } + else if (hDecoderConfig->output_Fs == 48000) + { + pFC_fx = pFC_48k; + } + else + { + assert(0);//update sample rate + } +#ifdef IVAS_FLOAT_FIXED + if ( ( error = ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC_fx) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -677,8 +935,11 @@ ivas_error ivas_spar_md_dec_init( /* DTX quant init */ PR_minmax[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax_fx[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min_fx; PR_minmax[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max; + PR_minmax_fx[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max_fx; ivas_spar_quant_dtx_init( &hMdDec->spar_md, PR_minmax ); + ivas_spar_quant_dtx_init_fx( &hMdDec->spar_md, PR_minmax_fx ); ivas_spar_arith_coeffs_com_init( &hMdDec->arith_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); ivas_spar_huff_coeffs_com_init( &hMdDec->huff_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); @@ -703,12 +964,20 @@ ivas_error ivas_spar_md_dec_init( hMdDec->td_decorr_flag = 1; set_f( hMdDec->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set32_fx( hMdDec->spar_md.en_ratio_slow_fx, 0, IVAS_MAX_NUM_BANDS ); set_f( hMdDec->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set32_fx( hMdDec->spar_md.ref_pow_slow_fx, 0, IVAS_MAX_NUM_BANDS ); set_zero( hMdDec->smooth_fac, IVAS_MAX_NUM_BANDS ); +#ifdef IVAS_FLOAT_FIXED + set32_fx( hMdDec->smooth_fac_fx,0, IVAS_MAX_NUM_BANDS ); +#endif for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) { set_zero( hMdDec->smooth_buf[i], 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 ); +#ifdef IVAS_FLOAT_FIXED + set32_fx(hMdDec->smooth_buf_fx[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1); +#endif } for ( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) @@ -716,6 +985,9 @@ ivas_error ivas_spar_md_dec_init( for ( j = 0; j < IVAS_SPAR_MAX_CH; j++ ) { set_zero( hMdDec->mixer_mat_prev2[i][j], IVAS_MAX_NUM_BANDS ); +#ifdef IVAS_FLOAT_FIXED + set32_fx(hMdDec->mixer_mat_prev2_fx[i][j], 0, IVAS_MAX_NUM_BANDS); +#endif } } hMdDec->first_valid_frame = 1; @@ -729,7 +1001,60 @@ ivas_error ivas_spar_md_dec_init( * * Set configuration for SPAR MD decoder *-----------------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static ivas_error ivas_spar_set_dec_config( + ivas_spar_md_dec_state_t *hMdDec, + const int16_t nchan_transport, + Word32 *pFC ) +{ + int16_t i, j, nchan, dmx_ch; + + for ( i = 0; i < nchan_transport; i++ ) + { + hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; + } + + nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order, ivas_spar_br_table_consts[hMdDec->table_idx].ivas_total_brate ); + + switch ( nchan ) + { + case 4: /* FOA_CHANNELS */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_3CH; + break; + case 9: /* IVAS_HOA_2_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_5CH; + break; + case 6: /* IVAS_HOA_2_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_2CH; + break; + case 8: /* IVAS_HOA_3_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_4CH; + break; + } + + hMdDec->spar_md_cfg.num_umx_chs = nchan; + + dmx_ch = 0; + for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) + { + dmx_ch = 0; + for ( j = 0; j < nchan_transport; j++ ) + { + if ( pFC[i] < hMdDec->spar_md_cfg.max_freq_per_chan[j] ) + { + dmx_ch += 1; + } + } + hMdDec->spar_md_cfg.num_dmx_chans_per_band[i] = hMdDec->spar_md_cfg.nchan_transport; + hMdDec->spar_md_cfg.num_decorr_per_band[i] = nchan - hMdDec->spar_md_cfg.nchan_transport; + } + + hMdDec->spar_md_cfg.nchan_transport = dmx_ch; + + return IVAS_ERR_OK; +} +#else static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, @@ -782,7 +1107,7 @@ static ivas_error ivas_spar_set_dec_config( return IVAS_ERR_OK; } - +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_dec_mono_sba_handling() @@ -794,17 +1119,22 @@ static void ivas_dec_mono_sba_handling( Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ ) { - int16_t mono_flag, b, block; + Word16 mono_flag, b, block; mono_flag = 1; - for ( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ ) + FOR ( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ ) { - for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) + FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) { float azimuth = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth[block]; float elevation = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth[block]; float energy_ratio = st_ivas->hQMetaData->q_direction[0].band_data[0].energy_ratio[block]; +#ifdef IVAS_FLOAT_FIXED + Word32 azimuth_fx = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth_fx[block]; + Word32 elevation_fx = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth_fx[block]; + Word32 energy_ratio_fx = st_ivas->hQMetaData->q_direction[0].band_data[0].energy_ratio_fx[block]; +#endif if ( ( azimuth != 0.0f ) || ( elevation != 0.0f ) || @@ -812,11 +1142,21 @@ static void ivas_dec_mono_sba_handling( { mono_flag = 0; } +#ifdef IVAS_FLOAT_FIXED + IF ( + ( NE_32(azimuth_fx, 0) ) || + (NE_32(elevation_fx, 0) ) || + (GT_32(energy_ratio_fx, 161061274) ) ) /* 0.15f is just above the lowest quantised value. */ + { + mono_flag = 0; + } +#endif } } /* Combine the SPAR prediction coefs flag with the azimuth, elevation and energy ratio flag.*/ - mono_flag = mono_flag && ivas_spar_chk_zero_coefs( st_ivas ); + //mono_flag = mono_flag && ivas_spar_chk_zero_coefs( st_ivas ); + mono_flag = mono_flag && ivas_spar_chk_zero_coefs_fx( st_ivas ); if ( mono_flag ) { @@ -824,6 +1164,9 @@ static void ivas_dec_mono_sba_handling( for ( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ ) { set_zero( st_ivas->hQMetaData->q_direction[0].band_data[b].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES ); +#ifdef IVAS_FLOAT_FIXED + set32_fx( st_ivas->hQMetaData->q_direction[0].band_data[b].energy_ratio_fx,0, MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif } if ( st_ivas->hDirAC != NULL ) { @@ -831,12 +1174,21 @@ static void ivas_dec_mono_sba_handling( { /* Set directional Energy Ratio values to be zero */ set_zero( st_ivas->hSpatParamRendCom->energy_ratio1[block], st_ivas->hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + set32_fx( st_ivas->hSpatParamRendCom->energy_ratio1_fx[block],0, st_ivas->hSpatParamRendCom->num_freq_bands ); +#endif if ( st_ivas->hQMetaData->no_directions == 2 ) { set_zero( st_ivas->hSpatParamRendCom->energy_ratio2[block], st_ivas->hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + set32_fx( st_ivas->hSpatParamRendCom->energy_ratio2_fx[block],0, st_ivas->hSpatParamRendCom->num_freq_bands ); +#endif } /* Set Diffuseness values to be 1.0 */ set_f( st_ivas->hSpatParamRendCom->diffuseness_vector[block], 1.0f, st_ivas->hSpatParamRendCom->num_freq_bands ); +#ifdef IVAS_FLOAT_FIXED + set32_fx( st_ivas->hSpatParamRendCom->diffuseness_vector_fx[block], ONE_IN_Q30, st_ivas->hSpatParamRendCom->num_freq_bands ); +#endif } } } @@ -899,6 +1251,21 @@ void ivas_spar_md_dec_process( } } + for (int i = 0; i < IVAS_MAX_NUM_BANDS; i++) + { + for (int ii = 0; ii < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; ii++) + { + for (int jj = 0; jj < IVAS_SPAR_MAX_DMX_CHS - 1; jj++) + { + hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] * (1 << 22); + } + } + for (int jj = 0; jj < IVAS_SPAR_MAX_DMX_CHS - 1; jj++) + { + hMdDec->spar_md.band_coeffs[i].pred_re_fx[jj] = hMdDec->spar_md.band_coeffs[i].pred_re[jj] * (1 << 22); + hMdDec->spar_md.band_coeffs[i].P_re_fx[jj] = hMdDec->spar_md.band_coeffs[i].P_re[jj] * (1 << 22); + } + } ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hQMetaData->sba_inactive_mode ); @@ -912,7 +1279,21 @@ void ivas_spar_md_dec_process( &hMdDec->base_band_coeffs_age[0], &hMdDec->first_valid_frame, nB ); - + for (int i = 0; i < IVAS_MAX_NUM_BANDS; i++) + { + for (int ii = 0; ii < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; ii++) + { + for (int jj = 0; jj < IVAS_SPAR_MAX_DMX_CHS - 1; jj++) + { + hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = (float)hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj] / (1 << 22); + } + } + for (int jj = 0; jj < IVAS_SPAR_MAX_DMX_CHS - 1; jj++) + { + hMdDec->spar_md.band_coeffs[i].pred_re[jj] = (float)hMdDec->spar_md.band_coeffs[i].pred_re_fx[jj] / (1 << 22); + hMdDec->spar_md.band_coeffs[i].P_re[jj] = (float)hMdDec->spar_md.band_coeffs[i].P_re_fx[jj] / (1 << 22); + } + } ivas_dec_mono_sba_handling( st_ivas ); /* SPAR to DirAC conversion */ @@ -932,6 +1313,7 @@ void ivas_spar_md_dec_process( for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j] = hMdDec->spar_md.band_coeffs[b].pred_re[j]; + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re_fx[j] = hMdDec->spar_md.band_coeffs[b].pred_re_fx[j]; } for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) @@ -939,12 +1321,14 @@ void ivas_spar_md_dec_process( for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) { hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j][k] = hMdDec->spar_md.band_coeffs[b].C_re[j][k]; + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re_fx[j][k] = hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k]; } } for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[j] = hMdDec->spar_md.band_coeffs[b].P_re[j]; + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re_fx[j] = hMdDec->spar_md.band_coeffs[b].P_re_fx[j]; } } } @@ -1021,6 +1405,50 @@ int16_t ivas_spar_chk_zero_coefs( return mono; } +Word16 ivas_spar_chk_zero_coefs_fx( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +) +{ + Word16 j, k, b; + ivas_spar_md_dec_state_t *hMdDec; + Word16 mono = 1; + Word16 ndec, ndm; + + hMdDec = st_ivas->hSpar->hMdDec; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + + FOR( b = 0; b < min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) + { + FOR( j = 0; j < ndm + ndec - 1; j++ ) + { + IF( NE_32( hMdDec->spar_md.band_coeffs[b].pred_re_fx[j], 0 ) ) + { + mono = 0; + } + } + FOR( j = 0; j < ndec; j++ ) + { + FOR( k = 0; k < ndm - 1; k++ ) + { + IF( NE_32( hMdDec->spar_md.band_coeffs[b].C_re_fx[j][k], 0 ) ) + { + mono = 0; + } + } + } + FOR( j = 0; j < ndec; j++ ) + { + IF( NE_32( hMdDec->spar_md.band_coeffs[b].P_re_fx[j], 0 ) ) + { + mono = 0; + } + } + } + + return mono; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_smooth_md_dtx() @@ -1285,6 +1713,10 @@ static void ivas_get_spar_matrices( { set_zero( &hMdDec->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); set_zero( &hMdDec->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); +#ifdef IVAS_FLOAT_FIXED + set32_fx(&hMdDec->spar_coeffs.C_re_fx[i][j][i_ts * IVAS_MAX_NUM_BANDS], 0, IVAS_MAX_NUM_BANDS); + set32_fx(&hMdDec->spar_coeffs.P_re_fx[i][j][i_ts * IVAS_MAX_NUM_BANDS], 0, IVAS_MAX_NUM_BANDS); +#endif } } num_bands = min( num_bands, nB ); @@ -1634,17 +2066,20 @@ static void ivas_spar_md_band_upmix( for ( ii = 0; ii < ndec + ndm - 1; ii++ ) { band_coeffs[idx].pred_re[ii] = band_coeffs[i].pred_re[ii]; + band_coeffs[idx].pred_re_fx[ii] = band_coeffs[i].pred_re_fx[ii]; } for ( ii = 0; ii < ndec; ii++ ) { for ( jj = 0; jj < ndm - 1; jj++ ) { band_coeffs[idx].C_re[ii][jj] = band_coeffs[i].C_re[ii][jj]; + band_coeffs[idx].C_re_fx[ii][jj] = band_coeffs[i].C_re_fx[ii][jj]; } } for ( jj = 0; jj < ndec; jj++ ) { band_coeffs[idx].P_re[jj] = band_coeffs[i].P_re[jj]; + band_coeffs[idx].P_re_fx[jj] = band_coeffs[i].P_re_fx[jj]; } valid_bands[idx] = valid_bands[i]; } @@ -1678,6 +2113,7 @@ static void ivas_spar_dec_parse_md_bs( int16_t strat, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; float quant[IVAS_SPAR_MAX_C_COEFF]; + Word32 quant_fx[IVAS_SPAR_MAX_C_COEFF]; int16_t do_repeat[IVAS_MAX_NUM_BANDS]; *dtx_vad = 1; *bands_bw = 1; @@ -1732,7 +2168,9 @@ static void ivas_spar_dec_parse_md_bs( for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].pred_re_fx[j] = 0; hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].P_re_fx[j] = 0; } hMdDec->valid_bands[i] = 1; } @@ -1744,6 +2182,7 @@ static void ivas_spar_dec_parse_md_bs( for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) { hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; + hMdDec->spar_md.band_coeffs[i].C_re_fx[j][k] = 0; } } } @@ -1837,6 +2276,7 @@ static void ivas_spar_dec_parse_md_bs( ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); + ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min_fx, qs.PR.max_fx, hMdDec->spar_md.band_coeffs[i].pred_re_fx, ndm + ndec - 1 ); j = 0; for ( ii = 0; ii < ndec; ii++ ) @@ -1844,11 +2284,13 @@ static void ivas_spar_dec_parse_md_bs( for ( jj = 0; jj < ndm - 1; jj++ ) { quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; + quant_fx[j] = hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj]; j++; } } ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); + ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min_fx, qs.C.max_fx, quant_fx, ndec * ( ndm - 1 ) ); j = 0; for ( ii = 0; ii < ndec; ii++ ) @@ -1856,11 +2298,13 @@ static void ivas_spar_dec_parse_md_bs( for ( jj = 0; jj < ndm - 1; jj++ ) { hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; + hMdDec->spar_md.band_coeffs[i].C_re_fx[ii][jj] = quant_fx[j]; j++; } } ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); + ivas_deindex_real_index_fx( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min_fx, qs.P_r.max_fx, hMdDec->spar_md.band_coeffs[i].P_re_fx, ndm + ndec - 1 ); /* Store prior coefficient indices */ for ( j = 0; j < ndm + ndec - 1; j++ ) @@ -2233,6 +2677,43 @@ static void ivas_spar_get_plc_interp_weights( return; } +static void ivas_spar_get_plc_interp_weights_fx( + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t last_valid_band_idx, + int16_t idx, + int16_t b, + Word16 *w, + int16_t *id0, + int16_t *id1) +{ + if (last_valid_band_idx < 0) /* Extrapolation */ + { + *id1 = valid_band_idx[0]; + *id0 = 0; + *w = MAX_WORD16; + } + else if (last_valid_band_idx == idx) /* Extrapolation */ + { + *id1 = valid_band_idx[last_valid_band_idx]; + *id0 = valid_band_idx[last_valid_band_idx]; + *w = 0; + } + else /* Interpolation */ + { + *id0 = valid_band_idx[last_valid_band_idx]; + *id1 = valid_band_idx[last_valid_band_idx + 1]; + if ((b - *id0) == 0) + { + *w = 0; + } + else + { + *w = divide3232((b - *id0), (*id1 - *id0)); + } + } + return; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_fill_invalid_bands() * @@ -2252,6 +2733,7 @@ static void ivas_spar_md_fill_invalid_bands( int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; float w = 0; + Word16 w_fx = 0; ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, last_valid_band_idx, valid_band_idx, &all_valid, &idx ); assert( idx > 0 ); /* some bands should be valid */ @@ -2261,17 +2743,24 @@ static void ivas_spar_md_fill_invalid_bands( for ( b = 0; b < num_bands; b++ ) { /* check against non zero in if and else if */ + if ( base_band_age[b] > 3 ) /* old invalid bands */ { int16_t id0, id1; ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], idx, b, &w, &id0, &id1 ); + ivas_spar_get_plc_interp_weights_fx(valid_band_idx, last_valid_band_idx[b], + idx, b, &w_fx, &id0, &id1); for ( i = 0; i < num_channels; i++ ) { for ( j = 0; j < num_channels; j++ ) { pSpar_coeffs->C_re[i][j][b] = ( 1 - w ) * pSpar_coeffs->C_re[i][j][id0] + w * pSpar_coeffs->C_re[i][j][id1]; pSpar_coeffs->P_re[i][j][b] = ( 1 - w ) * pSpar_coeffs->P_re[i][j][id0] + w * pSpar_coeffs->P_re[i][j][id1]; +#ifdef IVAS_FLOAT_FIXED + pSpar_coeffs->C_re_fx[i][j][b] = L_add(Mpy_32_16_1(pSpar_coeffs->C_re_fx[i][j][id0], sub(MAX_WORD16, w_fx)), Mpy_32_16_1(pSpar_coeffs->C_re_fx[i][j][id1], w_fx)); + pSpar_coeffs->P_re_fx[i][j][b] = L_add(Mpy_32_16_1(pSpar_coeffs->P_re_fx[i][j][id0], sub(MAX_WORD16, w_fx)), Mpy_32_16_1(pSpar_coeffs->P_re_fx[i][j][id1], w_fx)); +#endif } } } @@ -2285,6 +2774,10 @@ static void ivas_spar_md_fill_invalid_bands( { pSpar_coeffs->C_re[i][j][b] = pSpar_coeffs_prev->C_re[i][j][b]; pSpar_coeffs->P_re[i][j][b] = pSpar_coeffs_prev->P_re[i][j][b]; +#ifdef IVAS_FLOAT_FIXED + pSpar_coeffs->C_re_fx[i][j][b] = pSpar_coeffs_prev->C_re_fx[i][j][b]; + pSpar_coeffs->P_re_fx[i][j][b] = pSpar_coeffs_prev->P_re_fx[i][j][b]; +#endif } } } @@ -2301,6 +2794,10 @@ static void ivas_spar_md_fill_invalid_bands( { pSpar_coeffs->C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->C_re[i][j][b]; pSpar_coeffs->P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->P_re[i][j][b]; +#ifdef IVAS_FLOAT_FIXED + pSpar_coeffs->C_re_fx[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->C_re_fx[i][j][b]; + pSpar_coeffs->P_re_fx[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->P_re_fx[i][j][b]; +#endif } } } @@ -2323,6 +2820,7 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; float w = 0; + Word16 w_fx = 0; ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, last_valid_band_idx, valid_band_idx, &all_valid, &idx ); @@ -2339,10 +2837,13 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( int16_t id0, id1; ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], idx, b, &w, &id0, &id1 ); + ivas_spar_get_plc_interp_weights_fx(valid_band_idx, last_valid_band_idx[b], + idx, b, &w_fx, &id0, &id1); for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { pBand_coeffs[b].pred_re[j] = ( 1 - w ) * pBand_coeffs[id0].pred_re[j] + w * pBand_coeffs[id1].pred_re[j]; + pBand_coeffs[b].pred_re_fx[j] = L_add(Mpy_32_16_1(pBand_coeffs[id0].pred_re_fx[j], sub(MAX_WORD16, w_fx)), Mpy_32_16_1(pBand_coeffs[id1].pred_re_fx[j],w_fx)); } for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) @@ -2350,12 +2851,14 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) { pBand_coeffs[b].C_re[j][k] = ( 1 - w ) * pBand_coeffs[id0].C_re[j][k] + w * pBand_coeffs[id1].C_re[j][k]; + pBand_coeffs[b].C_re_fx[j][k] = L_add(Mpy_32_16_1(pBand_coeffs[id0].C_re_fx[j][k], sub(MAX_WORD16, w_fx)), Mpy_32_16_1(pBand_coeffs[id1].C_re_fx[j][k],w_fx)); } } for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { pBand_coeffs[b].P_re[j] = ( 1 - w ) * pBand_coeffs[id0].P_re[j] + w * pBand_coeffs[id1].P_re[j]; + pBand_coeffs[b].P_re_fx[j] = L_add(Mpy_32_16_1(pBand_coeffs[id0].P_re_fx[j], sub(MAX_WORD16, w_fx)), Mpy_32_16_1(pBand_coeffs[id1].P_re_fx[j], w_fx)); } } else /* young invalid bands */ @@ -2365,6 +2868,7 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { pBand_coeffs[b].pred_re[j] = pBand_coeffs_prev[b].pred_re[j]; + pBand_coeffs[b].pred_re_fx[j] = pBand_coeffs_prev[b].pred_re_fx[j]; } for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) @@ -2372,12 +2876,14 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) { pBand_coeffs[b].C_re[j][k] = pBand_coeffs_prev[b].C_re[j][k]; + pBand_coeffs[b].C_re_fx[j][k] = pBand_coeffs_prev[b].C_re_fx[j][k]; } } for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { pBand_coeffs[b].P_re[j] = pBand_coeffs_prev[b].P_re[j]; + pBand_coeffs[b].P_re_fx[j] = pBand_coeffs_prev[b].P_re_fx[j]; } } } @@ -2536,12 +3042,66 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( * * Unquantize SPAR MD DYX indices *-----------------------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED static void ivas_spar_unquant_dtx_indicies( ivas_spar_md_t *pSpar_md, const int16_t nB, const int16_t bw, int16_t *ndm_per_band ) +{ + int16_t i, b; + int16_t q_lvl; + //float val; + Word32 val_fx; + int16_t idx; + //float pr_min_max[2]; + Word32 pr_min_max_fx[2]; + + //pr_min_max[0] = pSpar_md->min_max[0]; + //pr_min_max[1] = pSpar_md->min_max[1]; + + pr_min_max_fx[0] = pSpar_md->min_max_fx[0]; + pr_min_max_fx[1] = pSpar_md->min_max_fx[1]; + + for ( b = 0; b < nB; b++ ) + { + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) + { + q_lvl = dtx_pr_real_q_levels[ndm_per_band[bw * b] - 1][i]; + //idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; + //ivas_deindex_real_index( &idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1 ); + //pSpar_md->band_coeffs[b].pred_re[i] = val; + //pSpar_md->band_coeffs[b].pred_re_fx[i] = val * (1 << 22); + + idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; + ivas_deindex_real_index_fx(&idx, q_lvl, pr_min_max_fx[0], pr_min_max_fx[1], &val_fx, 1); + pSpar_md->band_coeffs[b].pred_re_fx[i] = val_fx; + pSpar_md->band_coeffs[b].pred_re[i] = (float)val_fx / (1 << 22); + } + + for ( i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++ ) + { + q_lvl = dtx_pd_real_q_levels[ndm_per_band[bw * b] - 1][i]; + //idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; + //ivas_deindex_real_index( &idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1 ); + //pSpar_md->band_coeffs[b].P_re[i] = val; + //pSpar_md->band_coeffs[b].P_re_fx[i] = val*(1<<22); + + idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; + ivas_deindex_real_index_fx(&idx, q_lvl, dtx_pd_real_min_max_fx[0], dtx_pd_real_min_max_fx[1], &val_fx, 1); + pSpar_md->band_coeffs[b].P_re_fx[i] = val_fx; + pSpar_md->band_coeffs[b].P_re[i] = (float)val_fx / (1 << 22); + } + } + + return; +} +#else +static void ivas_spar_unquant_dtx_indicies( + ivas_spar_md_t *pSpar_md, + const int16_t nB, + const int16_t bw, + int16_t *ndm_per_band) { int16_t i, b; int16_t q_lvl; @@ -2552,35 +3112,132 @@ static void ivas_spar_unquant_dtx_indicies( pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; - for ( b = 0; b < nB; b++ ) + for (b = 0; b < nB; b++) { - for ( i = 0; i < FOA_CHANNELS - 1; i++ ) + for (i = 0; i < FOA_CHANNELS - 1; i++) { q_lvl = dtx_pr_real_q_levels[ndm_per_band[bw * b] - 1][i]; idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; - ivas_deindex_real_index( &idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1 ); + ivas_deindex_real_index(&idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1); pSpar_md->band_coeffs[b].pred_re[i] = val; } - for ( i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++ ) + for (i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++) { q_lvl = dtx_pd_real_q_levels[ndm_per_band[bw * b] - 1][i]; idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; - ivas_deindex_real_index( &idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1 ); + ivas_deindex_real_index(&idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1); pSpar_md->band_coeffs[b].P_re[i] = val; } } return; } - +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_parse_parameter_bitstream_dtx() * * parse DTX bitstream parameters *-----------------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_parse_parameter_bitstream_dtx( + ivas_spar_md_t *pSpar_md, + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + const int16_t bw, + const int16_t num_bands, + int16_t *num_dmx_per_band, + int16_t *num_dec_per_band ) +{ + int16_t i, j, ndec, ndm; + //float val; + Word32 val_fx; + int16_t idx; + //float pr_min_max[2]; + Word32 pr_min_max_fx[2]; + int16_t pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits; + int16_t zero_pad_bits, sid_bits_len; + + sid_bits_len = st0->next_bit_pos; + //pr_min_max[0] = pSpar_md->min_max[0]; + pr_min_max_fx[0] = pSpar_md->min_max_fx[0]; + //pr_min_max[1] = pSpar_md->min_max[1]; + pr_min_max_fx[1] = pSpar_md->min_max_fx[1]; + + for ( i = 0; i < num_bands; i++ ) + { + ndec = num_dec_per_band[bw * i]; + ndm = num_dmx_per_band[bw * i]; + + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + int16_t pr_idx_1, pr_idx_2, pd_idx_1, pd_idx_2; + uint16_t value; + + pr_idx_1 = pr_pr_idx_pairs[ndm - 1][j][0]; + pr_idx_2 = pr_pr_idx_pairs[ndm - 1][j][1]; + pd_idx_1 = pr_pd_idx_pairs[ndm - 1][j][0]; + pd_idx_2 = pr_pd_idx_pairs[ndm - 1][j][1]; + + if ( pr_idx_1 != 0 || pd_idx_1 != 0 || pr_idx_2 != 0 || pd_idx_2 != 0 ) + { + pr_q_lvls = dtx_pr_real_q_levels[ndm - 1][pd_idx_1 - 1]; + + if ( ( j + 1 ) > ndec ) + { + pd_q_lvls = 1; + } + else + { + pd_q_lvls = dtx_pd_real_q_levels[ndm - 1][pd_idx_2 - 1]; + } + + pr_pd_bits = ivas_get_bits_to_encode( pd_q_lvls * pr_q_lvls ); + + value = get_next_indice( st0, pr_pd_bits ); + + pr = (int16_t) floor( value / pd_q_lvls ); + pd = value - pr * pd_q_lvls; + //val = dtx_pd_real_min_max[0]; + val_fx = dtx_pd_real_min_max_fx[0]; + //ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); + ivas_quantise_real_values_fx( &val_fx, pd_q_lvls, dtx_pd_real_min_max_fx[0], dtx_pd_real_min_max_fx[1], &idx, &val_fx, 1 ); + pd = pd + idx; + + //val = pr_min_max[0]; + val_fx = pr_min_max_fx[0]; + //ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + ivas_quantise_real_values_fx( &val_fx, pr_q_lvls, pr_min_max_fx[0], pr_min_max_fx[1], &idx, &val_fx, 1 ); + pr = pr + idx; + + if ( ( j + 1 ) <= ndec ) + { + pSpar_md->band_coeffs_idx[i].decd_index_re[pd_idx_2 - 1] = pd; + } + + pSpar_md->band_coeffs_idx[i].pred_index_re[pd_idx_1 - 1] = pr; + } + } + } + + sid_bits_len = st0->next_bit_pos - sid_bits_len; + zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; + assert( zero_pad_bits >= 0 ); + if ( num_dmx_per_band[0] == 2 ) + { + zero_pad_bits -= 1; + } + + for ( j = 0; j < zero_pad_bits; j++ ) + { + get_next_indice( st0, 1 ); + } + + ivas_spar_unquant_dtx_indicies( pSpar_md, num_bands, bw, num_dmx_per_band ); + return; +} +#else static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ @@ -2669,7 +3326,7 @@ static void ivas_parse_parameter_bitstream_dtx( return; } - +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_deindex_real_index() @@ -2712,6 +3369,41 @@ static ivas_error ivas_deindex_real_index( return IVAS_ERR_OK; } +static ivas_error ivas_deindex_real_index_fx( + const int16_t *index, + const int16_t q_levels, + const Word32 min_value, + const Word32 max_value, + Word32 *quant, + const int16_t dim) +{ + int16_t i; + Word32 q_step_fx; + if (q_levels == 0) + { + return IVAS_ERR_INTERNAL; + } + + if (q_levels == 1) + { + for (i = 0; i < dim; i++) + { + quant[i] = 0; + } + } + else + { + q_step_fx = L_sub(max_value, min_value); + q_step_fx = Mpy_32_32(q_step_fx, one_by_q_level[(q_levels - 1)]); + for (i = 0; i < dim; i++) + { + quant[i] = Mpy_32_32(L_shl(index[i], 31 - 6), q_step_fx);//(25+28)-31 = 22 + } + } + + return IVAS_ERR_OK; +} + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_to_dirac() @@ -2732,18 +3424,27 @@ void ivas_spar_to_dirac( int16_t block, b; int16_t *band_grouping; float diffuseness[IVAS_MAX_NUM_BANDS]; + Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS]; int16_t sba_order_internal; float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; int16_t azi[IVAS_MAX_NUM_BANDS]; int16_t ele[IVAS_MAX_NUM_BANDS]; float dvx[IVAS_MAX_NUM_BANDS], dvy[IVAS_MAX_NUM_BANDS], dvz[IVAS_MAX_NUM_BANDS]; + Word32 dvx_q, dvy_q, dvz_q; + Word32 dvx_fx[IVAS_MAX_NUM_BANDS], dvy_fx[IVAS_MAX_NUM_BANDS], dvz_fx[IVAS_MAX_NUM_BANDS]; float radius; + Word32 radius_fx,radius_q; float en_ratio, res_pow; + Word32 en_ratio_fx, res_pow_fx; + Word32 en_ratio_q, res_pow_q; int16_t num_slots_in_subfr; int16_t tmp_write_idx_param_band; int16_t tmp_write_idx_band; float pred_re_20ms[IVAS_MAX_NUM_BANDS][IVAS_SPAR_MAX_CH - 1]; + Word32 pred_re_20ms_fx[IVAS_MAX_NUM_BANDS][IVAS_SPAR_MAX_CH - 1]; int16_t pred_idx; int16_t *dirac_to_spar_md_bands; int16_t enc_param_start_band; @@ -2772,70 +3473,205 @@ void ivas_spar_to_dirac( for ( band = start_band; band < end_band; band++ ) { float PR[3], Pd[3], dvnorm, g_pred; - + Word32 PR_fx[3], Pd_fx[3], dvnorm_fx, g_pred_fx; + Word16 q_g_pred; + Word16 q_dvnorm; PR[0] = hMdDec->spar_md.band_coeffs[band].pred_re[2]; + PR_fx[0] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[2]; PR[1] = hMdDec->spar_md.band_coeffs[band].pred_re[0]; + PR_fx[1] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[0]; PR[2] = hMdDec->spar_md.band_coeffs[band].pred_re[1]; + PR_fx[2] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[1]; g_pred = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + g_pred_fx = Mpy_32_32(PR_fx[0], PR_fx[0]) + Mpy_32_32(PR_fx[1], PR_fx[1]) + Mpy_32_32(PR_fx[2], PR_fx[2]); + q_g_pred = 22 + 22 - 31; + q_g_pred = 31 - q_g_pred; + q_dvnorm = q_g_pred; if ( g_pred <= EPSILON ) { dvx[band] = 1.0f; dvy[band] = 0.0f; dvz[band] = 0.0f; + + azi[band] = 0; + ele[band] = 0; + q_g_pred = 0; + q_dvnorm = 0; } else { g_pred = sqrtf( g_pred ); dvnorm = 1.0f / g_pred; + dvnorm_fx = ISqrt32(g_pred_fx, &q_dvnorm); + g_pred_fx = Sqrt32(g_pred_fx, &q_g_pred); + if (q_g_pred < 0) + { + g_pred_fx = L_shr(g_pred_fx, (-1 * q_g_pred)); + q_g_pred = 0; + } + dvx[band] = PR[0] * dvnorm; dvy[band] = PR[1] * dvnorm; dvz[band] = PR[2] * dvnorm; - } - - radius = sqrtf( dvx[band] * dvx[band] + dvy[band] * dvy[band] ); - azi[band] = (int16_t) ( max( -180.0f, min( 180.0f, atan2f( dvy[band], dvx[band] ) / EVS_PI * 180.0f ) ) + 0.5f ); - ele[band] = (int16_t) ( max( -90.0f, min( 180.0f, atan2f( dvz[band], radius ) / EVS_PI * 180.0f ) ) + 0.5f ); + dvx_fx[band] = Mpy_32_32(PR_fx[0], dvnorm_fx); + dvy_fx[band] = Mpy_32_32(PR_fx[1], dvnorm_fx); + dvz_fx[band] = Mpy_32_32(PR_fx[2], dvnorm_fx); + Word32 q_1 = (22) + (31 - q_dvnorm) - 31; + + Word32 temp = Mpy_32_32(dvx_fx[band], dvx_fx[band]) + Mpy_32_32(dvy_fx[band], dvy_fx[band] ); + Word32 q2 = q_1 + q_1 - 31; + Word32 q_temp = 31 - q2; + radius_fx = Sqrt32(temp, &q_temp); + radius = sqrtf(dvx[band] * dvx[band] + dvy[band] * dvy[band]); + + + float check_qzi = atan2f(dvy[band], dvx[band]); + Word16 check_azi_fx = BASOP_util_atan2(dvy_fx[band], dvx_fx[band],0); + Word32 check_azi_fx_32 = L_shl(check_azi_fx,16); + Word16 check_azi_fx_res; + if (check_azi_fx_32 < 0) + { + check_azi_fx_res = negate(divide3232(L_negate(check_azi_fx_32), 1686629760)); + } + else + { + check_azi_fx_res = divide3232(check_azi_fx_32, 1686629760); + } + Word32 azi_intermediate = Mpy_32_16_1(DEGREE_180_Q_22, check_azi_fx_res); + azi_intermediate = azi_intermediate + ONE_IN_Q21; + //Word16 azi_res = L_shr_r(azi_intermediate, 22); + Word16 azi_res = azi_intermediate / (1 << 22); + + Word16 check_ele_fx = BASOP_util_atan2(dvz_fx[band], radius_fx, (9+ q_dvnorm)-q_temp); + Word32 check_ele_fx_32 = L_shl(check_ele_fx, 16); + Word16 check_ele_fx_res; + if (check_azi_fx_32 < 0) + { + check_ele_fx_res = negate(divide3232(L_negate(check_ele_fx_32), 1686629760)); + } + else + { + check_ele_fx_res = divide3232(check_ele_fx_32, 1686629760); + } + Word32 ele_intermediate = Mpy_32_16_1(DEGREE_180_Q_22, check_ele_fx_res); + ele_intermediate = ele_intermediate + ONE_IN_Q21; + //Word16 ele_res = L_shr_r(ele_intermediate, 22); + Word16 ele_res = ele_intermediate/(1<<22); + + + azi[band] = (int16_t)(max(-180.0f, min(180.0f, atan2f(dvy[band], dvx[band]) / EVS_PI * 180.0f)) + 0.5f); + azi[band] = max(-180, min(180, azi_res)); + ele[band] = (int16_t)(max(-90.0f, min(180.0f, atan2f(dvz[band], radius) / EVS_PI * 180.0f)) + 0.5f); + ele[band] = max(-90, min(180, ele_res)); + } + + Word16 en_ratio_q = 0; if ( st_ivas->nchan_transport == 1 ) { float w_en_norm, f_scale; + Word32 w_en_norm_fx, f_scale_fx; + Word32 q_w_en_norm_fx; if ( active_w ) { if ( dtx_vad == 0 ) { f_scale = IVAS_ACTIVEW_DM_F_SCALE_DTX; + f_scale_fx = IVAS_ACTIVEW_DM_F_SCALE_DTX_FX; } else { f_scale = ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_SCALE_VLBR : IVAS_ACTIVEW_DM_F_SCALE; + f_scale_fx = ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX : IVAS_ACTIVEW_DM_F_SCALE_FX; } } else { f_scale = 0.0f; + f_scale_fx = 0; } w_en_norm = ( 1.0f - ( f_scale * g_pred * g_pred ) ); + Word32 temp_result = Mpy_32_32(Mpy_32_32(f_scale_fx, g_pred_fx), g_pred_fx); + temp_result = L_sub(L_shr(ONE_IN_Q31, q_g_pred), temp_result); w_en_norm *= w_en_norm; - + w_en_norm_fx = Mpy_32_32(temp_result, temp_result); + q_w_en_norm_fx = q_g_pred + q_g_pred; Pd[0] = hMdDec->spar_md.band_coeffs[band].P_re[1]; Pd[1] = hMdDec->spar_md.band_coeffs[band].P_re[0]; Pd[2] = hMdDec->spar_md.band_coeffs[band].P_re[2]; + Pd_fx[0] = hMdDec->spar_md.band_coeffs[band].P_re_fx[1]; + Pd_fx[1] = hMdDec->spar_md.band_coeffs[band].P_re_fx[0]; + Pd_fx[2] = hMdDec->spar_md.band_coeffs[band].P_re_fx[2]; en_ratio = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + en_ratio_fx = Mpy_32_32(PR_fx[0], PR_fx[0]) + Mpy_32_32(PR_fx[1], PR_fx[1]) + Mpy_32_32(PR_fx[2], PR_fx[2]); //22+22-31 = 13 + Word32 Pd_temp_res = Mpy_32_32(Pd_fx[0], Pd_fx[0]) + Mpy_32_32(Pd_fx[1], Pd_fx[1]) + Mpy_32_32(Pd_fx[2], Pd_fx[2]);//q = 22+22-31 = 13 res_pow = w_en_norm + en_ratio + ( Pd[0] * Pd[0] + Pd[1] * Pd[1] + Pd[2] * Pd[2] ); + res_pow_fx = L_shr(w_en_norm_fx, (31- q_w_en_norm_fx)-13) + en_ratio_fx + Pd_temp_res; + res_pow_q = 13; + res_pow_fx = L_shr(res_pow_fx, 1); res_pow *= 0.5f; hMdDec->spar_md.en_ratio_slow[band] = 0.75f * hMdDec->spar_md.en_ratio_slow[band] + 0.25f * en_ratio; + hMdDec->spar_md.en_ratio_slow_fx[band] = Mpy_32_32(1610612736, hMdDec->spar_md.en_ratio_slow_fx[band]) + Mpy_32_32(536870912, en_ratio_fx); hMdDec->spar_md.ref_pow_slow[band] = 0.75f * hMdDec->spar_md.ref_pow_slow[band] + 0.25f * res_pow; + hMdDec->spar_md.ref_pow_slow_fx[band] = Mpy_32_32(1610612736, hMdDec->spar_md.ref_pow_slow_fx[band]) + Mpy_32_32(536870912, res_pow_fx); en_ratio = sqrtf( hMdDec->spar_md.en_ratio_slow[band] ) / ( hMdDec->spar_md.ref_pow_slow[band] + EPSILON ); + en_ratio_q = 31 - 13; + en_ratio_fx = Sqrt32(hMdDec->spar_md.en_ratio_slow_fx[band], &en_ratio_q); + if (en_ratio_q < 0) + { + en_ratio_fx = L_shr(en_ratio_fx, -1 * (en_ratio_q)); + en_ratio_q = 0; + } + Word32 en_ratio_fx_scaled = L_shr(en_ratio_fx, (31 - en_ratio_q - 13)); + if (en_ratio_fx_scaled > hMdDec->spar_md.ref_pow_slow_fx[band]) + { + diffuseness_fx[band] = 0; + } + else if(en_ratio_fx_scaled == 0) + { + diffuseness_fx[band] = ONE_IN_Q30; + } + else if (en_ratio_fx_scaled == hMdDec->spar_md.ref_pow_slow_fx[band]) + { + diffuseness_fx[band] = ONE_IN_Q30; + } + else + { + en_ratio_fx = divide3232(en_ratio_fx_scaled, (hMdDec->spar_md.ref_pow_slow_fx[band] + EPSILON_FX)); + en_ratio_fx = L_shl(en_ratio_fx, 15); + diffuseness_fx[band] = ONE_IN_Q30 - en_ratio_fx; + } + } else { en_ratio = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + en_ratio_fx = Mpy_32_32(PR_fx[0] , PR_fx[0]) + Mpy_32_32(PR_fx[1] , PR_fx[1])+ Mpy_32_32(PR_fx[2] , PR_fx[2]); hMdDec->spar_md.en_ratio_slow[band] = 0.75f * hMdDec->spar_md.en_ratio_slow[band] + 0.25f * en_ratio; + hMdDec->spar_md.en_ratio_slow_fx[band] = Mpy_32_32(1610612736, hMdDec->spar_md.en_ratio_slow_fx[band]) + Mpy_32_32(536870912, en_ratio_fx); en_ratio = sqrtf( hMdDec->spar_md.en_ratio_slow[band] ); + en_ratio_q = 31 - 13; + en_ratio_fx = Sqrt32( hMdDec->spar_md.en_ratio_slow_fx[band], &en_ratio_q); + if (en_ratio_q < 0) + { + en_ratio_fx = L_shr(en_ratio_fx, -1 * (en_ratio_q)); + en_ratio_q = 0; + } + Word32 en_ratio_fx_scaled = L_shr(en_ratio_fx, 1); + if (en_ratio_fx_scaled > ONE_IN_Q30) + { + diffuseness_fx[band] = 0; + } + else + { + diffuseness_fx[band] = ONE_IN_Q30 - en_ratio_fx_scaled; + } + } diffuseness[band] = 1.0f - en_ratio; /*compute diffuseness*/ diffuseness[band] = ( ( diffuseness[band] < 1.0f ) ? ( ( diffuseness[band] < 0.0f ) ? 0.f : diffuseness[band] ) : 1.0f ); + diffuseness[band] = (float)diffuseness_fx[band] / (1 << 30); } for ( band = start_band; band < end_band; band++ ) @@ -2844,7 +3680,13 @@ void ivas_spar_to_dirac( tmp_write_idx_param_band = hDirAC->spar_to_dirac_write_idx; en_ratio = 1.0f - diffuseness[band]; + en_ratio_fx = ONE_IN_Q30 - diffuseness_fx[band]; + en_ratio = (float)en_ratio_fx / (1 << 30); + //cam delete the below function call masa_sq( 1.0f - en_ratio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); +#ifdef IVAS_FLOAT_FIXED + masa_sq_fx(ONE_IN_Q30 - en_ratio_fx, diffuseness_thresholds_fx, DIRAC_DIFFUSE_LEVELS ); +#endif qmf_band_start = band_grouping[band]; qmf_band_end = band_grouping[band + 1]; @@ -2862,6 +3704,9 @@ void ivas_spar_to_dirac( ele_dith = ele[band]; hSpatParamRendCom->energy_ratio1[block][b] = en_ratio; +#ifdef IVAS_FLOAT_FIXED + hSpatParamRendCom->energy_ratio1_fx[block][b] = en_ratio_fx; +#endif tmp_write_idx_band = tmp_write_idx_param_band; if ( hDirAC->hConfig->dec_param_estim == FALSE ) @@ -2869,6 +3714,9 @@ void ivas_spar_to_dirac( hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band]; +#ifdef IVAS_FLOAT_FIXED + hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = diffuseness_fx[band]; +#endif } else { @@ -2877,6 +3725,9 @@ void ivas_spar_to_dirac( hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band]; +#ifdef IVAS_FLOAT_FIXED + hSpatParamRendCom->diffuseness_vector_fx[tmp_write_idx_band][b] = diffuseness_fx[band]; +#endif tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; } } @@ -2921,15 +3772,26 @@ void ivas_spar_to_dirac( } azi_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[block]; ele_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].elevation[block]; +#ifdef IVAS_FLOAT_FIXED + azi_dirac_fx[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth_fx[block]; + ele_dirac_fx[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].elevation_fx[block]; +#endif } diffuseness[band] = 1.0f - st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; +#ifdef IVAS_FLOAT_FIXED + diffuseness_fx[band] = ONE_IN_Q30 - st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio_fx[0]; +#endif } /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */ if ( hMdDec->spar_md_cfg.nchan_transport > 1 ) { +#ifdef IVAS_FLOAT_FIXED + ivas_get_spar_md_from_dirac_fx( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); +#else ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); +#endif /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) @@ -2937,14 +3799,18 @@ void ivas_spar_to_dirac( for ( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ ) { pred_re_20ms[band][pred_idx] = hMdDec->spar_md.band_coeffs[band].pred_re[pred_idx]; + pred_re_20ms_fx[band][pred_idx] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[pred_idx]; } } } int16_t num_md_sub_frames; num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order_internal, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); +#ifdef IVAS_FLOAT_FIXED + ivas_get_spar_md_from_dirac_fx( azi_dirac, ele_dirac, diffuseness, num_md_sub_frames, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); +#else ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, num_md_sub_frames, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); - +#endif if ( st_ivas->hQMetaData->useLowerRes && dtx_vad ) { for ( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ ) @@ -2954,10 +3820,12 @@ void ivas_spar_to_dirac( for ( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */ { hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re[i] = hMdDec->spar_md.band_coeffs[band].pred_re[i]; + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re_fx[i] = hMdDec->spar_md.band_coeffs[band].pred_re_fx[i]; } for ( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */ { hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].P_re[i] = hMdDec->spar_md.band_coeffs[band].P_re[i]; + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].P_re_fx[i] = hMdDec->spar_md.band_coeffs[band].P_re_fx[i]; } } } @@ -2974,6 +3842,7 @@ void ivas_spar_to_dirac( { /* use 20ms coefficients only for residual channels */ hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re[pred_idx] = pred_re_20ms[band][pred_idx]; + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re_fx[pred_idx] = pred_re_20ms_fx[band][pred_idx]; } } } diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 37d7c0785..1fd5d06e8 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -852,6 +852,9 @@ typedef struct ivas_spar_md_dec_state_t Word16 smooth_fac_fx[IVAS_MAX_NUM_BANDS]; #endif float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; +#ifdef IVAS_FLOAT_FIXED + Word32 mixer_mat_prev2_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; +#endif int16_t first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index e89840855..285f06c26 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -4010,7 +4010,7 @@ void stereo_switching_dec( { FOR( i = 0; i < dft32ms_ovl; i++ ) { - hCPE->output_mem_fx[n][i] = Mpy_32_32( hCPE->hStereoDft->win32ms_fx[STEREO_DFT32MS_STEP * ( dft32ms_ovl - 1 - i )], hCPE->output_mem_fx[n][i] ); + hCPE->output_mem_fx[n][i] = Mpy_32_16_1(hCPE->output_mem_fx[n][i], hCPE->hStereoDft->win32ms_fx[STEREO_DFT32MS_STEP * (dft32ms_ovl - 1 - i)]); } } ELSE @@ -4028,7 +4028,7 @@ void stereo_switching_dec( } FOR( i = 0; i < dft32ms_ovl; i++ ) { - Word32 temp_result = Mpy_32_32( tmpF_fx, hCPE->hStereoDft->win32ms_fx[STEREO_DFT32MS_STEP * ( dft32ms_ovl - 1 - i )] ); + Word32 temp_result = Mpy_32_16_1(tmpF_fx, hCPE->hStereoDft->win32ms_fx[STEREO_DFT32MS_STEP * (dft32ms_ovl - 1 - i)]); hCPE->output_mem_fx[n][i] = L_shl_sat( Mpy_32_32( hCPE->output_mem_fx[n][i], temp_result ), 4 ); } FOR( i = 0; i < delay_comp_TD; i++ ) diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index b6e8442fb..ff5d9d0b0 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -2282,13 +2282,15 @@ typedef struct Decoder_State float enerLH; Word32 enerLH_fx; + Word16 enerLH_fx_Q; float prev_enerLH; Word32 prev_enerLH_fx; float enerLL; Word32 enerLL_fx; - + Word16 enerLL_fx_Q; + float prev_enerLL; Word32 prev_enerLL_fx; -- GitLab