From ceb63d2b1cb37881923c129394b29b67c8995f30 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 22 Jan 2024 22:31:16 +0530 Subject: [PATCH] Functions in ivas_ism_metadata_dec.c file converted [x] Functions in file ivas_ism_metadata_dec.c file converted. [x] Some cleanup will be required for the initialization function to remove initialization of floating point variables. --- lib_com/ivas_cnst.h | 6 + lib_com/ivas_ism_com.c | 81 ++ lib_com/ivas_prot_fx.h | 38 + lib_com/ivas_rom_com_fx.c | 10 + lib_com/ivas_rom_com_fx.h | 3 + lib_com/ivas_stat_com.h | 13 + lib_com/prot_fx2.h | 13 +- lib_com/stat_com.h | 1 + lib_dec/ivas_ism_dtx_dec.c | 26 + lib_dec/ivas_ism_metadata_dec.c | 1239 +++++++++++++++++++++++++++---- lib_dec/ivas_jbm_dec.c | 30 + 11 files changed, 1317 insertions(+), 143 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index acade335c..f16b68324 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -313,6 +313,8 @@ typedef enum #define ISM_AZIMUTH_NBITS 7 #define ISM_AZIMUTH_MIN -180.0f #define ISM_AZIMUTH_MAX 180.0f +#define ISM_AZIMUTH_MIN_FX -754974720 +#define ISM_AZIMUTH_MAX_FX 754974720 #define ISM_AZIMUTH_LOW_BORDER -140.0f #define ISM_AZIMUTH_HIGH_BORDER 135.0f @@ -351,10 +353,14 @@ typedef enum #define ISM_DTX_ELE_BITS_HIGH 7 #define ISM_Q_STEP_HIGH (ISM_Q_STEP / 2) #define ISM_Q_STEP_BORDER_HIGH (ISM_Q_STEP_BORDER / 2) +#define ISM_Q_STEP_HIGH_FX 5 * (1 << (22-2)) +#define ISM_Q_STEP_BORDER_HIGH_FX 5 * (1 << (22-1)) #define ISM_DTX_AZI_BITS_LOW 6 #define ISM_DTX_ELE_BITS_LOW 5 #define ISM_Q_STEP_LOW (ISM_Q_STEP * 2) #define ISM_Q_STEP_BORDER_LOW (ISM_Q_STEP_BORDER * 2) +#define ISM_Q_STEP_LOW_FX 5 * (1 << 22) +#define ISM_Q_STEP_BORDER_LOW_FX 10 * (1 << 22) /* ISM modes */ typedef enum diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index d8cb958cc..e9ec74717 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -390,11 +390,20 @@ void ivas_ism_reset_metadata( ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */ ) { +#ifdef IVAS_FLOAT_FIXED + hIsmMeta->azimuth_fx = 0; + hIsmMeta->elevation_fx = 0; + hIsmMeta->yaw_fx = 0; + hIsmMeta->pitch_fx = 0; + hIsmMeta->radius_fx = 1 << 9; +#endif + // To be removed later ///////////////////// hIsmMeta->azimuth = 0.0f; hIsmMeta->elevation = 0.0f; hIsmMeta->yaw = 0.0f; hIsmMeta->pitch = 0.0f; hIsmMeta->radius = 1.0f; + //////////////////////////////////////////// hIsmMeta->ism_metadata_flag = 0; hIsmMeta->non_diegetic_flag = 0; @@ -470,6 +479,43 @@ int16_t ism_quant_meta( *-------------------------------------------------------------------*/ /*! r: dequantized value */ +#ifdef IVAS_FLOAT_FIXED +Word32 ism_dequant_meta_fx( + const Word16 idx, /* i : quantizer index */ + 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 */ +) +{ + Word16 idx_start; + Word32 qlow_fx, step_fx, valQ_fx; + + IF ( idx <= L_shr(L_sub( borders_fx[1], borders_fx[0] ), 21) / L_shr(q_step_border_fx, 21) ) + { + qlow_fx = borders_fx[0]; + idx_start = 0; + step_fx = q_step_border_fx; + } + ELSE IF ( idx <= cbsize - 1 - L_shr( L_sub( borders_fx[3], borders_fx[2] ), 21) / L_shr(q_step_border_fx, 21) ) + { + qlow_fx = borders_fx[1]; + idx_start = (Word16) ( L_shr( L_sub( borders_fx[1], borders_fx[0] ), 21) / L_shr(q_step_border_fx , 21)); + step_fx = q_step_fx; + } + ELSE + { + qlow_fx = borders_fx[2]; + idx_start = (Word16) ( cbsize - 1 - L_shr(L_sub( borders_fx[3], borders_fx[2] ), 21) / L_shr(q_step_border_fx, 21) ); + step_fx = q_step_border_fx; + } + + valQ_fx = sub( idx, idx_start ) * step_fx + qlow_fx; + + return valQ_fx; +} +#endif + float ism_dequant_meta( const int16_t idx, /* i : quantizer index */ const float borders[], /* i : level borders */ @@ -618,6 +664,10 @@ void update_last_metadata( { if ( updt_flag[ch] == 1 ) { +#ifdef IVAS_FLOAT_FIXED + hIsmMeta[ch]->last_azimuth_fx = hIsmMeta[ch]->azimuth_fx; + hIsmMeta[ch]->last_elevation_fx = hIsmMeta[ch]->elevation_fx; +#endif hIsmMeta[ch]->last_azimuth = hIsmMeta[ch]->azimuth; hIsmMeta[ch]->last_elevation = hIsmMeta[ch]->elevation; } @@ -633,6 +683,37 @@ void update_last_metadata( * Set quantization bits based on the number of coded objects *----------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_get_ism_sid_quan_bitbudget_fx( + const Word16 nchan_ism, /* i : number of objects */ + Word16 *nBits_azimuth, /* o : number of Q bits for azimuth */ + Word16 *nBits_elevation, /* o : number of Q bits for elevation */ + Word32 *q_step_fx, /* o : quantization step */ + Word32 *q_step_border_fx, /* o : quantization step at the border */ + Word16 *nBits_coh, /* o : number of Q bits for coherence */ + Word16 *nBits_sce_id /* o : number of Q bits for sce_id_dtx */ +) +{ + *nBits_azimuth = ISM_DTX_AZI_BITS_HIGH; + *nBits_elevation = ISM_DTX_ELE_BITS_HIGH; + *q_step_fx = ISM_Q_STEP_HIGH_FX; + *q_step_border_fx = ISM_Q_STEP_BORDER_HIGH_FX; + *nBits_coh = ISM_DTX_COH_SCA_BITS; + *nBits_sce_id = 1; + + IF ( nchan_ism >= 3 ) + { + *nBits_azimuth = ISM_DTX_AZI_BITS_LOW; + *nBits_elevation = ISM_DTX_ELE_BITS_LOW; + *q_step_fx = ISM_Q_STEP_LOW_FX; + *q_step_border_fx = ISM_Q_STEP_BORDER_LOW_FX; + *nBits_sce_id = 2; + } + + return; +} +#endif + void ivas_get_ism_sid_quan_bitbudget( const int16_t nchan_ism, /* i : number of objects */ int16_t *nBits_azimuth, /* o : number of Q bits for azimuth */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index c52d0f012..adb8ab969 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -373,4 +373,42 @@ Word16 masa_sq_fx( const Word16 cb_sz /* i : codebook size */ ); +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 */ + Word16 *nchan_transport, /* o : number of transport channels */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ + const Word16 bfi, /* i : bfi flag */ + Word16 nb_bits_metadata[], /* o : number of metadata bits */ + ISM_MODE ism_mode, /* i : ISM mode */ + ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ + Word16 *ism_extmeta_active, /* i/o: Extended metadata active in renderer */ + Word16 *ism_extmeta_cnt, /* i/o: Number of change frames observed */ + DEC_CORE_HANDLE st0 /* i : core-coder handle */ +); + +void ivas_get_ism_sid_quan_bitbudget_fx( + const Word16 nchan_ism, /* i : number of objects */ + Word16 *nBits_azimuth, /* o : number of Q bits for azimuth */ + Word16 *nBits_elevation, /* o : number of Q bits for elevation */ + Word32 *q_step_fx, /* o : quantization step */ + Word32 *q_step_border_fx, /* o : quantization step at the border */ + Word16 *nBits_coh, /* o : number of Q bits for coherence */ + Word16 *nBits_sce_id /* o : number of Q bits for sce_id_dtx */ +); + +void ivas_ism_metadata_sid_dec_fx( + SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE decoder structure */ + const Word32 ism_total_brate, /* i : ISM total bitrate */ + const Word16 bfi, /* i : bfi flag */ + const Word16 nchan_ism, /* i : number of objects */ + const Word16 nchan_transport, /* i : number of transport channels*/ + const ISM_MODE ism_mode, /* i : ISM mode */ + Word16 *flag_noisy_speech, /* o : noisy speech flag */ + Word16 *sce_id_dtx, /* o : SCE DTX ID */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + Word16 nb_bits_metadata[] /* o : number of metadata bits */ +); #endif \ No newline at end of file diff --git a/lib_com/ivas_rom_com_fx.c b/lib_com/ivas_rom_com_fx.c index 7a0dcd35f..1b2be9afd 100644 --- a/lib_com/ivas_rom_com_fx.c +++ b/lib_com/ivas_rom_com_fx.c @@ -282,4 +282,14 @@ const Word16 ivas_divde_255[256] = { 30968, 31097, 31225, 31354, 31482, 31611, 31739, 31868, 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 +}; /* clang-format on */ diff --git a/lib_com/ivas_rom_com_fx.h b/lib_com/ivas_rom_com_fx.h index f507d4a70..797c39020 100644 --- a/lib_com/ivas_rom_com_fx.h +++ b/lib_com/ivas_rom_com_fx.h @@ -54,4 +54,7 @@ extern const Word16 dft_trigo_48k_fx[STEREO_DFT_N_MAX_ENC / 4 + 1]; extern const Word16 ivas_divde_255[256]; +extern const Word32 ism_azimuth_borders_fx[4]; +extern const Word32 ism_elevation_borders_fx[4]; + #endif \ No newline at end of file diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index eae5ae99a..2e2c90437 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -64,6 +64,13 @@ typedef struct float radius; /* radius value read from the input metadata file */ float yaw; /* yaw value read from the input metadata file */ float pitch; /* pitch value read from the input metadata file */ +#ifdef IVAS_FLOAT_FIXED + Word32 azimuth_fx; /* azimuth value read from the input metadata file */ + Word32 elevation_fx; /* elevation value read from the input metadata file */ + Word16 radius_fx; /* radius value read from the input metadata file */ + Word32 yaw_fx; /* yaw value read from the input metadata file */ + Word32 pitch_fx; /* pitch value read from the input metadata file */ +#endif int16_t non_diegetic_flag; /* Non-diegetic (non-headtracked) object flag */ @@ -76,6 +83,12 @@ typedef struct float last_elevation; /* MD smoothing in DTX - last Q elevation value */ float last_true_azimuth; /* MD smoothing in DTX- last true Q azimuth value */ float last_true_elevation; /* MD smoothing in DTX- last true Q elevation value */ +#ifdef IVAS_FLOAT_FIXED + Word32 last_azimuth_fx; /* MD smoothing in DTX- last Q azimuth value */ + Word32 last_elevation_fx; /* MD smoothing in DTX - last Q elevation value */ + Word32 last_true_azimuth_fx; /* MD smoothing in DTX- last true Q azimuth value */ + Word32 last_true_elevation_fx; /* MD smoothing in DTX- last true Q elevation value */ +#endif int16_t ism_md_fec_cnt_enc; /* counter of continuous frames where MD are not transmitted */ int16_t ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */ diff --git a/lib_com/prot_fx2.h b/lib_com/prot_fx2.h index dfaad821a..20c7537a4 100644 --- a/lib_com/prot_fx2.h +++ b/lib_com/prot_fx2.h @@ -8044,5 +8044,14 @@ void addBassPostFilter_fx( const int16_t samplesToProcess, Word32 **rAnalysis_fx, Word32 **iAnalysis_fx, - HANDLE_CLDFB_FILTER_BANK cldfb ); -#endif \ No newline at end of file + HANDLE_CLDFB_FILTER_BANK cldfb +); + +Word32 ism_dequant_meta_fx( + const Word16 idx, /* i : quantizer index */ + 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/stat_com.h b/lib_com/stat_com.h index ea9cb6670..57259fcab 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -496,6 +496,7 @@ typedef struct Word16 likelihood_noisy_speech; float coherence_flt; /* inter-channel coherence of noise */ + Word16 coherence_fx; /* inter-channel coherence of noise */ int16_t no_side_flag; /* indicates whether the side noise shape should be zeroed-out or not */ } FD_CNG_COM, *HANDLE_FD_CNG_COM; diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index c06c9bfe0..8884ae102 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -34,6 +34,7 @@ #include #include "options.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "prot.h" #include "wmc_auto.h" @@ -73,8 +74,33 @@ void ivas_ism_dtx_dec( } /* Metadata decoding and dequantization */ +#ifdef IVAS_FLOAT_FIXED + FOR (Word16 ind = 0; ind < st_ivas->nchan_ism; ind++) { + st_ivas->hIsmMetaData[ind]->azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->elevation * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_elevation * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_true_azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_true_elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_true_elevation * (1 << 22)); + } + FOR(Word16 ind = 0; ind < st_ivas->nchan_transport; ind++) + st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = (Word16)(st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt * 32767); + ivas_ism_metadata_sid_dec_fx( st_ivas->hSCE, ivas_total_brate, st_ivas->bfi, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode, + &flag_noisy_speech, &sce_id_dtx, st_ivas->hIsmMetaData, nb_bits_metadata ); + FOR (Word16 ind = 0; ind < st_ivas->nchan_ism; ind++) { + st_ivas->hIsmMetaData[ind]->azimuth = (float)(st_ivas->hIsmMetaData[ind]->azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->elevation = (float)(st_ivas->hIsmMetaData[ind]->elevation_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_azimuth = (float)(st_ivas->hIsmMetaData[ind]->last_azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_elevation = (float)(st_ivas->hIsmMetaData[ind]->last_elevation_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_true_azimuth = (float)(st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_true_elevation = (float)(st_ivas->hIsmMetaData[ind]->last_true_elevation_fx) / (float)(1 << 22); + } + FOR(Word16 ind = 0; ind < st_ivas->nchan_transport; ind++) + st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_flt = (float)(st_ivas->hSCE[ind]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx) / 32767.f; +#else ivas_ism_metadata_sid_dec( st_ivas->hSCE, ivas_total_brate, st_ivas->bfi, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode, &flag_noisy_speech, &sce_id_dtx, st_ivas->hIsmMetaData, nb_bits_metadata ); +#endif if ( ivas_total_brate == IVAS_SID_5k2 && !st_ivas->bfi ) { diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 4647b901f..f92bfbef8 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -34,8 +34,12 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#include "ivas_prot_fx.h" #include "ivas_rom_com.h" +#include "ivas_rom_com_fx.h" #include "prot.h" +#include "prot_fx1.h" +#include "prot_fx2.h" #include "ivas_stat_enc.h" #include #include "wmc_auto.h" @@ -129,6 +133,69 @@ static void ism_metadata_smooth( return; } +#ifdef IVAS_FLOAT_FIXED +static void ism_metadata_smooth_fx( + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const Word32 ism_total_brate, /* i : ISms total bitrate */ + const Word16 nchan_ism /* i : number of objects */ +) +{ + ISM_METADATA_HANDLE hIsmMetaData; + Word16 ch; + Word32 diff_fx; + + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMetaData = hIsmMeta[ch]; + + /* smooth azimuth */ + diff_fx = hIsmMetaData->last_true_azimuth_fx - hIsmMetaData->last_azimuth_fx; + + IF ( diff_fx > ISM_AZIMUTH_MAX_FX ) + { + diff_fx = L_sub(diff_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX )); + hIsmMetaData->last_azimuth_fx = L_add(hIsmMetaData->last_azimuth_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX )); + } + ELSE IF ( diff_fx < ISM_AZIMUTH_MIN_FX ) + { + diff_fx = L_add(diff_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX )); + } + + IF ( ism_total_brate > IVAS_SID_5k2 && L_abs( diff_fx ) > L_shl(IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_AZIMUTH, 22) ) + { + /* skip the smoothing */ + } + ELSE IF ( L_abs( diff_fx ) > L_shl(CNG_MD_MAX_DIFF_AZIMUTH , 22) ) + { + hIsmMetaData->azimuth_fx = L_add(hIsmMetaData->last_azimuth_fx, (diff_fx >= 0 ? 1 : -1) * L_shl( CNG_MD_MAX_DIFF_AZIMUTH, 22 )); + } + ELSE IF ( diff_fx != 0 ) + { + hIsmMetaData->azimuth_fx = hIsmMetaData->last_true_azimuth_fx; + } + + IF ( hIsmMetaData->azimuth_fx > ISM_AZIMUTH_MAX_FX ) + { + hIsmMetaData->azimuth_fx = L_sub(hIsmMetaData->azimuth_fx, ( ISM_AZIMUTH_MAX_FX - ISM_AZIMUTH_MIN_FX )); + } + + /* smooth elevation */ + diff_fx = hIsmMetaData->last_true_elevation_fx - hIsmMetaData->last_elevation_fx; + + IF ( ism_total_brate > IVAS_SID_5k2 && diff_fx > L_shl(IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_ELEVATION, 22) ) + { + /* skip the smoothing */ + } + ELSE IF ( L_abs( diff_fx ) > L_shl(CNG_MD_MAX_DIFF_ELEVATION, 22) ) + { + hIsmMetaData->elevation_fx = hIsmMetaData->last_elevation_fx + ( diff_fx >= 0 ? 1 : -1 ) * L_shl(CNG_MD_MAX_DIFF_ELEVATION, 22); + } + } + + return; +} +#endif + /*-------------------------------------------------------------------------* * ivas_ism_metadata_dec() @@ -639,183 +706,843 @@ ivas_error ivas_ism_metadata_dec( return IVAS_ERR_OK; } - -/*------------------------------------------------------------------------- - * ivas_ism_metadata_dec_create() - * - * Create, allocate, initialize and configure IVAS decoder ISM metadata handles - *-------------------------------------------------------------------------*/ - -ivas_error ivas_ism_metadata_dec_create( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t n_ISms, /* i : number of objects */ - int32_t element_brate_tmp[] /* o : element bitrate per object */ -) +#ifdef IVAS_FLOAT_FIXED +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 */ + Word16 *nchan_transport, /* o : number of transport channels */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + SCE_DEC_HANDLE hSCE[], /* i/o: SCE decoder handles */ + const Word16 bfi, /* i : bfi flag */ + Word16 nb_bits_metadata[], /* o : number of metadata bits */ + ISM_MODE ism_mode, /* i : ISM mode */ + ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ + const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */ + Word16 *ism_extmeta_active, /* i/o: Extended metadata active in renderer */ + Word16 *ism_extmeta_cnt, /* i/o: Number of change frames observed */ + DEC_CORE_HANDLE st0) /* i : core-coder handle */ { - int16_t ch; - ivas_error error; - - /* allocate ISM metadata handles */ - for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) - { - if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); - } + Word16 ch, nb_bits_start = 0, last_bit_pos; + Word16 idx_radius; + Word32 element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; + Word16 ism_extmeta_bitstream; + Word16 non_diegetic_flag_global; + Word32 yaw_fx, pitch_fx; + Word16 radius_fx; + Word16 flag_abs_radius; + Word16 flag_abs_orientation; + Word16 flag_abs_position; + Word16 idx_angle1; + Word16 idx_angle2; + Word16 next_bit_pos_orig; + UWord16 i, bstr_meta[MAX_BITS_ISM_METADATA], *bstr_orig; + ISM_METADATA_HANDLE hIsmMetaData; + Word16 nchan_transport_prev, ism_metadata_flag_global; + Word16 null_metadata_flag[MAX_NUM_OBJECTS]; + Word16 lowrate_metadata_flag[MAX_NUM_OBJECTS]; + Word16 ism_imp[MAX_NUM_OBJECTS]; + Word16 nbands, nblocks; + Word16 md_diff_flag[MAX_NUM_OBJECTS]; + ivas_error error; - st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; - st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; - st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); - st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; - st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); - st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ + push_wmops( "ism_meta_dec" ); - st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; - st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; - st_ivas->hIsmMetaData[ch]->last_azimuth = 0; - st_ivas->hIsmMetaData[ch]->last_elevation = 0; + /* initialization */ + ism_metadata_flag_global = 0; + nchan_transport_prev = *nchan_transport; - st_ivas->hIsmMetaData[ch]->ism_imp = -1; - st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; - st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; + last_bit_pos = (Word16) ( ( ism_total_brate / FRAMES_PER_SEC ) - 1 ); + bstr_orig = st0->bit_stream; + next_bit_pos_orig = st0->next_bit_pos; + st0->next_bit_pos = 0; + ism_extmeta_bitstream = 0; + non_diegetic_flag_global = 0; + set_s( null_metadata_flag, 0, nchan_ism ); + set_s( lowrate_metadata_flag, 0, nchan_ism ); - ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); + /* reverse the bitstream for easier reading of indices */ + FOR ( i = 0; i < s_min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ ) + { + bstr_meta[i] = st0->bit_stream[last_bit_pos - i]; } + st0->bit_stream = bstr_meta; + st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */ - if ( element_brate_tmp != NULL ) + IF ( !bfi ) { - if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) + /*----------------------------------------------------------------* + * Read ISM common signaling + *----------------------------------------------------------------*/ + IF ( ism_mode == ISM_SBA_MODE_DISC ) { - return error; + /* number of objects was read in ivas_dec_setup() */ + st0->next_bit_pos = add(st0->next_bit_pos, NO_BITS_MASA_ISM_NO_OBJ); } - } - - st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX; - - return IVAS_ERR_OK; -} + ELSE IF ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) + { + /* number of objects was read in ivas_dec_setup() */ + st0->next_bit_pos = add(st0->next_bit_pos, nchan_ism); + ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate ); + } -/*------------------------------------------------------------------------- - * decode_angle_indices() - * - * Decoding of a position/orientation angle - *-------------------------------------------------------------------------*/ + IF ( ism_mode == ISM_MODE_PARAM ) + { + *nchan_transport = MAX_PARAM_ISM_WAVE; + } + ELSE IF ( ism_mode == ISM_MODE_DISC ) + { + *nchan_transport = nchan_ism; + } -static void decode_angle_indices( - DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ - ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ - const int16_t non_diegetic_flag, /* i : Non diegetic flag */ - int16_t *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ -) -{ - int16_t idx_angle1, nbits_diff_angle1, diff, sgn; - int16_t idx_angle2, nbits_diff_angle2; + IF ( *nchan_transport != nchan_transport_prev ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); + } - /*----------------------------------------------------------------* - * Azimuth/yaw decoding and dequantization - *----------------------------------------------------------------*/ + /* read extended metadata presence flag */ + IF ( ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) && ism_total_brate >= ISM_EXTENDED_METADATA_BRATE ) + { + ism_extmeta_bitstream = get_next_indice_fx( st0, ISM_EXTENDED_METADATA_BITS ); - /* Decode azimuth/yaw index */ - if ( get_next_indice( st0, 1 ) == 1 ) /* azimuth_abs_flag */ - { - idx_angle1 = get_next_indice( st0, ISM_AZIMUTH_NBITS ); - *flag_abs_angle1 = 1; - } - else - { - diff = 0; - sgn = 1; + /* read global non-diegetic object flag */ + IF ( ism_extmeta_bitstream ) + { + non_diegetic_flag_global = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS ); + } + } - if ( get_next_indice( st0, 1 ) == 0 ) + /* Apply hysteresis in case rate switching causes fluctuation in presence of extended metadata */ + IF ( *ism_extmeta_active == -1 || *ism_extmeta_active == ism_extmeta_bitstream ) /* If first frame or bitstream matches internal state */ { - nbits_diff_angle1 = 1; + *ism_extmeta_active = ism_extmeta_bitstream; + *ism_extmeta_cnt = 0; } - else + ELSE { - nbits_diff_angle1 = 1; - - if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + ( *ism_extmeta_cnt )++; + IF ( *ism_extmeta_cnt == ISM_METADATA_RS_MAX_FRAMES ) /* ISM_METADATA_RS_MAX_FRAMES change frames observed - update state */ { - sgn = -1; + *ism_extmeta_active = ism_extmeta_bitstream; + *ism_extmeta_cnt = 0; } + } - nbits_diff_angle1++; - - /* read until the stop bit */ - while ( ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) && ( get_next_indice( st0, 1 ) == 1 ) ) + /* Read ISM metadata flags (one per object) */ + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + IF ( ism_mode == ISM_SBA_MODE_DISC ) { - diff++; - nbits_diff_angle1++; + ism_imp[ch] = get_next_indice_fx( st0, 1 ); } - - if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) + ELSE IF ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) { - /* count stop bit */ - nbits_diff_angle1++; + /* ISM importance flag is already read in ivas_masa_decode() */ + ism_imp[ch] = hIsmMeta[ch]->ism_imp; + } + ELSE + { + ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS ); } - } - idx_angle1 = angle->last_angle1_idx + sgn * diff; - } - - /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ - if ( idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - { - idx_angle1 -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* +180° -> -180° */ - } - else if ( idx_angle1 < 0 ) - { - idx_angle1 += ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* -180° -> +180° */ - } - - /* +180° == -180° */ - if ( idx_angle1 == ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - { - idx_angle1 = 0; - } - /* sanity check in case of FER or BER */ - if ( idx_angle1 < 0 || idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) - { - idx_angle1 = angle->last_angle1_idx; - } + IF ( ism_imp[ch] > ISM_NO_META ) + { + hIsmMeta[ch]->ism_metadata_flag = 1; + } + ELSE + { + hIsmMeta[ch]->ism_metadata_flag = 0; + } - /*----------------------------------------------------------------* - * Elevation/pitch decoding and dequantization - *----------------------------------------------------------------*/ + ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; + } - if ( non_diegetic_flag == 0 ) - { - /* Decode elevation/pitch index */ - if ( *flag_abs_angle1 == 0 && get_next_indice( st0, 1 ) == 1 ) /* elevation_abs_flag */ + FOR ( ; ch < nchan_ism; ch++ ) { - idx_angle2 = get_next_indice( st0, ISM_ELEVATION_NBITS ); + hIsmMeta[ch]->ism_metadata_flag = 1; + ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; } - else - { - diff = 0; - sgn = 1; - if ( get_next_indice( st0, 1 ) == 0 ) - { - nbits_diff_angle2 = 1; - } - else + /* read ISM_NO_META class signalling */ + IF ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC ) + { + FOR ( ch = 0; ch < *nchan_transport; ch++ ) { - nbits_diff_angle2 = 1; - - if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + IF ( ism_imp[ch] == ISM_NO_META ) { - sgn = -1; + /* low-rate ISM_NO_META frame */ + IF ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + null_metadata_flag[ch] = hIsmMeta[ch]->ism_md_null_flag; + } + ELSE + { + null_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS ); + } } + } - nbits_diff_angle2++; - - /* read until the stop bit */ - while ( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + IF ( ism_imp[ch] == ISM_NO_META ) { - diff++; - nbits_diff_angle2++; + IF ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + lowrate_metadata_flag[ch] = hIsmMeta[ch]->ism_md_lowrate_flag; + + IF ( null_metadata_flag[ch] == 0 ) + { + ism_metadata_flag_global |= lowrate_metadata_flag[ch]; + } + } + ELSE IF ( ism_mode != ISM_SBA_MODE_DISC ) + { + IF ( null_metadata_flag[ch] ) + { + /* read the true ISM class */ + ism_imp[ch] = get_next_indice_fx( st0, ISM_METADATA_FLAG_BITS ); + } + ELSE + { + /* read presence of MD in low-rate ISM_NO_META frame flag */ + lowrate_metadata_flag[ch] = get_next_indice_fx( st0, ISM_METADATA_INACTIVE_FLAG_BITS ); + + ism_metadata_flag_global |= lowrate_metadata_flag[ch]; + } + } + } + } + } + + IF ( ism_metadata_flag_global ) + { + /*----------------------------------------------------------------* + * Metadata decoding and dequantization, loop over all objects + *----------------------------------------------------------------*/ + + Word16 total_bits_metadata = 0, bits_metadata_ism = 0; + Word16 nb_bits_objcod_read; + + IF ( ism_mode == ISM_MODE_PARAM ) + { + nb_bits_start = st0->next_bit_pos; + } + + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMetaData = hIsmMeta[ch]; + IF ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + nb_bits_start = st0->next_bit_pos; + } + flag_abs_position = 0; + flag_abs_orientation = 0; + flag_abs_radius = 0; + + IF ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] ) + { + IF ( non_diegetic_flag_global ) + { + /* read non-diegetic flag for each object */ + hIsmMetaData->non_diegetic_flag = get_next_indice_fx( st0, ISM_METADATA_IS_NDP_BITS ); + } + ELSE + { + hIsmMetaData->non_diegetic_flag = 0; + } + + IF ( hIsmMetaData->non_diegetic_flag ) + { + /* Panning gain decoding */ + decode_angle_indices( st0, &( hIsmMetaData->position_angle ), hIsmMetaData->non_diegetic_flag, &flag_abs_position ); + idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx; + idx_angle2 = 1 << ( ISM_ELEVATION_NBITS - 1 ); + + /* Panning gain dequantization */ + hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, (Word32)(ISM_Q_STEP * (1<<22)), (Word32)(ISM_Q_STEP_BORDER * (1<<22)), 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation_fx = 0; + + /* save for smoothing metadata evolution */ + hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx; + hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx; + } + ELSE + { + decode_angle_indices( st0, &( hIsmMetaData->position_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_position ); + idx_angle1 = hIsmMetaData->position_angle.last_angle1_idx; + idx_angle2 = hIsmMetaData->position_angle.last_angle2_idx; + + /* Azimuth/Elevation dequantization */ + IF ( ism_mode == ISM_MODE_PARAM ) + { + hParamIsm->azi_index[ch] = idx_angle1; + hParamIsm->ele_index[ch] = idx_angle2; + } + ELSE /* ISM_MODE_DISC */ + { + hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, (Word32)(ISM_Q_STEP * (1<<22)), (Word32)(ISM_Q_STEP_BORDER * (1<<22)), 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_angle2, ism_elevation_borders_fx, (Word32)(ISM_Q_STEP * (1<<22)), (Word32)(ISM_Q_STEP_BORDER * (1<<22)), 1 << ISM_ELEVATION_NBITS ); + + /* radius/raw/pitch dequantization */ + IF ( ism_extmeta_bitstream ) + { + decode_angle_indices( st0, &( hIsmMetaData->orientation_angle ), hIsmMeta[ch]->non_diegetic_flag, &flag_abs_orientation ); + idx_angle1 = hIsmMetaData->orientation_angle.last_angle1_idx; + idx_angle2 = hIsmMetaData->orientation_angle.last_angle2_idx; + yaw_fx = ism_dequant_meta_fx( idx_angle1, ism_azimuth_borders_fx, (Word32)(ISM_Q_STEP * (1<<22)), (Word32)(ISM_Q_STEP_BORDER * (1<<22)), 1 << ISM_AZIMUTH_NBITS ); + pitch_fx = ism_dequant_meta_fx( idx_angle2, ism_elevation_borders_fx, (Word32)(ISM_Q_STEP * (1<<22)), (Word32)(ISM_Q_STEP_BORDER * (1<<22)), 1 << ISM_ELEVATION_NBITS ); + + idx_radius = decode_radius( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius ); + radius_fx = usdequant_fx( idx_radius, (Word16)(ISM_RADIUS_MIN * (1 << 9)) , (Word16)(ISM_RADIUS_DELTA * (1 << 9)) ); + IF ( *ism_extmeta_active == 1 ) + { + hIsmMetaData->yaw_fx = yaw_fx; + hIsmMetaData->pitch_fx = pitch_fx; + hIsmMetaData->radius_fx = radius_fx; + } + } + ELSE + { + IF ( *ism_extmeta_active == 0 ) + { + hIsmMetaData->yaw_fx = 0; + hIsmMetaData->pitch_fx = 0; + hIsmMetaData->radius_fx = 1 << 9; + } + } + } + /* save for smoothing metadata evolution */ + hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx; + hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx; + } + } + /* save number of metadata bits read */ + IF ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_SBA_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + nb_bits_metadata[ch] = st0->next_bit_pos - nb_bits_start; + } + } + + IF ( ism_mode == ISM_MODE_PARAM ) + { + hParamIsm->flag_noisy_speech = get_next_indice_fx( st0, 1 ); + + /* Loop over multiwave to read the object indices from 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++ ) + { + hParamIsm->obj_indices[nbands][nblocks][ch] = get_next_indice_fx( st0, PARAM_ISM_OBJ_IND_NBITS ); + } + } + } + + /* Loop over all bands to read power ratio's from bitstream */ + FOR ( nbands = 0; nbands < hParamIsm->nbands; nbands++ ) + { + FOR ( nblocks = 0; nblocks < hParamIsm->nblocks[nbands]; nblocks++ ) + { + hParamIsm->power_ratios_idx[nbands][nblocks] = get_next_indice_fx( st0, PARAM_ISM_POW_RATIO_NBITS ); + } + } + + /* save number of metadata bits read */ + total_bits_metadata = st0->next_bit_pos - nb_bits_start; + + /* bits per ISM*/ + bits_metadata_ism = (Word16) ( total_bits_metadata / *nchan_transport ); + + nb_bits_objcod_read = 0; + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + IF ( ch == *nchan_transport - 1 ) + { + nb_bits_metadata[ch] = total_bits_metadata - nb_bits_objcod_read; + } + ELSE + { + nb_bits_metadata[ch] = bits_metadata_ism; + nb_bits_objcod_read += bits_metadata_ism; + } + } + } + } + ELSE + { + set_s( nb_bits_metadata, 0, *nchan_transport ); + } + } + ELSE /* BFI */ + { + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; + } + + set_s( nb_bits_metadata, 0, *nchan_transport ); + + IF ( ism_mode == ISM_MODE_PARAM ) + { + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + hParamIsm->azi_index[ch] = hParamIsm->azi_index[ch] + hParamIsm->last_az_sgn[ch] * hParamIsm->last_az_diff[ch]; + hParamIsm->ele_index[ch] = hParamIsm->ele_index[ch] + hParamIsm->last_el_sgn[ch] * hParamIsm->last_el_diff[ch]; + hIsmMeta[ch]->position_angle.last_angle1_idx = hParamIsm->azi_index[ch]; + hIsmMeta[ch]->position_angle.last_angle2_idx = hParamIsm->ele_index[ch]; + } + } + } + + IF ( hISMDTX.ism_dtx_hangover_cnt < IVAS_ISM_DTX_HO_MAX ) + { + ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism ); + hISMDTX.ism_dtx_hangover_cnt += 1; + } + + IF ( ism_mode == ISM_SBA_MODE_DISC ) + { + /* set the bitstream pointer to its original position */ + nb_bits_metadata[0] = st0->next_bit_pos; + st0->bit_stream = bstr_orig; + st0->next_bit_pos = next_bit_pos_orig; + + /* updates*/ + set_s( md_diff_flag, 1, nchan_ism ); + + update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag ); + pop_wmops(); + return IVAS_ERR_OK; + } + + IF ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + ism_metadata_flag_global = 1; + } + + /*----------------------------------------------------------------* + * Configuration and decision about bitrates per channel + *----------------------------------------------------------------*/ + + IF ( !bfi ) + { + Word16 masa_ism_flag = 0; + IF ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + masa_ism_flag = 1; + + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + element_brate[ch] = hSCE[ch]->element_brate; + } + } + + IF ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, masa_ism_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; + + hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0; + IF ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + 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; + } + } + + IF ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) + { + hSCE[ch]->element_brate = element_brate[ch]; + } + hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch]; + } + + FOR ( ; ch < nchan_ism; ch++ ) + { + hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; + } + } + ELSE + { + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + hSCE[ch]->element_brate = hSCE[ch]->last_element_brate; + hSCE[ch]->hCoreCoder[0]->total_brate = hSCE[ch]->hCoreCoder[0]->last_total_brate; + } + } + + /*----------------------------------------------------------------* + * Set bitsream pointers + *----------------------------------------------------------------*/ + + /* set the bitstream pointer to its original position */ + st0->bit_stream = bstr_orig; + st0->next_bit_pos = next_bit_pos_orig; + + /* set bitstream pointers for each ISM */ + FOR ( ch = 1; ch < *nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->bit_stream = hSCE[ch - 1]->hCoreCoder[0]->bit_stream + ( hSCE[ch - 1]->hCoreCoder[0]->total_brate / FRAMES_PER_SEC ); + } + + /*----------------------------------------------------------------* + * Updates + *----------------------------------------------------------------*/ + + set_s( md_diff_flag, 1, nchan_ism ); + + update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag ); + + FOR ( ch = 0; ch < *nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->cng_ism_flag = 0; + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif + +/*------------------------------------------------------------------------- + * ivas_ism_metadata_dec_create() + * + * Create, allocate, initialize and configure IVAS decoder ISM metadata handles + *-------------------------------------------------------------------------*/ + +ivas_error ivas_ism_metadata_dec_create( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_ISms, /* i : number of objects */ + int32_t element_brate_tmp[] /* o : element bitrate per object */ +) +{ + int16_t ch; + ivas_error error; + + /* allocate ISM metadata handles */ + for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ ) + { + if ( ( st_ivas->hIsmMetaData[ch] = (ISM_METADATA_HANDLE) malloc( sizeof( ISM_METADATA_FRAME ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM MetaData\n" ) ); + } + + st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->position_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle1_idx = 0; + st_ivas->hIsmMetaData[ch]->orientation_angle.last_angle2_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); + st_ivas->hIsmMetaData[ch]->last_radius_idx = 8; /* Init to radius 1.0 */ + +#ifdef IVAS_FLOAT_FIXED + st_ivas->hIsmMetaData[ch]->last_true_azimuth_fx = 0; + st_ivas->hIsmMetaData[ch]->last_true_elevation_fx = 0; + st_ivas->hIsmMetaData[ch]->last_azimuth_fx = 0; + st_ivas->hIsmMetaData[ch]->last_elevation_fx = 0; +#endif + // To be removed later //////////////////////////////// + st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; + st_ivas->hIsmMetaData[ch]->last_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_elevation = 0; + ////////////////////////////////////////////////////// + + st_ivas->hIsmMetaData[ch]->ism_imp = -1; + st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0; + st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0; + + ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); + } + + if ( element_brate_tmp != NULL ) + { + if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * decode_angle_indices() + * + * Decoding of a position/orientation angle + *-------------------------------------------------------------------------*/ + +#ifdef IVAS_FLOAT_FIXED +static void decode_angle_indices( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + const Word16 non_diegetic_flag, /* i : Non diegetic flag */ + Word16 *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ +) +{ + Word16 idx_angle1, nbits_diff_angle1, diff, sgn; + Word16 idx_angle2, nbits_diff_angle2; + + /*----------------------------------------------------------------* + * Azimuth/yaw decoding and dequantization + *----------------------------------------------------------------*/ + + /* Decode azimuth/yaw index */ + IF ( get_next_indice_fx( st0, 1 ) == 1 ) /* azimuth_abs_flag */ + { + idx_angle1 = get_next_indice_fx( st0, ISM_AZIMUTH_NBITS ); + *flag_abs_angle1 = 1; + } + ELSE + { + diff = 0; + sgn = 1; + + IF ( get_next_indice_fx( st0, 1 ) == 0 ) + { + nbits_diff_angle1 = 1; + } + ELSE + { + nbits_diff_angle1 = 1; + + IF ( get_next_indice_fx( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle1++; + + /* read until the stop bit */ + WHILE ( ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) && ( get_next_indice_fx( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_angle1++; + } + + IF ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) + { + /* count stop bit */ + nbits_diff_angle1++; + } + } + idx_angle1 = angle->last_angle1_idx + sgn * diff; + } + + /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + IF ( idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* +180° -> -180° */ + } + ELSE IF ( idx_angle1 < 0 ) + { + idx_angle1 += ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* -180° -> +180° */ + } + + /* +180° == -180° */ + IF ( idx_angle1 == ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = 0; + } + + /* sanity check in case of FER or BER */ + IF ( idx_angle1 < 0 || idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = angle->last_angle1_idx; + } + + /*----------------------------------------------------------------* + * Elevation/pitch decoding and dequantization + *----------------------------------------------------------------*/ + + IF ( non_diegetic_flag == 0 ) + { + /* Decode elevation/pitch index */ + IF ( *flag_abs_angle1 == 0 && get_next_indice_fx( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + idx_angle2 = get_next_indice_fx( st0, ISM_ELEVATION_NBITS ); + } + ELSE + { + diff = 0; + sgn = 1; + + IF ( get_next_indice_fx( st0, 1 ) == 0 ) + { + nbits_diff_angle2 = 1; + } + ELSE + { + nbits_diff_angle2 = 1; + + IF ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle2 = add(nbits_diff_angle2, 1); + + /* read until the stop bit */ + WHILE ( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff = add(diff, 1); + nbits_diff_angle2 = add(nbits_diff_angle2, 1); + } + + IF ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) + { + /* count stop bit */ + nbits_diff_angle2 = add(nbits_diff_angle2, 1); + } + } + + idx_angle2 = add(angle->last_angle2_idx, sgn * diff); + } + + /* sanity check in case of FER or BER */ + IF ( idx_angle2 < 0 || idx_angle2 > ( 1 << ISM_ELEVATION_NBITS ) - 1 ) + { + idx_angle2 = angle->last_angle2_idx; + } + } + ELSE + { + idx_angle2 = angle->last_angle2_idx; /* second MD parameter is not transmitted for non-diegetic object */ + } + + /*----------------------------------------------------------------* + * Final updates + *----------------------------------------------------------------*/ + + angle->last_angle2_idx = idx_angle2; + angle->last_angle1_idx = idx_angle1; + + return; +} +#else +static void decode_angle_indices( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + ISM_METADATA_ANGLE_HANDLE angle, /* i/o: angle handle */ + const int16_t non_diegetic_flag, /* i : Non diegetic flag */ + int16_t *flag_abs_angle1 /* o : Azimuth/yaw encoding mode */ +) +{ + int16_t idx_angle1, nbits_diff_angle1, diff, sgn; + int16_t idx_angle2, nbits_diff_angle2; + + /*----------------------------------------------------------------* + * Azimuth/yaw decoding and dequantization + *----------------------------------------------------------------*/ + + /* Decode azimuth/yaw index */ + if ( get_next_indice( st0, 1 ) == 1 ) /* azimuth_abs_flag */ + { + idx_angle1 = get_next_indice( st0, ISM_AZIMUTH_NBITS ); + *flag_abs_angle1 = 1; + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_angle1 = 1; + } + else + { + nbits_diff_angle1 = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle1++; + + /* read until the stop bit */ + while ( ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_angle1++; + } + + if ( nbits_diff_angle1 < ISM_AZIMUTH_NBITS - 1 ) + { + /* count stop bit */ + nbits_diff_angle1++; + } + } + idx_angle1 = angle->last_angle1_idx + sgn * diff; + } + + /* azimuth/yaw is on a circle - check for diff coding for -180° -> 180° and vice versa changes */ + if ( idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 -= ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* +180° -> -180° */ + } + else if ( idx_angle1 < 0 ) + { + idx_angle1 += ( 1 << ISM_AZIMUTH_NBITS ) - 1; /* -180° -> +180° */ + } + + /* +180° == -180° */ + if ( idx_angle1 == ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = 0; + } + + /* sanity check in case of FER or BER */ + if ( idx_angle1 < 0 || idx_angle1 > ( 1 << ISM_AZIMUTH_NBITS ) - 1 ) + { + idx_angle1 = angle->last_angle1_idx; + } + + /*----------------------------------------------------------------* + * Elevation/pitch decoding and dequantization + *----------------------------------------------------------------*/ + + if ( non_diegetic_flag == 0 ) + { + /* Decode elevation/pitch index */ + if ( *flag_abs_angle1 == 0 && get_next_indice( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + idx_angle2 = get_next_indice( st0, ISM_ELEVATION_NBITS ); + } + else + { + diff = 0; + sgn = 1; + + if ( get_next_indice( st0, 1 ) == 0 ) + { + nbits_diff_angle2 = 1; + } + else + { + nbits_diff_angle2 = 1; + + if ( get_next_indice( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_angle2++; + + /* read until the stop bit */ + while ( ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_angle2++; } if ( nbits_diff_angle2 < ISM_ELEVATION_NBITS ) @@ -848,7 +1575,7 @@ static void decode_angle_indices( return; } - +#endif /*------------------------------------------------------------------------- * decode_radius() @@ -856,6 +1583,69 @@ static void decode_angle_indices( * Radius decoding and dequantization *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static Word16 decode_radius( + DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ + Word16 *last_radius_idx, /* i/o: last radius index */ + Word16 *flag_abs_radius /* o : Radius encoding mode */ +) +{ + Word16 idx_radius, nbits_diff_radius, diff, sgn; + + /* Decode radius index */ + IF ( get_next_indice_fx( st0, 1 ) == 1 ) /* elevation_abs_flag */ + { + *flag_abs_radius = 1; + idx_radius = get_next_indice_fx( st0, ISM_RADIUS_NBITS ); + } + ELSE + { + diff = 0; + sgn = 1; + + IF ( get_next_indice_fx( st0, 1 ) == 0 ) + { + nbits_diff_radius = 1; + } + ELSE + { + nbits_diff_radius = 1; + + IF ( get_next_indice_fx( st0, 1 ) == 1 ) /* negative sign */ + { + sgn = -1; + } + + nbits_diff_radius++; + + /* read until the stop bit */ + WHILE ( ( nbits_diff_radius < ISM_RADIUS_NBITS ) && ( get_next_indice( st0, 1 ) == 1 ) ) + { + diff++; + nbits_diff_radius++; + } + + IF ( nbits_diff_radius < ISM_RADIUS_NBITS ) + { + /* count stop bit */ + nbits_diff_radius++; + } + } + idx_radius = *last_radius_idx + sgn * diff; + } + + /* sanity check in case of FER or BER */ + IF ( idx_radius < 0 || idx_radius > ( 1 << ISM_RADIUS_NBITS ) - 1 ) + { + idx_radius = *last_radius_idx; + } + + /* Final updates */ + *last_radius_idx = idx_radius; + + return idx_radius; +} +#else static int16_t decode_radius( DEC_CORE_HANDLE st0, /* i/o: bitstream handle */ int16_t *last_radius_idx, /* i/o: last radius index */ @@ -917,6 +1707,7 @@ static int16_t decode_radius( return idx_radius; } +#endif /*-------------------------------------------------------------------* * ivas_ism_metadata_sid_dec() @@ -1087,3 +1878,169 @@ void ivas_ism_metadata_sid_dec( return; } + +#ifdef IVAS_FLOAT_FIXED +void ivas_ism_metadata_sid_dec_fx( + SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE decoder structure */ + const Word32 ism_total_brate, /* i : ISM total bitrate */ + const Word16 bfi, /* i : bfi flag */ + const Word16 nchan_ism, /* i : number of objects */ + const Word16 nchan_transport, /* i : number of transport channels*/ + const ISM_MODE ism_mode, /* i : ISM mode */ + Word16 *flag_noisy_speech, /* o : noisy speech flag */ + Word16 *sce_id_dtx, /* o : SCE DTX ID */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + Word16 nb_bits_metadata[] /* o : number of metadata bits */ +) +{ + Word16 i, ch, last_bit_pos; + Word32 q_step_fx, q_step_border_fx; + Word16 idx, idx_azimuth, idx_elevation; + Word16 nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id; + Word16 md_diff_flag[MAX_NUM_OBJECTS]; + ISM_MODE ism_mode_bstr; + DEC_CORE_HANDLE st0; + ISM_METADATA_HANDLE hIsmMetaData; + Word16 next_bit_pos_orig; + UWord16 bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig; + + IF ( ism_total_brate == FRAME_NO_DATA ) + { + ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism ); + + return; + } + + /* initialization */ + st0 = hSCE[0]->hCoreCoder[0]; + + last_bit_pos = (Word16) ( ( ism_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); + bstr_orig = st0->bit_stream; + next_bit_pos_orig = st0->next_bit_pos; + st0->next_bit_pos = 0; + + /* reverse the bitstream for easier reading of indices */ + FOR ( i = 0; i < min( MAX_BITS_ISM_METADATA, last_bit_pos ); i++ ) + { + bstr_meta[i] = st0->bit_stream[last_bit_pos - i]; + } + st0->bit_stream = bstr_meta; + st0->total_brate = ism_total_brate; /* needed for BER detection in get_next_indice() */ + + IF ( !bfi ) + { + /*----------------------------------------------------------------* + * ISm common signaling + *----------------------------------------------------------------*/ + + /* number of objects was already read in ivas_ism_get_dtx_dec() */ + /* update the position in the bitstream */ + st0->next_bit_pos += nchan_ism; + + /* read SID metadata flag( one per object ) */ + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + md_diff_flag[ch] = get_next_indice_fx( st0, 1 ); + } + + /*----------------------------------------------------------------* + * Set quantization bits based on the number of coded objects + *----------------------------------------------------------------*/ + + ivas_get_ism_sid_quan_bitbudget_fx( nchan_ism, &nBits_azimuth, &nBits_elevation, &q_step_fx, &q_step_border_fx, &nBits_coh, &nBits_sce_id ); + + /*----------------------------------------------------------------* + * Spatial parameters, loop over TCs - 1 + *----------------------------------------------------------------*/ + + *flag_noisy_speech = 0; + *sce_id_dtx = 0; + + /* read ISM mode flag to explicitly signal number of spatial parameters */ + IF ( nchan_ism > 2 ) + { + idx = get_next_indice_fx( st0, 1 ); + ism_mode_bstr = (ISM_MODE) ( idx + 1 ); + /* note: ISM mode was already read and used for configuration in in ivas_ism_dtx_dec() */ + + IF ( ism_mode_bstr == ISM_MODE_PARAM ) + { + /* read noisy speech flag */ + *flag_noisy_speech = get_next_indice_fx( st0, 1 ); + nBits_sce_id = 1; + } + } + + IF ( nchan_transport > 1 ) + { + /* read sce id */ + *sce_id_dtx = get_next_indice_fx( st0, nBits_sce_id ); + + /* decode the coherence */ + FOR ( ch = 0; ch < nchan_transport; ch++ ) + { + IF ( ch == *sce_id_dtx ) + { + hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = 32767; + continue; + } + + idx = get_next_indice_fx( st0, nBits_coh ); + hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = div_s( idx, ( ( 1 << nBits_coh ) - 1 ) ); + } + } + + IF ( ism_mode == ISM_MODE_PARAM ) + { + hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence_fx; + } + + /*----------------------------------------------------------------* + * Metadata decoding and dequantization, loop over all objects + *----------------------------------------------------------------*/ + + FOR ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMetaData = hIsmMeta[ch]; + IF ( md_diff_flag[ch] == 1 ) + { + /* Azimuth decoding */ + idx_azimuth = get_next_indice_fx( st0, nBits_azimuth ); + hIsmMetaData->azimuth_fx = ism_dequant_meta_fx( idx_azimuth, ism_azimuth_borders_fx, q_step_fx, q_step_border_fx, 1 << nBits_azimuth ); + + /* Elevation decoding */ + idx_elevation = get_next_indice_fx( st0, nBits_elevation ); + hIsmMetaData->elevation_fx = ism_dequant_meta_fx( idx_elevation, ism_elevation_borders_fx, q_step_fx, q_step_border_fx, 1 << 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 ); + } + + /* save for smoothing metadata evolution */ + hIsmMetaData->last_true_azimuth_fx = hIsmMetaData->azimuth_fx; + hIsmMetaData->last_true_elevation_fx = hIsmMetaData->elevation_fx; + } + } + + /* take into account padding bits as metadata bits to keep later bitrate checks valid */ + nb_bits_metadata[*sce_id_dtx] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + + /* set the bitstream pointer to its original position */ + st0->bit_stream = bstr_orig; + st0->next_bit_pos = next_bit_pos_orig; + } + + /* smooth the metadata evolution */ + ism_metadata_smooth_fx( hIsmMeta, ism_total_brate, nchan_ism ); + + return; +} +#endif diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index bfb4fba04..e04ba01ff 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -162,10 +162,40 @@ ivas_error ivas_jbm_dec_tc( } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { + +#ifdef IVAS_FLOAT_FIXED + FOR (Word16 ind = 0; ind < st_ivas->nchan_ism; ind++) { + st_ivas->hIsmMetaData[ind]->azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->elevation * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_elevation * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_true_azimuth * (1 << 22)); + st_ivas->hIsmMetaData[ind]->last_true_elevation_fx = (Word32)(st_ivas->hIsmMetaData[ind]->last_true_elevation * (1 << 22)); + st_ivas->hIsmMetaData[ind]->radius_fx = (Word16)(st_ivas->hIsmMetaData[ind]->radius * (1 << 9)); + st_ivas->hIsmMetaData[ind]->yaw_fx = (Word32)(st_ivas->hIsmMetaData[ind]->yaw * (1 << 22)); + st_ivas->hIsmMetaData[ind]->pitch_fx = (Word32)(st_ivas->hIsmMetaData[ind]->pitch * (1 << 22)); + } + IF ( ( error = ivas_ism_metadata_dec_fx( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + FOR (Word16 ind = 0; ind < st_ivas->nchan_ism; ind++) { + st_ivas->hIsmMetaData[ind]->azimuth = (float)(st_ivas->hIsmMetaData[ind]->azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->elevation = (float)(st_ivas->hIsmMetaData[ind]->elevation_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_azimuth = (float)(st_ivas->hIsmMetaData[ind]->last_azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_elevation = (float)(st_ivas->hIsmMetaData[ind]->last_elevation_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_true_azimuth = (float)(st_ivas->hIsmMetaData[ind]->last_true_azimuth_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->last_true_elevation = (float)(st_ivas->hIsmMetaData[ind]->last_true_elevation_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->radius = (float)(st_ivas->hIsmMetaData[ind]->radius_fx) / (float)(1 << 9); + st_ivas->hIsmMetaData[ind]->yaw = (float)(st_ivas->hIsmMetaData[ind]->yaw_fx) / (float)(1 << 22); + st_ivas->hIsmMetaData[ind]->pitch = (float)(st_ivas->hIsmMetaData[ind]->pitch_fx) / (float)(1 << 22); + } +#else if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) { return error; } +#endif } else /* ISM_MODE_DISC */ { -- GitLab