diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index f6c1fd9c0415226c267a8b19f17a90b80a0831e1..3f48b0b43e8c8596b538fc4642f68c89d22bff6b 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -341,9 +341,26 @@ typedef enum #define PARAM_ISM_MAX_CHAN 16 #define PARAM_ISM_HYS_BUF_SIZE 10 +/* ISM DTX */ +#ifdef DISCRETE_ISM_DTX_CNG +#define ISM_DTX_COH_SCA_BITS 4 +#else #define PARAM_ISM_DTX_COH_SCA_BITS 4 +#endif +#ifdef DISCRETE_ISM_DTX_CNG +#define ISM_DTX_AZI_BITS_HIGH 8 +#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_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) +#else #define PARAM_ISM_DTX_AZI_BITS 5 #define PARAM_ISM_DTX_ELE_BITS 4 +#endif + typedef enum { @@ -364,8 +381,13 @@ enum IND_ISM_METADATA_FLAG = IND_ISM_NUM_OBJECTS + MAX_NUM_OBJECTS, #endif IND_ISM_VAD_FLAG = IND_ISM_METADATA_FLAG + MAX_NUM_OBJECTS, +#ifdef DISCRETE_ISM_DTX_CNG + IND_ISM_NOISY_SPEECH_FLAG = IND_ISM_VAD_FLAG + MAX_NUM_OBJECTS, + IND_ISM_SCE_ID_DTX, +#else IND_ISM_SCE_ID_DTX = IND_ISM_VAD_FLAG + MAX_NUM_OBJECTS, IND_ISM_NOISY_SPEECH_FLAG, +#endif IND_ISM_DTX_COH_SCA, /* ------------- loop for objects -------------- */ diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index f8eaa8d05f0dc27fde7ed486add14a3f3b7e2805..cdcb3a9b1c980cb1f74ab89928e5048e4177c608 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -90,7 +90,7 @@ static void bitbudget_to_brate( ivas_error ivas_ism_config( const int32_t ism_total_brate, /* i : ISM total bitrate */ const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_obj, /* i : number of objects */ + const int16_t nchan_ism, /* i : number of objects */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ const int16_t localVAD[MAX_NUM_OBJECTS], /* i : local VAD flag */ const int16_t ism_imp[], /* i : ISM importance flags */ @@ -138,7 +138,7 @@ ivas_error ivas_ism_config( nb_bits_metadata[0] += ISM_EXTENDED_METADATA_BITS; } #endif - nb_bits_metadata[0] += n_ISms * ISM_METADATA_FLAG_BITS + num_obj; + nb_bits_metadata[0] += n_ISms * ISM_METADATA_FLAG_BITS + nchan_ism; for ( ch = 0; ch < n_ISms; ch++ ) { @@ -371,10 +371,12 @@ void ivas_ism_reset_metadata_API( /*! r: index of the winning codeword */ int16_t ism_quant_meta( - const float val, /* i : scalar value to quantize */ - float *valQ, /* o : quantized value */ - const float borders[], /* i : level borders */ - const int16_t cbsize /* i : codebook size */ + const float val, /* i : scalar value to quantize */ + float *valQ, /* o : quantized value */ + const float borders[], /* i : level borders */ + const float q_step, /* i : quantization step */ + const float q_step_border, /* i : quantization step at the border */ + const int16_t cbsize /* i : codebook size */ ) { int16_t idx, idx_start; @@ -384,19 +386,19 @@ int16_t ism_quant_meta( { qlow = borders[0]; idx_start = 0; - step = ISM_Q_STEP_BORDER; + step = q_step_border; } else if ( val <= borders[2] ) { qlow = borders[1]; - idx_start = (int16_t) ( ( borders[1] - borders[0] ) / ISM_Q_STEP_BORDER ); - step = ISM_Q_STEP; + idx_start = (int16_t) ( ( borders[1] - borders[0] ) / q_step_border ); + step = q_step; } else { qlow = borders[2]; - idx_start = (int16_t) ( cbsize - 1 - ( borders[3] - borders[2] ) / ISM_Q_STEP_BORDER ); - step = ISM_Q_STEP_BORDER; + idx_start = (int16_t) ( cbsize - 1 - ( borders[3] - borders[2] ) / q_step_border ); + step = q_step_border; } idx = idx_start + (int16_t) max( 0.f, min( cbsize - 1, ( ( val - qlow ) / step + 0.5f ) ) ); @@ -414,31 +416,33 @@ int16_t ism_quant_meta( /*! r: dequantized value */ float ism_dequant_meta( - const int16_t idx, /* i : quantizer index */ - const float borders[], /* i : level borders */ - const int16_t cbsize /* i : codebook size */ + const int16_t idx, /* i : quantizer index */ + const float borders[], /* i : level borders */ + const float q_step, /* i : quantization step */ + const float q_step_border, /* i : quantization step at the border */ + const int16_t cbsize /* i : codebook size */ ) { int16_t idx_start; float qlow, step, valQ; - if ( idx <= ( borders[1] - borders[0] ) / ISM_Q_STEP_BORDER ) + if ( idx <= ( borders[1] - borders[0] ) / q_step_border ) { qlow = borders[0]; idx_start = 0; - step = ISM_Q_STEP_BORDER; + step = q_step_border; } - else if ( idx <= cbsize - 1 - ( borders[3] - borders[2] ) / ISM_Q_STEP_BORDER ) + else if ( idx <= cbsize - 1 - ( borders[3] - borders[2] ) / q_step_border ) { qlow = borders[1]; - idx_start = (int16_t) ( ( borders[1] - borders[0] ) / ISM_Q_STEP_BORDER ); - step = ISM_Q_STEP; + idx_start = (int16_t) ( ( borders[1] - borders[0] ) / q_step_border ); + step = q_step; } else { qlow = borders[2]; - idx_start = (int16_t) ( cbsize - 1 - ( borders[3] - borders[2] ) / ISM_Q_STEP_BORDER ); - step = ISM_Q_STEP_BORDER; + idx_start = (int16_t) ( cbsize - 1 - ( borders[3] - borders[2] ) / q_step_border ); + step = q_step_border; } valQ = ( idx - idx_start ) * step + qlow; @@ -455,12 +459,22 @@ float ism_dequant_meta( void ivas_param_ism_config( PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: IVAS Param ISM Config Structure */ +#ifdef NCHAN_ISM_PARAMETER + , + const int16_t nchan_obj /* i : number of ISM channels */ +#endif ) { +#ifdef NCHAN_ISM_PARAMETER + int16_t i; + + hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; +#else int16_t i, num_obj; hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; num_obj = hParamIsm->num_obj; +#endif for ( i = 0; i < hParamIsm->nbands; i++ ) { @@ -468,7 +482,11 @@ void ivas_param_ism_config( } /* for elevation zero compute the max azi quantization indices */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_obj; i++ ) +#else for ( i = 0; i < num_obj; i++ ) +#endif { hParamIsm->last_az_diff[i] = 0; hParamIsm->last_az_sgn[i] = 1; @@ -535,3 +553,68 @@ void ivas_ism_metadata_close( return; } + + +#ifdef DISCRETE_ISM_DTX_CNG +/*-------------------------------------------------------------------* + * update_last_metadata() + * + * Store last metadata values + *-------------------------------------------------------------------*/ + +void update_last_metadata( + const int16_t nchan_ism, /* i : number of objects */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const int16_t updt_flag[] /* i : last metadata update flag */ +) +{ + int16_t ch; + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + if ( updt_flag[ch] == 1 ) + { + hIsmMeta[ch]->last_azimuth = hIsmMeta[ch]->azimuth; + hIsmMeta[ch]->last_elevation = hIsmMeta[ch]->elevation; + } + } + + return; +} + + +/*----------------------------------------------------------------* + * ivas_get_ism_sid_quan_bitbudget() + * + * Set quantization bits based on the number of coded objects + *----------------------------------------------------------------*/ + +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 */ + int16_t *nBits_elevation, /* o : number of Q bits for elevation */ + float *q_step, /* o : quantization step */ + float *q_step_border, /* o : quantization step at the border */ + int16_t *nBits_coh, /* o : number of Q bits for coherence */ + int16_t *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 = ISM_Q_STEP_HIGH; + *q_step_border = ISM_Q_STEP_BORDER_HIGH; + *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 = ISM_Q_STEP_LOW; + *q_step_border = ISM_Q_STEP_BORDER_LOW; + *nBits_sce_id = 2; + } + + return; +} +#endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9b3e52ed80a160332133f9b91f2454e6c2a073c5..e8597bbf3c87978d65fe7fe52a556c73ddd7f4ce 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -500,8 +500,10 @@ void stereo_tcx_core_dec( const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ const int16_t nchan_out, /* i : number of output channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM) */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +#ifndef DISCRETE_ISM_DTX_CNG + ,const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM) */ +#endif ); void stereo_tcx_init_dec( @@ -744,8 +746,8 @@ void dtx_read_padding_bits( ivas_error ivas_ism_config( const int32_t ism_total_brate, /* i : ISM total bitrate */ - const int16_t num_trans_ch, /* i : number of trans channels */ - const int16_t num_obj, /* i : number of objects */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t nchan_ism, /* i : number of objects */ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ const int16_t localVAD[MAX_NUM_OBJECTS], /* i : local VAD flag */ const int16_t ism_imp[], /* i : ISM importance flags */ @@ -767,6 +769,8 @@ int16_t ism_quant_meta( const float val, /* i : scalar value to quantize */ float *valQ, /* o : quantized value */ const float borders[], /* i : level borders */ + const float q_step, /* i : quantization step */ + const float q_step_border, /* i : quantization step at the border */ const int16_t cbsize /* i : codebook size */ ); @@ -774,6 +778,8 @@ int16_t ism_quant_meta( float ism_dequant_meta( const int16_t idx, /* i : quantizer index */ const float borders[], /* i : level borders */ + const float q_step, /* i : quantization step */ + const float q_step_border, /* i : quantization step at the border */ const int16_t cbsize /* i : codebook size */ ); @@ -811,6 +817,9 @@ ivas_error ivas_ism_enc( ivas_error ivas_ism_metadata_enc( const int32_t ism_total_brate, /* i : ISM total bitrate */ +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif 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 */ @@ -828,12 +837,18 @@ ivas_error ivas_ism_metadata_enc( ivas_error ivas_ism_metadata_dec( const int32_t ism_total_brate, /* i : ISM total bitrate */ +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif int16_t *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 int16_t bfi, /* i : bfi flag */ int16_t nb_bits_metadata[], /* o : number of metadata bits */ ISM_MODE ism_mode, /* i : ISM mode */ +#ifdef DISCRETE_ISM_DTX_CNG + ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ +#endif const PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Config Handle */ ); @@ -875,6 +890,10 @@ void ivas_param_ism_stereo_dmx( void ivas_param_ism_config( PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: IVAS Param ISM Config Structure */ +#ifdef NCHAN_ISM_PARAMETER + , + const int16_t nchan_ism /* i : number of ISM channels */ +#endif ); ivas_error ivas_ism_enc_config( @@ -882,8 +901,14 @@ ivas_error ivas_ism_enc_config( ); ivas_error ivas_ism_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t num_obj /* i : number of objects in the bitstream */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifdef DISCRETE_ISM_DTX_CNG + , + const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#endif +#ifndef NCHAN_ISM_PARAMETER + ,const int16_t num_obj /* i : number of objects in the bitstream */ +#endif ); ivas_error ivas_param_ism_dec_open( @@ -910,49 +935,116 @@ void ivas_param_ism_params_to_masa_param_mapping( *----------------------------------------------------------------------------------*/ ivas_error ivas_ism_dtx_open( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); +#ifdef DISCRETE_ISM_DTX_CNG +/*! r: indication of DTX frame */ +int16_t ivas_ism_dtx_enc( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism, /* i : number of objects */ + const int16_t nchan_transport, /* i : number of transport channels */ + int16_t vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + int16_t md_diff_flag[], /* o : metadata differential flag */ + int16_t *sid_flag /* o : indication of SID frame */ +); +#else +/*! r: indication of DTX frame */ +int16_t ivas_ism_dtx_enc( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + int16_t *sid_flag /* o : indication of SID frame */ +); +#endif + ivas_error ivas_ism_dtx_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - int16_t *nb_bits_metadata /* o : number of metadata bits */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + int16_t *nb_bits_metadata /* o : number of metadata bits */ ); +#ifdef DISCRETE_ISM_DTX_CNG +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 */ +); +#else void ivas_param_ism_metadata_dtx_enc( - BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ - ISM_METADATA_HANDLE hIsmMeta[], /* i : ISM metadata handles */ - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Enc Handle */ + BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ + ISM_METADATA_HANDLE hIsmMeta[], /* i : ISM metadata handles */ + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Enc Handle */ +#ifdef NCHAN_ISM_PARAMETER + ,const int16_t nchan_ism /* i : number of ISM channels */ +#endif ); +#endif +#ifdef DISCRETE_ISM_DTX_CNG +void ivas_ism_metadata_sid_dec( + SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int32_t ism_total_brate, /* i : ISms total bitrate */ + const int16_t bfi, /* i : bfi 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 */ + int16_t *flag_noisy_speech, /* o : noisy speech flag */ + int16_t *sce_id_dtx, /* o : SCE DTX ID */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + int16_t nb_bits_metadata[] /* o : number of metadata bits */ +); +#else void ivas_param_ism_metadata_dtx_dec( - Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); +#endif void ivas_ism_get_sce_id_dtx( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t input_frame /* i : input frame length per channel */ + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t input_frame /* i : input frame length per channel */ ); void ivas_param_ism_compute_noisy_speech_flag( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); -/*! r: indication of DTX frame */ -int16_t ivas_ism_dtx_enc( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - int16_t *sid_flag /* o : indication of SID frame */ +void ivas_ism_coh_estim_dtx_enc( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t input_frame /* i : input frame length */ ); -void ivas_ism_coh_estim_dtx_enc( - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ - SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t input_frame /* i : input frame length */ +#ifdef DISCRETE_ISM_DTX_CNG +void update_last_metadata( + const int16_t nchan_ism, /* i : number of objects */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const int16_t updt_flag[] /* i : last metadata update flag */ ); +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 */ + int16_t *nBits_elevation, /* o : number of Q bits for elevation */ + float *q_step, /* o : quantization step */ + float *q_step_border, /* o : quantization step at the border */ + int16_t *nBits_coh, /* o : number of Q bits for coherence */ + int16_t *nBits_sce_id /* o : number of Q bits for sce_id_dtx */ +); +#endif + + /*----------------------------------------------------------------------------------* * DFT Stereo prototypes *----------------------------------------------------------------------------------*/ @@ -1294,9 +1386,9 @@ int16_t adapt_GR_rpg1_ief( /*! r: number of bits written */ int16_t write_GR1( BSTR_ENC_HANDLE hBstr, /* i/o: Encoder bitstream handle */ - const int16_t ind, /* i : bitstream index */ - const int16_t *in, /* i : input vector */ - const int16_t len /* i : vector length */ + const int16_t ind, /* i : bitstream index */ + const int16_t *in, /* i : input vector */ + const int16_t len /* i : vector length */ ); /*! r: number of bits written */ @@ -2845,7 +2937,7 @@ void ivas_mct_dec_mct( void apply_MCT_dec( MCT_DEC_HANDLE hMCT, /* i/o: MCT decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ - float *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */ + float *x[MCT_MAX_CHANNELS][NB_DIV] /* i/o: decoded and dequan. spect. input to MCT */ ); void mctStereoIGF_dec( @@ -4193,7 +4285,7 @@ void ivas_transient_det_close( void ivas_transient_det_process( ivas_trans_det_state_t *hTranDet, /* i/o: SPAR TD handle */ float *pIn_pcm, /* i : input audio channels */ - const int16_t frame_len, /* i : frame length in samples */ + const int16_t frame_len, /* i : frame length in samples */ int16_t transient_det[2] /* o : transient det outputs */ ); @@ -4637,7 +4729,7 @@ void ivas_ism2sba( float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t num_objects, /* i : number of objects */ + const int16_t nchan_ism, /* i : number of objects */ const int16_t output_frame, /* i : output frame length per channel */ const int16_t sba_order /* i : SBA order */ ); diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 7e3326af238c9c21788c130009fa0270a2c6acd6..b445ac6f0487de5c710c7cf6c9d4d5355d727554 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -77,6 +77,13 @@ typedef struct int16_t elevation_diff_cnt; /* FEC counter of consecutive differentially elevation coded frames */ #endif +#ifdef DISCRETE_ISM_DTX_CNG + float last_azimuth; /* MD smoothing in DTX- last Q azimuth value */ + 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 */ +#endif + } ISM_METADATA_FRAME, *ISM_METADATA_HANDLE; @@ -149,7 +156,9 @@ typedef struct ivas_param_ism_data_structure int16_t nbands; int16_t nblocks[MAX_PARAM_ISM_NBANDS]; int16_t band_grouping[MAX_PARAM_ISM_NBANDS + 1]; +#ifndef NCHAN_ISM_PARAMETER int16_t num_obj; +#endif int16_t azi_index[MAX_NUM_OBJECTS]; int16_t ele_index[MAX_NUM_OBJECTS]; diff --git a/lib_com/options.h b/lib_com/options.h index 96361e3b899eef9802fce442a467ff0cbc20f26e..c054a9b5a7efb36bfdb4b4b749ab9492fc3861c9 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,11 +155,13 @@ #define FIX_373_MASA_DELAY_COMP_MSAN /* Nokia: Issue 373: MASA audio/meta delay compensation. MSAN bugfix */ #ifdef FIX_I109_ORIENTATION_TRACKING -#define OTR_REFERENCE_VECTOR_TRACKING /* FhG: enables the reference position orientation tracking mode */ +#define OTR_REFERENCE_VECTOR_TRACKING /* FhG: enables the reference position orientation tracking mode */ #endif #define FIX_380_BFI_PARAMISM /* VA: issue 380 - fix metadata recovery in ParamISM BFI */ #define FIX_MDCT_BASED_BWD /* FhG: fixes for BWD for issues with reaction to transients for MDCT-stereo and MCT */ +#define DISCRETE_ISM_DTX_CNG /* FhG/VA: contribution 15 - DTX/CNG for (discrete) ISM */ +#define NCHAN_ISM_PARAMETER /* VA: make 'nchan_ism' parameter part of st_ivas/hEncoderConfig */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_com/prot.h b/lib_com/prot.h index fc1dcad992ae4c7794d6b80f6887d605e529c6e0..c8f69fe832232b1373312c8ef0ecbf6fd8e3255e 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -8526,7 +8526,7 @@ void generate_comfort_noise_dec_hf( float **bufferReal, /* o : Real part of input bands */ float **bufferImag, /* o : Imaginary part of input bands */ HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t cng_flag /*i : CNG Flag */ + const int16_t cng_flag /* i : CNG Flag */ ); void generate_masking_noise( diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index b0d30e88dd8fa9ed29921243169f2cd0c05ebfa7..eb53379d6683c5d05f178ae3f0d2b4aef0dac910 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -529,7 +529,7 @@ ivas_error acelp_core_dec( ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } if ( !st->read_sid_info ) - // if (!st->read_sid_info && st->cng_paramISM_flag) /* read_sid_info can only be 0 in ParamISM mode */ + // if (!st->read_sid_info && st->cng_ism_flag) /* read_sid_info can only be 0 in ParamISM mode */ { float noise_lvl_highest; @@ -1125,7 +1125,7 @@ ivas_error acelp_core_dec( st->lp_noise = st->hFdCngDec->lp_noise; } - if ( st->element_mode != IVAS_CPE_TD && !st->cng_paramISM_flag ) + if ( st->element_mode != IVAS_CPE_TD && !st->cng_ism_flag ) { /*Noise estimate*/ ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1301,7 +1301,7 @@ ivas_error acelp_core_dec( /*WB/SWB-FD_CNG*/ if ( ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && ( st->cng_type == FD_CNG ) && ( st->hFdCngDec->hFdCngCom->numCoreBands < st->cldfbSyn->no_channels ) ) { - generate_comfort_noise_dec_hf( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_paramISM_flag ); + generate_comfort_noise_dec_hf( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_ism_flag ); if ( st->hFdCngDec->hFdCngCom->regularStopBand < st->cldfbSyn->no_channels ) { diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 1d4b2ccf905fd310a4db7cdc96b63f8b94939e8b..ab9465a93a246c2251e998f544b2b28f501cc084 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -420,6 +420,7 @@ void ApplyFdCng( hFdCngCom->sid_frame_counter = 0; /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ /* set noise estimation inactive when we have bit errors, as no update with noise generated by corrupt frame (biterror) should be performed. */ +#ifndef DISCRETE_ISM_DTX_CNG if ( concealWholeFrame == 0 && ( timeDomainInput == NULL || ( *timeDomainInput( -FLT_MAX ) && @@ -429,6 +430,17 @@ void ApplyFdCng( !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) || ( st->element_mode == IVAS_CPE_TD ) ) && ( !st->BER_detect ) ) +#else + if ( concealWholeFrame == 0 && + ( timeDomainInput == NULL || + ( *timeDomainInput( -FLT_MAX ) && + *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && + *( timeDomainInput + hFdCngCom->frameSize - 1 ) > ( -FLT_MAX ) ) ) && + ( ( ( ( st->element_mode != IVAS_CPE_TD && st->element_mode != IVAS_CPE_DFT && hFdCngDec->flag_dtx_mode ) || !st->VAD || ( st->ini_frame < 100 && st->is_ism_format ) ) && + !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) || + ( st->element_mode == IVAS_CPE_TD ) ) && + ( !st->BER_detect ) ) +#endif { /* Perform noise estimation at the decoder */ perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); @@ -1091,7 +1103,7 @@ void generate_comfort_noise_dec( c2 = (float) sqrt( 1 - hFdCngCom->coherence ); seed2 = &( hFdCngCom->seed2 ); - if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { seed2 = &( hFdCngCom->seed3 ); } @@ -1101,7 +1113,7 @@ void generate_comfort_noise_dec( if ( hFdCngCom->startBand == 0 ) { - if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1126,7 +1138,7 @@ void generate_comfort_noise_dec( for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) { /* Real part in FFT bins */ - if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1140,7 +1152,7 @@ void generate_comfort_noise_dec( ptr_r += 2; /* Imaginary part in FFT bins */ - if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1218,7 +1230,7 @@ void generate_comfort_noise_dec( for ( i = 0; i < hFdCngCom->numSlots; i++ ) { /* Real part in CLDFB band */ - if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1231,7 +1243,7 @@ void generate_comfort_noise_dec( bufferReal[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ - if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1328,10 +1340,10 @@ void generate_comfort_noise_dec( *-------------------------------------------------------------------*/ void generate_comfort_noise_dec_hf( - float **bufferReal, /* o : Real part of input bands */ - float **bufferImag, /* o : Imaginary part of input bands */ - HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ - const int16_t cng_coh_flag /* i : CNG Flag for coherence handling */ + float **bufferReal, /* o : Real part of input bands */ + float **bufferImag, /* o : Imaginary part of input bands */ + HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */ + const int16_t cng_coh_flag /* i : CNG Flag for coherence handling */ ) { int16_t i, j; @@ -1347,7 +1359,7 @@ void generate_comfort_noise_dec_hf( { seed2 = &( hFdCngCom->seed3 ); - c1 = (float) sqrt( hFdCngCom->coherence ); + c1 = (float) sqrt( hFdCngCom->coherence ); // VE!!!!! all occurences of "(float) sqrt()" should be replaced by "sqrtf()" c2 = (float) sqrt( 1 - hFdCngCom->coherence ); } diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index a8c24a11f5ef8e1afd5723f012d208e64bb2134d..34ee7a3cec83ca8730cb700ca95f065c0b062466 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -738,8 +738,11 @@ ivas_error init_decoder( st->tdm_LRTD_flag = 0; st->cna_dirac_flag = 0; st->cng_sba_flag = 0; - st->cng_paramISM_flag = 0; + st->cng_ism_flag = 0; st->read_sid_info = 1; /* by default read the sid info from bitstream */ +#ifdef DISCRETE_ISM_DTX_CNG + st->is_ism_format = 0; +#endif return error; diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index f1a897351f795869ed103400eb180358e0c9e8af..0811f9957afe9bb87019a364829083b89bc8d2b7 100755 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -341,7 +341,12 @@ ivas_error ivas_core_dec( if ( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { /* TCX decoder */ - stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hCPE == NULL ? NULL : hCPE->hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format, st_ivas == NULL ? 0 : st_ivas->ism_mode ); + stereo_tcx_core_dec( st, frameMode[n], output[n], synth[n], pitch_buf[n], sba_dirac_stereo_flag, hStereoTD, last_element_mode, flag_sec_CNA, hCPE == NULL ? NULL : hCPE->hStereoCng, nchan_out, st_ivas == NULL ? 0 : st_ivas->ivas_format +#ifndef DISCRETE_ISM_DTX_CNG + , + st_ivas == NULL ? 0 : st_ivas->ism_mode +#endif + ); } if ( st->core == HQ_CORE ) diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 45f31e9f84206b65ef423ef898fadd2d32afbc7b..0983aee6cbf0864a1c8b8b458a6dd51d6d07a2a8 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -149,11 +149,42 @@ ivas_error ivas_dec( } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { + // VE: call ivas_ism_metadata_dec() with 'st_ivas' - TBD +#ifdef DISCRETE_ISM_DTX_CNG +#ifdef NCHAN_ISM_PARAMETER + 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->hDirAC->hParamIsm ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( 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->hDirAC->hParamIsm ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#else +#ifdef NCHAN_ISM_PARAMETER + 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->hDirAC->hParamIsm ); +#else ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm ); +#endif +#endif } else /* ISM_MODE_DISC */ { +#ifdef DISCRETE_ISM_DTX_CNG +#ifdef NCHAN_ISM_PARAMETER + 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, NULL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#else +#ifdef NCHAN_ISM_PARAMETER + 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, NULL ); +#else ivas_ism_metadata_dec( ivas_total_brate, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, NULL ); +#endif +#endif } for ( n = 0; n < st_ivas->nchan_transport; n++ ) @@ -206,7 +237,11 @@ ivas_error ivas_dec( else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) { /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ +#ifdef NCHAN_ISM_PARAMETER + ivas_ism2sba( output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); +#else ivas_ism2sba( output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_transport, output_frame, st_ivas->hIntSetup.ambisonics_order ); +#endif } /* Binaural rendering */ diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index aeddb3b1b08cb992a86208e341fc61a02a505177..bc0a69ae560060b2c4ea351ca6c3b9fbaee33ada 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -66,7 +66,7 @@ ivas_error ivas_dec_setup( ) { int16_t k, idx, num_bits_read; - int16_t num_obj, element_mode_flag; + int16_t nchan_ism, element_mode_flag; Decoder_State *st; int32_t ivas_total_brate; ivas_error error; @@ -102,15 +102,34 @@ ivas_error ivas_dec_setup( { /* read the number of objects */ st_ivas->nchan_transport = 1; - num_obj = 1; + nchan_ism = 1; k = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 ); - while ( st_ivas->bit_stream[k] && num_obj < MAX_NUM_OBJECTS ) + while ( st_ivas->bit_stream[k] && nchan_ism < MAX_NUM_OBJECTS ) { - num_obj++; + nchan_ism++; k--; } - ivas_ism_dec_config( st_ivas, num_obj ); +#ifdef NCHAN_ISM_PARAMETER + st_ivas->nchan_ism = nchan_ism; +#endif + +#ifdef DISCRETE_ISM_DTX_CNG +#ifdef NCHAN_ISM_PARAMETER + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nchan_ism ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#else +#ifdef NCHAN_ISM_PARAMETER + ivas_ism_dec_config( st_ivas ); +#else + ivas_ism_dec_config( st_ivas, nchan_ism ); +#endif +#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -223,6 +242,11 @@ ivas_error ivas_dec_setup( case SID_MDCT_STEREO: st_ivas->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DISCRETE_ISM_DTX_CNG + case SID_ISM: + st_ivas->element_mode_init = IVAS_SCE; + break; +#endif case SID_MASA_1TC: st_ivas->element_mode_init = IVAS_SCE; st_ivas->nchan_transport = 1; @@ -402,16 +426,27 @@ static ivas_error ivas_read_format( break; case SID_ISM: st_ivas->ivas_format = ISM_FORMAT; - +#ifndef DISCRETE_ISM_DTX_CNG if ( st_ivas->ism_mode == ISM_MODE_DISC ) { - ivas_ism_dec_config( st_ivas, 1 ); /* currently DTX supported for 1 ISM when ISM Mode is DISC_ISM */ + ivas_ism_dec_config( st_ivas +#ifndef NCHAN_ISM_PARAMETER + , + 1 +#endif + ); /* currently DTX supported for 1 ISM when ISM Mode is DISC_ISM */ } if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - ivas_ism_dec_config( st_ivas, st_ivas->nSCE ); /* for Param-ISM, we need to generate 2 TCs */ + ivas_ism_dec_config( st_ivas +#ifndef NCHAN_ISM_PARAMETER + , + st_ivas->nSCE +#endif + ); /* for Param-ISM, we need to generate 2 TCs */ } +#endif break; case SID_MULTICHANNEL: st_ivas->ivas_format = MC_FORMAT; @@ -860,8 +895,8 @@ ivas_error ivas_init_decoder( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - st_ivas->nchan_transport = 2; - st_ivas->nSCE = 2; + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; + st_ivas->nSCE = MAX_PARAM_ISM_WAVE; if ( ( error = ivas_param_ism_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { @@ -882,6 +917,10 @@ ivas_error ivas_init_decoder( } reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); + +#ifdef DISCRETE_ISM_DTX_CNG + st_ivas->hSCE[sce_id]->hCoreCoder[0]->is_ism_format = 1; +#endif } if ( st_ivas->ism_mode == ISM_MODE_PARAM ) diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 51ea82bfe158df61f0d385f506bfbfc69019841b..5e0b475e3e0ad02c41c6621c2526b6e36fd163ac 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -49,8 +49,11 @@ static ivas_error ivas_ism_bitrate_switching( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nchan_transport_old, /* i : last number of transport channels */ - const ISM_MODE last_ism_mode, /* i : last ISM mode */ - const int16_t num_obj /* i : number of objects in the bitstream */ + const ISM_MODE last_ism_mode /* i : last ISM mode */ +#ifndef NCHAN_ISM_PARAMETER + , + const int16_t num_obj /* i : number of objects in the bitstream */ +#endif ) { ivas_error error; @@ -62,7 +65,11 @@ static ivas_error ivas_ism_bitrate_switching( nCPE_old = st_ivas->nCPE; nSCE_old = st_ivas->nSCE; +#ifdef NCHAN_ISM_PARAMETER + if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, num_obj, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -237,12 +244,21 @@ static ivas_error ivas_ism_bitrate_switching( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_dec_config( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - const int16_t num_obj /* i : number of objects in the bitstream */ + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +#ifdef DISCRETE_ISM_DTX_CNG + , + const ISM_MODE last_ism_mode /* i/o: last ISM mode */ +#endif +#ifndef NCHAN_ISM_PARAMETER + , + const int16_t num_obj /* i : number of objects in the bitstream */ +#endif ) { int32_t ivas_total_brate; +#ifndef DISCRETE_ISM_DTX_CNG ISM_MODE last_ism_mode; +#endif ivas_error error; int16_t nchan_transport_old; @@ -250,11 +266,17 @@ ivas_error ivas_ism_dec_config( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; +#ifndef DISCRETE_ISM_DTX_CNG /* store last frame ISM mode */ last_ism_mode = st_ivas->ism_mode; +#endif /* Assumes that num of input objects are constant */ +#ifdef NCHAN_ISM_PARAMETER + nchan_transport_old = st_ivas->nchan_ism; +#else nchan_transport_old = num_obj; +#endif if ( last_ism_mode == ISM_MODE_PARAM ) { @@ -264,43 +286,103 @@ ivas_error ivas_ism_dec_config( if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) { /* select ISM format mode */ +#ifdef NCHAN_ISM_PARAMETER + st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->nchan_ism, ivas_total_brate ); + + st_ivas->nchan_transport = st_ivas->nchan_ism; +#else st_ivas->ism_mode = ivas_ism_mode_select( num_obj, ivas_total_brate ); st_ivas->nchan_transport = num_obj; +#endif if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - st_ivas->nchan_transport = 2; + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) { +#ifdef NCHAN_ISM_PARAMETER + st_ivas->hDecoderConfig->nchan_out = st_ivas->nchan_ism; +#else st_ivas->hDecoderConfig->nchan_out = num_obj; +#endif } } if ( st_ivas->ini_active_frame != 0 ) { /* ISM bit-rate switching */ +#ifndef DISCRETE_ISM_DTX_CNG if ( st_ivas->hDecoderConfig->last_ivas_total_brate != IVAS_SID_5k2 && st_ivas->hDecoderConfig->last_ivas_total_brate != FRAME_NO_DATA ) +#endif { if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { - ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, num_obj ); +#ifdef NCHAN_ISM_PARAMETER + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, num_obj ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } } } } } else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { +#ifdef DISCRETE_ISM_DTX_CNG +#ifdef NCHAN_ISM_PARAMETER + st_ivas->nchan_transport = st_ivas->nchan_ism; +#else + st_ivas->nchan_transport = num_obj; +#endif + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { +#ifdef NCHAN_ISM_PARAMETER + st_ivas->hDecoderConfig->nchan_out = st_ivas->nchan_ism; +#else + st_ivas->hDecoderConfig->nchan_out = num_obj; +#endif + } + } + + /* ISM mode switching */ + if ( st_ivas->ism_mode != last_ism_mode ) + { +#ifdef NCHAN_ISM_PARAMETER + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, num_obj ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } +#else if ( last_ism_mode == ISM_MODE_PARAM ) { nchan_transport_old = MAX_PARAM_ISM_WAVE; } else { +#ifdef NCHAN_ISM_PARAMETER + st_ivas->nchan_transport = st_ivas->nchan_ism; +#else st_ivas->nchan_transport = num_obj; +#endif } +#endif } +#ifdef NCHAN_ISM_PARAMETER + switch ( st_ivas->nchan_ism ) +#else switch ( num_obj ) +#endif { case 1: st_ivas->transport_config = AUDIO_CONFIG_ISM1; diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index b9d00792df2fca472c46ed04235568b6327aa8a6..ef52c082b7330adf6f3b478ca4f0d98f8ef314a1 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -51,19 +51,24 @@ static void ivas_ism_preprocessing( const int16_t sce_id /* i : SCE # identifier */ ) { +#ifndef DISCRETE_ISM_DTX_CNG int32_t ivas_total_brate; - SCE_DEC_HANDLE hSCE; +#endif Decoder_State *st; - hSCE = st_ivas->hSCE[sce_id]; - st = hSCE->hCoreCoder[0]; + st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; +#ifndef DISCRETE_ISM_DTX_CNG ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; if ( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) +#endif { - /* reset the bitstream to atleast read the cng type and bandwidth for non transmitted SCE */ + /* reset the bitstream to at least read the cng type and bandwidth for non transmitted SCE */ st->bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream; +#ifdef DISCRETE_ISM_DTX_CNG + st->next_bit_pos = 0; /* note: needed in paramISM -> discISM switching */ +#endif if ( sce_id == st_ivas->hISMDTX.sce_id_dtx ) { @@ -74,12 +79,14 @@ static void ivas_ism_preprocessing( st->read_sid_info = 0; /* do not read the sid info from bitstream but use the estimated noise */ } - st->cng_paramISM_flag = 1; + st->cng_ism_flag = 1; } +#ifndef DISCRETE_ISM_DTX_CNG else { - st->cng_paramISM_flag = 0; + st->cng_ism_flag = 0; } +#endif return; } @@ -96,74 +103,166 @@ ivas_error ivas_ism_dtx_dec( int16_t *nb_bits_metadata /* o : number of metadata bits */ ) { - int16_t ch, pos, num_obj, num_obj_prev; + int16_t ch, pos, nchan_ism, nchan_ism_prev; int32_t ivas_total_brate; +#ifdef DISCRETE_ISM_DTX_CNG + int16_t md_diff_flag[MAX_NUM_OBJECTS]; + int16_t idx, flag_noisy_speech, sce_id_dtx; + ISM_MODE last_ism_mode, ism_mode_bstr; + ivas_error error; +#endif ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; +#ifndef DISCRETE_ISM_DTX_CNG if ( st_ivas->nchan_transport == 1 ) { nb_bits_metadata[0] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; return IVAS_ERR_OK; } +#endif +#ifdef NCHAN_ISM_PARAMETER + nchan_ism_prev = st_ivas->nchan_ism; +#else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - num_obj_prev = st_ivas->hDirAC->hParamIsm->num_obj; + nchan_ism_prev = st_ivas->hDirAC->hParamIsm->num_obj; } else /* ism_mode == ISM_MODE_DISC */ { - num_obj_prev = st_ivas->nchan_transport; + nchan_ism_prev = st_ivas->nchan_transport; } +#endif - /* read number of objects */ if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { - num_obj = 1; + /* read number of objects */ + nchan_ism = 1; pos = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); - while ( get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ) == 1 && num_obj < MAX_NUM_OBJECTS ) + while ( get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ) == 1 && nchan_ism < MAX_NUM_OBJECTS ) { - ( num_obj )++; + ( nchan_ism )++; pos--; } +#ifdef NCHAN_ISM_PARAMETER + st_ivas->nchan_ism = nchan_ism; +#endif +#ifdef DISCRETE_ISM_DTX_CNG + pos--; +#endif - if ( num_obj != num_obj_prev ) + if ( nchan_ism != nchan_ism_prev ) { /* IVAS_fmToDo: more work needed when the number of transported objects is not constant */ return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); } - ivas_ism_dec_config( st_ivas, num_obj ); +#ifdef DISCRETE_ISM_DTX_CNG + last_ism_mode = st_ivas->ism_mode; + + /* read ism_mode */ + if ( nchan_ism > 2 ) + { + pos -= nchan_ism; /* SID metadata flags */ + + idx = get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ); + ism_mode_bstr = (ISM_MODE) ( idx + 1 ); + st_ivas->ism_mode = ism_mode_bstr; + } + +#ifdef NCHAN_ISM_PARAMETER + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nchan_ism ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#else +#ifdef NCHAN_ISM_PARAMETER + ivas_ism_dec_config( st_ivas ); +#else + ivas_ism_dec_config( st_ivas, nchan_ism ); +#endif if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - st_ivas->hDirAC->hParamIsm->num_obj = num_obj; +#ifdef NCHAN_ISM_PARAMETER + st_ivas->nchan_transport = 2; +#else + st_ivas->hDirAC->hParamIsm->num_obj = nchan_ism; +#endif } else /* ism_mode == ISM_MODE_DISC */ { - st_ivas->nchan_transport = num_obj; + st_ivas->nchan_transport = nchan_ism; } +#endif } else { - num_obj = num_obj_prev; + nchan_ism = nchan_ism_prev; } /* Metadata decoding and dequantization */ +#ifdef DISCRETE_ISM_DTX_CNG + 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 ); + + if ( ivas_total_brate == IVAS_SID_5k2 && !st_ivas->bfi ) + { + if ( st_ivas->hDirAC != NULL ) + { + st_ivas->hDirAC->hParamIsm->flag_noisy_speech = flag_noisy_speech; + } + + st_ivas->hISMDTX.sce_id_dtx = sce_id_dtx; + } +#else ivas_param_ism_metadata_dtx_dec( st_ivas ); +#endif - for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) +#ifdef DISCRETE_ISM_DTX_CNG + set_s( md_diff_flag, 1, nchan_ism ); + + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - nb_bits_metadata[ch] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + for ( ch = 0; ch < nchan_ism; ch++ ) + { + st_ivas->hDirAC->azimuth_values[ch] = st_ivas->hIsmMetaData[ch]->azimuth; + st_ivas->hDirAC->elevation_values[ch] = st_ivas->hIsmMetaData[ch]->elevation; + } } + update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag ); + + st_ivas->hISMDTX.ism_dtx_hangover_cnt = 0; +#endif + + if ( ivas_total_brate == IVAS_SID_5k2 && !st_ivas->bfi ) + { + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { +#ifdef DISCRETE_ISM_DTX_CNG + nb_bits_metadata[ch] = nb_bits_metadata[sce_id_dtx]; +#else + nb_bits_metadata[ch] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; +#endif + } + } + +#ifdef DISCRETE_ISM_DTX_CNG + if ( !st_ivas->bfi ) +#else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) +#endif { for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) { - ivas_ism_preprocessing( st_ivas, ch ); + ivas_ism_preprocessing( st_ivas, ch ); // VE: after the acceptance of switches, replace the function call by its content } } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 8c54602e9f7b022b080b7a5a73cf97108b89212e..99f94fa536100b377a11fa6c43b62a525a6a9eb9 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -37,6 +37,9 @@ #include "ivas_rom_com.h" #include "prot.h" #include "ivas_stat_enc.h" +#ifdef DISCRETE_ISM_DTX_CNG +#include +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -53,6 +56,86 @@ static void decode_angle_indices( DEC_CORE_HANDLE st0, ISM_METADATA_ANGLE_HANDLE static int16_t decode_radius( DEC_CORE_HANDLE st0, int16_t *last_radius_idx, int16_t *flag_abs_radius ); #endif +#ifdef DISCRETE_ISM_DTX_CNG +/*-------------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------------*/ + +#define IVAS_ISM_DTX_HO_MAX 5 + +#define CNG_MD_MAX_DIFF_AZIMUTH 5 +#define CNG_MD_MAX_DIFF_ELEVATION 5 + + +/*-------------------------------------------------------------------* + * ism_metadata_smooth() + * + * Smooth the metadata evolution + *-------------------------------------------------------------------*/ + +static void ism_metadata_smooth( + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + const int32_t ism_total_brate, /* i : ISms total bitrate */ + const int16_t nchan_ism /* i : number of objects */ +) +{ + ISM_METADATA_HANDLE hIsmMetaData; + int16_t ch; + float diff; + + for ( ch = 0; ch < nchan_ism; ch++ ) + { + hIsmMetaData = hIsmMeta[ch]; + + /* smooth azimuth */ + diff = hIsmMetaData->last_true_azimuth - hIsmMetaData->last_azimuth; + + if ( diff > ISM_AZIMUTH_MAX ) + { + diff -= ( ISM_AZIMUTH_MAX - ISM_AZIMUTH_MIN ); + hIsmMetaData->last_azimuth += ( ISM_AZIMUTH_MAX - ISM_AZIMUTH_MIN ); + } + else if ( diff < ISM_AZIMUTH_MIN ) + { + diff += ( ISM_AZIMUTH_MAX - ISM_AZIMUTH_MIN ); + } + + if ( ism_total_brate > IVAS_SID_5k2 && fabsf( diff ) > IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_AZIMUTH ) + { + /* skip the smoothing */ + } + else if ( fabsf( diff ) > CNG_MD_MAX_DIFF_AZIMUTH ) + { + hIsmMetaData->azimuth = hIsmMetaData->last_azimuth + sign( diff ) * CNG_MD_MAX_DIFF_AZIMUTH; + } + else if ( diff != 0 ) + { + hIsmMetaData->azimuth = hIsmMetaData->last_true_azimuth; + } + + if ( hIsmMetaData->azimuth > ISM_AZIMUTH_MAX ) + { + hIsmMetaData->azimuth -= ( ISM_AZIMUTH_MAX - ISM_AZIMUTH_MIN ); + } + + /* smooth elevation */ + diff = hIsmMetaData->last_true_elevation - hIsmMetaData->last_elevation; + + if ( ism_total_brate > IVAS_SID_5k2 && diff > IVAS_ISM_DTX_HO_MAX * CNG_MD_MAX_DIFF_ELEVATION ) + { + /* skip the smoothing */ + } + else if ( fabsf( diff ) > CNG_MD_MAX_DIFF_ELEVATION ) + { + hIsmMetaData->elevation = hIsmMetaData->last_elevation + sign( diff ) * CNG_MD_MAX_DIFF_ELEVATION; + } + } + + return; +} +#endif + + /*-------------------------------------------------------------------------* * ivas_ism_metadata_dec() * @@ -60,13 +143,19 @@ static int16_t decode_radius( DEC_CORE_HANDLE st0, int16_t *last_radius_idx, int *-------------------------------------------------------------------------*/ ivas_error ivas_ism_metadata_dec( - const int32_t ism_total_brate, /* i : ISM total bitrate */ - int16_t *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 int16_t bfi, /* i : bfi flag */ - int16_t nb_bits_metadata[], /* o : number of metadata bits */ - ISM_MODE ism_mode, /* i : ISM mode */ + const int32_t ism_total_brate, /* i : ISM total bitrate */ +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif + int16_t *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 int16_t bfi, /* i : bfi flag */ + int16_t nb_bits_metadata[], /* o : number of metadata bits */ + ISM_MODE ism_mode, /* i : ISM mode */ +#ifdef DISCRETE_ISM_DTX_CNG + ISM_DTX_DATA_DEC hISMDTX, /* i/o: ISM DTX structure */ +#endif const PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Config Handle */ ) { @@ -94,13 +183,19 @@ ivas_error ivas_ism_metadata_dec( int16_t nchan_transport_prev, ism_metadata_flag_global; int16_t localVAD[MAX_NUM_OBJECTS]; int16_t ism_imp[MAX_NUM_OBJECTS]; - int16_t num_obj = 0, nbands, nblocks; +#ifdef NCHAN_ISM_PARAMETER + int16_t nbands, nblocks; +#else + int16_t nchan_ism = 0, nbands, nblocks; +#endif +#ifdef DISCRETE_ISM_DTX_CNG + int16_t md_diff_flag[MAX_NUM_OBJECTS]; +#endif ivas_error error; - error = IVAS_ERR_OK; - push_wmops( "ism_meta_dec" ); +#ifndef DISCRETE_ISM_DTX_CNG if ( ism_total_brate == IVAS_SID_5k2 || ism_total_brate == FRAME_NO_DATA ) { /* no metadata decoding in CNG */ @@ -121,8 +216,9 @@ ivas_error ivas_ism_metadata_dec( #endif pop_wmops(); - return error; + return IVAS_ERR_OK; } +#endif /* initialization */ st0 = hSCE[0]->hCoreCoder[0]; @@ -151,22 +247,31 @@ ivas_error ivas_ism_metadata_dec( * Read ISM common signaling *----------------------------------------------------------------*/ +#ifdef NCHAN_ISM_PARAMETER + /* number of objects was read in ivas_dec_setup() */ + st0->next_bit_pos += nchan_ism; +#else /* read number of objects */ - num_obj = 1; - while ( get_next_indice( st0, 1 ) == 1 && num_obj < MAX_NUM_OBJECTS ) + nchan_ism = 1; + while ( get_next_indice( st0, 1 ) == 1 && nchan_ism < MAX_NUM_OBJECTS ) { - ( num_obj )++; + ( nchan_ism )++; } +#endif - ism_mode = ivas_ism_mode_select( num_obj, ism_total_brate ); + ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate ); if ( ism_mode == ISM_MODE_PARAM ) { - hParamIsm->num_obj = num_obj; +#ifdef NCHAN_ISM_PARAMETER + *nchan_transport = MAX_PARAM_ISM_WAVE; +#else + hParamIsm->num_obj = nchan_ism; +#endif } else if ( ism_mode == ISM_MODE_DISC ) { - *nchan_transport = num_obj; + *nchan_transport = nchan_ism; } if ( *nchan_transport != nchan_transport_prev ) @@ -200,7 +305,7 @@ ivas_error ivas_ism_metadata_dec( ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; } - for ( ; ch < num_obj; ch++ ) + for ( ; ch < nchan_ism; ch++ ) { hIsmMeta[ch]->ism_metadata_flag = 1; ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; @@ -233,7 +338,7 @@ ivas_error ivas_ism_metadata_dec( nb_bits_start = st0->next_bit_pos; } - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { hIsmMetaData = hIsmMeta[ch]; if ( ism_mode == ISM_MODE_DISC ) @@ -262,8 +367,8 @@ ivas_error ivas_ism_metadata_dec( } else /* ISM_MODE_DISC */ { - hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); - hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); /* radius/raw/pitch dequantization */ if ( ism_extended_metadata_flag ) @@ -272,8 +377,8 @@ ivas_error ivas_ism_metadata_dec( idx_azimuth = hIsmMetaData->angle[1].last_azimuth_idx; idx_elevation = hIsmMetaData->angle[1].last_elevation_idx; - hIsmMetaData->yaw = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); - hIsmMetaData->pitch = ism_dequant_meta( idx_elevation, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + hIsmMetaData->yaw = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->pitch = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); idx_radius = decode_radius( st0, &hIsmMetaData->last_radius_idx, &flag_abs_radius ); hIsmMetaData->radius = usdequant( idx_radius, ISM_RADIUS_MIN, ISM_RADIUS_DELTA ); @@ -360,7 +465,7 @@ ivas_error ivas_ism_metadata_dec( } else /* ISM_MODE_DISC */ { - hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); } /*----------------------------------------------------------------* @@ -422,7 +527,7 @@ ivas_error ivas_ism_metadata_dec( } else /* ISM_MODE_DISC */ { - hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); } /*----------------------------------------------------------------* @@ -432,6 +537,11 @@ ivas_error ivas_ism_metadata_dec( /* updates */ hIsmMetaData->last_azimuth_idx = idx_azimuth; hIsmMetaData->last_elevation_idx = idx_elevation; +#endif +#ifdef DISCRETE_ISM_DTX_CNG + /* save for smoothing metadata evolution */ + hIsmMetaData->last_true_azimuth = hIsmMetaData->azimuth; + hIsmMetaData->last_true_elevation = hIsmMetaData->elevation; #endif } @@ -496,24 +606,25 @@ ivas_error ivas_ism_metadata_dec( else /* BFI */ { #ifdef FIX_380_BFI_PARAMISM - /* "num_obj", "hIsmMeta->azimuth" and "hIsmMeta->elevation" are recycled from the last frame */ +#ifndef NCHAN_ISM_PARAMETER + /* "nchan_ism", "hIsmMeta->azimuth" and "hIsmMeta->elevation" are recycled from the last frame */ if ( ism_mode == ISM_MODE_PARAM ) { - num_obj = hParamIsm->num_obj; + nchan_ism = hParamIsm->num_obj; } else if ( ism_mode == ISM_MODE_DISC ) { - num_obj = *nchan_transport; + nchan_ism = *nchan_transport; } - - for ( ch = 0; ch < num_obj; ch++ ) +#endif + for ( ch = 0; ch < nchan_ism; ch++ ) #else /* "*nISms", "hIsmMeta->azimuth" and "hIsmMeta->elevation" are recycled from the last frame */ for ( ch = 0; ch < *nchan_transport; ch++ ) { hIsmMeta[ch]->ism_metadata_flag = hIsmMeta[ch]->last_ism_metadata_flag; } - for ( ; ch < num_obj; ch++ ) + for ( ; ch < nchan_ism; ch++ ) #endif { hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; @@ -523,7 +634,7 @@ ivas_error ivas_ism_metadata_dec( if ( ism_mode == ISM_MODE_PARAM ) { - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { #ifdef FIX_380_BFI_PARAMISM hParamIsm->azi_index[ch] = hParamIsm->azi_index[ch] + hParamIsm->last_az_sgn[ch] * hParamIsm->last_az_diff[ch]; @@ -547,13 +658,21 @@ ivas_error ivas_ism_metadata_dec( } } +#ifdef DISCRETE_ISM_DTX_CNG + if ( hISMDTX.ism_dtx_hangover_cnt < IVAS_ISM_DTX_HO_MAX ) + { + ism_metadata_smooth( hIsmMeta, ism_total_brate, nchan_ism ); + hISMDTX.ism_dtx_hangover_cnt += 1; + } +#endif + /*----------------------------------------------------------------* * Configuration and decision about bitrates per channel *----------------------------------------------------------------*/ if ( !bfi ) { - if ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, num_obj, hIsmMeta, localVAD, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, localVAD, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK ) { return error; } @@ -575,7 +694,7 @@ ivas_error ivas_ism_metadata_dec( hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch]; } - for ( ; ch < num_obj; ch++ ) + for ( ; ch < nchan_ism; ch++ ) { hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; } @@ -589,6 +708,10 @@ ivas_error ivas_ism_metadata_dec( } } + /*----------------------------------------------------------------* + * Set bitsream pointers + *----------------------------------------------------------------*/ + /* set the bitstream pointer to its original position */ st0->bit_stream = bstr_orig; st0->next_bit_pos = next_bit_pos_orig; @@ -599,14 +722,24 @@ ivas_error ivas_ism_metadata_dec( hSCE[ch]->hCoreCoder[0]->bit_stream = hSCE[ch - 1]->hCoreCoder[0]->bit_stream + ( hSCE[ch - 1]->hCoreCoder[0]->total_brate / FRAMES_PER_SEC ); } +#ifdef DISCRETE_ISM_DTX_CNG + /*----------------------------------------------------------------* + * Updates + *----------------------------------------------------------------*/ + + set_s( md_diff_flag, 1, nchan_ism ); + + update_last_metadata( nchan_ism, hIsmMeta, md_diff_flag ); +#endif + for ( ch = 0; ch < *nchan_transport; ch++ ) { - hSCE[ch]->hCoreCoder[0]->cng_paramISM_flag = 0; + hSCE[ch]->hCoreCoder[0]->cng_ism_flag = 0; } pop_wmops(); - return error; + return IVAS_ERR_OK; } @@ -645,6 +778,11 @@ ivas_error ivas_ism_metadata_dec_create( st_ivas->hIsmMetaData[ch]->last_elevation_idx = 1 << ( ISM_ELEVATION_NBITS - 1 ); #endif +#ifdef DISCRETE_ISM_DTX_CNG + st_ivas->hIsmMetaData[ch]->last_true_azimuth = 0; + st_ivas->hIsmMetaData[ch]->last_true_elevation = 0; +#endif + ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); } @@ -653,6 +791,10 @@ ivas_error ivas_ism_metadata_dec_create( return error; } +#ifdef DISCRETE_ISM_DTX_CNG + st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX; +#endif + return IVAS_ERR_OK; } @@ -872,3 +1014,191 @@ static int16_t decode_radius( return idx_radius; } #endif + + +#ifdef DISCRETE_ISM_DTX_CNG +/*-------------------------------------------------------------------* + * ivas_ism_metadata_sid_dec() + * + * Decode ISM metadata in SID frame + *-------------------------------------------------------------------*/ + +void ivas_ism_metadata_sid_dec( + SCE_DEC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int32_t ism_total_brate, /* i : ISms total bitrate */ + const int16_t bfi, /* i : bfi 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 */ + int16_t *flag_noisy_speech, /* o : noisy speech flag */ + int16_t *sce_id_dtx, /* o : SCE DTX ID */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + int16_t nb_bits_metadata[] /* o : number of metadata bits */ +) +{ + int16_t i, ch, last_bit_pos; + float q_step, q_step_border; + int16_t idx, idx_azimuth, idx_elevation; + int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id; + int16_t md_diff_flag[MAX_NUM_OBJECTS]; + ISM_MODE ism_mode_bstr; + DEC_CORE_HANDLE st0; + ISM_METADATA_HANDLE hIsmMetaData; + int16_t next_bit_pos_orig; + uint16_t bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig; + + if ( ism_total_brate == FRAME_NO_DATA ) + { + ism_metadata_smooth( hIsmMeta, ism_total_brate, nchan_ism ); + + return; + } + + /* initialization */ + st0 = hSCE[0]->hCoreCoder[0]; + + last_bit_pos = (int16_t) ( ( 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_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( st0, 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 + *----------------------------------------------------------------*/ + + *flag_noisy_speech = 0; + *sce_id_dtx = 0; + + /* write ISM mode flag to explicitly signal number of spatial parameters */ + if ( nchan_ism > 2 ) + { + idx = get_next_indice( 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( st0, 1 ); + nBits_sce_id = 1; + } + } + + if ( nchan_transport > 1 ) + { + /* read sce id */ + *sce_id_dtx = get_next_indice( 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 = 1.0f; + continue; + } + + idx = get_next_indice( st0, nBits_coh ); + hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = (float) ( idx ) / (float) ( ( 1 << nBits_coh ) - 1 ); + } + } + else + { + *sce_id_dtx = 0; + } + + if ( ism_mode == ISM_MODE_PARAM ) + { + hSCE[*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = hSCE[!*sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence; + } + + /*----------------------------------------------------------------* + * 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( st0, nBits_azimuth ); + hIsmMetaData->azimuth = ism_dequant_meta( idx_azimuth, ism_azimuth_borders, q_step, q_step_border, 1 << nBits_azimuth ); + + /* Elevation decoding */ + idx_elevation = get_next_indice( st0, nBits_elevation ); + hIsmMetaData->elevation = ism_dequant_meta( idx_elevation, ism_elevation_borders, q_step, q_step_border, 1 << nBits_elevation ); + + /* update last indexes to correspond to active frames coding */ + if ( nBits_azimuth > ISM_AZIMUTH_NBITS ) + { +#ifdef TD5 + hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->angle[0].last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#else + hIsmMetaData->last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#endif + } + else + { +#ifdef TD5 + hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->angle[0].last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#else + hIsmMetaData->last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#endif + } + + /* save for smoothing metadata evolution */ + hIsmMetaData->last_true_azimuth = hIsmMetaData->azimuth; + hIsmMetaData->last_true_elevation = hIsmMetaData->elevation; + } + } + + /* 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( hIsmMeta, ism_total_brate, nchan_ism ); + + return; +} +#endif diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index acf62ba1a718f259da0e54fa256a0880e8a387f9..f66323d8a4f038b0a054d6678302cc758603f7cd 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -51,6 +51,10 @@ static void ivas_param_ism_dec_dequant_DOA( DIRAC_DEC_HANDLE hDirAC /* i/o: decoder DirAC handle */ +#ifdef NCHAN_ISM_PARAMETER + , + const int16_t nchan_ism /* i : number of ISM channels */ +#endif ) { int16_t i; @@ -58,13 +62,21 @@ static void ivas_param_ism_dec_dequant_DOA( hParamIsm = hDirAC->hParamIsm; +#ifdef NCHAN_ISM_PARAMETER + assert( nchan_ism <= MAX_NUM_OBJECTS ); +#else assert( hParamIsm->num_obj <= MAX_NUM_OBJECTS ); +#endif /* Get the azimuth and elevation values */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < hParamIsm->num_obj; i++ ) +#endif { - hDirAC->azimuth_values[i] = ism_dequant_meta( hParamIsm->azi_index[i], ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); - hDirAC->elevation_values[i] = ism_dequant_meta( hParamIsm->ele_index[i], ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + hDirAC->azimuth_values[i] = ism_dequant_meta( hParamIsm->azi_index[i], ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + hDirAC->elevation_values[i] = ism_dequant_meta( hParamIsm->ele_index[i], ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); } return; @@ -157,6 +169,9 @@ static void ivas_ism_get_proto_matrix( static void ivas_param_ism_compute_mixing_matrix( +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ ISM_DTX_DATA_DEC hISMDTX, /* i : ISM DTX handle */ float Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], @@ -183,12 +198,20 @@ static void ivas_param_ism_compute_mixing_matrix( proto_matrix = hDirAC->hParamIsmRendering->proto_matrix; +#ifdef NCHAN_ISM_PARAMETER + assert( ( nchan_ism == 3 ) || ( nchan_ism == 4 ) ); +#else assert( ( hDirAC->hParamIsm->num_obj == 3 ) || ( hDirAC->hParamIsm->num_obj == 4 ) ); +#endif assert( nchan_transport == 2 ); if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) { +#ifdef NCHAN_ISM_PARAMETER + num_wave = nchan_ism; +#else num_wave = hDirAC->hParamIsm->num_obj; +#endif } else { @@ -249,7 +272,11 @@ static void ivas_param_ism_compute_mixing_matrix( { if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) { +#ifdef NCHAN_ISM_PARAMETER + direct_power[w] = ( 1.0f / nchan_ism ) * ref_power; +#else direct_power[w] = ( 1.0f / hDirAC->hParamIsm->num_obj ) * ref_power; +#endif } else { @@ -395,7 +422,9 @@ ivas_error ivas_param_ism_dec_open( IVAS_OUTPUT_SETUP hOutSetup; AUDIO_CONFIG output_config; int32_t output_Fs; +#ifndef NCHAN_ISM_PARAMETER int16_t nchan_out; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -424,6 +453,10 @@ ivas_error ivas_param_ism_dec_open( output_Fs = st_ivas->hDecoderConfig->output_Fs; output_config = st_ivas->hDecoderConfig->output_config; +#ifdef NCHAN_ISM_PARAMETER + + ivas_param_ism_config( hDirAC->hParamIsm, st_ivas->nchan_ism ); +#else nchan_out = st_ivas->hDecoderConfig->nchan_out; if ( output_config == AUDIO_CONFIG_EXTERNAL ) @@ -435,6 +468,7 @@ ivas_error ivas_param_ism_dec_open( hDirAC->hParamIsm->num_obj = MAX_NUM_OBJECTS; } ivas_param_ism_config( hDirAC->hParamIsm ); +#endif /*-----------------------------------------------------------------* * set input parameters @@ -466,7 +500,11 @@ ivas_error ivas_param_ism_dec_open( if ( output_config == AUDIO_CONFIG_EXTERNAL ) { /* nchan_out is essential for memory initialization for CLDFB Synthesis */ +#ifdef NCHAN_ISM_PARAMETER + st_ivas->hIntSetup.nchan_out_woLFE = st_ivas->nchan_ism; +#else st_ivas->hIntSetup.nchan_out_woLFE = hDirAC->hParamIsm->num_obj; +#endif st_ivas->hIntSetup.is_loudspeaker_setup = 1; } @@ -837,7 +875,11 @@ void ivas_param_ism_dec( nchan_transport = st_ivas->nchan_transport; if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) { +#ifdef NCHAN_ISM_PARAMETER + nchan_out = st_ivas->nchan_ism; +#else nchan_out = st_ivas->hDirAC->hParamIsm->num_obj; +#endif nchan_out_woLFE = nchan_out; st_ivas->hDecoderConfig->nchan_out = nchan_out; } @@ -857,7 +899,11 @@ void ivas_param_ism_dec( /* De-quantization */ if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) { +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_dec_dequant_DOA( hDirAC, st_ivas->nchan_ism ); +#else ivas_param_ism_dec_dequant_DOA( hDirAC ); +#endif ivas_param_ism_dec_dequant_powrat( hDirAC ); st_ivas->hISMDTX.dtx_flag = 0; } @@ -869,7 +915,11 @@ void ivas_param_ism_dec( /* obtain the direct response using EFAP */ if ( !( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) ) { +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < st_ivas->nchan_ism; i++ ) +#else for ( i = 0; i < hDirAC->hParamIsm->num_obj; i++ ) +#endif { efap_determine_gains( st_ivas->hEFAPdata, direct_response[i], hDirAC->azimuth_values[i], hDirAC->elevation_values[i], EFAP_MODE_EFAP ); } @@ -878,7 +928,11 @@ void ivas_param_ism_dec( { int16_t j; +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < st_ivas->nchan_ism; i++ ) +#else for ( i = 0; i < hDirAC->hParamIsm->num_obj; i++ ) +#endif { for ( j = 0; j < nchan_out_woLFE; j++ ) { @@ -927,7 +981,11 @@ void ivas_param_ism_dec( } /* Compute mixing matrix */ +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, direct_response, nchan_transport, nchan_out_woLFE, 0, CLDFB_NO_COL_MAX, mixing_matrix ); +#else ivas_param_ism_compute_mixing_matrix( hDirAC, st_ivas->hISMDTX, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, direct_response, nchan_transport, nchan_out_woLFE, 0, CLDFB_NO_COL_MAX, mixing_matrix ); +#endif /* subframe loop for synthesis*/ for ( subframe_idx = 0; subframe_idx < hDirAC->nb_subframes; subframe_idx++ ) @@ -996,7 +1054,11 @@ void ivas_param_ism_dec( ivas_param_ism_update_mixing_matrix( hDirAC, mixing_matrix, nchan_transport, nchan_out_woLFE ); /* store MetaData parameters */ +#ifdef NCHAN_ISM_PARAMETER + for ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) +#else for ( ch = 0; ch < hDirAC->hParamIsm->num_obj; ch++ ) +#endif { if ( st_ivas->hDirAC->azimuth_values[ch] > 180.0f ) { @@ -1042,7 +1104,11 @@ void ivas_param_ism_params_to_masa_param_mapping( if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) { +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_dec_dequant_DOA( hDirAC, st_ivas->nchan_ism ); +#else ivas_param_ism_dec_dequant_DOA( hDirAC ); +#endif ivas_param_ism_dec_dequant_powrat( hDirAC ); st_ivas->hISMDTX.dtx_flag = 0; } @@ -1051,7 +1117,11 @@ void ivas_param_ism_params_to_masa_param_mapping( st_ivas->hISMDTX.dtx_flag = 1; } +#ifdef NCHAN_ISM_PARAMETER + if ( st_ivas->nchan_ism > 1 ) +#else if ( hDirAC->hParamIsm->num_obj > 1 ) +#endif { if ( st_ivas->hISMDTX.dtx_flag ) { @@ -1136,7 +1206,7 @@ void ivas_param_ism_params_to_masa_param_mapping( return; } - +#ifndef DISCRETE_ISM_DTX_CNG static void ivas_param_ism_dec_dequantize_DOA_dtx( int16_t azi_bits, int16_t ele_bits, @@ -1234,7 +1304,11 @@ void ivas_param_ism_metadata_dtx_dec( /* number of objects was already read in ivas_ism_get_dtx_dec() */ /* update the position in the bitstream */ +#ifdef NCHAN_ISM_PARAMETER + st0->next_bit_pos += st_ivas->nchan_ism; +#else st0->next_bit_pos += hParamIsm->num_obj; +#endif /* read sce id */ st_ivas->hISMDTX.sce_id_dtx = get_next_indice( st0, 1 ); @@ -1248,7 +1322,11 @@ void ivas_param_ism_metadata_dtx_dec( st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence; /* get the DOA'S */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < st_ivas->nchan_ism; i++ ) +#else for ( i = 0; i < hParamIsm->num_obj; i++ ) +#endif { /* read from bitstream and dequantize */ azi_idx = get_next_indice( st0, PARAM_ISM_DTX_AZI_BITS ); @@ -1267,3 +1345,4 @@ void ivas_param_ism_metadata_dtx_dec( return; } +#endif diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index a965a0ffed38a43b5e3472da691aae20348293ff..a5bdcc410046ad9acd629d86862610ac3b39714c 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -107,11 +107,15 @@ void ivas_ism_render( float tmp_output_f[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float gains[MAX_NUM_OBJECTS][MAX_OUTPUT_CHANNELS]; float g1, g2; - int16_t num_objects, nchan_out_woLFE, lfe_index; + int16_t nchan_ism, nchan_out_woLFE, lfe_index; int16_t azimuth, elevation; float Rmat[3][3]; - num_objects = st_ivas->nchan_transport; +#ifdef NCHAN_ISM_PARAMETER + nchan_ism = st_ivas->nchan_ism; +#else + nchan_ism = st_ivas->nchan_transport; +#endif nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; lfe_index = 0; @@ -121,7 +125,7 @@ void ivas_ism_render( set_f( tmp_output_f[j], 0.0f, output_frame ); } - for ( i = 0; i < num_objects; i++ ) + for ( i = 0; i < nchan_ism; i++ ) { mvr2r( output_f[i], input_f[i], output_frame ); } @@ -137,7 +141,7 @@ void ivas_ism_render( QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[st_ivas->hHeadTrackData->num_quaternions++], Rmat ); } - for ( i = 0; i < num_objects; i++ ) + for ( i = 0; i < nchan_ism; i++ ) { if ( st_ivas->intern_config == AUDIO_CONFIG_STEREO ) { diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index bd799f9d5fbff0499d68a83b4c26734f0a779ab9..a80986b39e7a41caf4b8a0844ac63951e90517a0 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -282,7 +282,7 @@ void ivas_ism2sba( float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t num_objects, /* i : number of objects */ + const int16_t nchan_ism, /* i : number of objects */ const int16_t output_frame, /* i : output frame length per channel */ const int16_t sba_order /* i : Ambisonic (SBA) order */ ) @@ -304,7 +304,7 @@ void ivas_ism2sba( set_zero( buffer_tmp[j], output_frame ); } - for ( i = 0; i < num_objects; i++ ) + for ( i = 0; i < nchan_ism; i++ ) { // TODO tmu review when #215 is resolved azimuth = (int16_t) floorf( hIsmMetaData[i]->azimuth + 0.5f ); diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 87a76599929caa2a2b2e9dbd5a7ab5acc00c24ab..5c06b4b49deb82d60934535de0006e7cfb3c03cb 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -77,9 +77,13 @@ ivas_error ivas_sce_dec( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; +#ifdef DISCRETE_ISM_DTX_CNG + if ( st_ivas->ivas_format == ISM_FORMAT ) +#else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) +#endif { - st->cng_type = FD_CNG; /* TODO: move to init if possible */ + st->cng_type = FD_CNG; } /*------------------------------------------------------------------* @@ -96,6 +100,12 @@ ivas_error ivas_sce_dec( { st->total_brate = ivas_total_brate; } +#ifdef DISCRETE_ISM_DTX_CNG + else if ( !st_ivas->bfi && st_ivas->ivas_format != ISM_FORMAT && last_ivas_total_brate <= IVAS_SID_5k2 ) + { + st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; + } +#else else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_5k2 ) ) { /* check if this is indeed needed? */ @@ -104,6 +114,7 @@ ivas_error ivas_sce_dec( st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; } } +#endif /* read the bandwidth */ if ( st_ivas->bfi || st->total_brate <= SID_2k40 ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index d8c0f65349f6d52e2b9f414659ba3a82338b036f..ab95c31b5e249606f4eb9cbe21d65e8521281069 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -391,6 +391,10 @@ typedef struct int16_t dtx_flag; int16_t sce_id_dtx; +#ifdef DISCRETE_ISM_DTX_CNG + int16_t ism_dtx_hangover_cnt; /* hangover counter for ISM DTX decoder */ +#endif + } ISM_DTX_DATA_DEC; /*----------------------------------------------------------------------------------* @@ -1211,6 +1215,9 @@ typedef struct Decoder_Struct LFE_DEC_HANDLE hLFE; /* LFE handle */ ISM_MODE ism_mode; /* ISM format mode */ +#ifdef NCHAN_ISM_PARAMETER + int16_t nchan_ism; /* number of ISM channels */ +#endif SBA_MODE sba_mode; /* SBA format mode */ MC_MODE mc_mode; /* MC format mode */ int16_t sba_order; /* Ambisonic (SBA) order */ diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index fc3e1db99d6d48b7d9f215d1b79b15339ea419eb..56059bd29dd020e1faea2125800610efa3300747 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -150,19 +150,22 @@ void stereo_tcx_init_dec( *-------------------------------------------------------------------*/ void stereo_tcx_core_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const FRAME_MODE frameMode, /* i : Decoder frame mode */ - float *signal_out, /* o : synthesis @internal_Fs */ - float *signal_outFB, /* o : synthesis @output_Fs */ - float pitch_buf[], /* o : floating pitch for each subframe */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ - const int16_t last_element_mode, /* i : last element mode */ - const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ - STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ - const int16_t nchan_out, /* i : number of output channels */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM)*/ + Decoder_State *st, /* i/o: decoder state structure */ + const FRAME_MODE frameMode, /* i : Decoder frame mode */ + float *signal_out, /* o : synthesis @internal_Fs */ + float *signal_outFB, /* o : synthesis @output_Fs */ + float pitch_buf[], /* o : floating pitch for each subframe */ + const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */ + const int16_t last_element_mode, /* i : last element mode */ + const int16_t flag_sec_CNA, /* i : CNA flag for secondary channel */ + STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */ + const int16_t nchan_out, /* i : number of output channels */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ +#ifndef DISCRETE_ISM_DTX_CNG + , + const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM)*/ +#endif ) { int16_t i, k; @@ -726,7 +729,11 @@ void stereo_tcx_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { +#ifndef DISCRETE_ISM_DTX_CNG if ( ivas_format == ISM_FORMAT && ism_mode == ISM_MODE_PARAM ) +#else + if ( ivas_format == ISM_FORMAT ) +#endif { float buffer[L_FRAME16k]; lerp( signal_outFB, buffer, st->L_frame, hTcxDec->L_frameTCX ); diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 9ba901352c2af44ebc5a816c044e8a25158cb38a..1a82d45587c8cd0ff656a4342d75b2a54735e592 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1345,8 +1345,11 @@ typedef struct Decoder_State /* MCT Channel mode indication: LFE, ignore channel? */ MCT_CHAN_MODE mct_chan_mode; - int16_t cng_paramISM_flag; /* CNG in Param-ISM flag */ - int16_t read_sid_info; /* For ParamISM, use the transmitted noise */ + int16_t cng_ism_flag; /* CNG in Param-ISM flag */ + int16_t read_sid_info; /* For ParamISM, use the transmitted noise */ +#ifdef DISCRETE_ISM_DTX_CNG + int16_t is_ism_format; /* Indication whether the codec operates in ISM format */ +#endif } Decoder_State, *DEC_CORE_HANDLE; diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index d3cc3f1743d561936a31b3a12961f1997d06c9a9..16b1cf0c29146414b805a25703a2cd90559e8936 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -463,7 +463,11 @@ ivas_error init_encoder( * LP-CNG *-----------------------------------------------------------------*/ +#ifdef DISCRETE_ISM_DTX_CNG + if ( ( ( idchan == 0 && st->Opt_DTX_ON && st->element_mode != IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && !( ism_mode == ISM_MODE_PARAM || ism_mode == ISM_MODE_DISC ) ) +#else if ( ( ( idchan == 0 && st->Opt_DTX_ON && st->element_mode != IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) && !( ism_mode == ISM_MODE_PARAM ) ) +#endif { if ( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) { diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index e53033ab98546480c4d75cce2b2a898d208dbf81..002e499f4b253c171c1201ec130527c304db90e7 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -448,6 +448,8 @@ ivas_error ivas_core_enc( dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "sp_aud_decision1", n, id, ENC ) ); dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "sp_aud_decision2", n, id, ENC ) ); + dbgwrite( &st->lp_noise, sizeof( float ), 1, input_frame, fname( debug_dir, "lp_noise", n, id, ENC ) ); + #if ( defined DEBUG_MODE_ACELP ) || ( defined DEBUG_MODE_TCX ) if ( st->coder_type == INACTIVE || st->coder_type == UNVOICED ) { diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 83161e761f3de331b9bc05df570077d5134eb721..dfaa321605d550937e2f1b10a5389479a40037c1 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -431,7 +431,11 @@ ivas_error ivas_init_encoder( } } +#ifdef DISCRETE_ISM_DTX_CNG + if ( st_ivas->hEncoderConfig->Opt_DTX_ON ) +#else if ( st_ivas->hEncoderConfig->Opt_DTX_ON && st_ivas->ism_mode == ISM_MODE_PARAM ) +#endif { if ( ( error = ivas_ism_dtx_open( st_ivas ) ) != IVAS_ERR_OK ) { diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c index fe358f6c90815691223046ce81053b5b023dfe66..3839a42a9df8518f01561990ac87dadefe70696f 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -42,6 +42,16 @@ #include "wmc_auto.h" +#ifdef DISCRETE_ISM_DTX_CNG +/*-----------------------------------------------------------------------* + * Local constants + *-----------------------------------------------------------------------*/ + +#define MD_MAX_DIFF_AZIMUTH 10 +#define MD_MAX_DIFF_ELEVATION 10 +#endif + + /*-------------------------------------------------------------------* * ivas_ism_dtx_open() * @@ -66,8 +76,11 @@ ivas_error ivas_ism_dtx_open( hISMDTX->dtx_flag = 0; hISMDTX->sce_id_dtx = 0; - +#ifdef DISCRETE_ISM_DTX_CNG + hISMDTX->cnt_SID_ISM = -1; +#else set_s( hISMDTX->dtx_speech_buffer_enc, 0, PARAM_ISM_HYS_BUF_SIZE ); +#endif for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { @@ -82,6 +95,209 @@ ivas_error ivas_ism_dtx_open( } +#ifdef DISCRETE_ISM_DTX_CNG +/*-------------------------------------------------------------------* + * ivas_ism_get_dtx_enc() + * + * Analysis and decision about DTX in ISM format + *-------------------------------------------------------------------*/ + +/*! r: indication of DTX frame */ +int16_t ivas_ism_dtx_enc( + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + SCE_ENC_HANDLE hSCE[MAX_SCE], /* i/o: SCE encoder structure */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism, /* i : number of objects */ + const int16_t nchan_transport, /* i : number of transport channels */ + int16_t vad_flag[MAX_NUM_OBJECTS], /* i : VAD flag */ + ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */ + int16_t md_diff_flag[], /* o : metadata differential flag */ + int16_t *sid_flag /* o : indication of SID frame */ +) +{ + int16_t ch, dtx_flag; + int16_t nBits, nBits_MD_max; + int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id; + float lp_noise[MAX_NUM_OBJECTS], lp_noise_variation, lp_noise_mean; + float lp_noise_max; + float tmp1, tmp2; + + /* initialization */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0; + } + + /*------------------------------------------------------------------* + * compute global ISM DTX flag + *-----------------------------------------------------------------*/ + + /* compute global ISM based on localVAD */ + dtx_flag = 1; + for ( ch = 0; ch < nchan_transport; ch++ ) + { + dtx_flag &= !vad_flag[ch]; + } + + /* compute global ISM based on long-term background noise */ + /* one of the channels is active -> no DTX */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + lp_noise[ch] = hSCE[ch]->hCoreCoder[0]->lp_noise; + } + + lp_noise_variation = var( lp_noise, nchan_transport ); + lp_noise_mean = mean( lp_noise, nchan_transport ); + + if ( lp_noise_mean > 50 || ( lp_noise_mean > 25 && lp_noise_variation > 32 ) ) + { + dtx_flag = 0; + } + + + /* default DTX is applied at lower bitrates; otherwise DTX is applied only in silence */ + maximum( lp_noise, nchan_transport, &lp_noise_max ); + + if ( !( ( nchan_ism == 1 && ivas_total_brate <= IVAS_24k4 ) || + ( nchan_ism == 2 && ivas_total_brate <= IVAS_48k ) || + ( nchan_ism == 3 && ivas_total_brate <= IVAS_80k ) || + ( nchan_ism == 4 && ivas_total_brate <= IVAS_96k ) || + lp_noise_max < 15 ) ) + { + dtx_flag = 0; + } + + /*------------------------------------------------------------------* + * Reset the bitstream + *-----------------------------------------------------------------*/ + + if ( dtx_flag ) + { + /* reset the bitstream (IVAS format signaling was already written) */ + reset_indices_enc( hSCE[0]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES ); + } + + /*------------------------------------------------------------------* + * decide about SID metadata to be sent or not (per object) + * estimate the MD bit-budget consumption + *-----------------------------------------------------------------*/ + + if ( dtx_flag ) + { + ivas_get_ism_sid_quan_bitbudget( nchan_ism, &nBits_azimuth, &nBits_elevation, &tmp1, &tmp2, &nBits_coh, &nBits_sce_id ); + + nBits = 0; + for ( ch = 0; ch < nchan_ism; ch++ ) + { + /* check difference between current and last metadata */ + md_diff_flag[ch] = 0; + if ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_azimuth ) > MD_MAX_DIFF_AZIMUTH ) + { + md_diff_flag[ch] = 1; + } + + if ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_elevation ) > MD_MAX_DIFF_ELEVATION ) + { + md_diff_flag[ch] = 1; + } + + /* estimate SID metadata bit-budget */ + nBits++; /* number of objects */ + nBits++; /* SID metadata flag */ + if ( md_diff_flag[ch] == 1 ) + { + nBits += nBits_azimuth; + nBits += nBits_elevation; + } + } + + /* calculate maximum available MD bit-budget */ + nBits_MD_max = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + nBits_MD_max -= SID_FORMAT_NBITS; + if ( nchan_transport > 1 ) + { + nBits_MD_max -= nBits_sce_id; + } + + for ( ch = 0; ch < nchan_transport - 1; ch++ ) + { + nBits_MD_max -= nBits_coh; /* coherence */ + } + + if ( nchan_ism > 3 ) + { + nBits_MD_max--; /* ism_mode flag */ + } + + /* too many metadata bits -> switch to active coding */ + if ( nBits > nBits_MD_max ) + { + dtx_flag = 0; + } + } + + /*------------------------------------------------------------------* + * set core_brate for all channels + * get 'sid_flag' value + *-----------------------------------------------------------------*/ + + *sid_flag = 0; + + if ( !dtx_flag ) + { + /* at least one of the channels is active -> no DTX */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->core_brate = -1; + set_bw( IVAS_SCE, hSCE[ch]->element_brate, hSCE[ch]->hCoreCoder[0], MODE1 ); + } + + hISMDTX->cnt_SID_ISM = -1; + + /* IVAS format signaling was erased in dtx() */ + if ( hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot == 0 ) + { + /* replicate ivas_write_format() */ + push_indice( hSCE[0]->hCoreCoder[0]->hBstr, IND_IVAS_FORMAT, 2 /* == ISM format */, IVAS_FORMAT_SIGNALING_NBITS ); + } + } + else /* ism_dtx_flag == 1 */ + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->cng_type = FD_CNG; + } + + /* * update the global SID counter */ + hISMDTX->cnt_SID_ISM++; + if ( hISMDTX->cnt_SID_ISM >= hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID ) + { + /* adaptive SID update interval */ + hSCE[0]->hCoreCoder[0]->hDtxEnc->max_SID = hSCE[0]->hCoreCoder[0]->hDtxEnc->interval_SID; + hISMDTX->cnt_SID_ISM = 0; + } + + /* encode SID in one channel only */ + for ( ch = 0; ch < nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->core_brate = FRAME_NO_DATA; + } + + if ( hISMDTX->cnt_SID_ISM == 0 ) + { + hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate = SID_2k40; + *sid_flag = 1; + } + } + + if ( dtx_flag == 1 && *sid_flag == 0 ) + { + set_s( md_diff_flag, 0, nchan_transport ); + } + + return dtx_flag; +} +#else /*-------------------------------------------------------------------* * ivas_ism_dtx_enc() * @@ -216,7 +432,7 @@ int16_t ivas_ism_dtx_enc( return dtx_flag; } - +#endif /*-------------------------------------------------------------------* * ivas_ism_get_sce_id_dtx() @@ -288,7 +504,11 @@ void ivas_ism_coh_estim_dtx_enc( { Encoder_State *st, *st_id0; int16_t sce_id, i; +#ifdef DISCRETE_ISM_DTX_CNG + float acorr_ene[MAX_NUM_OBJECTS], xcorr_ene; +#else float acorr_ene[PARAM_ISM_MAX_DMX], xcorr_ene; +#endif if ( nchan_transport == 1 ) { diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index ead873af0c148e40a814a06861c9133b3f6fec1c..25ce78ff2e2b9e7f4351bc3889546dc682dd7d9e 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -85,8 +85,17 @@ ivas_error ivas_ism_enc( float Etot_LR[1]; /* total energy; correlation shift */ float lf_E[1][2 * VOIC_BINS]; /* per bin spectrum energy in lf */ int16_t localVAD_HE_SAD[1]; /* local HE VAD */ +#ifdef DISCRETE_ISM_DTX_CNG + int16_t nchan_ism, dtx_flag, sid_flag, flag_noisy_speech; + int16_t md_diff_flag[MAX_NUM_OBJECTS]; +#else +#ifdef NCHAN_ISM_PARAMETER + int16_t nchan_ism, dtx_flag, sid_flag; +#else + int16_t dtx_flag, sid_flag, flag_noisy_speech; +#endif int16_t i, nBits; - int16_t dtx_flag, sid_flag; +#endif ivas_error error; push_wmops( "ivas_ism_enc" ); @@ -99,6 +108,25 @@ ivas_error ivas_ism_enc( dtx_flag = 0; sid_flag = 0; +#if ( !defined NCHAN_ISM_PARAMETER || defined DISCRETE_ISM_DTX_CNG ) + flag_noisy_speech = 0; +#endif + +#ifdef NCHAN_ISM_PARAMETER + nchan_ism = st_ivas->hEncoderConfig->nchan_ism; +#else +#ifdef DISCRETE_ISM_DTX_CNG + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + nchan_ism = st_ivas->hDirAC->hParamIsm->num_obj; + } + else /* ism_mode == ISM_MODE_DISC */ + { + nchan_ism = st_ivas->nchan_transport; + } +#endif +#endif + set_s( md_diff_flag, 1, nchan_ism ); /*------------------------------------------------------------------* * Preprocesing @@ -164,20 +192,37 @@ ivas_error ivas_ism_enc( return error; } - vad_flag[sce_id] = st->vad_flag; +#ifdef DISCRETE_ISM_DTX_CNG + if ( st_ivas->hEncoderConfig->Opt_DTX_ON ) + { + vad_flag[sce_id] = vad_flag_dtx[sce_id][0]; + } + else +#endif + { + vad_flag[sce_id] = st->vad_flag; + } } /*------------------------------------------------------------------* * DTX analysis *-----------------------------------------------------------------*/ +#ifdef DISCRETE_ISM_DTX_CNG + if ( st_ivas->hEncoderConfig->Opt_DTX_ON ) +#else if ( st_ivas->hEncoderConfig->Opt_DTX_ON && st_ivas->ism_mode == ISM_MODE_PARAM ) +#endif { /* compute the dominant sce_id using long term energy */ ivas_ism_get_sce_id_dtx( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->nchan_transport, input_frame ); /* analysis and decision about DTX */ +#ifdef DISCRETE_ISM_DTX_CNG + dtx_flag = ivas_ism_dtx_enc( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, st_ivas->nchan_transport, vad_flag, st_ivas->hIsmMetaData, md_diff_flag, &sid_flag ); +#else dtx_flag = ivas_ism_dtx_enc( st_ivas, &sid_flag ); +#endif if ( sid_flag ) { @@ -186,8 +231,11 @@ ivas_error ivas_ism_enc( } #ifdef DEBUG_MODE_PARAM_ISM - dbgwrite( &( st_ivas->hISMDTX->flag_noisy_speech ), sizeof( int16_t ), 1, 1, "./res/ParamISM_noisy_speech_flag_enc.dat" ); + if ( st_ivas->hDirAC != NULL ) + dbgwrite( &( st_ivas->hDirAC->hParamIsm->flag_noisy_speech ), sizeof( int16_t ), 1, 1, "./res/ParamISM_noisy_speech_flag_enc.dat" ); dbgwrite( &( st_ivas->hISMDTX->dtx_flag ), sizeof( int16_t ), 1, 1, "./res/ParamISM_DTX_CNG_flag_enc.dat" ); + dbgwrite( &( st_ivas->hISMDTX->sce_id_dtx ), sizeof( int16_t ), 1, input_frame, "./res/sce_id_dtx" ); + dbgwrite( &( dtx_flag ), sizeof( int16_t ), 1, input_frame, "./res/dtx_flag" ); #endif } @@ -199,42 +247,79 @@ ivas_error ivas_ism_enc( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { ivas_param_ism_compute_noisy_speech_flag( st_ivas ); +#ifdef DISCRETE_ISM_DTX_CNG + flag_noisy_speech = st_ivas->hDirAC->hParamIsm->flag_noisy_speech; +#endif } if ( dtx_flag ) { +#ifdef DISCRETE_ISM_DTX_CNG + ivas_ism_metadata_sid_enc( st_ivas->hISMDTX, flag_noisy_speech, nchan_ism, st_ivas->nchan_transport, st_ivas->ism_mode, st_ivas->hIsmMetaData, sid_flag, md_diff_flag, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata ); +#else if ( sid_flag ) { +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_metadata_dtx_enc( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, st_ivas->hIsmMetaData, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm, nchan_ism ); +#else ivas_param_ism_metadata_dtx_enc( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, st_ivas->hIsmMetaData, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm ); +#endif } +#endif } else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { + // VE: call ivas_ism_metadata_enc() with 'st_ivas' - TBD #ifdef TD5 - ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag ); + ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, +#ifdef NCHAN_ISM_PARAMETER + nchan_ism, +#endif + st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag ); #else - ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm ); + ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, +#ifdef NCHAN_ISM_PARAMETER + nchan_ism, +#endif + st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm ); #endif } else /* ISM_MODE_DISC */ { #ifdef TD5 - ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag ); + ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, +#ifdef NCHAN_ISM_PARAMETER + nchan_ism, +#endif + st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag ); #else - ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL ); + ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, +#ifdef NCHAN_ISM_PARAMETER + nchan_ism, +#endif + st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL ); #endif } +#ifdef DISCRETE_ISM_DTX_CNG + update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag ); +#endif + /*----------------------------------------------------------------* * Write IVAS format signaling in SID frames *----------------------------------------------------------------*/ st = st_ivas->hSCE[0]->hCoreCoder[0]; +#ifdef DISCRETE_ISM_DTX_CNG + if ( sid_flag ) +#else if ( st->core_brate == SID_2k40 ) +#endif { ivas_write_format_sid( st_ivas->hEncoderConfig->ivas_format, IVAS_SCE, st->hBstr ); +#ifndef DISCRETE_ISM_DTX_CNG if ( st_ivas->ism_mode != ISM_MODE_PARAM ) { /* write unused bits */ @@ -246,6 +331,7 @@ ivas_error ivas_ism_enc( nBits -= i; } } +#endif } /*------------------------------------------------------------------* @@ -314,10 +400,47 @@ ivas_error ivas_ism_enc( { st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_core; st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_core_brate = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->core_brate; + st_ivas->hSCE[sce_id]->hCoreCoder[0]->last_L_frame = st_ivas->hSCE[st_ivas->hISMDTX->sce_id_dtx]->hCoreCoder[0]->last_L_frame; } } } +#ifdef DISCRETE_ISM_DTX_CNG +#ifdef DEBUG_MODE_INFO + if ( dtx_flag ) + { + float tmpF; + int16_t id, n; + + n = 0; + for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ ) + { + if ( sce_id != st_ivas->hISMDTX->sce_id_dtx ) + { + st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; + id = st->id_element; + + dbgwrite( &st->core, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "core", n, id, ENC ) ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "extl", n, id, ENC ) ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "bwidth", n, id, ENC ) ); + tmpF = st->total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "total_brate", n, id, ENC ) ); + tmpF = st->core_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "core_brate", n, id, ENC ) ); + tmpF = st->extl_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "extl_brate", n, id, ENC ) ); + + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type", n, id, ENC ) ); + dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type_raw", n, id, ENC ) ); + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "vad_flag", n, id, ENC ) ); + dbgwrite( &st->localVAD, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "localVAD", n, id, ENC ) ); + + dbgwrite( &st->lp_noise, sizeof( float ), 1, input_frame, fname( debug_dir, "lp_noise", n, id, ENC ) ); + } + } + } +#endif +#endif pop_wmops(); return error; @@ -356,7 +479,7 @@ ivas_error ivas_ism_enc_config( /* Reset and Initialize */ if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - st_ivas->nchan_transport = 2; + st_ivas->nchan_transport = MAX_PARAM_ISM_WAVE; } else { diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 7ce4132321f991659830c4b41358ec65146bac57..1540e35ce4855a2dcc410a0d28ce171af2fff0b3 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -176,7 +176,10 @@ static void rate_ism_importance( *-------------------------------------------------------------------------*/ ivas_error ivas_ism_metadata_enc( - const int32_t ism_total_brate, /* i : ISM total bitrate */ + const int32_t ism_total_brate, /* i : ISM total bitrate */ +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif 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 */ @@ -212,49 +215,57 @@ ivas_error ivas_ism_metadata_enc( int32_t element_brate[MAX_NUM_OBJECTS], total_brate[MAX_NUM_OBJECTS]; int16_t ism_metadata_flag_global; int16_t ism_imp[MAX_NUM_OBJECTS]; - int16_t num_obj, nbands, nblocks; +#ifdef NCHAN_ISM_PARAMETER + int16_t nbands, nblocks; +#else + int16_t nchan_ism, nbands, nblocks; +#endif ivas_error error; error = IVAS_ERR_OK; push_wmops( "ism_meta_enc" ); +#ifndef NCHAN_ISM_PARAMETER if ( ism_mode == ISM_MODE_PARAM ) { - num_obj = hParamIsm->num_obj; + nchan_ism = hParamIsm->num_obj; } else if ( ism_mode == ISM_MODE_DISC ) { - num_obj = nchan_transport; + nchan_ism = nchan_transport; } else { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: incorrect ISM mode" ); } +#endif - if ( num_obj == 1 && ( hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) && ism_mode == ISM_MODE_DISC ) +#ifndef DISCRETE_ISM_DTX_CNG + if ( nchan_ism == 1 && ( hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) && ism_mode == ISM_MODE_DISC ) { /* no metadata encoding in CNG */ pop_wmops(); return error; } +#endif /* initialization */ ism_metadata_flag_global = 0; set_s( nb_bits_metadata, 0, nchan_transport ); - set_s( flag_abs_azimuth, 0, num_obj ); - set_s( flag_abs_elevation, 0, num_obj ); + set_s( flag_abs_azimuth, 0, nchan_ism ); + set_s( flag_abs_elevation, 0, nchan_ism ); #ifdef TD5 - set_s( flag_abs_azimuth_orientation, 0, num_obj ); - set_s( flag_abs_radius, 0, num_obj ); + set_s( flag_abs_azimuth_orientation, 0, nchan_ism ); + set_s( flag_abs_radius, 0, nchan_ism ); #endif /*----------------------------------------------------------------* * Set Metadata presence / importance flag *----------------------------------------------------------------*/ - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { if ( ism_mode == ISM_MODE_PARAM ) { @@ -264,11 +275,15 @@ ivas_error ivas_ism_metadata_enc( { #ifdef TD5 #ifdef TUNE_360_OBJECT_WITH_NOISE +#ifdef DISCRETE_ISM_DTX_CNG + hIsmMeta[ch]->ism_metadata_flag = localVAD[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10; +#else /* In case of low level noise for low bitrate inactive frames, do not sent metadata */ if ( localVAD[ch] == 0 && !( hSCE[ch]->hCoreCoder[0]->tcxonly ) && ( hSCE[ch]->hCoreCoder[0]->lp_noise <= 10 ) ) { hIsmMeta[ch]->ism_metadata_flag = 0; } +#endif #else if ( hIsmMeta[ch]->ism_metadata_flag ) { @@ -276,12 +291,12 @@ ivas_error ivas_ism_metadata_enc( if ( localVAD[ch] == 0 && !( hSCE[ch]->hCoreCoder[0]->tcxonly ) ) { /* send metadata even in inactive segments when noise is audible and metadata are changing */ - diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ); - diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); + diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_azimuth_idx, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->angle[0].last_elevation_idx, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ) ) ); if ( ism_total_brate >= ISM_EXTENDED_METADATA_BRATE && ism_extended_metadata_flag ) { - diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->yaw - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ) ); - diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->pitch - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->yaw - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_azimuth_idx, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ) ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->pitch - ism_dequant_meta( hIsmMeta[ch]->angle[1].last_elevation_idx, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ) ) ); } if ( !( hSCE[ch]->hCoreCoder[0]->lp_noise > 15 && diff >= 10 ) ) { @@ -299,8 +314,8 @@ ivas_error ivas_ism_metadata_enc( if ( hIsmMeta[ch]->ism_metadata_flag == 0 ) { /* send metadata even in inactive segments when noise is audible and metadata are changing */ - diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->last_azimuth_idx, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ) ); - diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->last_elevation_idx, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ) ) ); + diff = (int16_t) fabsf( hIsmMeta[ch]->azimuth - ism_dequant_meta( hIsmMeta[ch]->last_azimuth_idx, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ) ); + diff = max( diff, (int16_t) fabsf( hIsmMeta[ch]->elevation - ism_dequant_meta( hIsmMeta[ch]->last_elevation_idx, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ) ) ); if ( hSCE[ch]->hCoreCoder[0]->lp_noise > 15 && diff >= 10 ) { @@ -326,13 +341,13 @@ ivas_error ivas_ism_metadata_enc( #ifndef TUNE_360_OBJECT_WITH_NOISE /* relax the importance decision in "stereo" coding for noisy audio */ - if ( ism_mode == ISM_MODE_DISC && num_obj == 2 ) + if ( ism_mode == ISM_MODE_DISC && nchan_ism == 2 ) { float diff_F; if ( hIsmMeta[0]->ism_metadata_flag ^ hIsmMeta[1]->ism_metadata_flag ) { - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { diff_F = hSCE[ch]->hCoreCoder[0]->lp_speech - hSCE[ch]->hCoreCoder[0]->lp_noise; @@ -345,12 +360,13 @@ ivas_error ivas_ism_metadata_enc( } } #endif + /*----------------------------------------------------------------* * Write ISM common signaling *----------------------------------------------------------------*/ /* write number of objects - unary coding */ - for ( ch = 1; ch < num_obj; ch++ ) + for ( ch = 1; ch < nchan_ism; ch++ ) { push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 ); } @@ -370,7 +386,7 @@ ivas_error ivas_ism_metadata_enc( push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS ); } - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { ism_metadata_flag_global |= hIsmMeta[ch]->ism_metadata_flag; } @@ -402,7 +418,7 @@ ivas_error ivas_ism_metadata_enc( nb_bits_start = hBstr->nb_bits_tot; } - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { hIsmMetaData = hIsmMeta[ch]; if ( ism_mode == ISM_MODE_DISC ) @@ -419,8 +435,8 @@ ivas_error ivas_ism_metadata_enc( if ( ism_mode == ISM_MODE_DISC ) { - idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); - idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); } else /* ISM_MODE_PARAM */ { @@ -436,8 +452,8 @@ ivas_error ivas_ism_metadata_enc( if ( ism_mode == ISM_MODE_DISC && ism_extended_metadata_flag ) { - idx_azimuth_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); - idx_elevation_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + idx_azimuth_abs = ism_quant_meta( hIsmMetaData->yaw, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); + idx_elevation_abs = ism_quant_meta( hIsmMetaData->pitch, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); idx_radius_abs = usquant( hIsmMetaData->radius, &valQ, ISM_RADIUS_MIN, ISM_RADIUS_DELTA, 1 << ISM_RADIUS_NBITS ); encode_angle_indices( hBstr, &( hIsmMetaData->angle[1] ), hIsmMetaData->last_ism_metadata_flag, hSCE[0]->hCoreCoder[0]->ini_frame, idx_azimuth_abs, idx_elevation_abs, &flag_abs_azimuth_orientation[ch], &flag_abs_elevation[ch] ); encode_radius( hBstr, &hIsmMetaData->last_radius_idx, &hIsmMetaData->radius_diff_cnt, hIsmMetaData->last_ism_metadata_flag, idx_radius_abs, &flag_abs_radius[ch] ); @@ -456,7 +472,7 @@ ivas_error ivas_ism_metadata_enc( /* Azimuth quantization (quantize azimuth to the AZIMUTH_NBITS-bit index */ if ( ism_mode == ISM_MODE_DISC ) { - idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, 1 << ISM_AZIMUTH_NBITS ); + idx_azimuth_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); } else if ( ism_mode == ISM_MODE_PARAM ) { @@ -562,7 +578,7 @@ ivas_error ivas_ism_metadata_enc( /* Elevation quantization (quantize azimuth to the ELEVATION_NBITS-bit index */ if ( ism_mode == ISM_MODE_DISC ) { - idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + idx_elevation_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS ); } else /* ISM_MODE_PARAM */ { @@ -703,7 +719,7 @@ ivas_error ivas_ism_metadata_enc( *----------------------------------------------------------------*/ i = 0; - while ( i == 0 || i < num_obj / INTER_OBJECT_PARAM_CHECK ) + while ( i == 0 || i < nchan_ism / INTER_OBJECT_PARAM_CHECK ) { int16_t num, abs_num, abs_first, abs_next, pos_zero; #ifdef TD5 @@ -712,7 +728,7 @@ ivas_error ivas_ism_metadata_enc( int16_t abs_matrice[INTER_OBJECT_PARAM_CHECK * 2]; #endif - num = min( INTER_OBJECT_PARAM_CHECK, num_obj - i * INTER_OBJECT_PARAM_CHECK ); + 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 ); @@ -834,12 +850,12 @@ ivas_error ivas_ism_metadata_enc( * Configuration and decision about bitrates per channel *----------------------------------------------------------------*/ - if ( ( error = ivas_ism_config( ism_total_brate, nchan_transport, num_obj, hIsmMeta, localVAD, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_ism_config( ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, localVAD, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK ) { return error; } - for ( ch = 0; ch < num_obj; ch++ ) + for ( ch = 0; ch < nchan_ism; ch++ ) { hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag; } @@ -888,7 +904,7 @@ ivas_error ivas_ism_metadata_enc_create( if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { - nchan_transport = 2; + nchan_transport = MAX_PARAM_ISM_WAVE; } else { @@ -927,6 +943,11 @@ ivas_error ivas_ism_metadata_enc_create( st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0; ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] ); + +#ifdef DISCRETE_ISM_DTX_CNG + st_ivas->hIsmMetaData[ch]->last_azimuth = 0.0f; + st_ivas->hIsmMetaData[ch]->last_elevation = 0.0f; +#endif } if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK ) @@ -1284,3 +1305,159 @@ static void encode_angle_indices( return; } #endif + + +#ifdef DISCRETE_ISM_DTX_CNG +/*-------------------------------------------------------------------* + * ivas_ism_metadata_sid_enc() + * + * Quantize and encode ISM metadata in SID frame + *-------------------------------------------------------------------*/ + +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; + int16_t idx, idx_azimuth, idx_elevation; + int16_t nBits_azimuth, nBits_elevation, nBits_coh, nBits_sce_id; + float valQ; + 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_VAD_FLAG, 0, 1 ); + } + else + { + push_indice( hBstr, IND_ISM_VAD_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]; + + 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 ); + + 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 ) + { +#ifdef TD5 + hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->angle[0].last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#else + hIsmMetaData->last_azimuth_idx = idx_azimuth >> ( nBits_azimuth - ISM_AZIMUTH_NBITS ); + hIsmMetaData->last_elevation_idx = idx_elevation >> ( nBits_elevation - ISM_ELEVATION_NBITS ); +#endif + } + else + { +#ifdef TD5 + hIsmMetaData->angle[0].last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->angle[0].last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#else + hIsmMetaData->last_azimuth_idx = idx_azimuth << ( ISM_AZIMUTH_NBITS - nBits_azimuth ); + hIsmMetaData->last_elevation_idx = idx_elevation << ( ISM_ELEVATION_NBITS - nBits_elevation ); +#endif + } + } + } + + /* 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; +} +#endif diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index cde2327968bf85a5dc7869b96db8fb261317cbc9..63c1fcea810af6c5d04f93a96e162cd5c0d94c7b 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -47,16 +47,27 @@ static void ivas_param_ism_compute_obj_parameters( +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif float reference_power_obj[MAX_NUM_OBJECTS][PARAM_ISM_MDFT_NO_SLOTS][DIRAC_NO_FB_BANDS_MAX], /* i : Reference power */ PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM Enc Handle */ ) { +#ifdef NCHAN_ISM_PARAMETER + int16_t i, b, m, br, mr; +#else int16_t i, b, m, br, mr, num_obj; +#endif int16_t brange_start, brange_end, mrange_start, mrange_end, time_merge_fac; float power_ratios_m[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS]; +#ifdef NCHAN_ISM_PARAMETER + assert( nchan_ism == 3 || nchan_ism == 4 ); +#else num_obj = hParamIsm->num_obj; assert( num_obj == 3 || num_obj == 4 ); +#endif for ( b = 0; b < hParamIsm->nbands; b++ ) { @@ -81,7 +92,11 @@ static void ivas_param_ism_compute_obj_parameters( /* for each object, sum up reference power within current T/F tile */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < num_obj; i++ ) +#endif { for ( mr = mrange_start; mr < mrange_end; mr++ ) { @@ -103,7 +118,12 @@ static void ivas_param_ism_compute_obj_parameters( index_1 = 1; index_2 = 0; } - for ( i = 2; i < num_obj; i++ ) + +#ifdef NCHAN_ISM_PARAMETER + for ( i = MAX_PARAM_ISM_WAVE; i < nchan_ism; i++ ) +#else + for ( i = MAX_PARAM_ISM_WAVE; i < num_obj; i++ ) +#endif { if ( ref_power_local[i] > ref_power_local[index_1] ) { @@ -149,23 +169,36 @@ static void ivas_param_ism_compute_obj_parameters( static void ivas_param_ism_enc_quantize_DOA( +#ifdef NCHAN_ISM_PARAMETER + const int16_t nchan_ism, /* i : number of ISM channels */ +#endif ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata */ PARAM_ISM_CONFIG_HANDLE hParamIsm /* i/o: Param ISM encoder handle */ ) { +#ifdef NCHAN_ISM_PARAMETER + int16_t i, azi_idx, ele_idx; +#else int16_t i, azi_idx, ele_idx, num_obj; +#endif float valQ; +#ifndef NCHAN_ISM_PARAMETER num_obj = hParamIsm->num_obj; +#endif /* Loop over objects */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < num_obj; i++ ) +#endif { /* Quantize the elevation and obtain quantized elevation value and index */ - ele_idx = ism_quant_meta( hIsmMetaData[i]->elevation, &valQ, ism_elevation_borders, 1 << ISM_ELEVATION_NBITS ); + 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, 1 << ISM_AZIMUTH_NBITS ); + azi_idx = ism_quant_meta( hIsmMetaData[i]->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS ); /*Replace azimuth with quantized values */ hIsmMetaData[i]->azimuth = valQ; @@ -191,7 +224,11 @@ void ivas_param_ism_stereo_dmx( const int16_t input_frame /* i : Length of input frame */ ) { +#ifdef NCHAN_ISM_PARAMETER + int16_t i, j; +#else int16_t i, j, num_obj; +#endif float alpha, azi_shift, tmp, tmp_1; float cardioid_left[MAX_NUM_OBJECTS], cardioid_right[MAX_NUM_OBJECTS]; float stereo_dmx[2][L_FRAME48k]; @@ -202,14 +239,20 @@ void ivas_param_ism_stereo_dmx( /*Initialization*/ alpha = 0.5; azi_shift = 0; +#ifndef NCHAN_ISM_PARAMETER num_obj = st_ivas->hDirAC->hParamIsm->num_obj; +#endif /* Set the stereo dmx to zero */ set_zero( stereo_dmx[0], L_FRAME48k ); set_zero( stereo_dmx[1], L_FRAME48k ); /* Loop over all objects */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) +#else for ( i = 0; i < num_obj; i++ ) +#endif { hIsmMetaData = st_ivas->hIsmMetaData[i]; @@ -271,8 +314,10 @@ ivas_error ivas_param_ism_enc_open( input_Fs = st_ivas->hEncoderConfig->input_Fs; +#ifndef NCHAN_ISM_PARAMETER /* Assign the number of objects */ hDirAC->hParamIsm->num_obj = st_ivas->hEncoderConfig->nchan_inp; +#endif /* set FB config. */ if ( ( error = ivas_fb_set_cfg( &fb_cfg, ISM_FORMAT, SBA_MODE_NONE, st_ivas->hEncoderConfig->nchan_inp, 0, 0, input_Fs ) ) != IVAS_ERR_OK ) @@ -286,7 +331,11 @@ ivas_error ivas_param_ism_enc_open( return error; } +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_config( hDirAC->hParamIsm, st_ivas->hEncoderConfig->nchan_inp ); +#else ivas_param_ism_config( hDirAC->hParamIsm ); +#endif /* Assign memories for Band and Block grouping */ hDirAC->hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; @@ -353,6 +402,9 @@ void ivas_param_ism_enc( ) { int16_t i, j, ts, l_ts; +#ifdef NCHAN_ISM_PARAMETER + int16_t nchan_ism; +#endif int16_t num_time_slots; float *pcm_in[MAX_NUM_OBJECTS]; float fb_RealBuffer[MAX_NUM_OBJECTS][DIRAC_NO_FB_BANDS_MAX]; @@ -363,6 +415,9 @@ void ivas_param_ism_enc( DIRAC_ENC_HANDLE hDirAC; PARAM_ISM_CONFIG_HANDLE hParamIsm; +#ifdef NCHAN_ISM_PARAMETER + nchan_ism = st_ivas->hEncoderConfig->nchan_ism; +#endif hDirAC = st_ivas->hDirAC; hParamIsm = hDirAC->hParamIsm; @@ -371,7 +426,11 @@ void ivas_param_ism_enc( l_ts = input_frame / PARAM_ISM_MDFT_NO_SLOTS; num_time_slots = PARAM_ISM_MDFT_NO_SLOTS; +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < hParamIsm->num_obj; i++ ) +#endif { pcm_in[i] = &data[i][0]; @@ -380,12 +439,18 @@ void ivas_param_ism_enc( p_fb_RealBuffer[i] = &fb_RealBuffer[i][0]; p_fb_ImagBuffer[i] = &fb_ImagBuffer[i][0]; } + for ( ts = 0; ts < num_time_slots; ts++ ) { ivas_fb_mixer_get_windowed_fr( hDirAC->hFbMixer, pcm_in, p_fb_RealBuffer, p_fb_ImagBuffer, l_ts, l_ts ); + ivas_fb_mixer_update_prior_input( hDirAC->hFbMixer, pcm_in, l_ts ); +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < hParamIsm->num_obj; i++ ) +#endif { pcm_in[i] += l_ts; for ( j = 0; j < DIRAC_NO_FB_BANDS_MAX; j++ ) @@ -396,16 +461,25 @@ void ivas_param_ism_enc( } /* Quantize DOAs */ +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_enc_quantize_DOA( nchan_ism, st_ivas->hIsmMetaData, hParamIsm ); +#else ivas_param_ism_enc_quantize_DOA( st_ivas->hIsmMetaData, hParamIsm ); +#endif /* Compute object indices and power ratios */ +#ifdef NCHAN_ISM_PARAMETER + ivas_param_ism_compute_obj_parameters( nchan_ism, reference_power_obj, hParamIsm ); +#else ivas_param_ism_compute_obj_parameters( reference_power_obj, hParamIsm ); +#endif pop_wmops(); return; } +#ifndef DISCRETE_ISM_DTX_CNG static void ivas_param_ism_enc_quantize_DOA_dtx( float azimuth, float elevation, @@ -474,8 +548,12 @@ static void ivas_param_ism_enc_quantize_DOA_dtx( void ivas_param_ism_metadata_dtx_enc( BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ ISM_METADATA_HANDLE hIsmMeta[], /* i : ISM metadata handles */ - ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ + ISM_DTX_HANDLE hISMDTX, /* i/o: ISM DTX handle */ PARAM_ISM_CONFIG_HANDLE hParamIsm /* i : Param ISM Enc Handle */ +#ifdef NCHAN_ISM_PARAMETER + , + const int16_t nchan_ism /* i : number of ISM channels */ +#endif ) { int16_t i, nBits, nBits_unused; @@ -487,7 +565,11 @@ void ivas_param_ism_metadata_dtx_enc( /* Transmit the metadata */ /* write number of objects - unary coding */ +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 1; i < hParamIsm->num_obj; i++ ) +#endif { push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 ); } @@ -504,7 +586,11 @@ void ivas_param_ism_metadata_dtx_enc( assert( ( coh_idx >= 0 ) && ( coh_idx <= ( ( 1 << PARAM_ISM_DTX_COH_SCA_BITS ) - 1 ) ) ); push_indice( hBstr, IND_ISM_DTX_COH_SCA, coh_idx, PARAM_ISM_DTX_COH_SCA_BITS ); +#ifdef NCHAN_ISM_PARAMETER + for ( i = 0; i < nchan_ism; i++ ) +#else for ( i = 0; i < hParamIsm->num_obj; i++ ) +#endif { ivas_param_ism_enc_quantize_DOA_dtx( hIsmMeta[i]->azimuth, hIsmMeta[i]->elevation, PARAM_ISM_DTX_AZI_BITS, PARAM_ISM_DTX_ELE_BITS, &azi_idx, &ele_idx ); push_indice( hBstr, IND_ISM_AZIMUTH, azi_idx, PARAM_ISM_DTX_AZI_BITS ); @@ -530,7 +616,7 @@ void ivas_param_ism_metadata_dtx_enc( return; } - +#endif /*-------------------------------------------------------------------* * ivas_param_ism_compute_noisy_speech_flag() diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 1256955e87bb74866c910fdd4ec1d73ec08df9e4..a56f6423d39f2f3a055acd30b119f6537255237b 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -559,7 +559,11 @@ typedef struct int16_t dtx_flag; int16_t sce_id_dtx; +#ifdef DISCRETE_ISM_DTX_CNG + int16_t cnt_SID_ISM; +#else int16_t dtx_speech_buffer_enc[PARAM_ISM_HYS_BUF_SIZE]; +#endif float long_term_energy_stereo_dmx_enc[MAX_NUM_OBJECTS][PARAM_ISM_HYS_BUF_SIZE]; float coh[MAX_NUM_OBJECTS]; @@ -1010,6 +1014,9 @@ typedef struct encoder_config_structure int16_t element_mode_init; /* element mode used at initialization */ int16_t stereo_dmx_evs; /* flag to indicate that stereo downmix for EVS encoder */ +#ifdef NCHAN_ISM_PARAMETER + int16_t nchan_ism; /* number of ISM channels */ +#endif int16_t sba_order; /* Ambisonic (SBA) order */ int16_t sba_planar; /* Ambisonic (SBA) planar flag */ MC_LS_SETUP mc_input_setup; /* multichannel input ls setup */ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index a7b252c9d8f4e40d23823492b240afb2d2f80216..50052cda3c587c2a9962936f87777ff5bb39a521 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -391,6 +391,9 @@ ivas_error IVAS_ENC_ConfigureForObjects( st_ivas->hEncoderConfig->ivas_format = ISM_FORMAT; st_ivas->hEncoderConfig->element_mode_init = IVAS_SCE; st_ivas->hEncoderConfig->nchan_inp = numObjects; +#ifdef NCHAN_ISM_PARAMETER + st_ivas->hEncoderConfig->nchan_ism = numObjects; +#endif #ifdef TD5 st_ivas->hEncoderConfig->ism_extended_metadata_flag = ism_extended_metadata; #endif @@ -886,12 +889,15 @@ static ivas_error configureEncoder( } if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_format != MONO_FORMAT && - ( ( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->nchan_inp == 2 ) || // ToDo: see Issue 113 - ( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->nchan_inp > 2 && hEncoderConfig->ivas_total_brate != IVAS_24k4 && hEncoderConfig->ivas_total_brate != IVAS_32k ) || // ParamISM - ( hEncoderConfig->ivas_format == MASA_FORMAT && hEncoderConfig->ivas_total_brate > IVAS_128k ) || // ToDo: remove the bitrate limitation - ( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_get_sba_num_TCs( hEncoderConfig->ivas_total_brate, 1 ) > 2 ) || // ToDo: support for 3+ TCs to be done - hEncoderConfig->ivas_format == MC_FORMAT // ToDo: TBD - ) ) + ( +#ifndef DISCRETE_ISM_DTX_CNG + ( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->nchan_inp == 2 ) || // ToDo: see Issue 113 + ( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->nchan_inp > 2 && hEncoderConfig->ivas_total_brate != IVAS_24k4 && hEncoderConfig->ivas_total_brate != IVAS_32k ) || // ParamISM +#endif + ( hEncoderConfig->ivas_format == MASA_FORMAT && hEncoderConfig->ivas_total_brate > IVAS_128k ) || // ToDo: remove the bitrate limitation + ( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_get_sba_num_TCs( hEncoderConfig->ivas_total_brate, 1 ) > 2 ) || // ToDo: support for 3+ TCs to be done + hEncoderConfig->ivas_format == MC_FORMAT // ToDo: TBD + ) ) { return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } @@ -922,10 +928,12 @@ static ivas_error configureEncoder( return error; } +#ifndef DISCRETE_ISM_DTX_CNG if ( hEncoderConfig->Opt_DTX_ON && ( hEncoderConfig->ivas_format == ISM_FORMAT ) && !( st_ivas->ism_mode == ISM_MODE_DISC && hEncoderConfig->nchan_inp == 1 ) && !( st_ivas->ism_mode == ISM_MODE_PARAM && ( hEncoderConfig->nchan_inp == 3 || hEncoderConfig->nchan_inp == 4 ) ) ) { return IVAS_ERROR( IVAS_ERR_UNKNOWN, "DTX is not supported in this IVAS format and element mode." ); } +#endif if ( hEncoderConfig->ivas_format == MONO_FORMAT ) { @@ -2276,6 +2284,9 @@ static void init_encoder_config( hEncoderConfig->var_SID_rate_flag = 1; hEncoderConfig->mc_input_setup = MC_LS_SETUP_INVALID; hEncoderConfig->stereo_dmx_evs = 0; +#ifdef NCHAN_ISM_PARAMETER + hEncoderConfig->nchan_ism = 0; +#endif hEncoderConfig->sba_order = 0; hEncoderConfig->sba_planar = 0; #ifdef TD5 diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 67b73db6a6faac8a17013ece700d3dad16ca6ee0..67f73fab303e664b67d2ff67de0a8d732339a564 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -612,7 +612,10 @@ ivas_error ivas_td_binaural_open_ext( #ifdef TD5 #ifdef TD5_FIX_INVALID_MEMORY_ACCESS if ( NULL != hRendCfg ) + { directivity = hRendCfg->directivity; + } + return ivas_td_binaural_open_unwrap( &pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, directivity, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns ); #else return ivas_td_binaural_open_unwrap( &pTDRend->hHrtfTD, outFs, nchan_transport, ivas_format, transport_config, hRendCfg->directivity, hTransSetup, &pTDRend->hBinRendererTd, &pTDRend->binaural_latency_ns );