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
+}