diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 06e5e34b891cc68873029cb8f92ed61575f2bf33..1b6940be546336a64fdad66d7006591808482911 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -343,14 +343,22 @@ typedef enum #define ISM_AZIMUTH_MAX_FX 754974720 #define ISM_AZIMUTH_LOW_BORDER -140.0f #define ISM_AZIMUTH_HIGH_BORDER 135.0f +#define ISM_AZIMUTH_LOW_BORDER_FX -587202560 +#define ISM_AZIMUTH_HIGH_BORDER_FX 566231040 #define ISM_ELEVATION_NBITS 6 #define ISM_ELEVATION_MIN -90.0f #define ISM_ELEVATION_MAX 90.0f +#define ISM_ELEVATION_MIN_FX -377487360 +#define ISM_ELEVATION_MAX_FX 377487360 #define ISM_ELEVATION_LOW_BORDER -70.0f #define ISM_ELEVATION_HIGH_BORDER 65.0f +#define ISM_ELEVATION_LOW_BORDER_FX -293601280 +#define ISM_ELEVATION_HIGH_BORDER_FX 272629760 #define ISM_Q_STEP 2.5f +#define ISM_Q_STEP_FX 10485760 #define ISM_Q_STEP_BORDER 5.0f +#define ISM_Q_STEP_BORDER_FX 20971520 #define ISM_RADIUS_NBITS 6 #define ISM_RADIUS_MIN 0.0f diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index a27621adb5121ae6844925f6251d1e81f42a6dff..6f0b03286d802c16165da43771e79551c7cf0f1c 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -838,6 +838,62 @@ void ivas_ism_reset_metadata_API( *-------------------------------------------------------------------*/ /*! r: index of the winning codeword */ +#ifdef IVAS_FLOAT_FIXED +Word16 ism_quant_meta_fx( + const Word32 val, /* i : scalar value to quantize Q22 */ + Word32 *valQ, /* o : quantized value Q22 */ + const Word32 borders_fx[], /* i : level borders Q22 */ + const Word32 q_step_fx, /* i : quantization step Q22 */ + const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */ + const Word16 cbsize /* i : codebook size */ +) +{ + Word16 idx, idx_start; + Word32 qlow_fx, step_fx; + Word16 tmp, tmp_e; + + IF( val <= borders_fx[1] ) + { + qlow_fx = borders_fx[0]; + move32(); + idx_start = 0; + move32(); + step_fx = q_step_border_fx; + move32(); + } + ELSE IF( val <= borders_fx[2] ) + { + qlow_fx = borders_fx[1]; + move32(); + tmp = BASOP_Util_Divide3232_Scale( L_sub( borders_fx[1], borders_fx[0] ), q_step_border_fx, &tmp_e ); + idx_start = shr( tmp, sub( 15, tmp_e ) ); + step_fx = q_step_fx; + move32(); + } + ELSE + { + qlow_fx = borders_fx[2]; + move32(); + tmp = BASOP_Util_Divide3232_Scale( L_add( L_sub( borders_fx[3], borders_fx[2] ), L_sub( q_step_border_fx, ONE_IN_Q22 ) ), q_step_border_fx, &tmp_e ); + idx_start = sub( cbsize, add( 1, shr( tmp, sub( 15, tmp_e ) ) ) ); + step_fx = q_step_border_fx; + move32(); + } + + + tmp = BASOP_Util_Divide3232_Scale( L_sub( val, qlow_fx ), step_fx, &tmp_e ); + tmp = shl( tmp, sub( Q1, sub( 15, tmp_e ) ) ); + tmp = add( tmp, 1 ); + tmp = shr( tmp, 1 ); + idx = add( idx_start, s_max( 0, s_min( sub( cbsize, 1 ), tmp ) ) ); + + // idx = idx_start + (int16_t) max( 0.f, min( cbsize - 1, ( ( val - qlow_fx ) / step_fx + 0.5f ) ) ); + *valQ = L_add( imult3216( step_fx, sub( idx, idx_start ) ), qlow_fx ); + + return idx; +} +#endif + int16_t ism_quant_meta( const float val, /* i : scalar value to quantize */ float *valQ, /* o : quantized value */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index f7c387d2d85e1fd283d7d30c17634a54cc733835..8ae9ce4560bf2dff52165a8cfd122f9d765bb916 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -2384,4 +2384,13 @@ Word16 calculate_brate_limit_flag_fx( const Word16 ism_imp[], /* i : ISM importance flags */ const Word16 nchan_ism /* i : number of objects */ ); +Word16 ism_quant_meta_fx( + const Word32 val, /* i : scalar value to quantize */ + Word32 *valQ, /* o : quantized value */ + const Word32 borders_fx[], /* i : level borders */ + const Word32 q_step_fx, /* i : quantization step */ + const Word32 q_step_border_fx, /* i : quantization step at the border */ + const Word16 cbsize /* i : codebook size */ +); + #endif diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 70869d12ca6a8ccb477588bad35e15b6b39848be..c3b7456f3d2dd980090d24b77845ed534c910bc9 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -3576,6 +3576,19 @@ const float ism_elevation_borders[4] = ISM_ELEVATION_MIN, ISM_ELEVATION_LOW_BORDER, ISM_ELEVATION_HIGH_BORDER, ISM_ELEVATION_MAX }; +#ifdef IVAS_FLOAT_FIXED +const Word32 ism_azimuth_borders_fx[4] = +{ + ISM_AZIMUTH_MIN_FX, ISM_AZIMUTH_LOW_BORDER_FX, ISM_AZIMUTH_HIGH_BORDER_FX, ISM_AZIMUTH_MAX_FX +}; + +const Word32 ism_elevation_borders_fx[4] = +{ + ISM_ELEVATION_MIN_FX, ISM_ELEVATION_LOW_BORDER_FX, ISM_ELEVATION_HIGH_BORDER_FX, ISM_ELEVATION_MAX_FX +}; + +#endif + /*----------------------------------------------------------------------------------* * Param ISM ROM tables diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index c96f4e884739923008feb90e2072cb59e8ece9fe..e90ae83ac2f82687af9198058b061c4c4ce874ab 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -406,6 +406,11 @@ extern const Word32 dct12_fx[]; extern const float ism_azimuth_borders[4]; extern const float ism_elevation_borders[4]; +#ifdef IVAS_FLOAT_FIXED +extern const Word32 ism_azimuth_borders_fx[4]; +extern const Word32 ism_elevation_borders_fx[4]; +#endif + /*----------------------------------------------------------------------------------* * Param ISM ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index 726c23cb38b82dab0758670318d58faf3b1e4698..0570d4f3c3f4af6beb991ece86efb194c7d80d11 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -288,15 +288,15 @@ const Word16 ivas_divde_255[256] = { 31996, 32125, 32253, 32382, 32510, 32639, 32767 }; -const Word32 ism_azimuth_borders_fx[4] = -{ - -754974720, -587202560, 566231040, 754974720 -}; - -const Word32 ism_elevation_borders_fx[4] = -{ - -377487360, -293601280, 272639760, 377487360 -}; +//const Word32 ism_azimuth_borders_fx[4] = +//{ +// -754974720, -587202560, 566231040, 754974720 +//}; +// +//const Word32 ism_elevation_borders_fx[4] = +//{ +// -377487360, -293601280, 272639760, 377487360 +//}; const Word16 gridEq_Table[NO_THETA16_MAX] = { 430, 423, 422, 422, 422, 422, 421, 421, 420, 420, 419, 418, 417, 417, 416, diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 0b4a5e2e9a8f949feef8eac9e0c90a98d343d3a9..8f58798b3c5c67c9f888b63ca23e05b81eb7e871 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -36,8 +36,11 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include #include "wmc_auto.h" #ifdef IVAS_FLOAT_FIXED @@ -123,50 +126,673 @@ static void rate_ism_importance( { int16_t ch, ctype; - for ( ch = 0; ch < nchan_transport; ch++ ) - { - ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw; + for ( ch = 0; ch < nchan_transport; ch++ ) + { + ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw; + + if ( hSCE[ch]->hCoreCoder[0]->tcxonly ) + { + if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 ) + { + ctype = INACTIVE; + } + else if ( ctype == UNVOICED ) + { + ctype = GENERIC; + } + } + + if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 ) + { + ism_imp[ch] = ISM_NO_META; + } + else if ( ctype == INACTIVE || ctype == UNVOICED ) + { + ism_imp[ch] = ISM_LOW_IMP; + } + else if ( ctype == VOICED ) + { + ism_imp[ch] = ISM_MEDIUM_IMP; + } + else /* GENERIC */ + { + ism_imp[ch] = ISM_HIGH_IMP; + } + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_ism_metadata_enc() + * + * quantize and encode ISM metadata + *-------------------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED +ivas_error ivas_ism_metadata_enc( + int32_t *ism_total_brate, /* i/o: ISM total bitrate */ + const int16_t nchan_ism, /* i : number of ISM channels */ + const int16_t nchan_transport, /* i : number of transport channels */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + int16_t nb_bits_metadata[], /* o : number of metadata bits */ + const int16_t vad_flag[], /* i : VAD flag */ + const int16_t ism_mode, /* i : ISM mode */ + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Enc Handle */ + const int16_t ism_extended_metadata_flag, /* i : Extended metadata flag */ + const float lp_noise_CPE, + const int16_t flag_omasa_ener_brate, /* i : less bitrate for objects in OMASA flag */ + int16_t *omasa_stereo_sw_cnt, + const int16_t ini_frame ) +{ + int16_t i, ch, nb_bits_start = 0; + int16_t flag_abs_azimuth[MAX_NUM_OBJECTS]; + int16_t flag_abs_elevation[MAX_NUM_OBJECTS]; + int16_t idx_angle1_abs = 0; + int16_t idx_angle2_abs = 0; + int16_t flag_abs_yaw[MAX_NUM_OBJECTS]; + int16_t flag_abs_pitch[MAX_NUM_OBJECTS]; + int16_t idx_radius_abs = 0, flag_abs_radius[MAX_NUM_OBJECTS]; + float valQ; +#ifdef IVAS_FLOAT_FIXED + Word32 valQ_fx; +#endif + ISM_METADATA_HANDLE hIsmMetaData; + int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; + int16_t ism_metadata_flag_global; + int16_t non_diegetic_flag_global; + int16_t ism_imp[MAX_NUM_OBJECTS]; + int16_t null_metadata_flag[MAX_NUM_OBJECTS]; + int16_t lowrate_metadata_flag[MAX_NUM_OBJECTS]; + int16_t nbands, nblocks; + ivas_error error; + + error = IVAS_ERR_OK; + push_wmops( "ism_meta_enc" ); + + /* initialization */ + ism_metadata_flag_global = 0; + non_diegetic_flag_global = 0; + set_s( nb_bits_metadata, 0, nchan_transport ); + set_s( flag_abs_azimuth, 0, nchan_ism ); + set_s( flag_abs_elevation, 0, nchan_ism ); + set_s( flag_abs_yaw, 0, nchan_ism ); + set_s( flag_abs_pitch, 0, nchan_ism ); + set_s( flag_abs_radius, 0, nchan_ism ); + set_s( null_metadata_flag, 0, nchan_ism ); + set_s( lowrate_metadata_flag, 0, nchan_ism ); + + if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + /*----------------------------------------------------------------* + * Rate importance of particular ISM streams in combined format coding + *----------------------------------------------------------------*/ + + ivas_set_ism_importance_interformat( *ism_total_brate, nchan_transport, hIsmMeta, hSCE, lp_noise_CPE, ism_imp ); + } + else + { + /*----------------------------------------------------------------* + * Set Metadata presence / importance flag + *----------------------------------------------------------------*/ + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + if ( ism_mode == ISM_MODE_PARAM ) + { + hIsmMeta[ch]->ism_metadata_flag = 1; + } + else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + { + null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag; + + if ( hIsmMeta[ch]->ism_metadata_flag == 1 ) + { + if ( ism_mode != ISM_SBA_MODE_DISC ) + { + /* In case of low level noise for low bitrate inactive frames, do not sent metadata */ + hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10 || hSCE[ch]->hCoreCoder[0]->tcxonly; + } + + /* in inactive frames, send MD 1) in ISM_MD_INC_DIFF_CNT_MAX consecutive frames when MD significantly change, 2) at least every ISM_MD_FEC_DIFF frames */ + if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) + { + if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) || + ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_true_elevation ) > ISM_MD_FEC_DIFF ) || ( fabsf( hIsmMeta[ch]->radius - hIsmMeta[ch]->last_true_radius ) > ISM_MD_RAD_FEC_DIFF ) ) + { + + lowrate_metadata_flag[ch] = 1; + + hIsmMeta[ch]->ism_md_inc_diff_cnt = 0; + } + else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX ) + { + + lowrate_metadata_flag[ch] = 1; + + if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 ) + { + hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; + } + else + { + hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX; + } + } + else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX ) + { + + lowrate_metadata_flag[ch] = 1; + + hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX; + } + } + } + } + } + + /*----------------------------------------------------------------* + * Rate importance of particular ISM streams + *----------------------------------------------------------------*/ + + if ( ism_mode != ISM_SBA_MODE_DISC ) + { + rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp ); + } + } + + /*----------------------------------------------------------------* + * Write ISM common signaling + *----------------------------------------------------------------*/ + + if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ && ism_mode != ISM_SBA_MODE_DISC ) + { + /* write number of objects - unary coding */ + for ( ch = 1; ch < nchan_ism; ch++ ) + { + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 ); + } + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 ); + } + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; + ism_metadata_flag_global |= lowrate_metadata_flag[ch]; + non_diegetic_flag_global |= hIsmMeta[ch]->non_diegetic_flag; + } + + /* write extended metadata presence flag */ + if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE ) + { + push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS ); + + /* Write global non-diegetic object flag */ + if ( ism_extended_metadata_flag ) + { + push_indice( hBstr, IND_ISM_EXTENDED_NDP_FLAG, non_diegetic_flag_global, ISM_EXTENDED_METADATA_BITS ); + } + } + + /* write ISM metadata flag (one per object) */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + /* flags will be written in ivas_masa_encode() */ + hIsmMeta[ch]->ism_imp = ism_imp[ch]; + hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch]; + hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch]; + } + else + { + if ( null_metadata_flag[ch] ) + { + /* signal NULL metadata frame */ + push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS ); + + /* write the ISM class to ISM_NO_META and again the true ISM class */ + if ( ism_mode != ISM_SBA_MODE_DISC ) + { + push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS ); + push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS ); + } + else + { + push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, 1 ); + } + } + else if ( ism_mode != ISM_SBA_MODE_DISC ) + { + push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS ); + + if ( ism_imp[ch] == ISM_NO_META ) + { + /* signal low-rate ISM_NO_META frame */ + push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS ); + + /* signal presence of MD in low-rate ISM_NO_META frame */ + push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS ); + } + } + else /*ism_mode == ISM_SBA_MODE_DISC*/ + { + /* all objects are considered active*/ + push_indice( hBstr, IND_ISM_METADATA_FLAG, 1, 1 ); + } + } + } + + + if ( ism_metadata_flag_global ) + { + /*----------------------------------------------------------------* + * Metadata quantization and coding, loop over all objects + *----------------------------------------------------------------*/ + + int16_t total_bits_metadata = 0; + int16_t bits_metadata_ism = 0; + int16_t nb_bits_objcod_written; + + if ( ism_mode == ISM_MODE_PARAM ) + { + nb_bits_start = hBstr->nb_bits_tot; + } + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMetaData = hIsmMeta[ch]; + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC ) + { + nb_bits_start = hBstr->nb_bits_tot; + } + + if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] ) + { + /*----------------------------------------------------------------* + * Quantize and encode azimuth and elevation + *----------------------------------------------------------------*/ + + if ( ism_extended_metadata_flag && non_diegetic_flag_global ) + { + /* Write non-diegetic flag for each object */ + push_indice( hBstr, IND_ISM_NDP_FLAG, hIsmMeta[ch]->non_diegetic_flag, ISM_METADATA_IS_NDP_BITS ); + } + + if ( hIsmMeta[ch]->non_diegetic_flag && ism_extended_metadata_flag ) + { + /* Map azimuth to panning range [-90:90] */ + if ( hIsmMetaData->azimuth > 90.0f ) + { + hIsmMetaData->azimuth = 180.0f - hIsmMetaData->azimuth; + } + + if ( hIsmMetaData->azimuth < -90.0f ) + { + hIsmMetaData->azimuth = -180.0f - hIsmMetaData->azimuth; + } + +#ifdef IVAS_FLOAT_FIXED + /*===============================flt-2-fix======================================*/ + hIsmMetaData->azimuth_fx = floatToFixed( hIsmMetaData->azimuth, Q22 ); + /*===============================flt-2-fix======================================*/ + idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); + /*===============================fix-2-flt======================================*/ + valQ = fixedToFloat( valQ_fx, Q22 ); + /*===============================fix-2-flt======================================*/ +#else + idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); +#endif + encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_angle1_abs, 0, &flag_abs_azimuth[ch], NULL ); + } + else + { + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC ) + { +#ifdef IVAS_FLOAT_FIXED + /*===============================flt-2-fix======================================*/ + hIsmMetaData->azimuth_fx = floatToFixed( hIsmMetaData->azimuth, Q22 ); + hIsmMetaData->elevation_fx = floatToFixed( hIsmMetaData->elevation, Q22 ); + /*===============================flt-2-fix======================================*/ + idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta_fx( hIsmMetaData->elevation_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); + /*===============================fix-2-flt======================================*/ + valQ = fixedToFloat( valQ_fx, Q22 ); + /*===============================fix-2-flt======================================*/ +#else + idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif + } + else /* ISM_MODE_PARAM */ + { + idx_angle1_abs = hParamIsm->azi_index[ch]; + idx_angle2_abs = hParamIsm->ele_index[ch]; + } + encode_angle_indices( hBstr, &( hIsmMetaData->position_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_azimuth[ch], &flag_abs_elevation[ch] ); + + /*----------------------------------------------------------------* + * Quantize and encode radius, yaw, and pitch + *----------------------------------------------------------------*/ + if ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_extended_metadata_flag ) + { +#ifdef IVAS_FLOAT_FIXED + /*===============================flt-2-fix======================================*/ + hIsmMetaData->yaw_fx = floatToFixed( hIsmMetaData->yaw, Q22 ); + hIsmMetaData->pitch_fx = floatToFixed( hIsmMetaData->pitch, Q22 ); + /*===============================flt-2-fix======================================*/ + idx_angle1_abs = ism_quant_meta_fx( hIsmMetaData->yaw_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta_fx( hIsmMetaData->pitch_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); + /*===============================fix-2-flt======================================*/ + valQ = fixedToFloat( valQ_fx, Q22 ); + /*===============================fix-2-flt======================================*/ +#else + idx_angle1_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_angle2_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); +#endif + idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS ); + + encode_angle_indices( hBstr, &( hIsmMetaData->orientation_angle ), hIsmMetaData->last_ism_metadata_flag, ini_frame, idx_angle1_abs, idx_angle2_abs, &flag_abs_yaw[ch], &flag_abs_pitch[ch] ); + encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); + } + } + + /* save number of metadata bits written */ + if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_SBA_MODE_DISC ) + { + nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start; + } + + /* Updates */ + hIsmMeta[ch]->last_true_azimuth = hIsmMeta[ch]->azimuth; + hIsmMeta[ch]->last_true_elevation = hIsmMeta[ch]->elevation; + hIsmMeta[ch]->last_true_radius = hIsmMeta[ch]->radius; + } + } + + /*----------------------------------------------------------------* + * inter-object logic minimizing the use of several absolutely coded + * indexes in the same frame + *----------------------------------------------------------------*/ + + i = 0; + while ( i == 0 || i < nchan_ism / INTER_OBJECT_PARAM_CHECK ) + { + int16_t num, abs_num, abs_first, abs_next, pos_zero; + int16_t abs_matrice[INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM]; + + num = min( INTER_OBJECT_PARAM_CHECK, nchan_ism - i * INTER_OBJECT_PARAM_CHECK ); + i++; + + set_s( abs_matrice, 0, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM ); + + for ( ch = 0; ch < num; ch++ ) + { + if ( flag_abs_azimuth[ch] == 1 ) + { + abs_matrice[ch * ISM_NUM_PARAM] = 1; + } + + if ( flag_abs_elevation[ch] == 1 ) + { + abs_matrice[ch * ISM_NUM_PARAM + 1] = 1; + } + } + abs_num = sum_s( abs_matrice, INTER_OBJECT_PARAM_CHECK * ISM_NUM_PARAM ); + + abs_first = 0; + while ( abs_num > 1 ) + { + /* find first "1" entry */ + while ( abs_matrice[abs_first] == 0 ) + { + abs_first++; + } + + /* find next "1" entry */ + abs_next = abs_first + 1; + while ( abs_matrice[abs_next] == 0 ) + { + abs_next++; + } + + /* find "0" position */ + pos_zero = 0; + while ( abs_matrice[pos_zero] == 1 ) + { + pos_zero++; + } + + ch = abs_next / ISM_NUM_PARAM; + + if ( abs_next % ISM_NUM_PARAM == 0 ) + { + hIsmMeta[ch]->position_angle.angle1_diff_cnt = abs_num - 1; + } + + if ( abs_next % ISM_NUM_PARAM == 1 ) + { + hIsmMeta[ch]->position_angle.angle2_diff_cnt = abs_num - 1; + /*hIsmMeta[ch]->elevation_diff_cnt = min( hIsmMeta[ch]->elevation_diff_cnt, ISM_FEC_MAX );*/ + } + + abs_first++; + abs_num--; + } + } + + if ( ism_mode == ISM_SBA_MODE_DISC ) + { + int16_t md_diff_flag[MAX_NUM_OBJECTS]; + + set_s( md_diff_flag, 1, nchan_ism ); + for ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; + + if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) + { + hIsmMeta[ch]->ism_md_fec_cnt_enc++; + } + else + { + hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; + } + hIsmMeta[ch]->ism_md_inc_diff_cnt++; + hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX ); + } + + update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag ); + + pop_wmops(); + return error; + } + if ( ism_mode == ISM_MODE_PARAM ) + { + /* Keep the metdata transmission as is during active parts */ + /* But send the flag with 1 bit */ + push_next_indice( hBstr, hParamIsm->flag_noisy_speech, 1 ); + + /* Loop over multiwave to write the object indices into bitstream */ + for ( ch = 0; ch < MAX_PARAM_ISM_WAVE; ch++ ) + { + for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ ) + { + for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ ) + { + push_next_indice( hBstr, hParamIsm->obj_indices[nbands][nblocks][ch], PARAM_ISM_OBJ_IND_NBITS ); + } + } + } + + /* Loop over bands to write the power ratio's indices into bitstream */ + for ( nbands = 0; nbands < hParamIsm->nbands; nbands++ ) + { + for ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ ) + { + push_next_indice( hBstr, hParamIsm->power_ratios_idx[nbands][nblocks], PARAM_ISM_POW_RATIO_NBITS ); + } + } + + /* total metadata bits */ + total_bits_metadata = hBstr->nb_bits_tot - nb_bits_start; + + /* bits per ISM*/ + bits_metadata_ism = (int16_t) ( total_bits_metadata / nchan_transport ); + + /* Divide the metadata bits into n_Isms*/ + nb_bits_objcod_written = 0; + for ( ch = 0; ch < nchan_transport; ch++ ) + { + if ( ch == nchan_transport - 1 ) + { + nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_written; + } + else + { + nb_bits_metadata[ch] = bits_metadata_ism; + nb_bits_objcod_written += bits_metadata_ism; + } + } + } + } + else if ( ism_mode == ISM_SBA_MODE_DISC ) + { + pop_wmops(); + return error; + } + + /*----------------------------------------------------------------* + * Take into account the combined format bit-budget distribution + *----------------------------------------------------------------*/ + + if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + int16_t bits_ism, bits_element[MAX_NUM_OBJECTS]; + int16_t brate_limit_flag; + int32_t ism_total_brate_ref; + ism_total_brate_ref = *ism_total_brate; +#ifndef IVAS_FLOAT_FIXED + brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism ); +#else + brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, nchan_ism ); +#endif + + bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC ); + set_s( bits_element, bits_ism / nchan_ism, nchan_ism ); + bits_element[nchan_ism - 1] += bits_ism % nchan_ism; + bitbudget_to_brate( bits_element, element_brate, nchan_ism ); + + *ism_total_brate = 0; + for ( ch = 0; ch < nchan_ism; ch++ ) + { +#ifndef IVAS_FLOAT_FIXED + *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag ); +#else + *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag ) ); + move32(); +#endif + + if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 ) + { + *ism_total_brate -= ADJUST_ISM_BRATE_NEG; + } - if ( hSCE[ch]->hCoreCoder[0]->tcxonly ) + if ( brate_limit_flag == -1 && ism_imp[ch] >= 1 && nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) ) + { + *ism_total_brate += ADJUST_ISM_BRATE_POS; + } + } + ism_metadata_flag_global = 1; + + if ( ism_mode == ISM_MASA_MODE_DISC ) { - if ( hSCE[ch]->hCoreCoder[0]->localVAD == 0 ) + brate_limit_flag = 0; + for ( int16_t n = 0; n < nchan_ism; n++ ) { - ctype = INACTIVE; + brate_limit_flag += ism_imp[n]; } - else if ( ctype == UNVOICED ) + + if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 ) { - ctype = GENERIC; + *omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX; } } + } - if ( ( hIsmMeta[ch]->ism_metadata_flag == 0 || lowrate_metadata_flag[ch] == 1 ) && hSCE[ch]->hCoreCoder[0]->localVAD == 0 ) + /*----------------------------------------------------------------* + * Configuration and decision about bitrates per channel + *----------------------------------------------------------------*/ + + if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 1 ) ) != IVAS_ERR_OK ) { - ism_imp[ch] = ISM_NO_META; + return error; } - else if ( ctype == INACTIVE || ctype == UNVOICED ) + } + else + { + if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK ) { - ism_imp[ch] = ISM_LOW_IMP; + return error; } - else if ( ctype == VOICED ) + } + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; + + if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { - ism_imp[ch] = ISM_MEDIUM_IMP; + hIsmMeta[ch]->ism_md_fec_cnt_enc++; } - else /* GENERIC */ + else { - ism_imp[ch] = ISM_HIGH_IMP; + hIsmMeta[ch]->ism_md_fec_cnt_enc = 0; } + hIsmMeta[ch]->ism_md_inc_diff_cnt++; + hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX ); } - return; -} + for ( ch = 0; ch < nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0; + if ( ism_mode == ISM_MODE_DISC ) + { + if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) || + ( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) ) + { + hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1; + } + + hSCE[ch]->element_brate = element_brate[ch]; + } + else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + if ( ism_imp[ch] == ISM_INACTIVE_IMP ) + { + hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1; + } + } + hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch]; -/*-------------------------------------------------------------------------* - * ivas_ism_metadata_enc() - * - * quantize and encode ISM metadata - *-------------------------------------------------------------------------*/ + /* write metadata only in active frames */ + if ( hSCE[0]->hCoreCoder[0]->core_brate > SID_2k40 ) + { + reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot ); + } + } + + pop_wmops(); + return error; +} +#else ivas_error ivas_ism_metadata_enc( int32_t *ism_total_brate, /* i/o: ISM total bitrate */ const int16_t nchan_ism, /* i : number of ISM channels */ @@ -634,11 +1260,7 @@ ivas_error ivas_ism_metadata_enc( int16_t brate_limit_flag; int32_t ism_total_brate_ref; ism_total_brate_ref = *ism_total_brate; -#ifndef IVAS_FLOAT_FIXED brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism ); -#else - brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, nchan_ism ); -#endif bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SEC ); set_s( bits_element, bits_ism / nchan_ism, nchan_ism ); @@ -648,12 +1270,8 @@ ivas_error ivas_ism_metadata_enc( *ism_total_brate = 0; for ( ch = 0; ch < nchan_ism; ch++ ) { -#ifndef IVAS_FLOAT_FIXED - *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag ); -#else *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag ) ); move32(); -#endif if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 ) { @@ -751,6 +1369,7 @@ ivas_error ivas_ism_metadata_enc( return error; } +#endif /*------------------------------------------------------------------------- @@ -1238,6 +1857,163 @@ static void encode_angle_indices( * Quantize and encode ISM metadata in SID frame *-------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_metadata_sid_enc( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + const int16_t flag_noisy_speech, /* i : noisy speech flag */ + const int16_t nchan_ism, /* i : number of objects */ + const int16_t nchan_transport, /* i : number of transport channels */ + const ISM_MODE ism_mode, /* i : ISM mode */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const int16_t sid_flag, /* i : indication of SID frame */ + const int16_t md_diff_flag[], /* i : metadata differental flag */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + int16_t nb_bits_metadata[] /* o : number of metadata bits */ +) +{ + int16_t i, ch, nBits, nBits_start, nBits_unused; + float q_step, q_step_border; +#ifdef IVAS_FLOAT_FIXED + Word32 q_step_fx, q_step_border_fx; +#endif + int16_t idx, idx_azimuth, idx_elevation; + int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id; +#ifdef IVAS_FLOAT_FIXED + Word32 valQ_fx; +#endif + ISM_METADATA_HANDLE hIsmMetaData; + + if ( sid_flag ) + { + nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + nBits -= SID_FORMAT_NBITS; + nBits_start = hBstr->nb_bits_tot; + + /*----------------------------------------------------------------* + * Write ISm common signaling + *----------------------------------------------------------------*/ + + /* write number of objects - unary coding */ + for ( ch = 1; ch < nchan_ism; ch++ ) + { + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 ); + } + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 ); + + /* write SID metadata flag (one per object) */ + for ( ch = 0; ch < nchan_ism; ch++ ) + { + push_indice( hBstr, IND_ISM_METADATA_FLAG, md_diff_flag[ch], 1 ); + } + + /*----------------------------------------------------------------* + * Set quantization bits based on the number of coded objects + *----------------------------------------------------------------*/ + + ivas_get_ism_sid_quan_bitbudget( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step, &q_step_border, &nBits_coh, &nBits_sce_id ); + + /*----------------------------------------------------------------* + * Spatial parameters, loop over TCs - 1 + *----------------------------------------------------------------*/ + + /* write ISM mode flag to explicitly signal number of spatial parameters */ + if ( nchan_ism > 2 ) + { + if ( ism_mode == ISM_MODE_DISC ) + { + push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 0, 1 ); + } + else + { + push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, 1, 1 ); + } + + if ( ism_mode == ISM_MODE_PARAM ) + { + /* write noisy speech flag */ + push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, flag_noisy_speech, 1 ); + nBits_sce_id = 1; + } + } + + if ( nchan_transport > 1 ) + { + /* write sce id */ + push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, nBits_sce_id ); + + /* quantize and write coherence */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + if ( ch == hISMDTX->sce_id_dtx ) + { + continue; + } + + idx = (int16_t) ( hISMDTX->coh[ch] * ( ( 1 << nBits_coh ) - 1 ) + 0.5f ); + assert( ( idx >= 0 ) && ( idx <= ( ( 1 << nBits_coh ) - 1 ) ) ); + push_indice( hBstr, IND_ISM_DTX_COH_SCA, idx, nBits_coh ); + } + } + + /*----------------------------------------------------------------* + * Metadata quantization and coding, loop over all objects + *----------------------------------------------------------------*/ + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + if ( md_diff_flag[ch] == 1 ) + { + hIsmMetaData = hIsmMeta[ch]; + +#ifdef IVAS_FLOAT_FIXED + /*===============================flt-2-fix======================================*/ + hIsmMetaData->azimuth_fx = floatToFixed( hIsmMetaData->azimuth, Q22 ); + hIsmMetaData->elevation_fx = floatToFixed( hIsmMetaData->elevation, Q22 ); + q_step_fx = floatToFixed( q_step, Q22 ); + q_step_border_fx = floatToFixed( q_step_border, Q22 ); + /*===============================flt-2-fix======================================*/ + idx_azimuth = ism_quant_meta_fx( hIsmMetaData->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_azimuth ); + idx_elevation = ism_quant_meta_fx( hIsmMetaData->elevation_fx, &valQ_fx, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_elevation ); +#else + idx_azimuth = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth ); + idx_elevation = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation ); +#endif + + push_indice( hBstr, IND_ISM_AZIMUTH, idx_azimuth, nBits_azimuth ); + push_indice( hBstr, IND_ISM_ELEVATION, idx_elevation, nBits_elevation ); + + /* update last indexes to correspond to active frames coding */ + if ( nBits_azimuth > ISM_AZIMUTH_NBITS ) + { + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); + } + else + { + hIsmMetaData->position_angle.last_angle1_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->position_angle.last_angle2_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); + } + + hIsmMetaData->ism_md_fec_cnt_enc = 0; + hIsmMeta[ch]->ism_md_inc_diff_cnt = ISM_MD_INC_DIFF_CNT_MAX; + } + } + + /* Write unused (padding) bits */ + nBits_unused = nBits - hBstr->nb_bits_tot; + while ( nBits_unused > 0 ) + { + i = min( nBits_unused, 16 ); + push_indice( hBstr, IND_UNUSED, 0, i ); + nBits_unused -= i; + } + + nb_bits_metadata[0] = hBstr->nb_bits_tot - nBits_start; + } + + return; +} +#else void ivas_ism_metadata_sid_enc( ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ const int16_t flag_noisy_speech, /* i : noisy speech flag */ @@ -1377,3 +2153,4 @@ void ivas_ism_metadata_sid_enc( return; } +#endif diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 52b7bc0307fa8fae09ef61a8de3c46bafe5cbf44..c3a0881f616304e643548e2bfc8d1f194452c60e 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -35,7 +35,10 @@ #include #include "options.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "cnst.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" @@ -169,6 +172,56 @@ static void ivas_param_ism_compute_obj_parameters( } +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_enc_quantize_DOA( + const int16_t nchan_ism, /* i : number of ISM channels */ + ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata */ + PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM encoder handle */ +) +{ + int16_t i, azi_idx, ele_idx; + float valQ; +#ifdef IVAS_FLOAT_FIXED + Word32 valQ_fx; +#endif + + + /* Loop over objects */ + for ( i = 0; i < nchan_ism; i++ ) + { +#ifdef IVAS_FLOAT_FIXED + /*===============================flt-2-fix======================================*/ + hIsmMetaData[i]->azimuth_fx = floatToFixed( hIsmMetaData[i]->azimuth, Q22 ); + hIsmMetaData[i]->elevation_fx = floatToFixed( hIsmMetaData[i]->elevation, Q22 ); + /*===============================flt-2-fix======================================*/ + + /* Quantize the elevation and obtain quantized elevation value and index */ + ele_idx = ism_quant_meta_fx( hIsmMetaData[i]->elevation_fx, &valQ_fx, ism_elevation_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_ELEVATION_NBITS ); + + /* Obtain the index of quantized azimuth values */ + azi_idx = ism_quant_meta_fx( hIsmMetaData[i]->azimuth_fx, &valQ_fx, ism_azimuth_borders_fx, ISM_Q_STEP_FX, ISM_Q_STEP_BORDER_FX, 1 << ISM_AZIMUTH_NBITS ); + /*===============================fix-2-flt======================================*/ + valQ = fixedToFloat( valQ_fx, Q22 ); + /*===============================fix-2-flt======================================*/ +#else + /* Quantize the elevation and obtain quantized elevation value and index */ + ele_idx = ism_quant_meta( hIsmMetaData[i]->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); + + /* Obtain the index of quantized azimuth values */ + azi_idx = ism_quant_meta( hIsmMetaData[i]->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); +#endif + + /*Replace azimuth with quantized values */ + hIsmMetaData[i]->azimuth = valQ; + + /* Copy the quantized indices */ + hParamIsm->azi_index[i] = azi_idx; + hParamIsm->ele_index[i] = ele_idx; + } + + return; +} +#else static void ivas_param_ism_enc_quantize_DOA( const int16_t nchan_ism, /* i : number of ISM channels */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata */ @@ -198,6 +251,7 @@ static void ivas_param_ism_enc_quantize_DOA( return; } +#endif /*-------------------------------------------------------------------------*