diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 773dafc2c5babae03ebb5fb16a1def680dc72712..cb8c0cfa76f1ac0905ff530f211f108d4c1f6502 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -277,6 +277,8 @@ + + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 4dcff8d503d594bb101ae9d579828038b11b58e7..e6661b742de5618067ea2dbf12518ccb06a1bd0e 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -503,6 +503,12 @@ dec_ivas_c + + dec_ivas_c + + + dec_ivas_c + diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index a2d1e13ae78d01533bbbbd6520a5f4a010a48388..15f0d535745d95fec1fd22eb4d139f5ca5e8d06f 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -211,6 +211,7 @@ + diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 8fe608e0a69d52dffb9b576a8c26b439a5f62954..21941038ec37e6a53cc81c9c3c915e69cbe0ac5f 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -584,6 +584,9 @@ enc_ivas_c + + enc_ivas_c + diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index c6e981ef7dfd9c38324fa5148692a9f75f034d4a..d29a7d33facce6db6da7da91c073a8e2db580950 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -334,6 +334,12 @@ typedef enum #define PARAM_ISM_MAX_CHAN 16 #define PARAM_ISM_HYS_BUF_SIZE 10 +#ifdef PARAM_ISM_DTX_CNG +#define PARAM_ISM_DTX_COH_SCA_BITS 4 +#define PARAM_ISM_DTX_AZI_BITS 5 +#define PARAM_ISM_DTX_ELE_BITS 4 +#endif + typedef enum { ISM_MODE_NONE, @@ -348,9 +354,18 @@ enum IND_ISM_NUM_OBJECTS, IND_ISM_METADATA_FLAG = IND_ISM_NUM_OBJECTS + MAX_NUM_OBJECTS, IND_ISM_VAD_FLAG = IND_ISM_METADATA_FLAG + MAX_NUM_OBJECTS, +#ifdef PARAM_ISM_DTX_CNG + IND_ISM_SCE_ID_DTX = IND_ISM_VAD_FLAG + MAX_NUM_OBJECTS, + IND_ISM_NOISY_SPEECH_FLAG, + IND_ISM_DTX_COH_SCA, +#endif /* ------------- loop for objects -------------- */ +#ifdef PARAM_ISM_DTX_CNG + TAG_ISM_LOOP_START = IND_ISM_DTX_COH_SCA + MAX_NUM_OBJECTS, +#else TAG_ISM_LOOP_START = IND_ISM_VAD_FLAG + MAX_NUM_OBJECTS, + #endif IND_ISM_AZIMUTH_DIFF_FLAG = TAG_ISM_LOOP_START, IND_ISM_AZIMUTH = TAG_ISM_LOOP_START, IND_ISM_ELEVATION_DIFF_FLAG = TAG_ISM_LOOP_START, diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9098ae65212c426d0dd7e7726bcb94d0047e0d55..8c46ce6f2e8db89773df137de2732414172e9dd7 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -526,6 +526,11 @@ 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 */ +#ifdef PARAM_ISM_DTX_CNG + , + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM) */ +#endif ); void stereo_tcx_init_dec( @@ -939,6 +944,57 @@ void ivas_param_ism_params_to_masa_param_mapping( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); + +#ifdef PARAM_ISM_DTX_CNG +/*----------------------------------------------------------------------------------* + * ISM DTX prototypes + *----------------------------------------------------------------------------------*/ + +ivas_error ivas_ism_dtx_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + +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 */ +); + +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 */ +); + +void ivas_param_ism_metadata_dtx_dec( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); + +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 */ +); + +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 */ +); +#endif + /*----------------------------------------------------------------------------------* * DFT Stereo prototypes *----------------------------------------------------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h index 55cb7e63dd5e7c856602f165d1131bb97803e3fe..fe6c9fe2df75ec12b4d734615d5e92dcfefcaaf9 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -68,7 +68,7 @@ /*#define DEBUG_MODE_MDCT*/ /* output most important MDCT parameters to the subdirectory "res/" */ /*#define DEBUG_MODE_PARAM_MC */ /* output Parametric MC paramters to the subdirectory "res/" */ /*#define DEBUG_MODE_PARAM_ISM*/ /* output Parametric ISM paramters to the subdirectory "res/" */ -#define DEBUG_MODE_INFO_TWEAK /* enable command line switch to specify subdirectory for debug info output inside "./res/" */ +/*#define DEBUG_MODE_INFO_TWEAK*/ /* enable command line switch to specify subdirectory for debug info output inside "./res/" */ /*#define DEBUG_MODE_INFO_PLC */ /* define to output PLC related parameters */ /*#define DEBUG_MODE_INFO_ALLRAD*/ /* define to output generated HOA decoding mtx */ /*#define DEBUG_MODE_LFE */ /* define to output LFE relevant parameters */ @@ -165,7 +165,9 @@ #define FIX_343_TO_UPPER /* VA: issue 343: safeguard for function to_upper() */ -#define FIX_107_5MS_SUBFRAME_RENDERING /* Issue 107: use 5ms subframes everywhere in parametric binauralizer */ +#define FIX_107_5MS_SUBFRAME_RENDERING + +#define PARAM_ISM_DTX_CNG /* FhG: contribution 9 - DTX-CNG for ParamISM */ #define FIX_331_SBA_HBR_HOA_FIXES /* DLB: issue 331 - fix addressing low frequency stuttering with HOA inputs at high bitrates */ #ifdef FIX_331_SBA_HBR_HOA_FIXES diff --git a/lib_com/prot.h b/lib_com/prot.h index 784527e1bfadd8b7252f2c5ef9de827bafbc598c..f47c2d65b296a20b3afd25087f079e50f1dbd867 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2221,11 +2221,15 @@ void read_next_force( ); #endif ivas_error init_encoder( - Encoder_State *st, /* i/o: state structure */ - const int16_t idchan, /* i : channel ID */ - const int16_t var_SID_rate_flag, /* i : flag for variable SID update rate */ + Encoder_State *st, /* i/o: state structure */ + const int16_t idchan, /* i : channel ID */ + const int16_t var_SID_rate_flag, /* i : flag for variable SID update rate */ const int16_t interval_SID, /* i : interval for SID update */ const int16_t vad_only_flag /* i : flag to indicate front-VAD structure */ +#ifdef PARAM_ISM_DTX_CNG + , + const ISM_MODE ism_mode /* i : ISM mode */ +#endif ); void LPDmem_enc_init( @@ -8517,6 +8521,10 @@ 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 */ +#ifdef PARAM_ISM_DTX_CNG + , + int16_t cng_flag /*i: CNG Flag */ +#endif ); void generate_masking_noise( diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 1546092269c5d3327f266238ccb3b7432d5b1a02..79976efa88ab63a6d3eb8948712e899a1e5e1f12 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -406,6 +406,7 @@ typedef struct float coherence; /* inter-channel coherence of noise */ int16_t no_side_flag; /* indicates whether the side noise shape should be zeroed-out or not */ + } FD_CNG_COM, *HANDLE_FD_CNG_COM; diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 7fcc65f6f76c205133836324497a888c918ac9ab..571311ed124250ec488242fa3d6acb6e56a19652 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -512,7 +512,11 @@ ivas_error acelp_core_dec( } else { +#ifdef PARAM_ISM_DTX_CNG + if ( st->core_brate == SID_2k40 && st->element_mode != IVAS_CPE_MDCT && st->read_sid_info ) +#else if ( st->core_brate == SID_2k40 && st->element_mode != IVAS_CPE_MDCT ) +#endif { FdCng_decodeSID( st ); *sid_bw = 0; @@ -528,6 +532,19 @@ ivas_error acelp_core_dec( } ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); } +#ifdef PARAM_ISM_DTX_CNG + if ( !st->read_sid_info ) + // if (!st->read_sid_info && st->cng_paramISM_flag) /* read_sid_info can only be 0 in ParamISM mode */ + { + float noise_lvl_highest; + + noise_lvl_highest = st->hFdCngDec->hFdCngCom->cngNoiseLevel[st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand - 1]; + for ( int16_t b = st->hFdCngDec->hFdCngCom->stopFFTbin - st->hFdCngDec->hFdCngCom->startBand; b < st->hFdCngDec->hFdCngCom->stopBand; b++ ) + { + st->hFdCngDec->hFdCngCom->cngNoiseLevel[b] = noise_lvl_highest; + } + } +#endif generate_comfort_noise_dec( NULL, NULL, st, nchan_out ); @@ -1114,7 +1131,11 @@ ivas_error acelp_core_dec( st->lp_noise = st->hFdCngDec->lp_noise; } +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode != IVAS_CPE_TD && !st->cng_paramISM_flag ) +#else if ( st->element_mode != IVAS_CPE_TD ) +#endif { /*Noise estimate*/ ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1290,7 +1311,11 @@ 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 ) ) { +#ifdef PARAM_ISM_DTX_CNG + generate_comfort_noise_dec_hf( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom, st->cng_paramISM_flag ); +#else generate_comfort_noise_dec_hf( realBuffer, imagBuffer, st->hFdCngDec->hFdCngCom ); +#endif 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 cf55b4a619cc83cfd51bb79f89a60b156a9ce81a..314d0534a7678edced83084a97aba598a8405678 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1085,7 +1085,11 @@ void generate_comfort_noise_dec( c2 = (float) sqrt( 1 - hFdCngCom->coherence ); seed2 = &( hFdCngCom->seed2 ); +#ifdef PARAM_ISM_DTX_CNG + if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) +#endif { seed2 = &( hFdCngCom->seed3 ); } @@ -1095,7 +1099,11 @@ void generate_comfort_noise_dec( if ( hFdCngCom->startBand == 0 ) { +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT ) +#endif { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1120,7 +1128,11 @@ void generate_comfort_noise_dec( for ( ; ptr_level < cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; ptr_level++ ) { /* Real part in FFT bins */ +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT ) +#endif { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1134,7 +1146,11 @@ void generate_comfort_noise_dec( ptr_r += 2; /* Imaginary part in FFT bins */ +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT ) +#endif { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1212,7 +1228,11 @@ void generate_comfort_noise_dec( for ( i = 0; i < hFdCngCom->numSlots; i++ ) { /* Real part in CLDFB band */ +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT ) +#endif { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1225,7 +1245,11 @@ void generate_comfort_noise_dec( bufferReal[i][j] *= (float) sqrt( ( scaleCldfb * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ +#ifdef PARAM_ISM_DTX_CNG + if ( st->element_mode == IVAS_CPE_MDCT || ( st->element_mode == IVAS_SCE && st->cng_paramISM_flag ) ) +#else if ( st->element_mode == IVAS_CPE_MDCT ) +#endif { rand_gauss( &tmp1, seed ); rand_gauss( &tmp2, seed2 ); @@ -1325,13 +1349,31 @@ 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 */ +#ifdef PARAM_ISM_DTX_CNG + , + int16_t cng_coh_flag /* i: CNG Flag for coherence handling */ +#endif ) { int16_t i, j; float *ptr_level; + int16_t *seed = &( hFdCngCom->seed ); float scale = CLDFB_SCALING / hFdCngCom->scalingFactor; +#ifdef PARAM_ISM_DTX_CNG + int16_t *seed2 = &( hFdCngCom->seed ); + float tmp1, tmp2, c1 = 0.f, c2 = 0.f; + + if ( cng_coh_flag ) + { + seed2 = &( hFdCngCom->seed3 ); + + c1 = (float) sqrt( hFdCngCom->coherence ); + c2 = (float) sqrt( 1 - hFdCngCom->coherence ); + } +#endif + ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand; /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands @@ -1343,12 +1385,38 @@ void generate_comfort_noise_dec_hf( { for ( i = 0; i < hFdCngCom->numSlots; i++ ) { +#ifdef PARAM_ISM_DTX_CNG + if ( cng_coh_flag ) + { + /* Real part in CLDFB band */ + rand_gauss( &tmp1, seed ); + rand_gauss( &tmp2, seed2 ); + bufferReal[i][j] = tmp1 * c1 + tmp2 * c2; + bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + + /* Imaginary part in CLDFB band */ + rand_gauss( &tmp1, seed ); + rand_gauss( &tmp2, seed2 ); + bufferImag[i][j] = tmp1 * c1 + tmp2 * c2; + bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + } + else + { + /* Real part in CLDFB band */ + rand_gauss( &bufferReal[i][j], seed ); + bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + /* Imaginary part in CLDFB band */ + rand_gauss( &bufferImag[i][j], seed ); + bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); + } +#else /* Real part in CLDFB band */ rand_gauss( &bufferReal[i][j], seed ); bufferReal[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); /* Imaginary part in CLDFB band */ rand_gauss( &bufferImag[i][j], seed ); bufferImag[i][j] *= (float) sqrt( ( scale * *ptr_level ) * 0.5f ); +#endif } ptr_level++; } diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index a318d7e5604c2f79753ada3b1579fe2428eec3f1..402fdc78f5449592d418d2baf9ffdacb270d793d 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -738,6 +738,10 @@ ivas_error init_decoder( st->tdm_LRTD_flag = 0; st->cna_dirac_flag = 0; st->cng_sba_flag = 0; +#ifdef PARAM_ISM_DTX_CNG + st->cng_paramISM_flag = 0; + st->read_sid_info = 1; /* by default read the sid info from bitstream */ +#endif return error; diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 3fb50b5ca63096029c8c04be9f44869fe51e57be..ccc752fdc5f7f51877051799bd873879dbecdbee 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -341,7 +341,11 @@ ivas_error ivas_core_dec( if ( ( st->core == TCX_20_CORE || st->core == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { /* TCX decoder */ +#ifdef PARAM_ISM_DTX_CNG + 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 ); +#else 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 ); +#endif } if ( st->core == HQ_CORE ) diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 40b016244b283d430331474c42d2febbdab59d25..ec618917b7963429e303b8dde1366de1a1b3f938 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -139,7 +139,17 @@ ivas_error ivas_dec( else if ( st_ivas->ivas_format == ISM_FORMAT ) { /* Metadata decoding and configuration */ - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) +#ifdef PARAM_ISM_DTX_CNG + if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) + { + if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else +#endif + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { 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 ); } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c old mode 100644 new mode 100755 index f690129f8c4824b1f1258d77f3a1b79d32bc3d41..4e49799315f6300e82211243db2f5336a7146c3e --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -422,7 +422,20 @@ static ivas_error ivas_read_format( break; case SID_ISM: st_ivas->ivas_format = ISM_FORMAT; +#ifdef PARAM_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 */ + } + + 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 */ + } +#else ivas_ism_dec_config( st_ivas, 1 ); /* currently DTX supported for 1ISM only */ +#endif break; case SID_MULTICHANNEL: st_ivas->ivas_format = MC_FORMAT; @@ -840,6 +853,13 @@ ivas_error ivas_init_decoder( reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); } + +#ifdef PARAM_ISM_DTX_CNG + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2; + } +#endif } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..c354ca257e3f02d6f47dbe799384ab2bcdb29590 --- /dev/null +++ b/lib_dec/ivas_ism_dec.c @@ -0,0 +1,293 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------------* + * ivas_ism_bitrate_switching() + * + * + *-------------------------------------------------------------------------*/ + +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 */ +) +{ + ivas_error error; + int32_t element_brate_tmp[MAX_NUM_OBJECTS]; + int16_t nSCE_old, nCPE_old; + + error = IVAS_ERR_OK; + + nCPE_old = st_ivas->nCPE; + nSCE_old = st_ivas->nSCE; + + ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, num_obj, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); + st_ivas->nSCE = st_ivas->nchan_transport; + + ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, 0, st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport, ( st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ); + + ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ); + + /* Initialize the needed renderer struct and destroy the unnecessary renderer struct */ + + /* select the renderer */ + ivas_renderer_select( st_ivas ); + ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); + if ( ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->ism_mode == ISM_MODE_DISC ) ) + { + ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); + } + + if ( st_ivas->ism_mode != last_ism_mode ) + { + /* EFAP handle */ + efap_free_data( &st_ivas->hEFAPdata ); + } + + if ( st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM ) + { + /* switching from ParamISM to DiscISM */ + + /* Deallocate the ParamISM struct */ + if ( st_ivas->hDirAC != NULL ) + { + ivas_param_ism_dec_close( st_ivas->hDirAC, st_ivas->hDecoderConfig->output_config ); + st_ivas->hDirAC = NULL; + } + + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL ) + { + /* close the parametric binaural renderer */ + ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); + + /* Open the TD Binaural renderer */ + ivas_td_binaural_open( st_ivas ); + } + else + { + /* close the ISM renderer and reinitialize */ + if ( st_ivas->hIsmRendererData != NULL ) + { + free( st_ivas->hIsmRendererData ); + st_ivas->hIsmRendererData = NULL; + } + ivas_ism_renderer_open( st_ivas ); + } + + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) + { + /* close the parametric binaural renderer */ + ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); + + /* Open Crend Binaural renderer */ +#ifdef FIX_197_CREND_INTERFACE + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), + getRendAudioConfigFromIvasAudioConfig( st_ivas->hOutSetup.output_config ), + st_ivas->hRenderConfig, + st_ivas->hDecoderConfig->Opt_Headrotation, + st_ivas->hSetOfHRTF, + st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#else + ivas_crend_open( st_ivas ); +#endif + } + } + + if ( st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC ) + { + /* switching from Discrete ISM to ParamISM */ + + /* Allocate and initialize the ParamISM struct */ + ivas_param_ism_dec_open( st_ivas ); + + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL ) + { + /* open the parametric binaural renderer */ + ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ); + ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ); + + /* Close the TD Binaural renderer */ + if ( st_ivas->hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &st_ivas->hBinRendererTd ); + } + + if ( st_ivas->hHrtfTD != NULL ) + { + st_ivas->hHrtfTD = NULL; + } + } + else + { + /* Close the ISM renderer */ + if ( st_ivas->hIsmRendererData != NULL ) + { + free( st_ivas->hIsmRendererData ); + st_ivas->hIsmRendererData = NULL; + } + } + + if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) + { + /* open the parametric binaural renderer */ + ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ); + ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ); + + /* close the crend binaural renderer */ +#ifdef FIX_197_CREND_INTERFACE + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#else + ivas_crend_close( st_ivas ); + + if ( st_ivas->hHrtf != NULL ) + { + st_ivas->hHrtf = NULL; + } +#endif + } + } + + return error; +} + + +/*------------------------------------------------------------------------- + * ivas_ism_dec_config() + * + * - select ISM format mode + * - reconfigure the ISM format decoder + *-------------------------------------------------------------------------*/ + +/*! r : ISM format mode */ +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 */ +) +{ + int32_t ivas_total_brate; + ISM_MODE last_ism_mode; + ivas_error error; + int16_t nchan_transport_old; + + error = IVAS_ERR_OK; + + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + /* store last frame ISM mode */ + last_ism_mode = st_ivas->ism_mode; + + /* Assumes that num of input objects are constant */ + nchan_transport_old = num_obj; + + if ( last_ism_mode == ISM_MODE_PARAM ) + { + nchan_transport_old = MAX_PARAM_ISM_WAVE; + } + + if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) + { + /* select ISM format mode */ + st_ivas->ism_mode = ivas_ism_mode_select( num_obj, ivas_total_brate ); + + st_ivas->nchan_transport = num_obj; + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->nchan_transport = 2; + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) + { + st_ivas->hDecoderConfig->nchan_out = num_obj; + } + } + + if ( st_ivas->ini_active_frame != 0 ) + { + /* ISM bit-rate switching */ + if ( st_ivas->hDecoderConfig->last_ivas_total_brate != IVAS_SID_5k2 && st_ivas->hDecoderConfig->last_ivas_total_brate != FRAME_NO_DATA ) + { + 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 ); + } + } + } + } + else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) + { +#ifdef PARAM_ISM_DTX_CNG + if ( last_ism_mode == ISM_MODE_PARAM ) + { + nchan_transport_old = MAX_PARAM_ISM_WAVE; + } + else +#endif + { + st_ivas->nchan_transport = num_obj; + } + } + + switch ( num_obj ) + { + case 1: + st_ivas->transport_config = AUDIO_CONFIG_ISM1; + break; + case 2: + st_ivas->transport_config = AUDIO_CONFIG_ISM2; + break; + case 3: + st_ivas->transport_config = AUDIO_CONFIG_ISM3; + break; + case 4: + st_ivas->transport_config = AUDIO_CONFIG_ISM4; + break; + default: + st_ivas->transport_config = AUDIO_CONFIG_INVALID; + break; + } + + return error; +} diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..bd15569f9e26884d2b51cdf78a6ed8909e27b759 --- /dev/null +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -0,0 +1,173 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "ivas_prot.h" +#include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#ifdef PARAM_ISM_DTX_CNG +/*-------------------------------------------------------------------* + * ivas_ism_preprocessing() + * + * + *-------------------------------------------------------------------*/ + +static void ivas_ism_preprocessing( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t sce_id /* i : SCE # identifier */ +) +{ + int32_t ivas_total_brate; + SCE_DEC_HANDLE hSCE; + Decoder_State *st; + + hSCE = st_ivas->hSCE[sce_id]; + st = hSCE->hCoreCoder[0]; + + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + if ( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) + { + /* reset the bitstream to atleast read the cng type and bandwidth for non transmitted SCE */ + st->bit_stream = st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream; + + if ( sce_id == st_ivas->hISMDTX.sce_id_dtx ) + { + st->read_sid_info = 1; /* read the sid info from bitstream */ + } + else + { + st->read_sid_info = 0; /* do not read the sid info from bitstream but use the estimated noise */ + } + + st->cng_paramISM_flag = 1; + } + else + { + st->cng_paramISM_flag = 0; + } + + return; +} + + +/*-------------------------------------------------------------------* + * ivas_ism_dtx_dec() + * + * ISM DTX Metadata decoding routine + *-------------------------------------------------------------------*/ + +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 */ +) +{ + int16_t ch, pos, num_obj, num_obj_prev; + int32_t ivas_total_brate; + + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + if ( st_ivas->nchan_transport == 1 ) + { + nb_bits_metadata[0] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + + return IVAS_ERR_OK; + } + + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + num_obj_prev = st_ivas->hDirAC->hParamIsm->num_obj; + } + else /* ism_mode == ISM_MODE_DISC */ + { + num_obj_prev = st_ivas->nchan_transport; + } + + /* read number of objects */ + if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) + { + num_obj = 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 ) + { + ( num_obj )++; + pos--; + } + + if ( num_obj != num_obj_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 ); + + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->hDirAC->hParamIsm->num_obj = num_obj; + } + else /* ism_mode == ISM_MODE_DISC */ + { + st_ivas->nchan_transport = num_obj; + } + } + else + { + num_obj = num_obj_prev; + } + + /* Metadata decoding and dequantization */ + ivas_param_ism_metadata_dtx_dec( st_ivas ); + + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + nb_bits_metadata[ch] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + } + + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + for ( ch = 0; ch < st_ivas->nchan_transport; ch++ ) + { + ivas_ism_preprocessing( st_ivas, ch ); + } + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 75c8e6c6b78c9e09c044f2d3567401b8765f62e8..94784e435c263bf464ec9b469298b7c3b106b0e2 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -499,6 +499,13 @@ 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 PARAM_ISM_DTX_CNG + for ( ch = 0; ch < *nchan_transport; ch++ ) + { + hSCE[ch]->hCoreCoder[0]->cng_paramISM_flag = 0; + } +#endif + pop_wmops(); return error; diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index f2f008ff376d28c7ba1f4d0b3fa772df42a493b7..165dddb54628a60347e91ab561dafe6b416c47d1 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -157,6 +157,9 @@ static void ivas_ism_get_proto_matrix( static void ivas_param_ism_compute_mixing_matrix( DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */ +#ifdef PARAM_ISM_DTX_CNG + ISM_DTX_DATA_DEC hISMDTX, /* i : ISM DTX handle */ +#endif float Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN], @@ -184,7 +187,11 @@ static void ivas_param_ism_compute_mixing_matrix( assert( ( hDirAC->hParamIsm->num_obj == 3 ) || ( hDirAC->hParamIsm->num_obj == 4 ) ); assert( nchan_transport == 2 ); +#ifdef PARAM_ISM_DTX_CNG + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) +#else if ( hDirAC->hParamIsm->flag_noisy_speech ) +#endif { num_wave = hDirAC->hParamIsm->num_obj; } @@ -206,7 +213,11 @@ static void ivas_param_ism_compute_mixing_matrix( { set_zero( cy_diag_tmp[w], nchan_out_woLFE ); +#ifdef PARAM_ISM_DTX_CNG + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) +#else if ( hDirAC->hParamIsm->flag_noisy_speech ) +#endif { dir_res_ptr = direct_response[w]; } @@ -245,7 +256,11 @@ static void ivas_param_ism_compute_mixing_matrix( set_zero( cy_diag, nchan_out_woLFE ); for ( w = 0; w < num_wave; w++ ) { +#ifdef PARAM_ISM_DTX_CNG + if ( hDirAC->hParamIsm->flag_noisy_speech || hISMDTX.dtx_flag ) +#else if ( hDirAC->hParamIsm->flag_noisy_speech ) +#endif { direct_power[w] = ( 1.0f / hDirAC->hParamIsm->num_obj ) * ref_power; } @@ -532,6 +547,10 @@ ivas_error ivas_param_ism_dec_open( } } +#ifdef PARAM_ISM_DTX_CNG + st_ivas->hISMDTX.dtx_flag = 0; +#endif + st_ivas->hDirAC = hDirAC; pop_wmops(); @@ -726,6 +745,9 @@ void ivas_param_ism_dec( { int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i; int16_t subframe_idx, slot_idx, index_slot, bin_idx; +#ifdef PARAM_ISM_DTX_CNG + int32_t ivas_total_brate; +#endif /* CLDFB Input Buffers */ float Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; @@ -762,14 +784,31 @@ void ivas_param_ism_dec( nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; } +#ifdef PARAM_ISM_DTX_CNG + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; +#endif + hSetup = st_ivas->hIntSetup; push_wmops( "ivas_param_ism_dec" ); /* Frame-level Processing */ /* De-quantization */ +#ifdef PARAM_ISM_DTX_CNG + if ( !( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) ) + { + ivas_param_ism_dec_dequant_DOA( hDirAC ); + ivas_param_ism_dec_dequant_powrat( hDirAC ); + st_ivas->hISMDTX.dtx_flag = 0; + } + else + { + st_ivas->hISMDTX.dtx_flag = 1; + } +#else ivas_param_ism_dec_dequant_DOA( hDirAC ); ivas_param_ism_dec_dequant_powrat( hDirAC ); +#endif /* obtain the direct response using EFAP */ if ( !( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) ) @@ -832,7 +871,11 @@ void ivas_param_ism_dec( } /* Compute mixing matrix */ +#ifdef PARAM_ISM_DTX_CNG + 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 ); +#else ivas_param_ism_compute_mixing_matrix( hDirAC, 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++ ) @@ -938,13 +981,96 @@ void ivas_param_ism_params_to_masa_param_mapping( int16_t azimuth[2]; int16_t elevation[2]; float power_ratio[2]; +#ifdef PARAM_ISM_DTX_CNG + int32_t ivas_total_brate; +#endif + hDirAC = st_ivas->hDirAC; nBins = hDirAC->num_freq_bands; + +#ifdef PARAM_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 ) ) + { + ivas_param_ism_dec_dequant_DOA( hDirAC ); + ivas_param_ism_dec_dequant_powrat( hDirAC ); + st_ivas->hISMDTX.dtx_flag = 0; + } + else + { + st_ivas->hISMDTX.dtx_flag = 1; + } +#else ivas_param_ism_dec_dequant_DOA( hDirAC ); ivas_param_ism_dec_dequant_powrat( hDirAC ); +#endif if ( hDirAC->hParamIsm->num_obj > 1 ) { +#ifdef PARAM_ISM_DTX_CNG + if ( st_ivas->hISMDTX.dtx_flag ) + { + float energy_ratio; + energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence, 2.0f ); + + hDirAC->numSimultaneousDirections = 1; + azimuth[0] = (int16_t) roundf( hDirAC->azimuth_values[0] ); + elevation[0] = (int16_t) roundf( hDirAC->elevation_values[0] ); + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hDirAC->azimuth[sf_idx][bin_idx] = azimuth[0]; + hDirAC->elevation[sf_idx][bin_idx] = elevation[0]; + + hDirAC->energy_ratio1[sf_idx][bin_idx] = energy_ratio; + + hDirAC->spreadCoherence[sf_idx][bin_idx] = 0.0f; + hDirAC->surroundingCoherence[sf_idx][bin_idx] = 0.0; + } + } + } + else + { + hDirAC->numSimultaneousDirections = 2; + for ( band_idx = 0; band_idx < hDirAC->hParamIsm->nbands; band_idx++ ) + { + brange[0] = hDirAC->hParamIsm->band_grouping[band_idx]; + brange[1] = hDirAC->hParamIsm->band_grouping[band_idx + 1]; + + azimuth[0] = (int16_t) roundf( hDirAC->azimuth_values[hDirAC->hParamIsm->obj_indices[band_idx][0][0]] ); + elevation[0] = (int16_t) roundf( hDirAC->elevation_values[hDirAC->hParamIsm->obj_indices[band_idx][0][0]] ); + power_ratio[0] = hDirAC->power_ratios[band_idx][0][0]; + + azimuth[1] = (int16_t) roundf( hDirAC->azimuth_values[hDirAC->hParamIsm->obj_indices[band_idx][0][1]] ); + elevation[1] = (int16_t) roundf( hDirAC->elevation_values[hDirAC->hParamIsm->obj_indices[band_idx][0][1]] ); + power_ratio[1] = hDirAC->power_ratios[band_idx][0][1]; + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ ) + { + hDirAC->azimuth[sf_idx][bin_idx] = azimuth[0]; + hDirAC->elevation[sf_idx][bin_idx] = elevation[0]; + hDirAC->energy_ratio1[sf_idx][bin_idx] = power_ratio[0]; + hDirAC->azimuth2[sf_idx][bin_idx] = azimuth[1]; + hDirAC->elevation2[sf_idx][bin_idx] = elevation[1]; + hDirAC->energy_ratio2[sf_idx][bin_idx] = power_ratio[1]; + } + } + } + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( bin_idx = 0; bin_idx < nBins; bin_idx++ ) + { + hDirAC->spreadCoherence[sf_idx][bin_idx] = 0.0f; + hDirAC->spreadCoherence2[sf_idx][bin_idx] = 0.0f; + hDirAC->surroundingCoherence[sf_idx][bin_idx] = 0.0; + } + } + } +#else hDirAC->numSimultaneousDirections = 2; for ( band_idx = 0; band_idx < hDirAC->hParamIsm->nbands; band_idx++ ) { @@ -981,6 +1107,7 @@ void ivas_param_ism_params_to_masa_param_mapping( hDirAC->surroundingCoherence[sf_idx][bin_idx] = 0.0; } } +#endif } else { @@ -1004,243 +1131,135 @@ void ivas_param_ism_params_to_masa_param_mapping( } -/*-------------------------------------------------------------------------* - * ivas_ism_bitrate_switching() - * - * - *-------------------------------------------------------------------------*/ - -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 */ -) +#ifdef PARAM_ISM_DTX_CNG +static void ivas_param_ism_dec_dequantize_DOA_dtx( + int16_t azi_bits, + int16_t ele_bits, + int16_t azi_idx, + int16_t ele_idx, + float *azi_val, + float *ele_val ) { - ivas_error error; - int32_t element_brate_tmp[MAX_NUM_OBJECTS]; - int16_t nSCE_old, nCPE_old; + int16_t nbits, npoints, angle_spacing, az_alpha, ele_alpha, tmp_alpha; - error = IVAS_ERR_OK; - - nCPE_old = st_ivas->nCPE; - nSCE_old = st_ivas->nSCE; - - ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, num_obj, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); - st_ivas->nSCE = st_ivas->nchan_transport; - - ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, 0, st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport, ( st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ); - - ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ); + /* Step 1: Determine angle spacing/n_points based on minimum value among elevation/azimuth bits */ + nbits = min( azi_bits, ele_bits ); - /* Initialize the needed renderer struct and destroy the unnecessary renderer struct */ - - /* select the renderer */ - ivas_renderer_select( st_ivas ); - ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); - if ( ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) && ( st_ivas->ism_mode == ISM_MODE_DISC ) ) + if ( nbits == ISM_ELEVATION_NBITS ) { - ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); + angle_spacing = 5; } - - if ( st_ivas->ism_mode != last_ism_mode ) + else { - /* EFAP handle */ - efap_free_data( &st_ivas->hEFAPdata ); + angle_spacing = (int16_t) ( ( 180.f / (float) ( 1 << nbits ) ) + 0.5f ); } - if ( st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM ) + npoints = (int16_t) ( ( 90 / angle_spacing ) + 0.5f ); + + /* sanity check */ + if ( angle_spacing == 360 ) { - /* switching from ParamISM to DiscISM */ + assert( azi_idx == 0 ); + assert( ele_idx == 0 ); - /* Deallocate the ParamISM struct */ - if ( st_ivas->hDirAC != NULL ) - { - ivas_param_ism_dec_close( st_ivas->hDirAC, st_ivas->hDecoderConfig->output_config ); - st_ivas->hDirAC = NULL; - } + *azi_val = 0.f; + *ele_val = 0.f; + return; + } - if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL ) - { - /* close the parametric binaural renderer */ - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); + /* Get the azimuth and elevation values */ + ele_alpha = 2 * npoints - 1; + assert( ( 0 <= ele_idx ) && ( ele_idx < ele_alpha ) ); + *ele_val = (float) ( ( ele_idx - npoints ) * angle_spacing ); - /* Open the TD Binaural renderer */ - ivas_td_binaural_open( st_ivas ); - } - else - { - /* close the ISM renderer and reinitialize */ - if ( st_ivas->hIsmRendererData != NULL ) - { - free( st_ivas->hIsmRendererData ); - st_ivas->hIsmRendererData = NULL; - } - ivas_ism_renderer_open( st_ivas ); - } + az_alpha = 4 * npoints - 1; + assert( ( 0 <= azi_idx ) && ( azi_idx < az_alpha ) ); + tmp_alpha = (int16_t) ( azi_idx * ( 360.f / az_alpha ) ); - if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) - { - /* close the parametric binaural renderer */ - ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); - - /* Open Crend Binaural renderer */ -#ifdef FIX_197_CREND_INTERFACE - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), - getRendAudioConfigFromIvasAudioConfig( st_ivas->intern_config ), - getRendAudioConfigFromIvasAudioConfig( st_ivas->hOutSetup.output_config ), - st_ivas->hRenderConfig, - st_ivas->hDecoderConfig->Opt_Headrotation, - st_ivas->hSetOfHRTF, - st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; -#else - ivas_crend_open( st_ivas ); -#endif - } + if ( tmp_alpha > 180.0f ) + { + *azi_val = ( (float) tmp_alpha ) - 360.0f; } - - if ( st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC ) + else { - /* switching from Discrete ISM to ParamISM */ - - /* Allocate and initialize the ParamISM struct */ - ivas_param_ism_dec_open( st_ivas ); - - if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL ) - { - /* open the parametric binaural renderer */ - ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ); - ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ); - - /* Close the TD Binaural renderer */ - if ( st_ivas->hBinRendererTd != NULL ) - { - ivas_td_binaural_close( &st_ivas->hBinRendererTd ); - } - - if ( st_ivas->hHrtfTD != NULL ) - { - st_ivas->hHrtfTD = NULL; - } - } - else - { - /* Close the ISM renderer */ - if ( st_ivas->hIsmRendererData != NULL ) - { - free( st_ivas->hIsmRendererData ); - st_ivas->hIsmRendererData = NULL; - } - } - - if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) - { - /* open the parametric binaural renderer */ - ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ); - ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ); - - /* close the crend binaural renderer */ -#ifdef FIX_197_CREND_INTERFACE - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); -#else - ivas_crend_close( st_ivas ); - - if ( st_ivas->hHrtf != NULL ) - { - st_ivas->hHrtf = NULL; - } -#endif - } + *azi_val = (float) tmp_alpha; } - return error; + return; } + /*------------------------------------------------------------------------- - * ivas_ism_dec_config() + * ivas_param_ism_metadata_dtx_dec() + * * - * - select ISM format mode - * - reconfigure the ISM format decoder *-------------------------------------------------------------------------*/ -/*! r : ISM format mode */ -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 */ +void ivas_param_ism_metadata_dtx_dec( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { - int32_t ivas_total_brate; - ISM_MODE last_ism_mode; - ivas_error error; - int16_t nchan_transport_old; + int16_t azi_idx, ele_idx, i; + int16_t last_bit_pos, next_bit_pos_orig; + uint16_t bstr_meta[IVAS_SID_5k2 / FRAMES_PER_SEC], *bstr_orig; + DEC_CORE_HANDLE st0; + PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM handle */ + int16_t coh_idx; + + if ( st_ivas->hDecoderConfig->ivas_total_brate == FRAME_NO_DATA ) + { + return; + } - error = IVAS_ERR_OK; + st0 = st_ivas->hSCE[0]->hCoreCoder[0]; + hParamIsm = st_ivas->hDirAC->hParamIsm; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + last_bit_pos = (int16_t) ( ( st_ivas->hDecoderConfig->ivas_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; - /* store last frame ISM mode */ - last_ism_mode = st_ivas->ism_mode; - /* Assumes that num of input objects are constant */ - nchan_transport_old = num_obj; - if ( last_ism_mode == ISM_MODE_PARAM ) + /* reverse the bitstream for easier reading of indices */ + for ( i = 0; i < min( MAX_BITS_METADATA, last_bit_pos ); i++ ) { - nchan_transport_old = 2; + bstr_meta[i] = st0->bit_stream[last_bit_pos - i]; } + st0->bit_stream = bstr_meta; + st0->total_brate = st_ivas->hDecoderConfig->ivas_total_brate; /* needed for BER detection in get_next_indice() */ - if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) - { - /* select ISM format mode */ - st_ivas->ism_mode = ivas_ism_mode_select( num_obj, ivas_total_brate ); + /* number of objects was already read in ivas_ism_get_dtx_dec() */ + /* update the position in the bitstream */ + st0->next_bit_pos += hParamIsm->num_obj; - st_ivas->nchan_transport = num_obj; - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - st_ivas->nchan_transport = 2; - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) - { - st_ivas->hDecoderConfig->nchan_out = num_obj; - } - } + /* read sce id */ + st_ivas->hISMDTX.sce_id_dtx = get_next_indice( st0, 1 ); - if ( st_ivas->ini_active_frame != 0 ) - { - /* ISM bit-rate switching */ - if ( st_ivas->hDecoderConfig->last_ivas_total_brate != IVAS_SID_5k2 && st_ivas->hDecoderConfig->last_ivas_total_brate != FRAME_NO_DATA ) - { - 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 ); - } - } - } - } - else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) - { - st_ivas->nchan_transport = num_obj; - } + /* read the noisy speech flag */ + hParamIsm->flag_noisy_speech = get_next_indice( st0, 1 ); + + /* decode the coherence */ + coh_idx = get_next_indice( st0, PARAM_ISM_DTX_COH_SCA_BITS ); + st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = (float) ( coh_idx ) / (float) ( ( 1 << PARAM_ISM_DTX_COH_SCA_BITS ) - 1 ); + st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence; - switch ( num_obj ) + /* get the DOA'S */ + for ( i = 0; i < hParamIsm->num_obj; i++ ) { - case 1: - st_ivas->transport_config = AUDIO_CONFIG_ISM1; - break; - case 2: - st_ivas->transport_config = AUDIO_CONFIG_ISM2; - break; - case 3: - st_ivas->transport_config = AUDIO_CONFIG_ISM3; - break; - case 4: - st_ivas->transport_config = AUDIO_CONFIG_ISM4; - break; - default: - st_ivas->transport_config = AUDIO_CONFIG_INVALID; - break; + /* read from bitstream and dequantize */ + azi_idx = get_next_indice( st0, PARAM_ISM_DTX_AZI_BITS ); + ele_idx = get_next_indice( st0, PARAM_ISM_DTX_ELE_BITS ); + + ivas_param_ism_dec_dequantize_DOA_dtx( PARAM_ISM_DTX_AZI_BITS, PARAM_ISM_DTX_ELE_BITS, azi_idx, ele_idx, &( st_ivas->hDirAC->azimuth_values[i] ), &( st_ivas->hDirAC->elevation_values[i] ) ); } - return error; + /* set the bitstream pointer to its original position */ + st0->bit_stream = bstr_orig; + st0->next_bit_pos = next_bit_pos_orig; + +#ifdef DEBUG_MODE_PARAM_ISM + dbgwrite( &( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence ), sizeof( float ), 1, 1, "./res/ParamISM_coh_dec.dat" ); +#endif + + return; } +#endif diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 67e32389509914097b56a40f28758c6c1aa0ca1f..a09c0bb4e701922a23186424d104f05ad62d7126 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -77,6 +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 PARAM_ISM_DTX_CNG + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st->cng_type = FD_CNG; /* TODO: move to init if possible */ + } +#endif + /*------------------------------------------------------------------* * Read audio bandwidth info *-----------------------------------------------------------------*/ @@ -93,7 +100,15 @@ ivas_error ivas_sce_dec( } else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_5k2 ) ) { +#ifdef PARAM_ISM_DTX_CNG + /* check if this is indeed needed? */ + if ( st_ivas->ivas_format != ISM_FORMAT ) + { + st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; + } +#else st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; +#endif } /* read the bandwidth */ @@ -215,12 +230,15 @@ ivas_error ivas_sce_dec( * Decoder *----------------------------------------------------------------*/ +#ifdef PARAM_ISM_DTX_CNG + if ( ( error = ivas_core_dec( st_ivas, hSCE, NULL, NULL, 1, output, outputHB, NULL, st_ivas->sba_dirac_stereo_flag ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_core_dec( NULL, hSCE, NULL, NULL, 1, output, outputHB, NULL, st_ivas->sba_dirac_stereo_flag ) ) != IVAS_ERR_OK ) +#endif { return error; } - if ( st_ivas->sba_dirac_stereo_flag && ( st->core_brate > SID_2k40 || st->cng_type == LP_CNG ) ) { /* skip addition of ACELP BWE for now, will be done after upmix */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index a78f747b6a3495be691f12e4beca64b5c0896792..3d9ed18351fc81d3d4fcc34d5d9dd53d1724a148 100755 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -414,6 +414,19 @@ typedef struct stereo_icbwe_dec_data_structure } STEREO_ICBWE_DEC_DATA, *STEREO_ICBWE_DEC_HANDLE; +#ifdef PARAM_ISM_DTX_CNG +/*----------------------------------------------------------------------------------* + * ISM DTX structure + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int16_t dtx_flag; + int16_t sce_id_dtx; + +} ISM_DTX_DATA_DEC; +#endif + /*----------------------------------------------------------------------------------* * DirAC decoder structure *----------------------------------------------------------------------------------*/ @@ -1936,6 +1949,9 @@ typedef struct Decoder_Struct /* multichannel modules */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; /* ISM metadata handles (storage for one frame of read ISM metadata) */ +#ifdef PARAM_ISM_DTX_CNG + ISM_DTX_DATA_DEC hISMDTX; /* ISM DTX structure */ +#endif ISM_RENDERER_HANDLE hIsmRendererData; /* ISM renderer handle */ DIRAC_DEC_HANDLE hDirAC; /* DirAC handle */ SPAR_DEC_HANDLE hSpar; /* SPAR handle */ diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 785e74cc7351e17aaecc31d4401cc47940b3e694..378ddec9aa921002273f5e12022674cc1b4b9819 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -161,6 +161,11 @@ 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 */ +#ifdef PARAM_ISM_DTX_CNG + , + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const ISM_MODE ism_mode /* i : ISM mode (only needed if format is ISM) */ +#endif ) { int16_t i, k; @@ -724,7 +729,20 @@ void stereo_tcx_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { +#ifdef PARAM_ISM_DTX_CNG + if ( ivas_format == ISM_FORMAT && ism_mode == ISM_MODE_PARAM ) + { + float buffer[L_FRAME16k]; + lerp( signal_outFB, buffer, st->L_frame, hTcxDec->L_frameTCX ); + ApplyFdCng( buffer, NULL, NULL, NULL, st, st->bfi, 0 ); + } + else + { + ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); + } +#else ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); +#endif } /* Generate additional comfort noise to mask potential coding artefacts */ diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 68bbd4e9ca8acdf63054777ad087779f3461ee87..0950b529f67151e65578f61417c3e9eaae4cbfb7 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -1345,6 +1345,10 @@ typedef struct Decoder_State /* MCT Channel mode indication: LFE, ignore channel? */ MCT_CHAN_MODE mct_chan_mode; +#ifdef PARAM_ISM_DTX_CNG + int16_t cng_paramISM_flag; /* CNG in Param-ISM flag */ + int16_t read_sid_info; /* For ParamISM, use the transmitted noise */ +#endif } Decoder_State, *DEC_CORE_HANDLE; diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 29682d5e73269a943cc91046042785c6d9b1c38d..272d36fb9c53484bf7bd4e564c7d5b7db96c42d2 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -314,10 +314,17 @@ ivas_error acelp_core_enc( if ( st->core_brate == SID_2k40 ) { - tmpF = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, exc, st->L_frame ); - i = (int16_t) ( ( tmpF + 2.0f ) * STEP_SID ); - i = min( max( i, 0 ), 127 ); - st->hTdCngEnc->old_enr_index = i; +#ifdef PARAM_ISM_DTX_CNG + if ( st->hTdCngEnc != NULL ) + { +#endif + tmpF = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, exc, st->L_frame ); + i = (int16_t) ( ( tmpF + 2.0f ) * STEP_SID ); + i = min( max( i, 0 ), 127 ); + st->hTdCngEnc->old_enr_index = i; +#ifdef PARAM_ISM_DTX_CNG + } +#endif } } diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 20aa31f3cac2f148ef7de09ebdb16a188716b174..a17369923cc51b78f06940f41c6f70f1073afe2d 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -709,11 +709,18 @@ void generate_comfort_noise_enc( /* Perform STFT synthesis */ SynthesisSTFT( fftBuffer, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn, tcx_transition, hFdCngCom, -1, -1 ); - /* update CNG excitation energy for LP_CNG */ - /* calculate the residual signal energy */ - enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize ); +#ifdef PARAM_ISM_DTX_CNG + if ( st->hTdCngEnc != NULL ) + { +#endif + /* update CNG excitation energy for LP_CNG */ + /* calculate the residual signal energy */ + enr = cng_energy( st->element_mode, st->bwidth, st->hDtxEnc->CNG_mode, st->hTdCngEnc->CNG_att, hFdCngCom->exc_cng, hFdCngCom->frameSize ); - st->hTdCngEnc->lp_ener = (float) ( 0.8f * st->hTdCngEnc->lp_ener + 0.2f * pow( 2.0f, enr ) ); + st->hTdCngEnc->lp_ener = (float) ( 0.8f * st->hTdCngEnc->lp_ener + 0.2f * pow( 2.0f, enr ) ); +#ifdef PARAM_ISM_DTX_CNG + } +#endif /* Overlap-add when previous frame is active */ if ( st->last_core_brate > SID_2k40 && st->codec_mode == MODE2 ) diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index e456a52a614f6ba95bf0eb6dbfa0e65564ba4fb5..683356c6c084d7bb0abd5d72739d18835d46e4c8 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -59,6 +59,10 @@ ivas_error init_encoder( const int16_t var_SID_rate_flag, /* i : flag for variable SID update rate */ const int16_t interval_SID, /* i : interval for SID update */ const int16_t vad_only_flag /* i : flag to indicate front-VAD structure */ +#ifdef PARAM_ISM_DTX_CNG + , + const ISM_MODE ism_mode /* i : ISM mode */ +#endif ) { int16_t i; @@ -462,7 +466,11 @@ ivas_error init_encoder( * LP-CNG *-----------------------------------------------------------------*/ +#ifdef PARAM_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 ) ) +#else if ( ( ( idchan == 0 && st->Opt_DTX_ON && st->element_mode != IVAS_CPE_MDCT ) || st->element_mode == EVS_MONO ) ) +#endif { if ( ( st->hTdCngEnc = (TD_CNG_ENC_HANDLE) malloc( sizeof( TD_CNG_ENC_DATA ) ) ) == NULL ) { diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 4b734d2653db3c6c8bf9dda023350c33130e2cb5..b3b0e1787a13988d74f66c0d4d24bd224b7f3fb8 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -846,7 +846,11 @@ ivas_error create_cpe_enc( st->mct_chan_mode = MCT_CHAN_MODE_LFE; } +#ifdef PARAM_ISM_DTX_CNG + if ( ( error = init_encoder( st, n, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 0, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = init_encoder( st, n, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 0 ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index b67d21bf8bb57a0e7ef1995b5ec3f03438d083a1..8995ebe92a4c5e93fb74909461bb122d2f9ca338 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -276,6 +276,11 @@ void ivas_initialize_handles_enc( st_ivas->hIsmMetaData[i] = NULL; } +#ifdef PARAM_ISM_DTX_CNG + /* ISM DTX handle */ + st_ivas->hISMDTX = NULL; +#endif + /* Q Metadata handle */ st_ivas->hQMetaData = NULL; @@ -436,6 +441,16 @@ ivas_error ivas_init_encoder( return error; } } + +#ifdef PARAM_ISM_DTX_CNG + if ( st_ivas->hEncoderConfig->Opt_DTX_ON && st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( ( error = ivas_ism_dtx_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } else if ( ivas_format == SBA_FORMAT || ivas_format == MASA_FORMAT ) { @@ -923,6 +938,15 @@ void ivas_destroy_enc( } } +#ifdef PARAM_ISM_DTX_CNG + /* ISM DTX Handle */ + if ( st_ivas->hISMDTX != NULL ) + { + free( st_ivas->hISMDTX ); + st_ivas->hISMDTX = NULL; + } +#endif + /* Q Metadata handle */ ivas_qmetadata_close( &( st_ivas->hQMetaData ) ); diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..ab531bc291d1a4ab8ac6a87459078911cb269949 --- /dev/null +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -0,0 +1,339 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include "options.h" +#include "ivas_cnst.h" +#include "prot.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#ifdef PARAM_ISM_DTX_CNG + +/*-------------------------------------------------------------------* + * ivas_ism_dtx_open() + * + * Open ISM DTX handle + *-------------------------------------------------------------------*/ + +ivas_error ivas_ism_dtx_open( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + ivas_error error; + ISM_DTX_HANDLE hISMDTX; + int16_t i; + + error = IVAS_ERR_OK; + + /* Assign memory to DirAC handle */ + if ( ( hISMDTX = (ISM_DTX_HANDLE) malloc( sizeof( ISM_DTX_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM DTX Handle \n" ) ); + } + + hISMDTX->dtx_flag = 0; + hISMDTX->sce_id_dtx = 0; + + set_s( hISMDTX->dtx_speech_buffer_enc, 0, PARAM_ISM_HYS_BUF_SIZE ); + + for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) + { + set_f( hISMDTX->long_term_energy_stereo_dmx_enc[i], 0.0f, PARAM_ISM_HYS_BUF_SIZE ); + } + + set_f( hISMDTX->coh, 0.0f, MAX_NUM_OBJECTS ); + + st_ivas->hISMDTX = hISMDTX; + + return error; +} + + +/*-------------------------------------------------------------------* + * ivas_ism_dtx_enc() + * + * Analysis and decision about DTX in ISM format + *-------------------------------------------------------------------*/ + +/*! 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 */ +) +{ + int16_t i, val, dtx_flag; + + dtx_flag = 0; + *sid_flag = 0; + + /* Move the DTX/CNG speech buffer */ + for ( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = st_ivas->hISMDTX->dtx_speech_buffer_enc[i + 1]; + } + + /* If both TCs are active frame, do not do any post processing */ + if ( !( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == -1 && st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == -1 ) ) + { + /* covers 3 cases + * case 1: ch0 -> Inactive Frame, ch 1 -> Inactive Frame -> do not do any post-processing (Activate DTX) + * case 2: ch0 -> Inactive Frame, ch 1 -> Active Frame + * case 3: ch0 -> Active Frame, ch 1 -> Inactive Frame + */ + + /* case 2 -> ch 0 is inactive, set it to active */ + if ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == -1 && ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = 0; + } + + /* case 3 -> ch 1 is inactive, set it to active */ + if ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == -1 && ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = 0; + } + + /* case 1: both TCs are inactive */ + if ( ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) && ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = 1; + } + } + else + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = 0; + } + + /* Do a decision based on hysteresis */ + st_ivas->hISMDTX->dtx_flag = 1; + + for ( i = 1; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) + { + if ( ( st_ivas->hISMDTX->dtx_speech_buffer_enc[i + 1] == 1 ) && ( st_ivas->hISMDTX->dtx_speech_buffer_enc[i - 1] == 1 ) && ( st_ivas->hISMDTX->dtx_speech_buffer_enc[i] == 0 ) ) + { + st_ivas->hISMDTX->dtx_speech_buffer_enc[i] = 1; + } + } + + val = sum_s( st_ivas->hISMDTX->dtx_speech_buffer_enc, PARAM_ISM_HYS_BUF_SIZE ); + + if ( val < 7 ) + { + for ( i = 0; i < PARAM_ISM_HYS_BUF_SIZE; i++ ) + { + st_ivas->hISMDTX->dtx_flag = st_ivas->hISMDTX->dtx_flag && st_ivas->hISMDTX->dtx_speech_buffer_enc[i]; + } + } + + if ( st_ivas->hISMDTX->dtx_flag ) + { + /* case 1 */ + /* force FD-CNG */ + st_ivas->hSCE[0]->hCoreCoder[0]->cng_type = FD_CNG; + st_ivas->hSCE[1]->hCoreCoder[0]->cng_type = FD_CNG; + + /* synchronize the core bitrate */ + if ( ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == -1 ) && ( st_ivas->hSCE[0]->hCoreCoder[0]->last_core_brate == SID_2k40 || st_ivas->hSCE[0]->hCoreCoder[0]->last_core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hSCE[0]->hCoreCoder[0]->core_brate = st_ivas->hSCE[0]->hCoreCoder[0]->last_core_brate; + reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES ); + } + + st_ivas->hSCE[1]->hCoreCoder[0]->core_brate = st_ivas->hSCE[0]->hCoreCoder[0]->core_brate; + } + else + { + if ( ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) && ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hSCE[0]->hCoreCoder[0]->core_brate = -1; + st_ivas->hSCE[1]->hCoreCoder[0]->core_brate = -1; + + /* since ch0 is detected as inactive frame and we are setting it as active frame, + we need to reset bitstream pointer and write the ivas_format once more */ + ivas_write_format( st_ivas ); + } + + /* case 3 -> ch 1 is inactive, set it to active */ + if ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == -1 && ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hSCE[1]->hCoreCoder[0]->core_brate = -1; + } + + /* case 2 -> ch 0 is inactive, set it to active */ + if ( st_ivas->hSCE[1]->hCoreCoder[0]->core_brate == -1 && ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 || st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) ) + { + st_ivas->hSCE[0]->hCoreCoder[0]->core_brate = -1; + + /* since ch0 is detected as inactive frame and we are setting it as active frame, + we need to reset bitstream pointer and write the ivas_format once more */ + ivas_write_format( st_ivas ); + } + } + + if ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == SID_2k40 ) + { + *sid_flag = 1; + dtx_flag = 1; + } + + if ( st_ivas->hSCE[0]->hCoreCoder[0]->core_brate == FRAME_NO_DATA ) + { + dtx_flag = 1; + } + + return dtx_flag; +} + + +/*-------------------------------------------------------------------* + * ivas_ism_get_sce_id_dtx() + * + * + *-------------------------------------------------------------------*/ + +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 */ + +) +{ + float tmp_energy[MAX_NUM_OBJECTS], total_energy; + int16_t i, j; + + if ( nchan_transport == 1 ) + { + hISMDTX->sce_id_dtx = 0; + + return; + } + + /* Initialize*/ + set_f( tmp_energy, 0.0f, MAX_NUM_OBJECTS ); + + /* compute long term energy parameter */ + total_energy = 0.0f; + for ( j = 0; j < nchan_transport; j++ ) + { + for ( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) + { + hISMDTX->long_term_energy_stereo_dmx_enc[j][i] = hISMDTX->long_term_energy_stereo_dmx_enc[j][i + 1]; + } + + hISMDTX->long_term_energy_stereo_dmx_enc[j][PARAM_ISM_HYS_BUF_SIZE - 1] = sum2_f( hSCE[j]->hCoreCoder[0]->input, input_frame ); + + tmp_energy[j] = sum_f( hISMDTX->long_term_energy_stereo_dmx_enc[j], PARAM_ISM_HYS_BUF_SIZE ); + + total_energy += tmp_energy[j]; + } + + /* determine the sce_id */ + hISMDTX->sce_id_dtx = 0; + for ( j = 1; j < nchan_transport; j++ ) + { + if ( tmp_energy[j] > tmp_energy[hISMDTX->sce_id_dtx] ) + { + hISMDTX->sce_id_dtx = j; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * ivas_ism_coh_estim_dtx_enc() + * + * + *-------------------------------------------------------------------*/ + +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 */ + +) +{ + Encoder_State *st, *st_id0; + int16_t sce_id, i; + float acorr_ene[PARAM_ISM_MAX_DMX], xcorr_ene; + + if ( nchan_transport == 1 ) + { + hISMDTX->coh[0] = 0.f; + return; + } + + /* Compute Coherence */ + acorr_ene[hISMDTX->sce_id_dtx] = 0.0f; + st_id0 = hSCE[hISMDTX->sce_id_dtx]->hCoreCoder[0]; + + for ( i = 0; i < input_frame; i++ ) + { + acorr_ene[hISMDTX->sce_id_dtx] += st_id0->input[i] * st_id0->input[i]; + } + + for ( sce_id = 0; sce_id < nchan_transport; sce_id++ ) + { + if ( sce_id == hISMDTX->sce_id_dtx ) + { + hISMDTX->coh[sce_id] = 1.0f; + continue; + } + + st = hSCE[sce_id]->hCoreCoder[0]; + + acorr_ene[sce_id] = 0.0f; + xcorr_ene = 0.0f; + + for ( i = 0; i < input_frame; i++ ) + { + acorr_ene[sce_id] += st->input[i] * st->input[i]; + xcorr_ene += st_id0->input[i] * st->input[i]; + } + + hISMDTX->coh[sce_id] = fabsf( xcorr_ene ) / ( sqrtf( ( acorr_ene[hISMDTX->sce_id_dtx] * acorr_ene[sce_id] ) + EPSILON ) ); + + /* ensure value of coherence is between [0,1] */ + hISMDTX->coh[sce_id] = check_bounds( hISMDTX->coh[sce_id], 0.0f, 1.0f ); + } + + return; +} +#endif diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 0207961e51930d9d78424c94976a234939ffc7d1..9f9637d95e13f552f79d4fae0c4cc797d8e427bb 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -86,11 +86,23 @@ ivas_error ivas_ism_enc( float lf_E[1][2 * VOIC_BINS]; /* per bin spectrum energy in lf */ int16_t localVAD_HE_SAD[1]; /* local HE VAD */ int16_t i, nBits; +#ifdef PARAM_ISM_DTX_CNG + int16_t dtx_flag, sid_flag; +#endif ivas_error error; + push_wmops( "ivas_ism_enc" ); + + /*------------------------------------------------------------------* + * Initialization + *-----------------------------------------------------------------*/ + error = IVAS_ERR_OK; - push_wmops( "ivas_ism_enc" ); +#ifdef PARAM_ISM_DTX_CNG + dtx_flag = 0; + sid_flag = 0; +#endif /*------------------------------------------------------------------* * Preprocesing @@ -167,13 +179,55 @@ ivas_error ivas_ism_enc( vad_flag[sce_id] = st->vad_flag; } +#ifdef PARAM_ISM_DTX_CNG + /*------------------------------------------------------------------* + * DTX analysis + *-----------------------------------------------------------------*/ + + if ( st_ivas->hEncoderConfig->Opt_DTX_ON && st_ivas->ism_mode == ISM_MODE_PARAM ) + { + /* 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 */ + dtx_flag = ivas_ism_dtx_enc( st_ivas, &sid_flag ); + + if ( sid_flag ) + { + /* estimate coherence between objects */ + ivas_ism_coh_estim_dtx_enc( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->nchan_transport, input_frame ); + } + +#ifdef DEBUG_MODE_PARAM_ISM + dbgwrite( &( st_ivas->hISMDTX->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" ); +#endif + } +#endif + /*------------------------------------------------------------------* * Analysis of objects, configuration and decision about bitrates per channel + * Metadata quantization and encoding *-----------------------------------------------------------------*/ - /* Metadata encoding */ +#ifdef PARAM_ISM_DTX_CNG if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { + ivas_param_ism_compute_noisy_speech_flag( st_ivas ); + } + + if ( dtx_flag ) + { + if ( sid_flag ) + { + ivas_param_ism_metadata_dtx_enc( st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, st_ivas->hIsmMetaData, st_ivas->hISMDTX, st_ivas->hDirAC->hParamIsm ); + } + } + else +#endif + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { +#ifndef PARAM_ISM_DTX_CNG /* Move the Noisy speech buffer */ for ( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) { @@ -203,7 +257,7 @@ ivas_error ivas_ism_enc( { st_ivas->hDirAC->hParamIsm->flag_noisy_speech = st_ivas->hDirAC->hParamIsm->flag_noisy_speech && st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i]; } - +#endif 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 ); } else /* ISM_MODE_DISC */ @@ -221,13 +275,18 @@ ivas_error ivas_ism_enc( { ivas_write_format_sid( st_ivas->hEncoderConfig->ivas_format, IVAS_SCE, st->hBstr ); - /* write unused bits */ - nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; - while ( nBits > 0 ) +#ifdef PARAM_ISM_DTX_CNG + if ( st_ivas->ism_mode != ISM_MODE_PARAM ) +#endif { - i = min( nBits, 16 ); - push_indice( st->hBstr, IND_UNUSED, 0, i ); - nBits -= i; + /* write unused bits */ + nBits = ( IVAS_SID_5k2 - SID_2k40 ) / 50 - SID_FORMAT_NBITS; + while ( nBits > 0 ) + { + i = min( nBits, 16 ); + push_indice( st->hBstr, IND_UNUSED, 0, i ); + nBits -= i; + } } } @@ -270,9 +329,14 @@ ivas_error ivas_ism_enc( * Encoder *----------------------------------------------------------------*/ - if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8[sce_id], old_inp_16k[sce_id], ener[sce_id], A[sce_id], Aw[sce_id], epsP[sce_id], lsp_new[sce_id], lsp_mid[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer[sce_id], imagBuffer[sce_id], old_wsp[sce_id], loc_harm[sce_id], cor_map_sum[sce_id], vad_flag_dtx[sce_id], enerBuffer[sce_id], fft_buff[sce_id], 0, ISM_FORMAT, 0 ) ) != IVAS_ERR_OK ) +#ifdef PARAM_ISM_DTX_CNG + if ( !dtx_flag || ( dtx_flag && sce_id == st_ivas->hISMDTX->sce_id_dtx ) ) +#endif { - return error; + if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8[sce_id], old_inp_16k[sce_id], ener[sce_id], A[sce_id], Aw[sce_id], epsP[sce_id], lsp_new[sce_id], lsp_mid[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer[sce_id], imagBuffer[sce_id], old_wsp[sce_id], loc_harm[sce_id], cor_map_sum[sce_id], vad_flag_dtx[sce_id], enerBuffer[sce_id], fft_buff[sce_id], 0, ISM_FORMAT, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } } /*----------------------------------------------------------------* @@ -286,7 +350,90 @@ ivas_error ivas_ism_enc( st->hTranDet->transientDetector.prev_bIsAttackPresent = st->hTranDet->transientDetector.bIsAttackPresent; } +#ifdef PARAM_ISM_DTX_CNG + if ( dtx_flag ) + { + for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ ) + { + if ( sce_id != st_ivas->hISMDTX->sce_id_dtx ) + { + 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; + } + } + } +#endif + pop_wmops(); return error; } + + +/*------------------------------------------------------------------------- + * ivas_ism_enc_config() + * + * - select ISM format mode + * - reconfigure the ISM format encoder + *-------------------------------------------------------------------------*/ + +/*! r : ISM format mode */ +ivas_error ivas_ism_enc_config( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + ivas_error error; + ISM_MODE last_ism_mode; + int16_t nchan_transport_old; + int16_t nSCE_old, nCPE_old; + + error = IVAS_ERR_OK; + last_ism_mode = st_ivas->ism_mode; + + /* select ISM format mode */ + st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); + + /* ISM bit-rate switching */ + if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hEncoderConfig->ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) ) + { + int32_t element_brate_tmp[MAX_NUM_OBJECTS]; + + nchan_transport_old = st_ivas->nchan_transport; + + /* Reset and Initialize */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->nchan_transport = 2; + } + else + { + st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp; + } + + nCPE_old = st_ivas->nCPE; + nSCE_old = st_ivas->nSCE; + st_ivas->nSCE = st_ivas->nchan_transport; + st_ivas->nCPE = 0; + + ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); + ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ); + + if ( st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC ) + { + /* Allocate and Initialize the memory used by ParamISM when switch from Discrete ISM */ + if ( ( error = ivas_param_ism_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM ) + { + /* Deallocate the memory used by ParamISM when switch to Discrete ISM */ + ivas_param_ism_enc_close( st_ivas->hDirAC, st_ivas->hEncoderConfig->input_Fs ); + st_ivas->hDirAC = NULL; + } + } + + return error; +} diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index 970a54b665f106d03312ce0325c479df4026454f..9aaa3af4b41a20d4eb3ee8794d81d230da96d959 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -184,7 +184,7 @@ ivas_error ivas_ism_metadata_enc( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: incorrect ISM mode" ); } - 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 ) ) + 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 ) { /* no metadata encoding in CNG */ pop_wmops(); diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 98054cf51ef6c8d0c0de66abfdd0662e9ca161e9..d7e3a9a35d2aba477f133b5cf6defb554ee2f52b 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -286,10 +286,8 @@ ivas_error ivas_param_ism_enc_open( return error; } - ivas_param_ism_config( hDirAC->hParamIsm ); - /* Assign memories for Band and Block grouping */ hDirAC->hParamIsm->nbands = MAX_PARAM_ISM_NBANDS; @@ -318,8 +316,8 @@ ivas_error ivas_param_ism_enc_open( *-------------------------------------------------------------------------*/ void ivas_param_ism_enc_close( - DIRAC_ENC_HANDLE hDirAC, /* i/o: encoder DirAC handle */ - const int32_t input_Fs /* i : input sampling_rate */ + DIRAC_ENC_HANDLE hDirAC, /* i/o: encoder DirAC handle */ + const int32_t input_Fs /* i : input sampling_rate */ ) { ivas_FB_mixer_close( &hDirAC->hFbMixer, input_Fs ); @@ -400,70 +398,178 @@ void ivas_param_ism_enc( return; } + +#ifdef PARAM_ISM_DTX_CNG +static void ivas_param_ism_enc_quantize_DOA_dtx( + float azimuth, + float elevation, + int16_t azi_bits, + int16_t ele_bits, + int16_t *azi_idx, + int16_t *ele_idx ) +{ + int16_t nbits, npoints, angle_spacing, az_alpha, ele_alpha; + float azi_val; + + /* Step 1: Determine angle spacing/n_points based on minimum value among elevation/azimuth bits */ + nbits = min( azi_bits, ele_bits ); + + if ( nbits == ISM_ELEVATION_NBITS ) + { + angle_spacing = 5; + } + else + { + angle_spacing = (int16_t) ( ( 180.f / (float) ( 1 << nbits ) ) + 0.5f ); + } + + npoints = (int16_t) ( ( 90 / angle_spacing ) + 0.5f ); + + /* Step 2: Quantize Elevation */ + ele_alpha = 2 * npoints - 1; + *ele_idx = (int16_t) ( ( elevation / angle_spacing ) + 0.5f ) + npoints; + if ( *ele_idx >= ele_alpha ) + { + *ele_idx = ele_alpha - 1; + } + assert( ( 0 <= *ele_idx ) && ( *ele_idx < ele_alpha ) ); + + /* Step 3: Quantize Azimuth */ + az_alpha = 4 * npoints - 1; + + /* Convert azimuth in {-180,180} into {0,360} before quantization */ + if ( azimuth >= 0 ) + { + azi_val = azimuth; + } + else + { + azi_val = azimuth + 360.f; + } + + /* Obtain the index of quantized azimuth values */ + *azi_idx = (int16_t) ( ( ( azi_val / 360.f ) * az_alpha ) + 0.5f ); + if ( *azi_idx == az_alpha ) + { + /*wrap around the azimuth angle*/ + *azi_idx = 0; + } + assert( ( 0 <= *azi_idx ) && ( *azi_idx < az_alpha ) ); + + return; +} + + /*------------------------------------------------------------------------- - * ivas_ism_enc_config() + * ivas_param_ism_metadata_dtx_enc() * - * - select ISM format mode - * - reconfigure the ISM format encoder *-------------------------------------------------------------------------*/ -/*! r : ISM format mode */ -ivas_error ivas_ism_enc_config( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +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 */ ) { - ivas_error error; - ISM_MODE last_ism_mode; - int16_t nchan_transport_old; - int16_t nSCE_old, nCPE_old; + int16_t i, nBits, nBits_unused; + int16_t azi_idx, ele_idx; + int16_t coh_idx; - error = IVAS_ERR_OK; - last_ism_mode = st_ivas->ism_mode; + nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; + nBits -= SID_FORMAT_NBITS; + + /* Transmit the metadata */ + /* write number of objects - unary coding */ + for ( i = 1; i < hParamIsm->num_obj; i++ ) + { + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 ); + } + push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 ); + + /* write sce id */ + push_indice( hBstr, IND_ISM_SCE_ID_DTX, hISMDTX->sce_id_dtx, 1 ); - /* select ISM format mode */ - st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); + /* write noisy speech flag */ + push_indice( hBstr, IND_ISM_NOISY_SPEECH_FLAG, hParamIsm->flag_noisy_speech, 1 ); - /* ISM bit-rate switching */ - if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hEncoderConfig->ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) ) + /* quantize and write coherence */ + coh_idx = (int16_t) ( hISMDTX->coh[0] * ( ( 1 << PARAM_ISM_DTX_COH_SCA_BITS ) - 1 ) + 0.5f ); + 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 ); + + for ( i = 0; i < hParamIsm->num_obj; i++ ) { - int32_t element_brate_tmp[MAX_NUM_OBJECTS]; + 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 ); + push_indice( hBstr, IND_ISM_ELEVATION, ele_idx, PARAM_ISM_DTX_ELE_BITS ); + } - nchan_transport_old = st_ivas->nchan_transport; +#ifdef DEBUG_MODE_PARAM_ISM + dbgwrite( &( hParamIsm->coh ), sizeof( float ), 1, 1, "./res/ParamISM_coh_enc.dat" ); +#endif - /* Reset and Initialize */ - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - st_ivas->nchan_transport = 2; - } - else - { - st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp; - } + /* 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; + } - nCPE_old = st_ivas->nCPE; - nSCE_old = st_ivas->nSCE; - st_ivas->nSCE = st_ivas->nchan_transport; - st_ivas->nCPE = 0; +#ifdef DEBUGGING + assert( hBstr->nb_bits_tot == nBits ); +#endif - ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); - ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport, ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE ); + return; +} + + +/*-------------------------------------------------------------------* + * ivas_param_ism_compute_noisy_speech_flag() + * + * + *-------------------------------------------------------------------*/ + +void ivas_param_ism_compute_noisy_speech_flag( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + int16_t i; - if ( st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC ) + /* Move the Noisy speech buffer */ + for ( i = 0; i < ( PARAM_ISM_HYS_BUF_SIZE - 1 ); i++ ) + { + st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i] = st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i + 1]; + } + + /* For the current frame, make a decision based on some core-coder flags */ + if ( st_ivas->hSCE[0]->hCoreCoder[0]->flag_noisy_speech_snr && st_ivas->hSCE[1]->hCoreCoder[0]->flag_noisy_speech_snr ) + { + if ( st_ivas->hSCE[0]->hCoreCoder[0]->vad_flag && st_ivas->hSCE[1]->hCoreCoder[0]->vad_flag ) { - /* Allocate and Initialize the memory used by ParamISM when switch from Discrete ISM */ - if ( ( error = ivas_param_ism_enc_open( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i] = 0; } - - if ( st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM ) + else { - /* Deallocate the memory used by ParamISM when switch to Discrete ISM */ - ivas_param_ism_enc_close( st_ivas->hDirAC, st_ivas->hEncoderConfig->input_Fs ); - st_ivas->hDirAC = NULL; + st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i] = 1; } } + else + { + + st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i] = 0; + } - return error; + /* Do a decision based on hysterisis */ + st_ivas->hDirAC->hParamIsm->flag_noisy_speech = 1; + for ( i = 0; i < PARAM_ISM_HYS_BUF_SIZE; i++ ) + { + st_ivas->hDirAC->hParamIsm->flag_noisy_speech = st_ivas->hDirAC->hParamIsm->flag_noisy_speech && st_ivas->hDirAC->hParamIsm->noisy_speech_buffer[i]; + } + + + return; } +#endif diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index a3efe9ac7622acc3d7bc64970d03719cb334ca5d..195fc01cf757e155ade5d714b45c947321b6377b 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -343,7 +343,11 @@ ivas_error create_sce_enc( st->total_brate = hSCE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; +#ifdef PARAM_ISM_DTX_CNG + if ( ( error = init_encoder( st, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = init_encoder( st, 0, st_ivas->hEncoderConfig->var_SID_rate_flag, st_ivas->hEncoderConfig->interval_SID, 0 ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index ab5ef2c9620382f367e92ca8c90e8e1b81e75752..36505b966c90a109defd0a54197ab5949af7c487 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -189,7 +189,11 @@ ivas_error ivas_spar_enc_open( hSpar->hCoreCoderVAD->total_brate = hEncoderConfig->ivas_total_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ hSpar->hCoreCoderVAD->mct_chan_mode = MCT_CHAN_MODE_IGNORE; +#ifdef PARAM_ISM_DTX_CNG + if ( ( error = init_encoder( hSpar->hCoreCoderVAD, 0, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 1, st_ivas->ism_mode ) ) != IVAS_ERR_OK ) +#else if ( ( error = init_encoder( hSpar->hCoreCoderVAD, 0, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 1 ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index ecf730cffa5fd4e854c9d85e75b179ad40308242..1f88d0c0c1e9c371edbad7bd526f17cf6769c5dc 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -551,6 +551,24 @@ typedef struct ivas_stereo_classifier_data_structure } STEREO_CLASSIF_DATA, *STEREO_CLASSIF_HANDLE; +#ifdef PARAM_ISM_DTX_CNG +/*----------------------------------------------------------------------------------* + * ISM DTX structure + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int16_t dtx_flag; + int16_t sce_id_dtx; + + int16_t dtx_speech_buffer_enc[PARAM_ISM_HYS_BUF_SIZE]; + + float long_term_energy_stereo_dmx_enc[MAX_NUM_OBJECTS][PARAM_ISM_HYS_BUF_SIZE]; + float coh[MAX_NUM_OBJECTS]; + +} ISM_DTX_DATA, *ISM_DTX_HANDLE; +#endif + /*----------------------------------------------------------------------------------* * Front-VAD structure *----------------------------------------------------------------------------------*/ @@ -1057,6 +1075,9 @@ typedef struct /* multichannel modules */ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS]; /* ISM metadata handles (storage for one frame of read ISM metadata) */ +#ifdef PARAM_ISM_DTX_CNG + ISM_DTX_HANDLE hISMDTX; /* ISM DTX handle */ +#endif DIRAC_ENC_HANDLE hDirAC; /* DirAC data handle */ SPAR_ENC_HANDLE hSpar; /* SPAR encoder handle */ MASA_ENCODER_HANDLE hMasa; /* MASA encoder data and configuration */ diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index b11435e25b35644090fd77828b51c80b2198909f..0005d8c6f6fa29e771f5c71899513b4a485eec1b 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -457,7 +457,11 @@ void stereo_tcx_core_enc( mvr2r( lsp_q, st->lsp_old, M ); } +#ifdef PARAM_ISM_DTX_CNG + if ( st->Opt_DTX_ON && !st->tcxonly && st->hTdCngEnc != NULL ) +#else if ( st->Opt_DTX_ON && !st->tcxonly ) +#endif { /* update CNG parameters in active frames */ if ( st->bwidth == NB && st->enableTcxLpc && st->core != ACELP_CORE ) diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c old mode 100644 new mode 100755 index 8049f5215c329d6e7b7d121196321aeb8d1763cc..33f1d0243788f63e56b10a888dc27933438af8c7 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -873,12 +873,22 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "8kHz input sampling rate is not supported in IVAS." ); } +#ifdef PARAM_ISM_DTX_CNG + 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 + ) ) +#else if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_format != MONO_FORMAT && ( ( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->nchan_inp > 1 ) || // ToDo: see Issue 113 ( 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 ) ) +#endif { return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } @@ -909,6 +919,13 @@ static ivas_error configureEncoder( return error; } +#ifdef PARAM_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 ) { hIvasEnc->hCoreCoder = st_ivas->hSCE[0]->hCoreCoder[0]; /* Note: this is needed for switching in EVS mono */ diff --git a/lib_enc/rst_enc.c b/lib_enc/rst_enc.c index e069d6d94ee42b919c2bff1fc92068db5d63db34..2f19c41665aba07c87b803d0589eb8e2041e6090 100644 --- a/lib_enc/rst_enc.c +++ b/lib_enc/rst_enc.c @@ -84,8 +84,15 @@ void CNG_reset_enc( set_f( voice_factors, 1.0, NB_SUBFR16k ); - /* Reset active frame counter */ - st->hTdCngEnc->act_cnt2 = 0; +#ifdef PARAM_ISM_DTX_CNG + if ( st->hTdCngEnc != NULL ) + { +#endif + /* Reset active frame counter */ + st->hTdCngEnc->act_cnt2 = 0; +#ifdef PARAM_ISM_DTX_CNG + } +#endif /* deactivate bass post-filter */ st->bpf_off = 1; diff --git a/scripts/config/ivas_modes.json b/scripts/config/ivas_modes.json index 5eabeae024dadadb69f1efce29905234f711e7b5..77ffb55c1a9f36b18cbbe1b30d104b97ff2a0fa2 100644 --- a/scripts/config/ivas_modes.json +++ b/scripts/config/ivas_modes.json @@ -2047,6 +2047,42 @@ 256000 ] } + }, + "ISM3_b{bitrate}_dtx_{bandwidth}_cbr": { + "encmodeoption": [ + "-dtx", + "-ism", + "3" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM3", + "table_name": "ISM3@{table_bitrate} kbps DTX {bandwidth}", + "nummetadata": 3, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": false, + "amr": false, + "mono": false, + "bitrates": { + "wb": [ + 24400, + 32000 + ], + "swb": [ + 24400, + 32000 + ], + "fb": [ + 32000 + ] + } } }, "ISM4": { @@ -2108,6 +2144,42 @@ 256000 ] } + }, + "ISM4_b{bitrate}_dtx_{bandwidth}_cbr": { + "encmodeoption": [ + "-dtx", + "-ism", + "4" + ], + "encoptions": [ + "-max_band", + "{bandwidth}" + ], + "dec": { + "EXT": [] + }, + "in_config": "ISM4", + "table_name": "ISM4@{table_bitrate} kbps DTX {bandwidth}", + "nummetadata": 4, + "metadatafilenames": [ + "test_ISM_trajectory{mdi}.csv" + ], + "rs": false, + "amr": false, + "mono": false, + "bitrates": { + "wb": [ + 24400, + 32000 + ], + "swb": [ + 24400, + 32000 + ], + "fb": [ + 32000 + ] + } } }, "stereo": { @@ -2915,4 +2987,4 @@ } } } -} \ No newline at end of file +}