diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 5860b0a9708d869b8a4f66c31a0022ea33a2e12e..2b44db88b233462776db5d8a62daa8c2fb0de5b8 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -291,6 +291,7 @@
+
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index 5476cf558887abd6d7b549246ce9da5696876e3b..df6c4bb090b495e402e70480ea5747b8532edb33 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -584,6 +584,9 @@
dec_ivas_c
+
+ dec_ivas_c
+
diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com.c
index 2441cf7973792d920a5b72a94ecf98317ba1356f..a080befbaac6ae00ccf1f91e1a2480e2019164e0 100644
--- a/lib_com/ivas_mcmasa_com.c
+++ b/lib_com/ivas_mcmasa_com.c
@@ -91,6 +91,7 @@ void ivas_mcmasa_set_separate_channel_mode(
return;
}
+#ifndef MCMASA_BITRATE_SWITCHING
/*--------------------------------------------------------------------------*
* ivas_mcmasa_mono_brate()
*
@@ -112,3 +113,39 @@ int32_t ivas_mcmasa_mono_brate(
return ( const int32_t )( MCMASA_MONOBITRATIO * ivas_total_brate );
}
}
+#else
+/*--------------------------------------------------------------------------*
+ * ivas_mcmasa_split_brate()
+ *
+ * Split the total bitrate to elements in McMASA
+ *--------------------------------------------------------------------------*/
+void ivas_mcmasa_split_brate(
+ const uint8_t separateChannelEnabled, /* i : Transport running in "separate channel" mode */
+ const int32_t ivas_total_brate, /* i : Total bitrate available to be split */
+ const int16_t nSCE, /* i : Number of SCEs in use (0 or 1) */
+ const int16_t nCPE, /* i : Number of CPEs in use (0 or 1) */
+ int32_t *brate_sce, /* o : Pointer to SCE element bitrate */
+ int32_t *brate_cpe /* o : Pointer to CPE element bitrate */
+)
+{
+ if ( separateChannelEnabled )
+ {
+ /* 25% of total bitrate is used for SCE below 96 kb/s (separated mono channel), otherwise 30% */
+ if ( ivas_total_brate < IVAS_96k )
+ {
+ *brate_sce = (int32_t) ( MCMASA_MONOBITRATIO_64k * ivas_total_brate );
+ }
+ else
+ {
+ *brate_sce = (int32_t) ( MCMASA_MONOBITRATIO * ivas_total_brate );
+ }
+
+ *brate_cpe = ivas_total_brate - *brate_sce;
+ }
+ else
+ {
+ *brate_sce = nSCE > 0 ? ivas_total_brate / ( nCPE + nSCE ) : 0;
+ *brate_cpe = nCPE > 0 ? ivas_total_brate / ( nCPE + nSCE ) : 0;
+ }
+}
+#endif
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index 27b9d21c0d5f6818b768c66c559392a9f62dccec..d6b64c820368a6501b42a40e24adf94a1461c0a3 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -128,7 +128,14 @@ ivas_error ivas_corecoder_enc_reconfig(
Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
const int16_t nSCE_old, /* i : number of SCEs in previous frame */
const int16_t nCPE_old, /* i : number of CPEs in previous frame */
+#ifdef MCMASA_BITRATE_SWITCHING
+ const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
+ const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */
+ const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */
+ const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */
+#else
const int16_t nchan_transport_old /* i : number of TCs in previous frame */
+#endif
);
#endif
@@ -333,11 +340,22 @@ void ivas_mct_dec_close(
#ifdef CORECODER_BITRATE_SWITCHING
ivas_error ivas_corecoder_dec_reconfig(
+#ifdef MCMASA_BITRATE_SWITCHING
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int16_t nSCE_old, /* i : number of SCEs in previous frame */
+ int16_t nCPE_old, /* i : number of CPEs in previous frame */
+ const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
+ const int16_t sba_dirac_stereo_flag_old, /* i : signal stereo rendering using DFT upmix in previous frame */
+ const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */
+ const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */
+ const MC_MODE last_mc_mode /* i : MC mode in the previous frame */
+#else
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
const int16_t nSCE_old, /* i : number of SCEs in previous frame */
const int16_t nCPE_old, /* i : number of CPEs in previous frame */
const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
const int16_t sba_dirac_stereo_flag_old /* i : signal stereo output for SBA DirAC in previous frame */
+#endif
);
ivas_error ivas_hp20_dec_reconfig(
@@ -4779,6 +4797,16 @@ void ivas_mcmasa_enc_close(
const int32_t input_Fs /* i : input sampling rate */
);
+#ifdef MCMASA_BITRATE_SWITCHING
+ivas_error ivas_mcmasa_enc_reconfig(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
+);
+
+ivas_error ivas_mcmasa_dec_reconfig(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
+);
+#endif
+
void ivas_mcmasa_setNumTransportChannels(
int16_t* nchan_transport, /* o : Pointer to number of transport channels to be set */
int16_t* element_mode, /* o : Pointer to element mode to be set */
@@ -4791,10 +4819,21 @@ void ivas_mcmasa_set_separate_channel_mode(
const int32_t ivas_total_brate /* i : Total bitrate of IVAS */
);
+#ifndef MCMASA_BITRATE_SWITCHING
/*! r: McMASA SCE bitrate */
int32_t ivas_mcmasa_mono_brate(
const int32_t ivas_total_brate /* i : IVAS total bitrate */
);
+#else
+void ivas_mcmasa_split_brate(
+ const uint8_t separateChannelEnabled, /* i : Transport running in "separate channel" mode */
+ const int32_t ivas_total_brate, /* i : Total bitrate available to be split */
+ const int16_t nSCE, /* i : Number of SCEs in use (0 or 1) */
+ const int16_t nCPE, /* i : Number of CPEs in use (0 or 1) */
+ int32_t *brate_sce, /* o : Pointer to SCE element bitrate */
+ int32_t *brate_cpe /* o : Pointer to CPE element bitrate */
+);
+#endif
void ivas_mcmasa_enc(
MCMASA_ENC_HANDLE hMcMasa, /* i/o: Encoder McMASA handle */
@@ -4819,6 +4858,15 @@ void ivas_mcmasa_param_est_enc(
const int16_t nchan_inp /* i : Number of input channels */
);
+#ifdef MCMASA_BITRATE_SWITCHING
+void ivas_mcmasa_dmx_modify(
+ const int16_t n_samples, /* i : input frame length in samples */
+ float dmx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format */
+ const uint8_t n_chnls_dmx_old, /* i : number of downmix channels in the old format */
+ const uint8_t n_chnls_dmx_new /* i : number of downmix channels in the target format */
+);
+#endif
+
void v_multc_acc(
const float x[], /* i : Input vector */
const float c, /* i : Constant */
diff --git a/lib_com/options.h b/lib_com/options.h
index 28fb60c2e906588c2082b812cd74fe5e64ce46c8..6b63e63f714cf98aaca5e2e08f39f98de5715fbc 100755
--- a/lib_com/options.h
+++ b/lib_com/options.h
@@ -58,7 +58,7 @@
#ifdef DEBUGGING
-#define MEM_COUNT_DETAILS /* RAM counting tool: print per sub-structure details */
+/*#define MEM_COUNT_DETAILS*/ /* RAM counting tool: print per sub-structure details */
/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */
#ifdef DEBUG_MODE_INFO
@@ -159,7 +159,9 @@
#define CORECODER_BITRATE_SWITCHING /* Issue 133: support bitrate switching in core-coder */
#define MC_BITRATE_SWITCHING /* Issue 116: support bitrate switching in MC format */
-
+#ifdef MC_BITRATE_SWITCHING
+#define MCMASA_BITRATE_SWITCHING /* Issue 116: support bitrate switching in MC format: sub-part of McMASA modes */
+#endif
/* ################## End DEVELOPMENT switches ######################### */
/* clang-format on */
diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c
index 4291feaed934a14e5251457f2bb1e0d8a58f388e..c8961f88ddb515bd5dbfee9a811af873261c8c80 100644
--- a/lib_com/swb_tbe_com.c
+++ b/lib_com/swb_tbe_com.c
@@ -1891,6 +1891,10 @@ void tbe_celp_exc(
return;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ assert( bwe_exc != NULL && "BWE excitation is NULL" );
+#endif
+
if ( L_frame == L_FRAME )
{
offset = tbe_celp_exc_offset( T0, T0_frac );
diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c
index ad350f4e303b65fe68f533fb564bca9989d9b56d..12274f87629538d63a3871323bf78ddc7bcecd1d 100644
--- a/lib_dec/ivas_core_dec.c
+++ b/lib_dec/ivas_core_dec.c
@@ -442,7 +442,6 @@ ivas_error ivas_core_dec(
}
}
#endif
-
}
/*---------------------------------------------------------------------*
diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c
index 8f0ba78857f52da592bdfb787bb5755796db2711..811b7211adbf356623b07742a2bef07f0861ce95 100644
--- a/lib_dec/ivas_corecoder_dec_reconfig.c
+++ b/lib_dec/ivas_corecoder_dec_reconfig.c
@@ -54,11 +54,22 @@
*-------------------------------------------------------------------*/
ivas_error ivas_corecoder_dec_reconfig(
+#ifdef MCMASA_BITRATE_SWITCHING
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int16_t nSCE_old, /* i : number of SCEs in previous frame */
+ int16_t nCPE_old, /* i : number of CPEs in previous frame */
+ const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
+ const int16_t sba_dirac_stereo_flag_old, /* i : signal stereo rendering using DFT upmix in previous frame */
+ const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */
+ const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */
+ const MC_MODE last_mc_mode /* i : MC mode in the previous frame */
+#else
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
const int16_t nSCE_old, /* i : number of SCEs in previous frame */
const int16_t nCPE_old, /* i : number of CPEs in previous frame */
const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
const int16_t sba_dirac_stereo_flag_old /* i : signal stereo output for SBA DirAC in previous frame */
+#endif
)
{
int16_t n, sce_id, cpe_id, output_frame;
@@ -82,7 +93,12 @@ ivas_error ivas_corecoder_dec_reconfig(
*-----------------------------------------------------------------*/
/* remove dummy CPE element for DFT stereo-like upmix */
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( st_ivas->ivas_format == SBA_FORMAT && sba_dirac_stereo_flag_old && !st_ivas->sba_dirac_stereo_flag ) ||
+ ( st_ivas->ivas_format == MC_FORMAT && last_mc_mode == MC_MODE_MCMASA && sba_dirac_stereo_flag_old && !st_ivas->sba_dirac_stereo_flag ) )
+#else
if ( st_ivas->ivas_format == SBA_FORMAT && sba_dirac_stereo_flag_old && !st_ivas->sba_dirac_stereo_flag )
+#endif
{
st_ivas->hCPE[0]->hCoreCoder[0] = NULL;
st_ivas->hCPE[0]->hCoreCoder[1] = NULL;
@@ -99,18 +115,29 @@ ivas_error ivas_corecoder_dec_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->nchan_transport == nchan_transport_old && st_ivas->nSCE == nSCE_old && st_ivas->nCPE == nCPE_old )
+#else
if ( st_ivas->nchan_transport == nchan_transport_old )
+#endif
{
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hSCE[sce_id]->element_brate = brate_SCE;
+#else
st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
+#endif
st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
}
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->element_brate = brate_CPE;
+#else
st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
-
+#endif
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
{
@@ -145,6 +172,19 @@ ivas_error ivas_corecoder_dec_reconfig(
st_ivas->hCPE[cpe_id] = NULL;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ /* the CPE-internal settings depend from ivas_format and mc_mode, so clean-up when switching between mc_modes */
+ if ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode != last_mc_mode && ( st_ivas->mc_mode == MC_MODE_MCMASA || last_mc_mode == MC_MODE_MCMASA ) )
+ {
+ for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ )
+ {
+ destroy_cpe_dec( st_ivas->hCPE[cpe_id] );
+ st_ivas->hCPE[cpe_id] = NULL;
+ }
+ nCPE_old = 0;
+ nCPE_existing = min( nCPE_old, st_ivas->nCPE );
+ }
+#endif
if ( st_ivas->nCPE <= 1 && st_ivas->hMCT != NULL )
{
ivas_mct_dec_close( &st_ivas->hMCT );
@@ -159,12 +199,20 @@ ivas_error ivas_corecoder_dec_reconfig(
for ( sce_id = 0; sce_id < nSCE_existing; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hSCE[sce_id]->element_brate = brate_SCE;
+#else
st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
+#endif
st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
}
for ( ; sce_id < st_ivas->nSCE; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( error = create_sce_dec( st_ivas, sce_id, brate_SCE ) ) != IVAS_ERR_OK )
+#else
if ( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -172,8 +220,11 @@ ivas_error ivas_corecoder_dec_reconfig(
for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->element_brate = brate_CPE;
+#else
st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
-
+#endif
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
{
@@ -182,7 +233,11 @@ ivas_error ivas_corecoder_dec_reconfig(
}
for ( ; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( error = create_cpe_dec( st_ivas, cpe_id, brate_CPE ) ) != IVAS_ERR_OK )
+#else
if ( ( error = create_cpe_dec( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -235,7 +290,12 @@ ivas_error ivas_corecoder_dec_reconfig(
}
/* create dummy CPE element for DFT stereo-like upmix */
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_dirac_stereo_flag && !sba_dirac_stereo_flag_old ) ||
+ ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->sba_dirac_stereo_flag && !sba_dirac_stereo_flag_old ) )
+#else
if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_dirac_stereo_flag && !sba_dirac_stereo_flag_old )
+#endif
{
if ( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK )
{
diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c
index e8c0493ad115d63df6c6dcd9157fa31f56febf31..e8da2b8e487927ba4bc04197c58208b220ad7f8e 100644
--- a/lib_dec/ivas_cpe_dec.c
+++ b/lib_dec/ivas_cpe_dec.c
@@ -535,8 +535,13 @@ ivas_error ivas_cpe_dec(
for ( i = 0; i < n; i++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate.cpe", 0, cpe_id, DEC ) );
+ dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode.cpe", 0, cpe_id, DEC ) );
+#else
dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate", 0, cpe_id, DEC ) );
dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode", 0, cpe_id, DEC ) );
+#endif
for ( int16_t j = 0; j < CPE_CHANNELS; j++ )
{
diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c
index e183eda8e07f9306eba0feada69fce17a4cacece..3d4fc869fed23e8eaec1c0c3eba5c7b6ba7cc687 100644
--- a/lib_dec/ivas_init_dec.c
+++ b/lib_dec/ivas_init_dec.c
@@ -272,7 +272,7 @@ ivas_error ivas_dec_setup(
{
if ( ( error = doSanityChecks_IVAS( st_ivas ) ) != IVAS_ERR_OK )
{
- return IVAS_ERROR( error, "Sanitiy checks failed" );
+ return IVAS_ERROR( error, "Sanity checks failed" );
}
if ( ( error = ivas_init_decoder( st_ivas ) ) != IVAS_ERR_OK )
@@ -724,7 +724,7 @@ ivas_error ivas_init_decoder(
}
/*-----------------------------------------------------------------*
- * Allocate and initalize SCE/CPE and other handles
+ * Allocate and initialize SCE/CPE and other handles
*-----------------------------------------------------------------*/
if ( st_ivas->ivas_format == MONO_FORMAT )
@@ -1056,6 +1056,10 @@ ivas_error ivas_init_decoder(
}
else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ int32_t brate_sce, brate_cpe;
+#endif
+
ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
@@ -1092,8 +1096,18 @@ ivas_error ivas_init_decoder(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ ivas_mcmasa_split_brate( st_ivas->hOutSetup.separateChannelEnabled, ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &brate_sce, &brate_cpe );
+#endif
+
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( error = create_sce_dec( st_ivas, sce_id, brate_sce ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
if ( st_ivas->hOutSetup.separateChannelEnabled )
{
if ( ( error = create_sce_dec( st_ivas, sce_id, ivas_mcmasa_mono_brate( ivas_total_brate ) ) ) != IVAS_ERR_OK )
@@ -1108,15 +1122,23 @@ ivas_error ivas_init_decoder(
return error;
}
}
+#endif
reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
}
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->element_mode_init = IVAS_CPE_MDCT; /* element_mode_init was IVAS_SCE for SCE initialization */
+ if ( ( error = create_cpe_dec( st_ivas, cpe_id, brate_cpe ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
if ( st_ivas->hOutSetup.separateChannelEnabled )
{
- st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ st_ivas->element_mode_init = IVAS_CPE_MDCT; /* element_mode_init was IVAS_SCE for SCE initialization */
if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate - st_ivas->hSCE[0]->element_brate ) ) != IVAS_ERR_OK )
{
@@ -1132,6 +1154,7 @@ ivas_error ivas_init_decoder(
return error;
}
}
+#endif
for ( n = 0; n < CPE_CHANNELS; n++ )
{
diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c
index b4aa18f2a17a0beeb1cdca50f972a8b37e46003a..3d30ba2071cc84dce5b32783819de936a87fd6f7 100644
--- a/lib_dec/ivas_masa_dec.c
+++ b/lib_dec/ivas_masa_dec.c
@@ -1063,7 +1063,7 @@ ivas_error ivas_masa_dec_reconfigure(
last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate;
/*-----------------------------------------------------------------*
- * Allocate and initalize SCE/CPE and other handles
+ * Allocate and initialize SCE/CPE and other handles
*-----------------------------------------------------------------*/
bit_stream = st_ivas->hSCE[0] != NULL ? st_ivas->hSCE[0]->hCoreCoder[0]->bit_stream : st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream;
diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b7cf935a487ea90993eed4b62c5d6898daa852b
--- /dev/null
+++ b/lib_dec/ivas_mcmasa_dec.c
@@ -0,0 +1,148 @@
+/******************************************************************************************************
+
+(C) 2022 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 "ivas_cnst.h"
+#include "ivas_prot.h"
+#include "options.h"
+#include "prot.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmops.h"
+
+#ifdef MCMASA_BITRATE_SWITCHING
+
+/*-------------------------------------------------------------------------
+ * Local constants
+ *------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------
+ * Local function prototypes
+ *------------------------------------------------------------------------*/
+
+/*-------------------------------------------------------------------------
+ * ivas_mcmasa_dec_reconfig()
+ *
+ * Reconfigure McMASA decoder
+ *------------------------------------------------------------------------*/
+ivas_error ivas_mcmasa_dec_reconfig(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ ivas_error error;
+ int32_t ivas_total_brate;
+
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+
+ /* close the old MASA instance */
+ if ( st_ivas->hMasa != NULL )
+ {
+ ivas_masa_dec_close( st_ivas->hMasa );
+ }
+
+ /* get new McMASA settings */
+ ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), ivas_total_brate );
+ ivas_mcmasa_set_separate_channel_mode( &( st_ivas->hOutSetup.separateChannelEnabled ), &( st_ivas->hOutSetup.separateChannelIndex ), ivas_total_brate );
+
+ /* renderer might change as an effect from the transport mode change */
+ ivas_renderer_select( st_ivas );
+
+ /* side effect of the renderer selection can be a changed internal config. this is also needed when switching from non-McMASA */
+ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config );
+ ivas_mcmasa_set_separate_channel_mode( &( st_ivas->hIntSetup.separateChannelEnabled ), &( st_ivas->hIntSetup.separateChannelIndex ), ivas_total_brate );
+
+ if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hOutSetup.output_config == AUDIO_CONFIG_STEREO );
+
+ if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO )
+ {
+ if ( st_ivas->hDirAC == NULL )
+ {
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ /*-------------------------------------------------------------------*
+ * Close binaural rendering handles and re-allocate proper ones
+ * in McMASA renderer_type can be only RENDERER_BINAURAL_PARAMETRIC, RENDERER_BINAURAL_PARAMETRIC_ROOM
+ *--------------------------------------------------------------------*/
+ if ( st_ivas->hBinRenderer != NULL )
+ {
+ ivas_binRenderer_close( &st_ivas->hBinRenderer );
+ }
+
+ if ( st_ivas->hDiracDecBin == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ /* open parametric binaural renderer */
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->hDiracDecBin != NULL )
+ {
+ if ( st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM )
+ {
+ /* close unneeded renderer */
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+ }
+ else
+ {
+ /* the decision for useTdDecorr is done in ivas_dirac_dec_init_binaural_data(). here, comparing against the same condition. */
+ if ( st_ivas->hDiracDecBin->useTdDecorr != ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_48k && st_ivas->nchan_transport == 1 ) )
+ {
+ /* st_ivas->hDiracDecBin->useTdDecorr will change => close and re-open. */
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ }
+ return error;
+}
+#endif
diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c
index bb46fbdea0a82a00ef756e03be6188d8f6fc655e..eed6452a4dd60329e83aa67361b07f9d5ee10870 100755
--- a/lib_dec/ivas_mct_dec.c
+++ b/lib_dec/ivas_mct_dec.c
@@ -644,11 +644,18 @@ ivas_error ivas_mc_dec_reconfig(
const int16_t last_mc_mode /* i : last frame MC mode */
)
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old, nchan_hp20_old;
+#else
int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old;
+#endif
int16_t numCldfbAnalyses_old, numCldfbAnalyses, numCldfbSyntheses, numCldfbSyntheses_old, i;
RENDERER_TYPE renderer_type_old;
ivas_error error;
MC_MODE mc_mode;
+#ifdef MCMASA_BITRATE_SWITCHING
+ int32_t new_brate_SCE, new_brate_CPE;
+#endif
error = IVAS_ERR_OK;
nchan_transport_old = st_ivas->nchan_transport;
@@ -664,13 +671,24 @@ ivas_error ivas_mc_dec_reconfig(
nCPE_old = st_ivas->nCPE;
sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag;
+#ifdef MCMASA_BITRATE_SWITCHING
+ /* special handling needed for the hp20 buffers for McMASA */
+ if ( last_mc_mode == MC_MODE_MCMASA )
+ {
+ nchan_hp20_old = getNumChanSynthesis( st_ivas );
+ }
+ else
+ {
+ nchan_hp20_old = nchan_transport_old;
+ }
+ st_ivas->sba_dirac_stereo_flag = 0; /* needs to be after getNumChanSynthesis() */
+#endif
/* renderer might have changed, reselect */
renderer_type_old = st_ivas->renderer_type;
ivas_renderer_select( st_ivas );
+
if ( st_ivas->mc_mode == MC_MODE_MCT )
{
-
-
st_ivas->nchan_transport = ivas_mc_ls_setup_get_num_channels( ivas_mc_map_output_config_to_mc_ls_setup( st_ivas->transport_config ) );
st_ivas->nSCE = 0;
st_ivas->nCPE = st_ivas->nchan_transport / 2;
@@ -758,7 +776,9 @@ ivas_error ivas_mc_dec_reconfig(
}
else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
{
+#ifdef MCMASA_BITRATE_SWITCHING
ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->element_mode_init ), st_ivas->hDecoderConfig->ivas_total_brate );
+#endif
if ( last_mc_mode != MC_MODE_MCMASA )
{
@@ -767,12 +787,19 @@ ivas_error ivas_mc_dec_reconfig(
return error;
}
+#ifndef MCMASA_BITRATE_SWITCHING
if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
}
-
+#else
+ }
+ if ( ( error = ivas_mcmasa_dec_reconfig( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#endif
/* ls conversion */
if ( st_ivas->hLsSetUpConversion != NULL )
{
@@ -801,6 +828,19 @@ ivas_error ivas_mc_dec_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode != MC_MODE_MCMASA )
+ {
+ if ( st_ivas->nchan_transport == 1 )
+ {
+ st_ivas->element_mode_init = IVAS_SCE;
+ }
+ else
+ {
+ st_ivas->element_mode_init = IVAS_CPE_MDCT;
+ }
+ }
+#else
if ( st_ivas->nchan_transport == 1 )
{
st_ivas->element_mode_init = IVAS_SCE;
@@ -809,7 +849,7 @@ ivas_error ivas_mc_dec_reconfig(
{
st_ivas->element_mode_init = IVAS_CPE_MDCT;
}
-
+#endif
/* re-configure core coder*/
/* special case: MCT->ParamMC with more than 2 TC, CPE 1 stays, but has the wrong mct_chan_mode in channel 1
@@ -848,13 +888,33 @@ ivas_error ivas_mc_dec_reconfig(
st->mct_chan_mode = MCT_CHAN_MODE_LFE;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ uint8_t separateChannelEnabled;
+ int16_t separateChannelIndex;
+ ivas_mcmasa_set_separate_channel_mode( &separateChannelEnabled, &separateChannelIndex, st_ivas->hDecoderConfig->ivas_total_brate );
+ ivas_mcmasa_split_brate( separateChannelEnabled, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &new_brate_SCE, &new_brate_CPE );
+ }
+ else
+ {
+ new_brate_SCE = st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport;
+ new_brate_CPE = ( st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
+ }
+ if ( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old, new_brate_SCE, new_brate_CPE, last_mc_mode ) ) != IVAS_ERR_OK )
+#else
if ( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
/* re-configure hp20 memories */
+#ifdef MCMASA_BITRATE_SWITCHING
+ ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old );
+#else
ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old );
+#endif
/*-----------------------------------------------------------------*
* CLDFB instances
@@ -884,6 +944,21 @@ ivas_error ivas_mc_dec_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( last_mc_mode == MC_MODE_MCMASA ) && ( nchan_transport_old == 1 ) && ( ( renderer_type_old == RENDERER_BINAURAL_PARAMETRIC ) || ( renderer_type_old == RENDERER_BINAURAL_PARAMETRIC_ROOM ) || ( renderer_type_old == RENDERER_STEREO_PARAMETRIC ) ) )
+ {
+ /* cldfbAnaDec[1] might be modified by DirAC (ivas_dirac_dec_binaural_internal) -> re-instantiate it */
+ if ( ( numCldfbAnalyses_old > 1 ) && ( numCldfbAnalyses > 1 ) )
+ {
+ deleteCldfb( &( st_ivas->cldfbAnaDec[1] ) );
+ st_ivas->cldfbAnaDec[1] = NULL;
+ if ( ( error = openCldfb( &( st_ivas->cldfbAnaDec[1] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+#endif
/* Synthesis */
if ( numCldfbSyntheses_old > numCldfbSyntheses )
{
@@ -906,7 +981,7 @@ ivas_error ivas_mc_dec_reconfig(
}
}
- /* Allocat the LFE handle that is coded seperately after the allocation of the core coders*/
+ /* Allocate the LFE handle that is coded separately after the allocation of the core coders */
if ( st_ivas->mc_mode == MC_MODE_MCT && st_ivas->hLFE == NULL )
{
@@ -923,8 +998,37 @@ ivas_error ivas_mc_dec_reconfig(
set_zero( st_ivas->hLFE->prior_out_buffer, L_FRAME48k );
}
-
/* renderers */
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ if ( ( st_ivas->renderer_type != RENDERER_DISABLE ) && ( st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO ) )
+ {
+ if ( st_ivas->hDirAC != NULL )
+ {
+ /* reconfigure existing DirAC dec */
+ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ /* init a new DirAC dec */
+ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ else if ( ( st_ivas->renderer_type == RENDERER_DISABLE ) && ( st_ivas->hDirAC != NULL ) )
+ {
+ ivas_dirac_dec_close( st_ivas->hDirAC );
+ st_ivas->hDirAC = NULL;
+ }
+ }
+#endif
+
if ( renderer_type_old != st_ivas->renderer_type )
{
AUDIO_CONFIG output_config;
@@ -946,10 +1050,29 @@ ivas_error ivas_mc_dec_reconfig(
{
ivas_td_binaural_close( &st_ivas->hBinRendererTd );
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->hDiracDecBin != NULL )
+ {
+ if ( st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+ }
+ else
+ {
+ /* useTdDecorr may change => close and re-open */
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+#else
if ( st_ivas->hDiracDecBin != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
{
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
}
+#endif
/* init necessary new renderers */
if ( st_ivas->hBinRenderer == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) )
{
diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c
index bd02907991663f3b451782c9c4eeaaaccf47c19e..0897393ca89708f163f37f534c85197578c3f63f 100644
--- a/lib_dec/ivas_sba_dec.c
+++ b/lib_dec/ivas_sba_dec.c
@@ -605,7 +605,11 @@ ivas_error ivas_sba_dec_reconfigure(
*-----------------------------------------------------------------*/
#ifdef CORECODER_BITRATE_SWITCHING
+#ifdef MCMASA_BITRATE_SWITCHING
+ ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old, st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport, ( st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE );
+#else
ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old );
+#endif
/*-----------------------------------------------------------------*
* HP20 memories
diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c
index 1eadd39cb0a0a0d0a709a10e42ecd6ec0725ba68..fcc5cc89854e032cab6def94efab9eb1348bfc35 100644
--- a/lib_dec/ivas_sce_dec.c
+++ b/lib_dec/ivas_sce_dec.c
@@ -285,8 +285,13 @@ ivas_error ivas_sce_dec(
for ( i = 0; i < n; i++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate.sce", 0, sce_id, DEC ) );
+ dbgwrite( &st->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode.sce", 0, sce_id, DEC ) );
+#else
dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate", 0, sce_id, DEC ) );
dbgwrite( &st->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode", 0, sce_id, DEC ) );
+#endif
dbgwrite( output, sizeof( float ), output_frame, 1, fname( debug_dir, "output.sce", 0, sce_id, DEC ) );
tmpF = 0;
diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c
old mode 100755
new mode 100644
diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c
index f4b302eefd69a6f0b04dab44d94d2141e3271551..371a376007b5bca242e23a583d115cb6b5d4b3b7 100644
--- a/lib_enc/ivas_corecoder_enc_reconfig.c
+++ b/lib_enc/ivas_corecoder_enc_reconfig.c
@@ -51,10 +51,20 @@
*-------------------------------------------------------------------*/
ivas_error ivas_corecoder_enc_reconfig(
+#ifdef MCMASA_BITRATE_SWITCHING
+ Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
+ const int16_t nSCE_old, /* i : number of SCEs in previous frame */
+ const int16_t nCPE_old, /* i : number of CPEs in previous frame */
+ const int16_t nchan_transport_old, /* i : number of TCs in previous frame */
+ const int32_t brate_SCE, /* i : bitrate to be set for the SCEs */
+ const int32_t brate_CPE, /* i : bitrate to be set for the CPEs */
+ const MC_MODE last_mc_mode /* i : switching between MC modes: last mode */
+#else
Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */
const int16_t nSCE_old, /* i : number of SCEs in previous frame */
const int16_t nCPE_old, /* i : number of CPEs in previous frame */
const int16_t nchan_transport_old /* i : number of TCs in previous frame */
+#endif
)
{
int16_t n, sce_id, cpe_id;
@@ -63,7 +73,9 @@ ivas_error ivas_corecoder_enc_reconfig(
BSTR_ENC_HANDLE hBstr, hMetaData;
Indice *ind_list, *ind_list_metadata;
int16_t nb_bits_tot, next_ind, last_ind;
+#ifndef MCMASA_BITRATE_SWITCHING
int32_t ivas_total_brate;
+#endif
ENCODER_CONFIG_HANDLE hEncoderConfig;
ivas_error error;
@@ -72,7 +84,9 @@ ivas_error ivas_corecoder_enc_reconfig(
*-----------------------------------------------------------------*/
hEncoderConfig = st_ivas->hEncoderConfig;
+#ifndef MCMASA_BITRATE_SWITCHING
ivas_total_brate = hEncoderConfig->ivas_total_brate;
+#endif
error = IVAS_ERR_OK;
len_inp_memory = (int16_t) ( hEncoderConfig->input_Fs / FRAMES_PER_SEC );
@@ -84,20 +98,30 @@ ivas_error ivas_corecoder_enc_reconfig(
/*-----------------------------------------------------------------*
* Switching between SCE(s)/CPE(s)/MCT
*-----------------------------------------------------------------*/
-
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->nchan_transport == nchan_transport_old && st_ivas->nSCE == nSCE_old && st_ivas->nCPE == nCPE_old ) /* in McMASA, nchan_transport may be the same, but nSCE/nCPE differs */
+#else
if ( st_ivas->nchan_transport == nchan_transport_old )
+#endif
{
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
{
copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 );
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hSCE[sce_id]->element_brate = brate_SCE;
+#else
st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
+#endif
st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
}
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->element_brate = brate_CPE;
+#else
st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
-
+#endif
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
{
@@ -117,7 +141,32 @@ ivas_error ivas_corecoder_enc_reconfig(
}
else
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ int16_t nchan_transport_real, nchan_transport_old_real;
+ if ( last_mc_mode == MC_MODE_MCMASA )
+ {
+ /* in SCE+CPE McMASA nchan_transport is still 2 */
+ nchan_transport_old_real = nSCE_old + CPE_CHANNELS * nCPE_old;
+ }
+ else
+ {
+ nchan_transport_old_real = nchan_transport_old;
+ }
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ nchan_transport_real = st_ivas->nSCE + CPE_CHANNELS * st_ivas->nCPE;
+ }
+ else
+ {
+ nchan_transport_real = st_ivas->nchan_transport;
+ }
+
+ /* something in transport changes */
ind_list = NULL;
+ ind_list_metadata = NULL;
+#else
+ ind_list = NULL;
+#endif
hBstr = NULL;
hMetaData = NULL;
@@ -140,13 +189,41 @@ ivas_error ivas_corecoder_enc_reconfig(
#endif
/* save bitstream information */
- ind_list = hBstr->ind_list;
+ ind_list = hBstr->ind_list; /* pointer to the beginning of the global list */
nb_bits_tot = hBstr->nb_bits_tot;
next_ind = hBstr->next_ind;
last_ind = hBstr->last_ind;
- ind_list_metadata = hMetaData->ind_list;
+ ind_list_metadata = hMetaData->ind_list; /* pointer to the beginning of the global list */
+
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ /* within McMASA we can modify the transport signals when switching */
+ /* copy earlier dmx buffers */
+ if ( nSCE_old > 0 )
+ {
+ set_zero( input_buff[0], len_inp_memory );
+ mvr2r( st_ivas->hSCE[0]->hCoreCoder[0]->input_buff, input_buff[0], len_inp_memory );
+ }
+ for ( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ set_zero( input_buff[n + 1], len_inp_memory );
+ if ( nCPE_old > 0 )
+ {
+ mvr2r( st_ivas->hCPE[0]->hCoreCoder[n]->input_buff, input_buff[n + 1], len_inp_memory );
+ }
+ }
+ ivas_mcmasa_dmx_modify( len_inp_memory, input_buff, nSCE_old + CPE_CHANNELS * nCPE_old, st_ivas->nSCE + CPE_CHANNELS * st_ivas->nCPE );
+ n_CoreCoder_existing = 0;
+ }
+ else
+ {
+ n_CoreCoder_existing = min( nchan_transport_real, nchan_transport_old_real );
+ }
+#else
n_CoreCoder_existing = min( st_ivas->nchan_transport, nchan_transport_old );
+#endif
/* destroy superfluous core-coder elements */
for ( sce_id = st_ivas->nSCE; sce_id < nSCE_old; sce_id++ )
@@ -168,7 +245,7 @@ ivas_error ivas_corecoder_enc_reconfig(
{
if ( n_CoreCoder_existing > cpe_id * CPE_CHANNELS + n )
{
- mvr2r( st_ivas->hCPE[cpe_id]->hCoreCoder[0]->input_buff, input_buff[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n], len_inp_memory );
+ mvr2r( st_ivas->hCPE[cpe_id]->hCoreCoder[0]->input_buff, input_buff[( cpe_id - st_ivas->nCPE ) * CPE_CHANNELS + n], len_inp_memory ); /* TODO VoiceAge: Please check if this should be hCoreCoder[n] */
}
}
@@ -197,13 +274,21 @@ ivas_error ivas_corecoder_enc_reconfig(
for ( sce_id = 0; sce_id < nSCE_existing; sce_id++ )
{
copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 );
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hSCE[sce_id]->element_brate = brate_SCE;
+#else
st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport;
+#endif
st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
}
for ( sce_id = nSCE_existing; sce_id < st_ivas->nSCE; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( error = create_sce_enc( st_ivas, sce_id, brate_SCE ) ) != IVAS_ERR_OK )
+#else
if ( ( error = create_sce_enc( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -240,19 +325,44 @@ ivas_error ivas_corecoder_enc_reconfig(
for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->element_brate = brate_CPE;
+#else
st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
-
+#endif
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
{
copy_encoder_config( st_ivas, st_ivas->hCPE[cpe_id]->hCoreCoder[n], 0 );
st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
+
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->ind_list = ind_list + ( cpe_id * CPE_CHANNELS + n + st_ivas->nSCE ) * MAX_NUM_INDICES;
+ if ( cpe_id * CPE_CHANNELS + n > 0 || ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->nSCE > 0 ) )
+ {
+ reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, MAX_NUM_INDICES );
+ }
+ else
+ {
+ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->last_ind = last_ind;
+ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_bits_tot = nb_bits_tot;
+ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->next_ind = next_ind;
+ }
+#endif
}
}
for ( cpe_id = nCPE_existing; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->hMcMasa->separateChannelEnabled )
+ {
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+ }
+ if ( ( error = create_cpe_enc( st_ivas, cpe_id, brate_CPE ) ) != IVAS_ERR_OK )
+#else
if ( ( error = create_cpe_enc( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
@@ -262,15 +372,20 @@ ivas_error ivas_corecoder_enc_reconfig(
{
if ( n_CoreCoder_existing > cpe_id * CPE_CHANNELS + n )
{
- mvr2r( input_buff[n], st_ivas->hCPE[cpe_id]->hCoreCoder[0]->input_buff, len_inp_memory );
+ mvr2r( input_buff[n], st_ivas->hCPE[cpe_id]->hCoreCoder[0]->input_buff, len_inp_memory ); /* TODO VoiceAge: Please check if this should be hCoreCoder[n] */
}
}
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->ind_list = ind_list + ( cpe_id * CPE_CHANNELS + n + st_ivas->nSCE ) * MAX_NUM_INDICES;
+ if ( cpe_id * CPE_CHANNELS + n > 0 || ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->nSCE > 0 ) )
+#else
st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->ind_list = ind_list + ( cpe_id * CPE_CHANNELS + n ) * MAX_NUM_INDICES;
if ( cpe_id * CPE_CHANNELS + n > 0 )
+#endif
{
reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, MAX_NUM_INDICES );
}
@@ -289,6 +404,24 @@ ivas_error ivas_corecoder_enc_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ /* restore modified transport signal */
+ if ( st_ivas->nSCE )
+ {
+ mvr2r( input_buff[0], st_ivas->hSCE[0]->hCoreCoder[0]->input_buff, len_inp_memory );
+ }
+ if ( st_ivas->nCPE )
+ {
+ for ( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ mvr2r( input_buff[n + 1], st_ivas->hCPE[0]->hCoreCoder[n]->input_buff, len_inp_memory );
+ }
+ }
+ }
+#endif
+
if ( st_ivas->nCPE > 1 && nCPE_old <= 1 )
{
if ( nCPE_old == 1 )
@@ -340,7 +473,11 @@ ivas_error ivas_corecoder_enc_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->ind_list = ind_list_metadata + st_ivas->nSCE * MAX_NUM_INDICES;
+#else
st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->ind_list = ind_list_metadata;
+#endif
reset_indices_enc( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, MAX_BITS_METADATA );
for ( cpe_id = 0; cpe_id < st_ivas->nCPE - 1; cpe_id++ )
diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c
index 15e3dcd6bac2a2e5d2bdf10a6a81ba29f5e65434..dbc5f44a25a850f0aec37973062352268071fc54 100644
--- a/lib_enc/ivas_cpe_enc.c
+++ b/lib_enc/ivas_cpe_enc.c
@@ -420,7 +420,11 @@ ivas_error ivas_cpe_enc(
{
dbgwrite( sts[0]->input - NS2SA( sts[0]->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, fname( debug_dir, "input_DMX", n, sts[n]->id_element, ENC ) );
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode.cpe", 0, sts[0]->id_element, ENC ) );
+#else
dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, sts[0]->id_element, ENC ) );
+#endif
#endif
/*----------------------------------------------------------------*
@@ -821,7 +825,7 @@ ivas_error create_cpe_enc(
/* we need the meta data handle also if we init as MC_FORMAT/MCT since it might be needed
at a bit rate switch to ParamMC or McMASA and the metadata index list is only really reachable
in the ivas_init_encoder() function and has to be connected to the MD handle there */
- if ( cpe_id == ( st_ivas->nCPE - 1 ))
+ if ( cpe_id == ( st_ivas->nCPE - 1 ) )
#else
if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) && ( cpe_id == ( st_ivas->nCPE - 1 ) ) )
#endif
@@ -888,7 +892,7 @@ ivas_error create_cpe_enc(
#ifdef DEBUGGING
if ( hEncoderConfig->Opt_DTX_ON && ( hCPE->element_mode == IVAS_CPE_TD || hEncoderConfig->stereo_mode_cmdl == 1 ) && !( ivas_format == MASA_FORMAT && element_mode_init == IVAS_CPE_MDCT ) )
#else
-if ( hEncoderConfig->Opt_DTX_ON && element_mode_init != IVAS_CPE_MDCT )
+ if ( hEncoderConfig->Opt_DTX_ON && element_mode_init != IVAS_CPE_MDCT )
#endif
{
for ( n = 0; n < CPE_CHANNELS; n++ )
diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c
index 4768eb3b241ab7e1753c0b49be047b2b66df3aeb..e64c4e058bb76112a9559479bddee943a7f1450f 100644
--- a/lib_enc/ivas_init_enc.c
+++ b/lib_enc/ivas_init_enc.c
@@ -617,6 +617,10 @@ ivas_error ivas_init_encoder(
}
else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ int32_t brate_sce, brate_cpe;
+#endif
+
ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( hEncoderConfig->element_mode_init ), ivas_total_brate );
if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
@@ -634,8 +638,18 @@ ivas_error ivas_init_encoder(
return error;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ ivas_mcmasa_split_brate( st_ivas->hMcMasa->separateChannelEnabled, ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &brate_sce, &brate_cpe );
+#endif
+
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( ( error = create_sce_enc( st_ivas, sce_id, brate_sce ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
if ( st_ivas->hMcMasa->separateChannelEnabled )
{
if ( ( error = create_sce_enc( st_ivas, sce_id, ivas_mcmasa_mono_brate( ivas_total_brate ) ) ) != IVAS_ERR_OK )
@@ -650,6 +664,7 @@ ivas_error ivas_init_encoder(
return error;
}
}
+#endif
/* prepare bitstream buffers */
st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->ind_list = ind_list[sce_id];
@@ -661,6 +676,14 @@ ivas_error ivas_init_encoder(
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+
+ if ( ( error = create_cpe_enc( st_ivas, cpe_id, brate_cpe ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
if ( st_ivas->hMcMasa->separateChannelEnabled )
{
hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
@@ -677,6 +700,7 @@ ivas_error ivas_init_encoder(
return error;
}
}
+#endif
/* prepare bitstream buffers */
for ( n = 0; n < CPE_CHANNELS; n++ )
diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c
index 8de7f442f55473fd572a0fbf9413a2ccec8c51af..238a58109b002ee38396887c7ec36b801905de94 100644
--- a/lib_enc/ivas_mc_param_enc.c
+++ b/lib_enc/ivas_mc_param_enc.c
@@ -282,7 +282,7 @@ ivas_error ivas_param_mc_reconfig(
#ifdef DEBUGGING
assert( hParamMC->hMetadataPMC.icc_map_full[i] != NULL );
#endif
- if (hParamMC->hMetadataPMC.icc_map_full[i] != NULL)
+ if ( hParamMC->hMetadataPMC.icc_map_full[i] != NULL )
{
count_free( hParamMC->hMetadataPMC.icc_map_full[i] );
hParamMC->hMetadataPMC.icc_map_full[i] = NULL;
diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c
index a281ec4760f04279d30f5f4a6d6e17683d5ad6fe..e79ac261ca46b6d94b8f7b0ac8333513b97e64a7 100644
--- a/lib_enc/ivas_mcmasa_enc.c
+++ b/lib_enc/ivas_mcmasa_enc.c
@@ -395,6 +395,50 @@ ivas_error ivas_mcmasa_enc_open(
return error;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+/*-------------------------------------------------------------------------
+ * ivas_mcmasa_enc_reconfig()
+ *
+ * Reconfigure McMASA encoder
+ *------------------------------------------------------------------------*/
+ivas_error ivas_mcmasa_enc_reconfig(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
+)
+{
+ int32_t ivas_total_brate;
+ ivas_error error;
+
+ error = IVAS_ERR_OK;
+
+ ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
+
+ if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate )
+ {
+ /* bitrate changed, may need to do something */
+
+ /* brute-force solution: close McMASA and re-instantiate with new settings */
+ ivas_masa_enc_close( st_ivas->hMasa, st_ivas->nchan_transport, st_ivas->hEncoderConfig->ivas_format );
+ ivas_mcmasa_enc_close( st_ivas->hMcMasa, st_ivas->hEncoderConfig->input_Fs );
+
+ /* Determine if to separate some channels from the analysis */
+ ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), ivas_total_brate );
+
+ if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( ( error = ivas_mcmasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* core SCE, CPE reconfiguration happens later */
+ }
+
+ return error;
+}
+#endif
/*--------------------------------------------------------------------------*
* ivas_mcmasa_enc_close()
@@ -1145,7 +1189,77 @@ void ivas_mcmasa_param_est_enc(
return;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+void ivas_mcmasa_dmx_modify(
+ const int16_t n_samples, /* i : input frame length in samples */
+ float dmx[][L_FRAME48k + NS2SA( 48000, IVAS_FB_ENC_DELAY_NS )], /* i/o: downmix signal to be transformed into another format. TODO: buffer size into define? */
+ const uint8_t n_chnls_dmx_old, /* i : number of downmix channels in the old format */
+ const uint8_t n_chnls_dmx_new ) /* i : number of downmix channels in the target format */
+{
+ /* assumed data ordering in **dmx: [sce][cpe_chnl0][cpe_chnl1], i.e., [c][l][r] */
+ int16_t i;
+
+ assert( ( n_chnls_dmx_old == 1 || n_chnls_dmx_old == 2 || n_chnls_dmx_old == 3 ) && "Input downmix may contain only 1-3 channels." );
+ assert( ( n_chnls_dmx_new == 1 || n_chnls_dmx_new == 2 || n_chnls_dmx_new == 3 ) && "Output downmix may contain only 1-3 channels." );
+ if ( n_chnls_dmx_old == n_chnls_dmx_new )
+ {
+ /* same dmx layout -> nothing to do */
+ return;
+ }
+ if ( n_chnls_dmx_old == 1 )
+ {
+ /* split mono energy into identical channels */
+ for ( i = 0; i < n_samples; i++ )
+ {
+ if ( n_chnls_dmx_new == 2 )
+ {
+ dmx[1][i] = dmx[0][i] * INV_SQRT2;
+ dmx[2][i] = dmx[1][i];
+ }
+ else if ( n_chnls_dmx_new == 3 )
+ {
+ dmx[0][i] = dmx[0][i] * INV_SQRT3;
+ }
+ }
+ }
+ else if ( n_chnls_dmx_old == 2 )
+ {
+ for ( i = 0; i < n_samples; i++ )
+ {
+ if ( n_chnls_dmx_new == 1 )
+ {
+ /* sum l and r */
+ dmx[0][i] = dmx[1][i] + dmx[2][i];
+ }
+ else if ( n_chnls_dmx_new == 3 )
+ {
+ dmx[0][i] = 0.5f * ( dmx[1][i] + dmx[2][i] );
+ dmx[1][i] = dmx[1][i] - dmx[0][i];
+ dmx[2][i] = dmx[2][i] - dmx[0][i];
+ }
+ }
+ }
+ else if ( n_chnls_dmx_old == 3 )
+ {
+ for ( i = 0; i < n_samples; i++ )
+ {
+ if ( n_chnls_dmx_new == 1 )
+ {
+ /* sum all channels */
+ dmx[0][i] = dmx[0][i] + dmx[1][i] + dmx[2][i];
+ }
+ else if ( n_chnls_dmx_new == 2 )
+ {
+ /* mix center into sides */
+ dmx[0][i] *= INV_SQRT2;
+ dmx[1][i] += dmx[0][i];
+ dmx[2][i] += dmx[0][i];
+ }
+ }
+ }
+}
+#endif
/*--------------------------------------------------------------------------*
* Local functions
*--------------------------------------------------------------------------*/
diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c
index f4f8e6b8ee5396b6d1a6ce54a7ab91780f755de8..0abc613a8c66b2e6472173489202a39fe0103eb5 100755
--- a/lib_enc/ivas_mct_enc.c
+++ b/lib_enc/ivas_mct_enc.c
@@ -602,6 +602,9 @@ ivas_error ivas_mc_enc_reconfig(
{
int16_t nchan_transport_old, nSCE_old, nCPE_old;
ivas_error error;
+#ifdef MCMASA_BITRATE_SWITCHING
+ int32_t new_brate_SCE, new_brate_CPE;
+#endif
error = IVAS_ERR_OK;
@@ -696,10 +699,17 @@ ivas_error ivas_mc_enc_reconfig(
}
else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
{
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( last_mc_mode != MC_MODE_MCMASA )
+ {
+ ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), st_ivas->hEncoderConfig->ivas_total_brate );
+
+#else
ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( st_ivas->hEncoderConfig->element_mode_init ), st_ivas->hEncoderConfig->ivas_total_brate );
if ( last_mc_mode != MC_MODE_MCMASA )
{
+#endif
if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
{
return error;
@@ -716,6 +726,17 @@ ivas_error ivas_mc_enc_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ else
+ {
+ /* reconfigure McMASA instance */
+ if ( ( error = ivas_mcmasa_enc_reconfig( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#endif
+
if ( st_ivas->hParamMC != NULL )
{
ivas_param_mc_enc_close( st_ivas->hParamMC, st_ivas->hEncoderConfig->input_Fs );
@@ -737,6 +758,19 @@ ivas_error ivas_mc_enc_reconfig(
}
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode != MC_MODE_MCMASA )
+ {
+ if ( st_ivas->nchan_transport == 1 )
+ {
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_SCE;
+ }
+ else
+ {
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+ }
+ }
+#else
if ( st_ivas->nchan_transport == 1 )
{
st_ivas->hEncoderConfig->element_mode_init = IVAS_SCE;
@@ -745,6 +779,7 @@ ivas_error ivas_mc_enc_reconfig(
{
st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
}
+#endif
/* re-configure core coder*/
/* special case: MCT->ParamMC with more than 2 TC, CPE 1 stays, but has the wrong mct_chan_mode in channel 1
@@ -789,12 +824,25 @@ ivas_error ivas_mc_enc_reconfig(
st->mct_chan_mode = MCT_CHAN_MODE_LFE;
}
+#ifdef MCMASA_BITRATE_SWITCHING
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ ivas_mcmasa_split_brate( st_ivas->hMcMasa->separateChannelEnabled, st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &new_brate_SCE, &new_brate_CPE );
+ }
+ else
+ {
+ new_brate_SCE = st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport;
+ new_brate_CPE = ( st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS;
+ }
+ if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, new_brate_SCE, new_brate_CPE, last_mc_mode ) ) != IVAS_ERR_OK )
+#else
if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old ) ) != IVAS_ERR_OK )
+#endif
{
return error;
}
return error;
}
-#endif
\ No newline at end of file
+#endif
diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c
index e3564725f53f439a5a9029f781eafed3faba98c3..397a04e4a4fd25ac259a39aae12715ed4f698104 100644
--- a/lib_enc/ivas_sba_enc.c
+++ b/lib_enc/ivas_sba_enc.c
@@ -272,7 +272,11 @@ ivas_error ivas_sba_enc_reconfigure(
* Allocate, initalize, and configure SCE/CPE/MCT handles
*-----------------------------------------------------------------*/
+#ifdef MCMASA_BITRATE_SWITCHING
+ ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, ivas_total_brate / st_ivas->nchan_transport, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS, MC_MODE_NONE );
+#else
ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old );
+#endif
#else
if ( hEncoderConfig->nchan_transport == nchan_transport_old )
diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c
index 651ba3b9e5aeffa4e70e0e32df6bc6809eb7e756..bd460c038cdf53dfa1024ff5b519d6cb76cdaed7 100644
--- a/lib_enc/ivas_sce_enc.c
+++ b/lib_enc/ivas_sce_enc.c
@@ -178,7 +178,11 @@ ivas_error ivas_sce_enc(
#ifdef DEBUG_MODE_INFO
dbgwrite( st->input - NS2SA( st->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, "res/input_DMX" );
+#ifdef MCMASA_BITRATE_SWITCHING
+ dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode.sce", 0, st->id_element, ENC ) );
+#else
dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) );
+#endif
#endif
/*----------------------------------------------------------------*