diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 342a6c4dc8f3d0dcd2229f2a3d65bd81523605c6..760f908abd8558b580ebdfd9d8d39bcadac4d2fc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -281,13 +281,11 @@ build-codec-instrumented-linux:
# make sure that the codec builds with msan, asan and usan
build-codec-sanitizers-linux:
extends:
- - .build-job-with-check-for-warnings
+ - .build-job-linux
- .rules-basis
script:
- *print-common-info
- bash ci/build_codec_sanitizers_linux.sh
- # need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...<
- - ci/check_for_warnings.py $BUILD_OUTPUT || exit $?
build-codec-windows-cmake:
extends:
diff --git a/Makefile b/Makefile
index d14ddfbd1b4afd69ae2f608d70dcae08794182aa..a3cd95733473cbbbeacd5241e363690b4f551da0 100644
--- a/Makefile
+++ b/Makefile
@@ -67,7 +67,7 @@ LDLIBS += -lm
CCCLANG = clang
ifeq "$(CLANG)" "1"
CC = $(CCCLANG)
-CFLAGS += -fsanitize=memory
+CFLAGS += -fsanitize=memory -fsanitize-memory-track-origins
LDFLAGS += -fsanitize=memory
endif
ifeq "$(CLANG)" "2"
diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj
index 62f0c3b2098c60bad5fea5f09d00cff6f821f154..0769491d34fd06efcaf5b6fda6b57166e5f72b86 100644
--- a/Workspace_msvc/lib_com.vcxproj
+++ b/Workspace_msvc/lib_com.vcxproj
@@ -254,6 +254,7 @@
+
diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters
index 7b6854e7184cd0ec212f9819aa783944db688a6a..02b89d239320bfa5f5a975d62fc5bfa11c2bb2c1 100644
--- a/Workspace_msvc/lib_com.vcxproj.filters
+++ b/Workspace_msvc/lib_com.vcxproj.filters
@@ -466,6 +466,9 @@
common_ivas_c
+
+ common_ivas_c
+
diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj
index 2851fd82e92daf535338b92b45ea87c42f9e3603..808b173a000957b098a90ec9a6e7527b136ba34c 100644
--- a/Workspace_msvc/lib_dec.vcxproj
+++ b/Workspace_msvc/lib_dec.vcxproj
@@ -271,7 +271,10 @@
+
+
+
@@ -293,6 +296,7 @@
+
diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters
index a7eb87f148c3b90ba5ca4e4fdefe4f1f60417709..ab87fd504674c00544b9323a3e29a99c61e9162a 100644
--- a/Workspace_msvc/lib_dec.vcxproj.filters
+++ b/Workspace_msvc/lib_dec.vcxproj.filters
@@ -16,6 +16,15 @@
dec_ivas_c
+
+ dec_ivas_c
+
+
+ dec_ivas_c
+
+
+ dec_ivas_c
+
dec_ivas_c
@@ -515,6 +524,9 @@
dec_ivas_c
+
+ dec_ivas_c
+
diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj
index 6f88f77c4f760903c6b2a7cdbc2597ed4349c09e..e13746ea0e9953776662e1f337f5fb8c80e58a4c 100644
--- a/Workspace_msvc/lib_enc.vcxproj
+++ b/Workspace_msvc/lib_enc.vcxproj
@@ -215,6 +215,7 @@
+
diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters
index b3970764c0f9218533e6f7e63c8f1d270540c0e1..c2b2c275b959eb14bb0e7239dd651ebeb5e2fe90 100644
--- a/Workspace_msvc/lib_enc.vcxproj.filters
+++ b/Workspace_msvc/lib_enc.vcxproj.filters
@@ -590,6 +590,9 @@
enc_ivas_c
+
+ enc_ivas_c
+
diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj
index 3e5f8bee133b3600bbe891fbc67950d48db39c33..6e3943249f2e64991a5cd27b6e6a09aa25ad2f33 100644
--- a/Workspace_msvc/lib_rend.vcxproj
+++ b/Workspace_msvc/lib_rend.vcxproj
@@ -222,10 +222,6 @@
-
-
-
-
diff --git a/apps/decoder.c b/apps/decoder.c
index 6e3e23bb4764b32f8f0bf2ea2b74251a014aa58e..fbbe04c0d30d9675526ede7e7795ed627b7a63f8 100644
--- a/apps/decoder.c
+++ b/apps/decoder.c
@@ -156,6 +156,12 @@ typedef struct
uint16_t frontendFetchSizeMs;
#endif
#endif
+#ifdef MASAISM_EDIT_OBJECTS
+ bool editing_ism_enabled;
+ int16_t index_of_edited_ism;
+ int16_t azimuth_edited_ism;
+ int16_t elevation_edited_ism;
+#endif
} DecArguments;
@@ -678,6 +684,17 @@ int main(
}
}
+#ifdef MASAISM_EDIT_OBJECTS
+ /*------------------------------------------------------------------------------------------*
+ * Set edited object positions
+ *------------------------------------------------------------------------------------------*/
+
+ if ( arg.editing_ism_enabled )
+ {
+ IVAS_DEC_SetEditedIsmPositions( hIvasDec, arg.index_of_edited_ism, arg.azimuth_edited_ism, arg.elevation_edited_ism );
+ }
+#endif
+
/*-----------------------------------------------------------------*
* Decoding
*-----------------------------------------------------------------*/
@@ -894,6 +911,9 @@ static bool parseCmdlIVAS_dec(
{
int16_t i;
char argv_to_upper[FILENAME_MAX];
+#ifdef MASAISM_EDIT_OBJECTS
+ int32_t tmp1;
+#endif
#ifdef DEBUGGING
float ftmp;
@@ -963,6 +983,13 @@ static bool parseCmdlIVAS_dec(
#endif
#endif
+#ifdef MASAISM_EDIT_OBJECTS
+ arg->editing_ism_enabled = false;
+ arg->index_of_edited_ism = 0;
+ arg->azimuth_edited_ism = 0;
+ arg->elevation_edited_ism = 0;
+#endif
+
/*-----------------------------------------------------------------*
* Initialization
*-----------------------------------------------------------------*/
@@ -1324,6 +1351,39 @@ static bool parseCmdlIVAS_dec(
}
}
+#ifdef MASAISM_EDIT_OBJECTS
+ else if ( strcmp( argv_to_upper, "-EDIT_ISM" ) == 0 ) /* Edit ISM position: objectID, azimuth (deg), elevation (deg) */
+ {
+ arg->editing_ism_enabled = true;
+ i++;
+
+ if ( argc - i <= 6 || argv[i][0] == '-' )
+ {
+ fprintf( stderr, "Error: Edited ISM position parameters not defined! \n\n" );
+ usage_dec();
+ return false;
+ }
+
+ if ( sscanf( argv[i], "%d", &tmp1 ) > 0 )
+ {
+ arg->index_of_edited_ism = (int16_t) tmp1;
+ i++;
+ }
+
+ if ( sscanf( argv[i], "%d", &tmp1 ) > 0 )
+ {
+ arg->azimuth_edited_ism = (int16_t) tmp1;
+ i++;
+ }
+
+ if ( sscanf( argv[i], "%d", &tmp1 ) > 0 )
+ {
+ arg->elevation_edited_ism = (int16_t) tmp1;
+ i++;
+ }
+ }
+#endif
+
/*-----------------------------------------------------------------*
* Option not recognized
*-----------------------------------------------------------------*/
@@ -1682,7 +1742,11 @@ static ivas_error initOnFirstGoodFrame(
}
/* If outputting ISM, get number of objects, open output files and write zero metadata for initial bad frames */
+#ifdef OMASA_EXT_OUTPUT
+ if ( *pBsFormat == IVAS_DEC_BS_OBJ || *pBsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
if ( *pBsFormat == IVAS_DEC_BS_OBJ )
+#endif
{
if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, pNumObj ) ) != IVAS_ERR_OK )
{
@@ -1720,8 +1784,13 @@ static ivas_error initOnFirstGoodFrame(
}
}
}
+
/* If outputting MASA, open output file and write metadata for initial bad frames */
+#ifdef OMASA_EXT_OUTPUT
+ if ( *pBsFormat == IVAS_DEC_BS_MASA || *pBsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
else if ( *pBsFormat == IVAS_DEC_BS_MASA )
+#endif
{
if ( ( error = MasaFileWriter_open( arg.outputWavFilename, arg.delayCompensationEnabled, ppMasaWriter ) ) != IVAS_ERR_OK )
{
@@ -1729,26 +1798,33 @@ static ivas_error initOnFirstGoodFrame(
return error;
}
- /* Duplicate good first frame metadata to fill the beginning of stream. */
- MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL;
+#ifdef OMASA_EXT_OUTPUT
+ if ( numInitialBadFrames > 0 )
+ {
+#endif
+ /* Duplicate good first frame metadata to fill the beginning of stream. */
+ MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL;
#ifdef FIX_470_MASA_JBM_EXT
- if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK )
+ if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK )
#else
if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta ) ) != IVAS_ERR_OK )
#endif
- {
- fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
- return error;
- }
-
- for ( int16_t j = 0; j < numInitialBadFrames; ++j )
- {
- if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK )
{
- fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( *ppMasaWriter ) );
+ fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) );
return error;
}
+
+ for ( int16_t j = 0; j < numInitialBadFrames; ++j )
+ {
+ if ( ( error = MasaFileWriter_writeFrame( *ppMasaWriter, hMasaExtOutMeta ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nError writing MASA metadata to file: %s\n", MasaFileWriter_getFilePath( *ppMasaWriter ) );
+ return error;
+ }
+ }
+#ifdef OMASA_EXT_OUTPUT
}
+#endif
}
}
@@ -2075,10 +2151,14 @@ static ivas_error decodeG192(
#endif
}
- /* Write ISM metadata to external file(s) */
+ /* Write MASA/ISM metadata to external file(s) */
if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT )
{
+#ifdef OMASA_EXT_OUTPUT
+ if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
if ( bsFormat == IVAS_DEC_BS_OBJ )
+#endif
{
if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
{
@@ -2103,7 +2183,12 @@ static ivas_error decodeG192(
}
}
}
+#ifdef OMASA_EXT_OUTPUT
+
+ if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
else if ( bsFormat == IVAS_DEC_BS_MASA )
+#endif
{
MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta;
#ifdef FIX_470_MASA_JBM_EXT
@@ -2190,6 +2275,16 @@ static ivas_error decodeG192(
{
fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) );
}
+#ifdef OMASA_EXT_OUTPUT
+ else if ( bsFormat == IVAS_DEC_BS_MASA_ISM )
+ {
+ for ( i = 0; i < numObj; i++ )
+ {
+ fprintf( stdout, "\nOutput ISM metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) );
+ }
+ fprintf( stdout, "\nOutput MASA metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) );
+ }
+#endif
}
/*------------------------------------------------------------------------------------------*
@@ -2656,7 +2751,11 @@ static ivas_error decodeVoIP(
{
int16_t i;
+#ifdef OMASA_EXT_OUTPUT
+ if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
if ( bsFormat == IVAS_DEC_BS_OBJ )
+#endif
{
if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
{
@@ -2681,7 +2780,12 @@ static ivas_error decodeVoIP(
}
}
}
+#ifdef OMASA_EXT_OUTPUT
+
+ if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
else if ( bsFormat == IVAS_DEC_BS_MASA )
+#endif
{
MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta;
#ifdef FIX_470_MASA_JBM_EXT
@@ -3086,7 +3190,11 @@ static ivas_error decodeVariableSpeed(
/* Write ISm metadata to external file(s) */
if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT )
{
+#ifdef OMASA_EXT_OUTPUT
+ if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
if ( bsFormat == IVAS_DEC_BS_OBJ )
+#endif
{
if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
{
@@ -3111,7 +3219,12 @@ static ivas_error decodeVariableSpeed(
}
}
}
+#ifdef OMASA_EXT_OUTPUT
+
+ if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
else if ( bsFormat == IVAS_DEC_BS_MASA )
+#endif
{
MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta;
#ifdef FIX_470_MASA_JBM_EXT
@@ -3265,7 +3378,11 @@ static ivas_error decodeVariableSpeed(
/* Write ISm metadata to external file(s) */
if ( decodedGoodFrame && arg.outputFormat == IVAS_DEC_OUTPUT_EXT )
{
+#ifdef OMASA_EXT_OUTPUT
+ if ( bsFormat == IVAS_DEC_BS_OBJ || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
if ( bsFormat == IVAS_DEC_BS_OBJ )
+#endif
{
if ( ( error = IVAS_DEC_GetNumObjects( hIvasDec, &numObj ) ) != IVAS_ERR_OK )
{
@@ -3290,7 +3407,12 @@ static ivas_error decodeVariableSpeed(
}
}
}
+#ifdef OMASA_EXT_OUTPUT
+
+ if ( bsFormat == IVAS_DEC_BS_MASA || bsFormat == IVAS_DEC_BS_MASA_ISM )
+#else
else if ( bsFormat == IVAS_DEC_BS_MASA )
+#endif
{
MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta;
#ifdef FIX_470_MASA_JBM_EXT
@@ -3354,6 +3476,16 @@ static ivas_error decodeVariableSpeed(
{
fprintf( stdout, "\nOutput metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) );
}
+#ifdef OMASA_EXT_OUTPUT
+ else if ( bsFormat == IVAS_DEC_BS_MASA_ISM )
+ {
+ for ( i = 0; i < numObj; i++ )
+ {
+ fprintf( stdout, "\nOutput ISM metadata file: %s", IsmFileWriter_getFilePath( ismWriters[i] ) );
+ }
+ fprintf( stdout, "\nOutput MASA metadata file: %s\n", MasaFileWriter_getFilePath( masaWriter ) );
+ }
+#endif
}
/* add zeros at the end to have equal length of synthesized signals */
diff --git a/apps/encoder.c b/apps/encoder.c
index 75798f240d0545b66151f788de31cf1a9442c88a..4ff90a8d39e394c5ff3cfc55327ed771c1d87c7c 100644
--- a/apps/encoder.c
+++ b/apps/encoder.c
@@ -89,6 +89,15 @@ typedef union _EncInputFormatConfig
/* MC details */
IVAS_ENC_MC_LAYOUT mcLayout;
+#ifdef MASA_AND_OBJECTS
+ struct EncMasaIsmConfig
+ {
+ int16_t numObjects;
+ const char *metadataFiles[IVAS_MAX_NUM_OBJECTS];
+ IVAS_ENC_MASA_VARIANT masaVariant;
+ } masa_ism;
+#endif
+
} EncInputFormatConfig;
/* Struct for storing cmdln arguments */
@@ -427,6 +436,15 @@ int main(
goto cleanup;
}
break;
+#ifdef MASA_AND_OBJECTS
+ case IVAS_ENC_INPUT_MASA_ISM:
+ if ( ( error = IVAS_ENC_ConfigureForMASAObjects( hIvasEnc, arg.inputFs, totalBitrate, bandwidth, arg.dtxConfig, arg.inputFormatConfig.masa_ism.numObjects, arg.inputFormatConfig.masa_ism.masaVariant ) ) != IVAS_ERR_OK )
+ {
+ fprintf( stderr, "\nIVAS_ENC_ConfigureForMASAObjects failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) );
+ exit( -1 );
+ }
+ break;
+#endif
default:
fprintf( stderr, "\nInvalid input type\n\n" );
goto cleanup;
@@ -511,7 +529,11 @@ int main(
}
}
+#ifdef MASA_AND_OBJECTS
+ const int16_t numIsmInputs = ( arg.inputFormat == IVAS_ENC_INPUT_ISM || arg.inputFormat == IVAS_ENC_INPUT_MASA_ISM ) ? arg.inputFormatConfig.ism.numObjects : 0;
+#else
const int16_t numIsmInputs = arg.inputFormat == IVAS_ENC_INPUT_ISM ? arg.inputFormatConfig.ism.numObjects : 0;
+#endif
for ( i = 0; i < numIsmInputs; ++i )
{
@@ -1490,6 +1512,100 @@ static bool parseCmdlIVAS_enc(
return false;
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( strcmp( to_upper( argv[i] ), "-ISM_MASA" ) == 0 )
+ {
+ arg->inputFormat = IVAS_ENC_INPUT_MASA_ISM;
+ i++;
+
+ if ( i < argc - 5 )
+ {
+ if ( sscanf( argv[i], "%d", &tmp ) > 0 )
+ {
+ i++;
+ }
+
+ if ( tmp <= 0 )
+ {
+ fprintf( stderr, "Error: Too low number of ISM channels specified!\n\n" );
+ usage_enc();
+ }
+ else
+ {
+ if ( tmp <= IVAS_MAX_NUM_OBJECTS ) /* number of ISM channels */
+ {
+ arg->inputFormatConfig.masa_ism.numObjects = (int16_t) tmp;
+ }
+ else
+ {
+ fprintf( stderr, "Error: Too high number of ISM channels!\n\n" );
+ usage_enc();
+ }
+ }
+ }
+ else
+ {
+ fprintf( stderr, "Error: Number of ISM channels not specified!\n\n" );
+ usage_enc();
+ }
+ if ( i < argc - 4 )
+ {
+ if ( sscanf( argv[i], "%d", &tmp ) > 0 )
+ {
+ i++;
+ }
+
+ switch ( tmp )
+ {
+ case 1:
+ arg->inputFormatConfig.masa_ism.masaVariant = IVAS_ENC_MASA_1CH;
+ break;
+ case 2:
+ arg->inputFormatConfig.masa_ism.masaVariant = IVAS_ENC_MASA_2CH;
+ break;
+ default:
+ fprintf( stderr, "Error: MASA channels must for the moment be 1 or 2.\n\n" );
+ usage_enc();
+ break;
+ }
+ }
+
+ /* read input metadata files */
+ for ( j = 0; j < arg->inputFormatConfig.masa_ism.numObjects; j++ )
+ {
+ if ( i < argc - 4 )
+ {
+ if ( strcmp( argv[i], "NULL" ) == 0 || strcmp( argv[i], "null" ) == 0 )
+ {
+ /* no metadata input file -> encode only audio streams */
+ arg->inputFormatConfig.masa_ism.metadataFiles[j] = NULL;
+ }
+ else
+ {
+ arg->inputFormatConfig.masa_ism.metadataFiles[j] = argv[i];
+ }
+
+ i++;
+ }
+ else
+ {
+ fprintf( stderr, "Error: not enough arguments\n\n" );
+ usage_enc();
+ }
+ }
+
+ if ( i < argc - 4 )
+ {
+ arg->masaMetadataFile = argv[i];
+ i++;
+ }
+ else
+ {
+ fprintf( stderr, "Error: not enough MASA arguments\n\n" );
+ usage_enc();
+ }
+ }
+#endif
else if ( strcmp( argv_to_upper, "-STEREO_DMX_EVS" ) == 0 )
{
arg->inputFormat = IVAS_ENC_INPUT_MONO;
@@ -1671,6 +1787,10 @@ static void usage_enc( void )
fprintf( stdout, " for 4 ISM also 512000 \n" );
fprintf( stdout, " for IVAS SBA, MASA, MC R=(13200, 16400, 24400, 32000, 48000, 64000, 80000, \n" );
fprintf( stdout, " 96000, 128000, 160000, 192000, 256000, 384000, 512000) \n" );
+#ifdef MASA_AND_OBJECTS
+ fprintf( stdout, " for IVAS objects-MASA R =(13200, 16400, 24400, 32000, 48000, 64000, 96000, 128000, \n" );
+ fprintf( stdout, " 160000, 192000, 256000, 384000, 512000)\n" );
+#endif
fprintf( stdout, " Alternatively, R can be a bitrate switching file which consists of R values\n" );
fprintf( stdout, " indicating the bitrate for each frame in bps. These values are stored in\n" );
fprintf( stdout, " binary format using 4 bytes per value\n" );
@@ -1694,6 +1814,13 @@ static void usage_enc( void )
fprintf( stdout, "-masa Ch File : MASA format \n" );
fprintf( stdout, " where Ch specifies the number of input/transport channels (1 or 2): \n" );
fprintf( stdout, " and File specifies input file containing parametric MASA metadata \n" );
+#ifdef MASA_AND_OBJECTS
+ fprintf( stdout, "-ism_masa IsmChannels MasaChannels IsmFiles MasaFile : MASA and objects format \n" );
+ fprintf( stdout, " where IsmChannels specifies the number of ISms (1-4)\n" );
+ fprintf( stdout, " and MasaChannels specifies the number of MASA input/transport channels (1 or 2) \n" );
+ fprintf( stdout, " and IsmFiles specify input files containing metadata, one file per object \n" );
+ fprintf( stdout, " and MasaFile specifies MASA input file containing parametric metadata \n" );
+#endif
fprintf( stdout, "-mc InputConf : Multi-channel format\n" );
fprintf( stdout, " where InputConf specifies the channel configuration: 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4\n" );
fprintf( stdout, " Loudspeaker positions are assumed to have azimuth and elevation as per \n" );
diff --git a/ci/build_codec_sanitizers_linux.sh b/ci/build_codec_sanitizers_linux.sh
index 4e40f89b9a028d89363c97ec2fbab109474334b8..d352fa32ec1cd6d8d3283c4984ba428c117b5769 100755
--- a/ci/build_codec_sanitizers_linux.sh
+++ b/ci/build_codec_sanitizers_linux.sh
@@ -40,5 +40,4 @@ make CLANG=1 -j
make clean
make CLANG=2 -j
make clean
-# write out one build for warnings check
-make CLANG=3 -j 2>&1 | tee build_output.txt
+make CLANG=3 -j
diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c
index 3fe32b04e3f36efd20836eb59ad6b314e810d247..fb27e89e00cc65a63de236f563cadf82bd2900ff 100644
--- a/lib_com/bitstream.c
+++ b/lib_com/bitstream.c
@@ -532,6 +532,51 @@ int16_t get_ivas_max_num_indices(
return 1650;
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( ivas_total_brate <= IVAS_16k4 )
+ {
+ return 300;
+ }
+ else if ( ivas_total_brate <= IVAS_32k )
+ {
+ return 400;
+ }
+ else if ( ivas_total_brate <= IVAS_48k )
+ {
+ return 650;
+ }
+ else if ( ivas_total_brate <= IVAS_80k )
+ {
+ return 750;
+ }
+ else if ( ivas_total_brate <= IVAS_160k )
+ {
+ return 850;
+ }
+ else if ( ivas_total_brate <= IVAS_192k )
+ {
+ return 950;
+ }
+ else if ( ivas_total_brate <= IVAS_256k )
+ {
+#ifdef OMASA_BIT_BUFF_SZ
+ return 1300;
+#else
+ return 1150;
+#endif
+ }
+ else if ( ivas_total_brate <= IVAS_384k )
+ {
+ return 1450;
+ }
+ else
+ {
+ return 1650;
+ }
+ }
+#endif
else if ( ivas_format == MC_FORMAT )
{
if ( ivas_total_brate <= IVAS_16k4 )
@@ -900,6 +945,51 @@ int16_t get_ivas_max_num_indices_metadata(
return 1750;
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( ivas_total_brate <= IVAS_16k4 )
+ {
+ return 80;
+ }
+ else if ( ivas_total_brate <= IVAS_32k )
+ {
+ return 125 + 100;
+ }
+ else if ( ivas_total_brate <= IVAS_48k )
+ {
+ return 205 + 100;
+ }
+ else if ( ivas_total_brate <= IVAS_96k )
+ {
+ return 240 + 150;
+ }
+ else if ( ivas_total_brate <= IVAS_128k )
+ {
+ return 305 + 30;
+ }
+ else if ( ivas_total_brate <= IVAS_160k )
+ {
+ return 425 + 30;
+ }
+ else if ( ivas_total_brate <= IVAS_192k )
+ {
+ return 630 + 30;
+ }
+ else if ( ivas_total_brate <= IVAS_256k )
+ {
+ return 850 + 30;
+ }
+ else if ( ivas_total_brate <= IVAS_384k )
+ {
+ return 1000 + 30;
+ }
+ else
+ {
+ return 1750 + 30;
+ }
+ }
+#endif
else if ( ivas_format == MC_FORMAT )
{
if ( ivas_total_brate <= IVAS_13k2 )
@@ -2715,6 +2805,25 @@ ivas_error preview_indices(
break;
case 2:
st_ivas->ivas_format = ISM_FORMAT;
+
+ if ( total_brate >= IVAS_24k4 )
+ {
+ if ( bit_stream[2] )
+ {
+#ifdef MASA_AND_OBJECTS
+ if ( bit_stream[3] )
+ {
+ /* Placeholder for SBA + objects */
+ }
+ else
+ {
+ st_ivas->ivas_format = MASA_ISM_FORMAT;
+ }
+#else
+ /* placeholder for combined format signaling */
+#endif
+ }
+ }
break;
case 3:
if ( bit_stream[2] == 0 )
@@ -2877,6 +2986,20 @@ ivas_error preview_indices(
ivas_sba_config( total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ) );
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ /* read number of objects from the bitstream */
+ st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */
+ st_ivas->nchan_ism = 0;
+
+ if ( total_brate != SID_2k40 && total_brate != FRAME_NO_DATA )
+ {
+ st_ivas->nchan_ism = 2 * bit_stream[total_brate / FRAMES_PER_SEC - 1] + bit_stream[total_brate / FRAMES_PER_SEC - 2] + 1;
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( total_brate, st_ivas->nchan_ism );
+ }
+ }
+#endif
}
st_ivas->hDecoderConfig->ivas_total_brate = total_brate;
diff --git a/lib_com/cnst.h b/lib_com/cnst.h
index b6e033b7c54926f9123f6ea40a5831aa5150c7e2..a66938354e7046307039c8cbcc34eaad13853e39 100644
--- a/lib_com/cnst.h
+++ b/lib_com/cnst.h
@@ -263,6 +263,9 @@ enum{
enum
{
IND_IVAS_FORMAT,
+#ifdef MASA_AND_OBJECTS
+ IND_SMODE_OMASA,
+#endif
IND_SMODE,
IND_SID_TYPE,
IND_BWIDTH,
diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c
index 7d2d5deb5298ff04b5a77d058f93aa436d7e78ea..74ae97311e6aafde538db09657d4ce976870f4b5 100644
--- a/lib_com/delay_comp.c
+++ b/lib_com/delay_comp.c
@@ -73,7 +73,11 @@ int32_t get_delay(
{
delay = IVAS_ENC_DELAY_NS;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
delay = 0; /* All delay is compensated in the decoder with MASA */
}
@@ -115,7 +119,11 @@ int32_t get_delay(
}
#endif
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
delay += IVAS_ENC_DELAY_NS; /* Compensate also the encoder delay in the decoder with MASA */
}
diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h
index 4cd06c6ed45e1bdf67dcc36a717ca47b599211c4..f4db6dd47b1ef98e26c46d935f0e884049c0c101 100644
--- a/lib_com/ivas_cnst.h
+++ b/lib_com/ivas_cnst.h
@@ -69,7 +69,9 @@ typedef enum
SBA_FORMAT, /* IVAS SBA (ambisonics) format */
MASA_FORMAT, /* IVAS MASA format */
MC_FORMAT, /* IVAS multi-channel format */
-
+#ifdef MASA_AND_OBJECTS
+ MASA_ISM_FORMAT, /* IVAS combined MASA + objects format*/
+#endif
} IVAS_FORMAT;
@@ -79,6 +81,9 @@ typedef enum
#define IVAS_FORMAT_SIGNALING_NBITS 2 /* number of bits for signaling the IVAS format */
#define IVAS_FORMAT_SIGNALING_NBITS_EXTENDED ( IVAS_FORMAT_SIGNALING_NBITS + 1 )
+#ifdef MASA_AND_OBJECTS
+#define IVAS_COMBINED_FORMAT_SIGNALLING_BITS 1
+#endif
/*----------------------------------------------------------------------------------*
@@ -208,7 +213,7 @@ typedef enum
#define MAX_JBM_SUBFRAMES_5MS 8
#define DEFAULT_JBM_SUBFRAMES_5MS 4
#define JBM_CLDFB_SLOTS_IN_SUBFRAME 4
-#define MAX_JBM_CLDFB_TIMESLOTS 32
+#define MAX_JBM_CLDFB_TIMESLOTS 32
#define DEFAULT_JBM_CLDFB_TIMESLOTS 16
#define MAX_JBM_L_FRAME48k 1920
#define MAX_JBM_L_FRAME_NS 40000000L
@@ -313,7 +318,13 @@ typedef enum
#define MIN_BRATE_SWB_SCE ACELP_9k60 /* min. SCE bitrate where SWB is supported */
#define MIN_BRATE_SWB_STEREO IVAS_13k2 /* min. stereo bitrate where SWB is supported */
#define MIN_BRATE_FB_STEREO IVAS_32k /* min. SCE and stereo bitrate where FB is supported */
+#ifdef ISM_FB
+#ifdef ISM_FB_16k4
#define MIN_BRATE_FB_ISM 16000 /* min. SCE bitrate where FB is supported in ISM format */
+#else
+#define MIN_BRATE_FB_ISM 24000 /* min. SCE bitrate where FB is supported in ISM format */
+#endif
+#endif
#define MIN_TDM_BRATE_WB_TBE_1k05 12000 /* min. per channel bitrate where WB TBE @1.05 kbps is supported (0.35kbs at lower bitrates) */
#define MIN_BRATE_WB_TBE_1k05 9650 /* min. per channel bitrate where WB TBE @1.05 kbps is supported (0.35kbs at lower bitrates) */
@@ -337,11 +348,23 @@ typedef enum
#define ISM_METADATA_INACTIVE_FLAG_BITS 1 /* flag to signal whether MD are sent in low-rate inactive frame */
#define ISM_METADATA_FLAG_BITS 2
+#ifdef MASA_AND_OBJECTS
+#define ISM_INACTIVE_IMP 0 /* == ISM_NO_META */
+#endif
#define ISM_NO_META 0
#define ISM_LOW_IMP 1
#define ISM_MEDIUM_IMP 2
#define ISM_HIGH_IMP 3
+#ifdef MASA_AND_OBJECTS
+#define BRATE_ISM_INACTIVE 2450 /* CoreCoder bitrate in ISM no meta / inactive frames */
+#define BITS_ISM_INACTIVE ( BRATE_ISM_INACTIVE / FRAMES_PER_SEC )
+#ifdef MASA_AND_OBJECTS
+#define ADJUST_ISM_BRATE_NEG 6000
+#define ADJUST_ISM_BRATE_POS 8000
+#endif
+#endif
+
#define ISM_AZIMUTH_NBITS 7
#define ISM_AZIMUTH_MIN -180.0f
#define ISM_AZIMUTH_MAX 180.0f
@@ -395,6 +418,13 @@ typedef enum
ISM_MODE_NONE,
ISM_MODE_DISC, /* discrete ISM */
ISM_MODE_PARAM /* parametric ISM */
+#ifdef MASA_AND_OBJECTS
+ ,
+ ISM_MASA_MODE_MASA_ONE_OBJ, /* MASA ISM mode when one object is encoded separately and remainder using MASA parameters */
+ ISM_MASA_MODE_PARAM_ONE_OBJ, /* MASA ISM mode when one object is encoded separately and remainder using parametric object model */
+ ISM_MASA_MODE_DISC /* MASA ISM mode when all objects are encoded separarately */
+#endif
+
} ISM_MODE;
@@ -403,7 +433,7 @@ enum
{
IND_ISM_NUM_OBJECTS,
IND_ISM_EXTENDED_FLAG = IND_ISM_NUM_OBJECTS + MAX_NUM_OBJECTS,
- IND_ISM_EXTENDED_NDP_FLAG,
+ IND_ISM_EXTENDED_NDP_FLAG,
IND_ISM_METADATA_FLAG,
IND_ISM_MD_NULL_FLAG = IND_ISM_METADATA_FLAG + MAX_NUM_OBJECTS,
IND_ISM_MD_INACTIVE_FLAG = IND_ISM_MD_NULL_FLAG + MAX_NUM_OBJECTS,
@@ -655,7 +685,7 @@ enum
IND_STEREO_DFT_SIDEGAIN_FLAG,
IND_STEREO_DFT_SIDEGAINS,
- IND_STEREO_DFT_ITD_MODE = IND_STEREO_DFT_SIDEGAINS + 4 * STEREO_DFT_BAND_MAX + 72,
+ IND_STEREO_DFT_ITD_MODE = IND_STEREO_DFT_SIDEGAINS + 4 * STEREO_DFT_BAND_MAX + 120,
IND_STEREO_DFT_ITD_HUFF,
IND_STEREO_DFT_ITD_NEG,
@@ -1173,6 +1203,12 @@ enum
#define MASA_DELTA_AZI_DCT 10
#define MASA_TRANSP_BITS 1
+#ifdef MASA_AND_OBJECTS
+#define NO_BITS_MASA_ISM_NO_OBJ 2
+#define MASA2TOTAL_THR 0.98f
+#define BITS_MASA2TOTTAL_DCT0 6
+#define STEP_M2T 0.1f
+#endif
#define MASA_HEADER_BITS 2
#define MASA_SUBFRAME_BITS 1
#define MASA_LOWBITRATE_MODE_BITS 1
@@ -1236,6 +1272,13 @@ enum
#define MASA_ANGLE_AT_EQUATOR_DEG 0.738796268264740f
#define MASA_INV_ANGLE_AT_EQUATOR_DEG 1.353553128183453f
#define MASA_STEREO_MIN_BITRATE IVAS_24k4
+#ifdef MASA_AND_OBJECTS
+#define MAXIMUM_OMASA_FREQ_BANDS 8 /* Corresponds to maximum number of coding bands at 32 kbps */
+#ifdef MASA_AND_OBJECTS
+#define OMASA_STEREO_SW_CNT_MAX 100
+#define OMASA_STEREO_SW_CNT_MAX2 5
+#endif
+#endif
#define MASA_BIT_REDUCT_PARAM 10
#define MASA_MAXIMUM_TWO_DIR_BANDS 24
@@ -1426,8 +1469,12 @@ typedef enum
#define PARAM_MC_MAX_BAND_ABS_COV_DEC 10
#define PARAM_MC_ENER_LIMIT_INTRAFRAME (1.5f)
#define PARAM_MC_ENER_LIMIT_INTERFRAME (2.0f)
+#ifdef FIX_563_PARAMMC_LIMITER
#define PARAM_MC_ENER_LIMIT_MAX_DELTA_FAC (15.0f)
+#endif
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
#define PARAM_MC_NUM_ATTACK_ILD_THRESH (3)
+#endif
#define PARAM_MC_LFE_ON_THRESH (8000.0f)
#define PARAM_MC_BAND_TO_MDCT_BAND_RATIO 16 /* Ratio of resolution of CLDFB Bands to MDCT Bands */
#define PARAM_MC_SLOT_ENC_NS 2500000L
diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c
index 7944311470c85fc0c79707a2aa804764d9d2ddd0..1c25269f6b82703629e5d1aafa106e00407469e9 100644
--- a/lib_com/ivas_ism_com.c
+++ b/lib_com/ivas_ism_com.c
@@ -54,7 +54,9 @@
#define BETA_ISM_LOW_IMP 0.6f
#define BETA_ISM_MEDIUM_IMP 0.8f
+#ifdef FIX_562_ISM2_64KBPS
#define MAX_BRATE_TCX_32k 48000
+#endif
/*-------------------------------------------------------------------*
@@ -63,7 +65,11 @@
* Convert bit-budget to bitrate
*-------------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+void bitbudget_to_brate(
+#else
static void bitbudget_to_brate(
+#endif
const int16_t x[], /* i : bitbudgets */
int32_t y[], /* o : bitrates */
const int16_t N /* i : number of entries to be converted */
@@ -97,6 +103,10 @@ ivas_error ivas_ism_config(
int32_t element_brate[], /* o : element bitrate per object */
int32_t total_brate[], /* o : total bitrate per object */
int16_t nb_bits_metadata[] /* i/o: number of metadata bits */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t combined_format_flag /* i : flag indicating combined format */
+#endif
)
{
int16_t ch;
@@ -109,8 +119,18 @@ ivas_error ivas_ism_config(
ivas_error error;
error = IVAS_ERR_OK;
-
- n_ISms = nchan_transport;
+#ifdef MASA_AND_OBJECTS
+ if ( combined_format_flag )
+ {
+ n_ISms = nchan_ism;
+ }
+ else
+ {
+#endif
+ n_ISms = nchan_transport;
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
/* initialization */
ism_metadata_flag_global = 0;
@@ -123,6 +143,59 @@ ivas_error ivas_ism_config(
}
}
+#ifdef MASA_AND_OBJECTS
+ /* decision about bitrates per channel */
+ if ( combined_format_flag )
+ {
+ /* combined format: decision about bitrates per channel - variable during the session (at one ivas_total_brate) */
+ bits_ism = (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
+ set_s( bits_element, bits_ism / n_ISms, n_ISms );
+ bits_element[n_ISms - 1] += bits_ism % n_ISms;
+
+ /* ISM common signaling bits are counted in MASA MD bit-budget */
+ }
+ else
+ {
+ /* ISM format: decision about bitrates per channel - constant during the session (at one ivas_total_brate) */
+ bits_ism = (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
+ set_s( bits_element, bits_ism / n_ISms, n_ISms );
+ bits_element[n_ISms - 1] += bits_ism % n_ISms;
+ bitbudget_to_brate( bits_element, element_brate, n_ISms );
+
+ /* count ISm common signaling bits */
+ if ( hIsmMeta != NULL )
+ {
+ nb_bits_metadata[0] += n_ISms * ISM_METADATA_FLAG_BITS + nchan_ism;
+
+ if ( ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
+ {
+ nb_bits_metadata[0] += ISM_EXTENDED_METADATA_BITS;
+
+ if ( ism_extended_metadata_flag )
+ {
+ nb_bits_metadata[0] += ISM_METADATA_IS_NDP_BITS;
+ }
+ }
+
+ for ( ch = 0; ch < n_ISms; ch++ )
+ {
+ if ( null_metadata_flag[ch] )
+ {
+ nb_bits_metadata[0] += ISM_METADATA_MD_FLAG_BITS;
+ nb_bits_metadata[0] += ISM_METADATA_FLAG_BITS;
+ }
+ else
+ {
+ if ( ism_imp[ch] == ISM_NO_META )
+ {
+ nb_bits_metadata[0] += ISM_METADATA_MD_FLAG_BITS;
+ nb_bits_metadata[0] += ISM_METADATA_INACTIVE_FLAG_BITS;
+ }
+ }
+ }
+ }
+ }
+#else
/* decision about bitrates per channel - constant during the session (at one ivas_total_brate) */
bits_ism = (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
set_s( bits_element, bits_ism / n_ISms, n_ISms );
@@ -160,6 +233,7 @@ ivas_error ivas_ism_config(
}
}
}
+#endif
/* split metadata bitbudget equally between channels */
if ( nb_bits_metadata != NULL )
@@ -290,7 +364,8 @@ ivas_error ivas_ism_config(
bits_CoreCoder[ch] = tmp;
}
- /* limitaton to avoid too high bitrate in one active TCX channel */
+#ifdef FIX_562_ISM2_64KBPS
+ /* limitation to avoid too high bitrate in one active TCX channel */
if ( element_brate[0] >= SCE_CORE_16k_LOW_LIMIT && element_brate[0] <= IVAS_32k )
{
diff = 0;
@@ -304,6 +379,7 @@ ivas_error ivas_ism_config(
bits_CoreCoder[ch] = tmp;
}
}
+#endif
if ( diff > 0 )
{
@@ -326,12 +402,44 @@ ivas_error ivas_ism_config(
printf( "\nWarning: ISM bitbudget equal to SID!\n" );
}
#endif
+
+#ifdef MASA_AND_OBJECTS
+ if ( combined_format_flag )
+ {
+ diff = 0;
+ }
+#endif
break;
}
}
}
}
+#ifdef MASA_AND_OBJECTS
+ if ( combined_format_flag )
+ {
+ if ( diff > 0 )
+ {
+ for ( ch = 0; ch < n_ISms; ch++ )
+ {
+ if ( ism_imp[ch] <= ISM_MEDIUM_IMP )
+ {
+ if ( diff > limit_high )
+ {
+ diff += bits_CoreCoder[ch] - limit_high;
+ bits_CoreCoder[ch] = limit_high;
+ }
+ else
+ {
+ bits_CoreCoder[ch] += diff;
+ break;
+ }
+ }
+ }
+ }
+ }
+#endif
+
bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
}
@@ -340,7 +448,11 @@ ivas_error ivas_ism_config(
{
int32_t tmpL;
tmpL = sum_l( total_brate, n_ISms ) + bits_side * FRAMES_PER_SEC;
+#ifdef MASA_AND_OBJECTS
+ if ( ism_total_brate != tmpL )
+#else
if ( sum_l( element_brate, n_ISms ) != tmpL )
+#endif
{
return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "\nError: Mismatch in ISM bit-budget distribution. Exiting!\n" );
}
@@ -506,8 +618,10 @@ void ivas_param_ism_config(
hParamIsm->last_el_sgn[i] = 1;
}
+#ifdef FIX_549_DMX_GAIN
hParamIsm->last_dmx_gain = 1.0f;
set_f( hParamIsm->last_cardioid_left, 1.0f, MAX_NUM_OBJECTS );
+#endif
return;
}
@@ -546,7 +660,11 @@ ISM_MODE ivas_ism_mode_select(
* ---------------------------------------------------------------*/
void ivas_ism_metadata_close(
- ISM_METADATA_HANDLE hIsmMetaData[] /* i/o : object metadata handles */
+ ISM_METADATA_HANDLE hIsmMetaData[] /* i/o : object metadata handles */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t first_idx /* i : index of first handle to deallocate */
+#endif
)
{
int16_t n;
@@ -556,7 +674,11 @@ void ivas_ism_metadata_close(
return;
}
+#ifdef MASA_AND_OBJECTS
+ for ( n = first_idx; n < MAX_NUM_OBJECTS; n++ )
+#else
for ( n = 0; n < MAX_NUM_OBJECTS; n++ )
+#endif
{
if ( hIsmMetaData[n] != NULL )
{
diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com.c
index b1a6c256d2a0eaf785e58ebadcc74dde392fd337..94d537494ed2cf1837d0cb02c154fca9bbe15daf 100644
--- a/lib_com/ivas_masa_com.c
+++ b/lib_com/ivas_masa_com.c
@@ -69,13 +69,19 @@ static int16_t quantize_phi_masa( float phi, const int16_t flag_delta, float *ph
*---------------------------------------------------------------*/
void ivas_masa_set_elements(
- const int32_t ivas_total_brate, /* i : codec total bitrate */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t mc_mode, /* i : MC format mode */
const int16_t nchan_transport, /* i : number of MASA input/transport channels */
IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
int16_t *element_mode, /* o : element mode */
int16_t *nSCE, /* o : number of SCEs */
int16_t *nCPE /* o : number of CPEs */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t ivas_format, /* i : IVAS format */
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int32_t ism_total_brate /* i : initial ISM total bitrate */
+#endif
)
{
if ( nchan_transport == 2 )
@@ -87,17 +93,42 @@ void ivas_masa_set_elements(
*element_mode = IVAS_SCE; /* This is needed for the initialization phase to initialize codec mode to SCE, since it is written first to the file*/
}
+#ifdef MASA_AND_OBJECTS
+ else if ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE )
+ {
+ *nCPE = 1;
+
+ if ( *element_mode == -1 )
+ {
+ *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
+ }
+ if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
+ {
+ *element_mode = IVAS_CPE_MDCT;
+ if ( ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) && ( ivas_total_brate - ism_total_brate < MIN_BRATE_MDCT_STEREO ) )
+ {
+ *element_mode = IVAS_CPE_DFT;
+ }
+ }
+ }
+#endif
else
{
*nCPE = 1;
*nSCE = 0;
- if ( ivas_total_brate > IVAS_48k )
+ if ( ivas_total_brate > MIN_BRATE_MDCT_STEREO )
{
*element_mode = IVAS_CPE_MDCT;
}
}
hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC );
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ hQMetaData->bits_frame_nominal -= (int16_t) ( ism_total_brate / FRAMES_PER_SEC );
+ }
+#endif
}
else if ( nchan_transport == 1 )
{
@@ -187,7 +218,7 @@ void generate_gridEq(
void ivas_masa_set_coding_config(
MASA_CODEC_CONFIG *config, /* i/o: MASA coding config structure */
int16_t *band_mapping, /* o : Band mapping used */
- const int32_t ivas_total_brate, /* i : codec total bitrate */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t nchan_transport, /* i : number of transport channels (mono/stereo) */
const uint8_t isMcMasa /* i : toggle for selecting mcMASA specific config */
)
@@ -768,3 +799,207 @@ void deindex_sph_idx(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*---------------------------------------------------------------
+ * valid_ratio_index()
+ *
+ * Checking validity of the index of an ISM ratio index vector,
+ * within the indexing function.
+ *---------------------------------------------------------------*/
+
+/*! r: valid or not 1/0 */
+int16_t valid_ratio_index(
+ int16_t index, /* i : index to be checked */
+ const int16_t K, /* i : L1 norm to check against */
+ const int16_t len /* i : vector length */
+)
+{
+ int16_t out;
+ int16_t i, sum, elem;
+ int16_t base[4];
+
+ sum = 0;
+ set_s( base, 1, len );
+
+
+ for ( i = 1; i < len; i++ )
+ {
+ base[i] = base[i - 1] * 10;
+ }
+ sum = 0;
+ for ( i = len - 1; i >= 0; i-- )
+ {
+ elem = index / base[i];
+ sum += elem;
+ index -= elem * base[i];
+ }
+ if ( sum <= K )
+ {
+ out = 1;
+ }
+ else
+ {
+ out = 0;
+ }
+
+ return out;
+}
+
+
+/*---------------------------------------------------------------
+ * reconstruct_ism_ratios()
+ *
+ * Obtains ISM ratio values from the quantized indexes
+ *---------------------------------------------------------------*/
+
+void reconstruct_ism_ratios(
+ int16_t *ratio_ism_idx, /* i : index vector */
+ const int16_t nchan_ism, /* i : number of components/objects */
+ const float step, /* i : quantization step */
+ float *q_energy_ratio_ism /* o : reconstructed ISM values */
+)
+{
+ int16_t i;
+ float sum;
+
+ sum = 0;
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ q_energy_ratio_ism[i] = ratio_ism_idx[i] * step;
+ sum += q_energy_ratio_ism[i];
+ }
+
+ q_energy_ratio_ism[nchan_ism - 1] = 1.0f - sum;
+
+ if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
+ {
+ q_energy_ratio_ism[nchan_ism - 1] = 0.0f;
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * modify_masa_energy_ratios()
+ *
+ * Updates energy ratios by taking into account the MASA content contribution
+ * to the total audio scene
+ *---------------------------------------------------------------*/
+
+void modify_masa_energy_ratios(
+ IVAS_QMETADATA_HANDLE hQMetaData /* i/o: Metadata handle */
+)
+{
+ int16_t i, m, d, b;
+
+ for ( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
+ {
+ if ( hQMetaData->q_direction[0].cfg.nblocks == 1 )
+ {
+ i = 0;
+ }
+ else
+ {
+ i = m;
+ }
+
+ for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
+ {
+ for ( d = 0; d < hQMetaData->no_directions; d++ )
+ {
+ hQMetaData->q_direction[d].band_data[b].energy_ratio[m] = hQMetaData->q_direction[d].band_data[b].energy_ratio[m] * hQMetaData->masa_to_total_energy_ratio[i][b];
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * distribute_evenly_ism()
+ *
+ * Obtain ISM ratio indexes for even content distribution bbetween objects
+ *---------------------------------------------------------------*/
+
+void distribute_evenly_ism(
+ int16_t *idx, /* o : index values */
+ const int16_t K, /* i : sum of indexes */
+ const int16_t nchan_ism /* i : number of objects */
+)
+{
+ int16_t i;
+ int16_t sum;
+
+ sum = 0;
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+ idx[i] = (int16_t) ( K / nchan_ism );
+ sum += idx[i];
+ }
+
+ assert( sum <= K );
+
+ i = 0;
+ while ( sum < K )
+ {
+ if ( i == nchan_ism )
+ {
+ i = 0;
+ }
+ idx[i]++;
+ sum++;
+ i++;
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * calculate_cpe_brate_MASA_ISM()
+ *
+ * Calculates bitrate for MASA_ISM mode that is not used for separated objects,
+ * * but for the CPE part (metadata included)
+ *---------------------------------------------------------------*/
+
+/*! r: CPE bitrate value */
+int32_t calculate_cpe_brate_MASA_ISM(
+ const ISM_MODE ism_mode, /* i : ism mode */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t nchan_ism /* i : number of objects */
+)
+{
+ int32_t cpe_brate;
+ int16_t k, sce_id;
+
+ k = 0;
+ while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
+ {
+ k++;
+ }
+
+ if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ cpe_brate = ivas_total_brate - sep_object_brate[k - 2][0]; /* take data from the first column */
+ }
+ else if ( ism_mode == ISM_MASA_MODE_DISC )
+ {
+ cpe_brate = ivas_total_brate;
+
+ for ( sce_id = 0; sce_id < nchan_ism; sce_id++ )
+ {
+ cpe_brate -= sep_object_brate[k - 2][nchan_ism - 1];
+ }
+ }
+ else
+ {
+ cpe_brate = ivas_total_brate;
+ }
+
+ return cpe_brate;
+}
+#endif
diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com.c
index 1b7db4ff01a7c1426c65eb74c0cba4ab76cc8eaa..7e81e1fd1cd8317beeb8c359c34433a113896e02 100644
--- a/lib_com/ivas_mcmasa_com.c
+++ b/lib_com/ivas_mcmasa_com.c
@@ -101,7 +101,7 @@ void ivas_mcmasa_set_separate_channel_mode(
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 int32_t ivas_total_brate, /* i : IVAS 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 */
diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com.c
new file mode 100644
index 0000000000000000000000000000000000000000..8e385537c3738d0099c6f0ff060192ff4ba7eb0d
--- /dev/null
+++ b/lib_com/ivas_omasa_com.c
@@ -0,0 +1,523 @@
+/******************************************************************************************************
+
+ (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 "options.h"
+#include
+#include "ivas_cnst.h"
+#include "ivas_prot.h"
+#include "prot.h"
+#include "ivas_rom_com.h"
+#include
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+
+#ifdef MASA_AND_OBJECTS
+/*---------------------------------------------------------------
+ * Local constants
+ *---------------------------------------------------------------*/
+
+#define GAMMA_ISM_LOW_IMP 0.8f
+#define GAMMA_ISM_MEDIUM_IMP 1.2f
+#define GAMMA_ISM_HIGH_IMP 1.4f
+
+#define GAMMA_ISM_LOW_IMP2 0.9f
+#define GAMMA_ISM_MEDIUM_IMP2 1.2f
+#define GAMMA_ISM_HIGH_IMP2 1.35f
+
+#define GAMMA_ISM_LOW_IMP3 0.85f
+#define GAMMA_ISM_MEDIUM_IMP3 1.15f
+#define GAMMA_ISM_HIGH_IMP3 1.3f
+
+#define GAMMA_ISM_LOW_IMP4 0.8f
+#define GAMMA_ISM_MEDIUM_IMP4 1.0f
+#define GAMMA_ISM_HIGH_IMP4 1.2f
+
+
+/*---------------------------------------------------------------
+ * ivas_omasa_ism_mode_select()
+ *
+ * selects the ISM mode base on IVAS total bit-rate and
+ * the number of objects in the combined ISM MASA format mode
+ * ---------------------------------------------------------------*/
+
+/*! r : ISM format mode */
+ISM_MODE ivas_omasa_ism_mode_select(
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t nchan_ism /* i : number of input ISM's */
+)
+{
+ ISM_MODE ism_mode = ISM_MODE_NONE;
+
+ switch ( nchan_ism )
+ {
+ case 1:
+ if ( ivas_total_brate >= IVAS_24k4 )
+ {
+ ism_mode = ISM_MASA_MODE_DISC;
+ }
+ else
+ {
+ ism_mode = ISM_MODE_NONE;
+ }
+ break;
+ case 2:
+ if ( ivas_total_brate >= IVAS_48k )
+ {
+ ism_mode = ISM_MASA_MODE_DISC;
+ }
+ else if ( ivas_total_brate >= IVAS_32k )
+ {
+ ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
+ }
+ else
+ {
+ ism_mode = ISM_MODE_NONE;
+ }
+ break;
+ case 3:
+ if ( ivas_total_brate >= IVAS_96k )
+ {
+ ism_mode = ISM_MASA_MODE_DISC;
+ }
+ else if ( ivas_total_brate >= IVAS_64k )
+ {
+ ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
+ }
+ else if ( ivas_total_brate >= IVAS_32k )
+ {
+ ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
+ }
+ else
+ {
+ ism_mode = ISM_MODE_NONE;
+ }
+ break;
+ case 4:
+ if ( ivas_total_brate >= IVAS_128k )
+ {
+ ism_mode = ISM_MASA_MODE_DISC;
+ }
+ else if ( ivas_total_brate >= IVAS_64k )
+ {
+ ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
+ }
+ else if ( ivas_total_brate >= IVAS_32k )
+ {
+ ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
+ }
+ else
+ {
+ ism_mode = ISM_MODE_NONE;
+ }
+ break;
+ }
+
+ return ism_mode;
+}
+
+
+/*---------------------------------------------------------------
+ * ivas_set_omasa_TC()
+ *
+ * set number of transport channels in OMASA format
+ * ---------------------------------------------------------------*/
+
+void ivas_set_omasa_TC(
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int16_t nchan_ism, /* i : number of input ISMs */
+ int16_t *nSCE, /* o : number of SCEs */
+ int16_t *nCPE /* o : number of CPEs */
+)
+{
+ switch ( ism_mode )
+ {
+ case ISM_MASA_MODE_MASA_ONE_OBJ:
+ case ISM_MASA_MODE_PARAM_ONE_OBJ:
+ *nCPE = 1;
+ *nSCE = 1;
+ break;
+ case ISM_MASA_MODE_DISC:
+ *nCPE = 1;
+ *nSCE = nchan_ism;
+ break;
+ case ISM_MODE_NONE:
+ *nCPE = 1;
+ *nSCE = 0;
+ break;
+ default:
+ break;
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * ivas_interformat_brate()
+ *
+ * Bit-budget distribution in case of combined-format coding
+ * ---------------------------------------------------------------*/
+
+/*! r: adjusted bitrate */
+int32_t ivas_interformat_brate(
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int16_t nchan_ism, /* i : number of ISM channels */
+ const int32_t element_brate, /* i : element bitrate */
+ const int16_t ism_imp, /* i : ISM importance flag */
+ const int16_t limit_flag /* i : flag to limit the bitrate increase */
+)
+{
+ int32_t element_brate_out;
+ int16_t nBits, limit_low, limit_high;
+
+ nBits = (int16_t) ( element_brate / FRAMES_PER_SEC );
+
+ if ( ism_imp == ISM_INACTIVE_IMP )
+ {
+ nBits = BITS_ISM_INACTIVE;
+ }
+ else
+ {
+ if ( ism_mode == ISM_MASA_MODE_DISC && ( ( nchan_ism == 4 && element_brate == 24000 ) || ( nchan_ism == 3 && element_brate <= 24000 ) || ( nchan_ism == 2 && element_brate <= 11000 ) ) ) /* for border case in DISC mode */
+ {
+ if ( limit_flag == 1 && ( ( nchan_ism == 4 && element_brate == 24000 ) || ( nchan_ism == 3 && element_brate == 20000 ) || ( nchan_ism == 2 && element_brate <= 11000 ) ) )
+ {
+ return element_brate;
+ }
+
+ if ( ism_imp == ISM_LOW_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP4 );
+ }
+ else if ( ism_imp == ISM_MEDIUM_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP4 );
+ if ( limit_flag == -1 )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
+ }
+ }
+ else /* ISM_HIGH_IMP */
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
+ if ( limit_flag == -1 )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
+ }
+ }
+ }
+ else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ||
+ ( ism_mode == ISM_MASA_MODE_DISC && element_brate == 9600 ) /* this condition corresponds to the ivas_total_brate = 24400 and 1 object */
+ )
+ {
+ if ( ism_imp == ISM_LOW_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP3 );
+ }
+ else if ( ism_imp == ISM_MEDIUM_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP3 );
+ }
+ else /* ISM_HIGH_IMP */
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP3 );
+ }
+ }
+ else
+ {
+ if ( ism_imp == ISM_LOW_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP );
+ }
+ else if ( ism_imp == ISM_MEDIUM_IMP )
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP );
+ }
+ else /* ISM_HIGH_IMP */
+ {
+ nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP );
+ }
+ }
+ }
+
+ limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
+ if ( ism_imp == ISM_INACTIVE_IMP )
+ {
+ limit_low = BITS_ISM_INACTIVE;
+ }
+ else if ( element_brate >= SCE_CORE_16k_LOW_LIMIT )
+ {
+ limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
+ }
+
+ limit_high = IVAS_512k / FRAMES_PER_SEC;
+ if ( element_brate < SCE_CORE_16k_LOW_LIMIT )
+ {
+ limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
+ }
+
+ nBits = check_bounds_s( nBits, limit_low, limit_high );
+
+ element_brate_out = nBits * FRAMES_PER_SEC;
+
+ return element_brate_out;
+}
+
+
+/*---------------------------------------------------------------
+ * ivas_combined_format_brate_sanity()
+ *
+ * Sanity check in combined format coding
+ * ---------------------------------------------------------------*/
+
+void ivas_combined_format_brate_sanity(
+ const int32_t element_brate, /* i : element bitrate */
+ const int16_t core, /* i : core */
+ int32_t *core_brate, /* i/o: core bitrate */
+ int16_t *diff_nBits /* o : number of differential bits */
+)
+{
+ int16_t limit_high, nBits;
+
+ /* sanity check: at lowest IVAS bit-rates and one ISM channel coded by
+ low-rate core-coder mode, it can happen that the CPE (MASA) bit-budget
+ for ACELP core-coding @12.8 kHz is too high */
+
+ if ( element_brate < ACELP_12k8_HIGH_LIMIT )
+ {
+ limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
+ nBits = (int16_t) ( *core_brate / FRAMES_PER_SEC );
+
+ *diff_nBits = nBits - limit_high;
+ if ( *diff_nBits > 0 )
+ {
+ if ( core == TCX_20_CORE || core == TCX_10_CORE )
+ {
+ *diff_nBits = 0;
+ }
+ else /* ACELP core */
+ {
+ *core_brate -= ( *diff_nBits * FRAMES_PER_SEC );
+ }
+ }
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * bits_index_ism_ratio()
+ *
+ *
+ * ---------------------------------------------------------------*/
+
+/*!r : number of bits for ISM ratio index */
+int16_t bits_index_ism_ratio(
+ const int16_t nchan_ism /* i : number of objects */
+)
+{
+ int16_t bits_index;
+
+ bits_index = 0;
+ if ( nchan_ism == 2 )
+ {
+ bits_index = 3;
+ }
+ else if ( nchan_ism == 3 )
+ {
+ bits_index = 6;
+ }
+ else if ( nchan_ism == 4 )
+ {
+ bits_index = 7;
+ }
+ else
+ {
+ assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
+ }
+
+ return bits_index;
+}
+
+
+/*---------------------------------------------------------------
+ * calculate_nbits_meta()
+ *
+ *
+ * ---------------------------------------------------------------*/
+
+void calculate_nbits_meta(
+ const int16_t nchan_ism,
+ float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ const int16_t numSf,
+ const int16_t numCodingBands,
+ int16_t *bits_ism,
+ const int16_t idx_sep_obj,
+ const int16_t ism_imp )
+{
+ int16_t sf, band, obj;
+ float priority[MAX_NUM_OBJECTS], max_p;
+
+ if ( nchan_ism > 1 )
+ {
+ set_f( priority, 0.0f, nchan_ism );
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ for ( obj = 0; obj < nchan_ism; obj++ )
+ {
+ priority[obj] = max( priority[obj], ( q_energy_ratio_ism[sf][band][obj] * ( 1 - masa_to_total_energy_ratio[sf][band] ) ) );
+ }
+ }
+ }
+ }
+ else
+ {
+ priority[0] = 1;
+ }
+
+ /* decide parameters for ISM metadata quantization */
+ maximum( priority, nchan_ism, &max_p );
+ for ( obj = 0; obj < nchan_ism; obj++ )
+ {
+ if ( obj == idx_sep_obj )
+ {
+ if ( ism_imp == 3 )
+ {
+ priority[obj] = 1;
+ }
+ else if ( ism_imp == 2 )
+ {
+ priority[obj] = ( 1 + max_p ) * 0.5f;
+ }
+ else
+ {
+ priority[obj] = max_p;
+ }
+ }
+ bits_ism[obj] = bits_direction_masa[0] - (int16_t) ( ( 1 - ( (int16_t) ( priority[obj] * 1000.0f ) ) * 0.001f ) * 6 );
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * ivas_get_stereo_panning_gains()
+ *
+ *
+ *---------------------------------------------------------------*/
+
+void ivas_get_stereo_panning_gains(
+ const float aziDeg,
+ const float eleDeg,
+ float panningGains[2] )
+{
+ float aziRad, eleRad;
+ float y, mappedX, aziRadMapped, A, A2, A3;
+ const float LsAngleRad = 30.0f * PI_OVER_180;
+ /* Convert azi and ele to an azi value of the cone of confusion */
+ aziRad = aziDeg * PI_OVER_180;
+ eleRad = eleDeg * PI_OVER_180;
+ y = ( sinf( aziRad ) * cosf( eleRad ) );
+ mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) );
+ aziRadMapped = atan2f( y, mappedX );
+
+ if ( aziRadMapped >= LsAngleRad )
+ { /* Left side */
+ panningGains[0] = 1.0f;
+ panningGains[1] = 0.0f;
+ }
+ else if ( aziRadMapped <= -LsAngleRad )
+ { /* Right side */
+ panningGains[0] = 0.0f;
+ panningGains[1] = 1.0f;
+ }
+ else /* Tangent panning law */
+ {
+ A = tanf( aziRadMapped ) / tanf( LsAngleRad );
+ A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f );
+ A3 = 1.0f / ( A2 * A2 + 1.0f );
+ panningGains[0] = sqrtf( A3 );
+ panningGains[1] = sqrtf( 1.0f - A3 );
+ }
+
+ return;
+}
+
+
+/*---------------------------------------------------------------
+ * calculate_brate_limit_flag()
+ *
+ *
+ *---------------------------------------------------------------*/
+
+/*! r: limitation flag */
+int16_t calculate_brate_limit_flag(
+ const int16_t ism_imp[], /* i : ISM importance flags */
+ const int16_t nchan_ism /* i : number of objects */
+)
+{
+ int16_t n;
+ int16_t brate_limit_flag;
+ int16_t nzeros;
+
+ brate_limit_flag = 0;
+ nzeros = 0;
+ for ( n = 0; n < nchan_ism; n++ )
+ {
+ brate_limit_flag += ism_imp[n];
+ if ( ism_imp[n] == 0 )
+ {
+ nzeros++;
+ }
+ }
+
+ if ( brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) )
+ {
+ brate_limit_flag = 1;
+ }
+ else
+ {
+ if ( nzeros / (float) nchan_ism >= 0.5f )
+ {
+ brate_limit_flag = -1; /* there is no limitation, on the contrary */
+ }
+ }
+
+ return brate_limit_flag;
+}
+#endif
diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h
index 885de082817bae5459551d03c98c3aaf853071b5..63395cccd7b89c85ec5dd6096fdc1b5ae2a44a92 100644
--- a/lib_com/ivas_prot.h
+++ b/lib_com/ivas_prot.h
@@ -109,9 +109,9 @@ ivas_error mct_enc_reconfigure(
ivas_error ivas_spar_md_enc_init
(
- ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */
- const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
- const int16_t sba_order /* i : Ambisonic (SBA) order */
+ ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */
+ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */
+ const int16_t sba_order /* i : Ambisonic (SBA) order */
);
ivas_error ivas_sba_enc_reconfigure(
@@ -789,8 +789,8 @@ ivas_error ivas_jbm_dec_flush_renderer(
ivas_error ivas_jbm_dec_feed_tc_to_renderer(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */
- int16_t *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
+ const int16_t nSamplesForRendering, /* i : number of TC samples available for rendering */
+ int16_t *nSamplesResidual, /* o : number of samples not fitting into the renderer grid and buffer for the next call*/
float *data /* i/o: transport channels/output synthesis signal */
);
@@ -900,7 +900,18 @@ ivas_error ivas_ism_config(
int32_t element_brate[], /* o : element bitrate per object */
int32_t total_brate[], /* o : total bitrate per object */
int16_t nb_bits_metadata[] /* i/o: number of metadata bits */
+#ifdef MASA_AND_OBJECTS
+ , const int16_t combined_format_flag /* i : flag indicating combined format */
+#endif
+);
+
+#ifdef MASA_AND_OBJECTS
+void bitbudget_to_brate(
+ const int16_t x[], /* i : bitbudgets */
+ int32_t y[], /* o : bitrates */
+ const int16_t N /* i : number of entries to be converted */
);
+#endif
void ivas_ism_reset_metadata(
ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handles */
@@ -956,10 +967,18 @@ ivas_error ivas_ism_enc(
float data[MAX_NUM_OBJECTS][L_FRAME48k], /* i : input signal */
const int16_t input_frame, /* i : input frame length per channel */
int16_t *nb_bits_metadata /* i : number of metadata bits */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */
+#endif
);
ivas_error ivas_ism_metadata_enc(
+#ifdef MASA_AND_OBJECTS
+ int32_t *ism_total_brate, /* i/o: ISM total bitrate */
+#else
const int32_t ism_total_brate, /* i : ISM total bitrate */
+#endif
const int16_t nchan_ism, /* i : number of ISM channels */
const int16_t nchan_transport, /* i : number of transport channels */
ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
@@ -970,6 +989,12 @@ ivas_error ivas_ism_metadata_enc(
const int16_t ism_mode, /* i : ISM mode */
const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Config Handle */
const int16_t ism_extended_metadata_flag /* i : Extended metadata flag */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const float lp_noise_CPE, /* i : LP filterend total noise estimation */
+ const int16_t flag_omasa_ener_brate, /* i : less bitrate for objects in OMASA flag */
+ int16_t *omasa_stereo_sw_cnt
+#endif
);
ivas_error ivas_ism_metadata_dec(
@@ -1015,6 +1040,10 @@ void ivas_param_ism_enc_close(
void ivas_ism_metadata_close(
ISM_METADATA_HANDLE hIsmMetaData[] /* i/o : object metadata handles */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t first_idx /* i : index of first handle to deallocate */
+#endif
);
void ivas_param_ism_stereo_dmx(
@@ -1045,7 +1074,6 @@ ivas_error ivas_param_ism_dec_open(
void ivas_param_ism_dec_close(
DIRAC_DEC_HANDLE *hDirAC, /* i/o: decoder DirAC handle */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: common spatial renderer data */
const AUDIO_CONFIG output_config /* i : output audio configuration */
);
@@ -1060,8 +1088,8 @@ void ivas_ism_dec_digest_tc(
void ivas_param_ism_dec_digest_tc(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- const uint16_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */
- float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */
+ const uint16_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */
+ float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output */
);
void ivas_param_ism_dec_render(
@@ -1925,7 +1953,11 @@ void stereo_tdm_prep_dwnmx (
const float *input1, /* i : right channel input */
const int16_t input_frame /* i : frame lenght */
);
+
int16_t stereo_tdm_ener_analysis(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+#endif
CPE_ENC_HANDLE hCPE, /* i : CPE structure */
const int16_t input_frame, /* i : Number of samples */
int16_t *tdm_SM_or_LRTD_Pri, /* o : channel combination scheme flag in TD stereo OR LRTD primary channel */
@@ -1948,6 +1980,10 @@ void stereo_td_init_dec(
);
void tdm_configure_dec(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i : ISM mode in combined format */
+#endif
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
int16_t *tdm_ratio_idx, /* o : ratio index */
const int16_t nb_bits_metadata /* i : number of metadata bits */
@@ -1997,6 +2033,10 @@ void tdm_ol_pitch_comparison(
);
void tdm_configure_enc(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i : ISM mode in combined format */
+#endif
CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
const float Etot_last[CPE_CHANNELS], /* i/o: Energy of last frame */
const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */
@@ -2013,6 +2053,10 @@ ivas_error signaling_enc_secondary(
);
void tdm_bit_alloc(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i : ISM mode in combined format */
+#endif
const int32_t element_brate_wo_meta, /* i : element bitrate without metadata */
const int16_t tdm_lp_reuse_flag, /* i : LPC reusage flag */
int32_t *total_brate_pri, /* o : Allocated primary channel bitrate */
@@ -3171,9 +3215,8 @@ int16_t ivas_qmetadata_dec_sid_decode(
void ivas_qmetadata_to_dirac(
const IVAS_QMETADATA_HANDLE hQMetaData, /* i : frame of MASA q_metadata */
- DIRAC_DEC_HANDLE hDirAC, /* i : DirAC decoder structure */
+ DIRAC_DEC_HANDLE hDirAC, /* o : DirAC decoder structure */
MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const IVAS_FORMAT ivas_format, /* i : IVAS format */
const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
@@ -3501,7 +3544,7 @@ void ivas_sba_dirac_stereo_smooth_parameters(
ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD handle for upmixing */
const int16_t cross_fade_start_offset, /* i : SPAR mixer delay compensation */
const int32_t output_Fs, /* i : Fs for delay calculation */
- const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */
+ const int16_t num_md_sub_frames /* i : number of subframes in mixing matrix */
);
void ivas_sba2mc_cldfb(
@@ -3537,12 +3580,12 @@ void ivas_dirac_enc(
IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
BSTR_ENC_HANDLE hMetaData, /* i/o: Metadata bitstream handle */
float data_f[][L_FRAME48k], /* i/o: SBA channels */
- float **ppIn_FR_real, /* o : real freq domain values */
- float **ppIn_FR_imag, /* o : imag freq domain values */
- const int16_t input_frame, /* i : input frame length */
- const int16_t dtx_vad, /* i : DTX vad flag */
- const IVAS_FORMAT ivas_format, /* i : ivas format */
- int16_t hodirac_flag /* i : hodirac flag */
+ float **ppIn_FR_real, /* o : real freq domain values */
+ float **ppIn_FR_imag, /* o : imag freq domain values */
+ const int16_t input_frame, /* i : input frame length */
+ const int16_t dtx_vad, /* i : DTX vad flag */
+ const IVAS_FORMAT ivas_format, /* i : ivas format */
+ int16_t hodirac_flag /* i : hodirac flag */
);
ivas_error ivas_dirac_config(
void *st_ivas, /* i/o: IVAS encoder/decoder state structure */
@@ -3575,20 +3618,33 @@ ivas_error ivas_dirac_sba_config(
const int16_t nbands /* i : number of frequency bands */
);
+ivas_error ivas_dirac_dec_open(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+);
+
+ivas_error ivas_dirac_allocate_parameters(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
+ const int16_t params_flag /* i : set of parameters flag */
+);
+
ivas_error ivas_dirac_dec_config(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
const DIRAC_CONFIG_FLAG flag_configopen /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
);
void ivas_dirac_dec_close(
- DIRAC_DEC_HANDLE *hDirAC_out
+ DIRAC_DEC_HANDLE *hDirAC /* i/o: decoder DirAC handle */
+);
+
+void ivas_dirac_deallocate_parameters(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
+ const int16_t params_flag /* i : set of parameters flag */
);
void ivas_dirac_dec_read_BS(
const int32_t ivas_total_brate, /* i : IVAS total bitrate */
Decoder_State *st, /* i/o: decoder Core state structure */
DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial rendering data handle */
IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q metadata */
int16_t *nb_bits, /* o : number of bits read */
const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
@@ -3639,6 +3695,12 @@ ivas_error ivas_td_decorr_reconfig_dec(
uint16_t *useTdDecorr /* i/o: TD decorrelator flag */
);
+/*! r: Configured reqularization factor value */
+float configure_reqularization_factor(
+ const IVAS_FORMAT ivas_format, /* i : IVAS format */
+ const int32_t ivas_total_brate /* i : total IVAS bitrate */
+);
+
void computeDiffuseness_mdft(
float **buffer_intensity[DIRAC_NUM_DIMS],
const float *buffer_energy,
@@ -3665,6 +3727,109 @@ void computeDiffuseness(
float *diffuseness
);
+ivas_error ivas_dirac_dec_onset_detection_open(
+ const int16_t num_channels,
+ const int16_t num_freq_bands,
+ const int16_t max_band_decorr,
+ DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params,
+ DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state
+);
+
+void ivas_dirac_dec_onset_detection_process(
+ const float *input_power_f,
+ float *onset_filter,
+ const int16_t num_protos_diff,
+ DIRAC_ONSET_DETECTION_PARAMS h_dirac_onset_detection_params,
+ DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state
+);
+
+ivas_error ivas_dirac_dec_decorr_open(
+ DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params,
+ DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state,
+ const int16_t num_freq_bands,
+ int16_t num_outputs_diff,
+ const int16_t num_protos_diff,
+ const DIRAC_SYNTHESIS_CONFIG synthesisConf,
+ float *frequency_axis,
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const int32_t output_Fs /* i : output sampling rate */
+);
+
+void ivas_dirac_dec_decorr_process(
+ const int16_t num_freq_bands,
+ int16_t num_channels,
+ const int16_t num_protos_diff,
+ const DIRAC_SYNTHESIS_CONFIG synthesisConf,
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const float *input_frame_f,
+ const int16_t num_protos_dir,
+ const int16_t *proto_index_dir,
+ float *frame_dec_f,
+ float *onset_filter,
+ HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params,
+ HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state
+);
+
+void ivas_dirac_dec_decorr_close(
+ HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params,
+ HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state
+);
+
+ivas_error ivas_dirac_dec_output_synthesis_open(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const RENDERER_TYPE renderer_type, /* i : renderer type */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const int32_t output_Fs /* i : output sampling rate */
+ ,
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+);
+
+void ivas_dirac_dec_output_synthesis_init(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+);
+
+void ivas_dirac_dec_output_synthesis_close(
+ DIRAC_DEC_HANDLE hDirAC /* i/o: DirAC handle */
+);
+
+void ivas_dirac_dec_output_synthesis_process_slot(
+ const float *reference_power, /* i : Estimated power */
+ const float *onset, /* i : onset filter */
+ const int16_t *azimuth,
+ const int16_t *elevation,
+ const float *diffuseness,
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t sh_rot_max_order,
+ const float *p_Rmat, /* i : rotation matrix */
+ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
+ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const int16_t ind_slot, /* i : index of the slot to be added to the input covariance */
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+);
+
+void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const int16_t nbslots, /* i : number of slots to process */
+ const float *onset_filter,
+ float *diffuseness,
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+);
+
+void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t nbslots, /* i : number of slots to process */
+ float *diffuseness_vector, /* i : diffuseness (needed for direction smoothing)*/
+ float *reference_power_smooth,
+ float qualityBasedSmFactor
+);
void ivas_dirac_dec_get_response(
const int16_t azimuth,
@@ -3673,54 +3838,99 @@ void ivas_dirac_dec_get_response(
const int16_t ambisonics_order
);
+void compute_hoa_encoder_mtx(
+ const float *azimuth,
+ const float *elevation,
+ float *response,
+ const int16_t num_responses,
+ const int16_t ambisonics_order );
+
+void ivas_dirac_dec_compute_gain_factors(
+ const int16_t num_freq_bands,
+ const float *diffuseness,
+ const int16_t max_band_decorr,
+ float *direct_gain_factor,
+ float *diffuse_gain_factor
+);
+
+void ivas_dirac_dec_compute_power_factors(
+ const int16_t num_freq_bands,
+ const float *diffuseness,
+ const int16_t max_band_decorr,
+ float *direct_power_factor,
+ float *diffuse_power_factor
+);
+
+void ivas_dirac_dec_compute_directional_responses(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
+ const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
+#ifdef MASA_AND_OBJECTS
+ MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */
+#endif
+ const int16_t *azimuth,
+ const int16_t *elevation,
+ const int16_t md_idx,
+ const float *surCohRatio,
+ const int16_t shd_rot_max_order, /* i : split-order rotation method */
+ const float *p_Rmat, /* i : rotation matrix */
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+);
+
+void ivas_dirac_dec_get_frequency_axis(
+ float *frequency_axis, /* o : array of center frequencies of a real filter bank */
+ const int32_t output_Fs, /* i : sampling frequency */
+ const int16_t num_freq_bands /* i : number of frequency bands */
+);
+
void calculate_hodirac_sector_parameters(
- DIRAC_ENC_HANDLE hDirAC,
- float RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX],/* i : signal vector (L+1)^2 x N_bins, real part */
- float ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX],/* i : signal vector, imaginary part */
- const float beta, /* i : forgetting factor for average filtering */
- const int16_t *band_grouping, /* i : indices of band groups */
- const int16_t N_bands, /* i : number of bands (groups) */
- const int16_t enc_param_start_band, /* i : first band to process */
- float *azi, /* o : array of sector azimuth angles, flat */
- float *ele, /* o : array of sector elevation angles, flat */
- float *diff, /* o : array of sector diffuseness values, flat */
- float *ene /* o : array of sector energy values, flat */
+ DIRAC_ENC_HANDLE hDirAC,
+ float RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX],/* i : signal vector (L+1)^2 x N_bins, real part */
+ float ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX],/* i : signal vector, imaginary part */
+ const float beta, /* i : forgetting factor for average filtering */
+ const int16_t *band_grouping, /* i : indices of band groups */
+ const int16_t N_bands, /* i : number of bands (groups) */
+ const int16_t enc_param_start_band, /* i : first band to process */
+ float *azi, /* o : array of sector azimuth angles, flat */
+ float *ele, /* o : array of sector elevation angles, flat */
+ float *diff, /* o : array of sector diffuseness values, flat */
+ float *ene /* o : array of sector energy values, flat */
);
void ivas_mc_paramupmix_enc(
- Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */
- BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */
+ Encoder_Struct *st_ivas, /* i/o: IVAS Encoder handle */
+ BSTR_ENC_HANDLE hMetaData, /* i/o: IVAS Metadata bitstream handle */
float data_f[][L_FRAME48k], /* i/o: input: MC data */
- const int16_t input_frame /* i : input frame length */
+ const int16_t input_frame /* i : input frame length */
);
ivas_error ivas_mc_paramupmix_enc_open(
- Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
);
void ivas_mc_paramupmix_enc_close(
- MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */
+ MC_PARAMUPMIX_ENC_HANDLE *hMCParamUpmix, /* i/o: MC Param-Upmix encoder handle */
const int32_t input_Fs /* i : input sampling rate */
);
void ivas_mc_paramupmix_dec(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
+ float output_f[][L_FRAME48k] /* i/o: synthesized core-coder transport channels/DirAC output */
);
ivas_error ivas_mc_paramupmix_dec_open(
- Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
);
void ivas_mc_paramupmix_dec_close(
- MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */
+ MC_PARAMUPMIX_DEC_HANDLE *hMCParamUpmix_out /* i/o: Parametric MC decoder handle */
);
void ivas_mc_paramupmix_dec_read_BS(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- Decoder_State *st, /* i/o: decoder state structure */
- MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */
- int16_t *nb_bits /* o : number of bits written */
+ Decoder_State *st, /* i/o: decoder state structure */
+ MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, /* i/o: decoder MC Param-Upmix handle */
+ int16_t *nb_bits /* o : number of bits written */
);
#ifdef JBM_PARAMUPMIX
@@ -3809,7 +4019,7 @@ void ivas_param_mc_dec_read_BS(
void ivas_param_mc_dec_digest_tc(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */
+ const uint8_t nCldfbSlots, /* i : number of CLFBS slots in the transport channels */
float *transport_channels_f[] /* i : synthesized core-coder transport channels/DirAC output*/
);
@@ -4459,7 +4669,7 @@ void ivas_spar_to_dirac(
ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t dtx_vad, /* i : DTX frame flag */
const int16_t num_bands_out, /* i : number of output bands */
- const int16_t bw /* i : band joining factor */
+ const int16_t bw /* i : band joining factor */
);
void ivas_spar_update_md_hist(
@@ -4469,13 +4679,13 @@ void ivas_spar_update_md_hist(
void ivas_spar_smooth_md_dtx(
ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t num_bands_out, /* i : number of output bands */
- const int16_t num_md_sub_frames /* i : number of metadata subframes */
+ const int16_t num_md_sub_frames /* i : number of metadata subframes */
);
void ivas_spar_setup_md_smoothing(
ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */
const int16_t num_bands_out, /* i : number of output bands */
- const int16_t num_md_sub_frames /* i : number of metadata subframes */
+ const int16_t num_md_sub_frames /* i : number of metadata subframes */
);
void ivas_spar_dec_gen_umx_mat(
@@ -4553,7 +4763,7 @@ void ivas_transient_det_close(
void ivas_transient_det_process(
ivas_trans_det_state_t *hTranDet, /* i/o: SPAR TD handle */
float *pIn_pcm, /* i : input audio channels */
- const int16_t frame_len, /* i : frame length in samples */
+ const int16_t frame_len, /* i : frame length in samples */
int16_t transient_det[2] /* o : transient det outputs */
);
@@ -4744,15 +4954,14 @@ void ivas_spar_arith_coeffs_com_init(
);
int16_t ivas_arith_encode_cmplx_cell_array(
-
- ivas_arith_t *pArith_re,
- ivas_arith_t *pArith_re_diff,
- const int16_t *pDo_diff,
- const int16_t nB,
- int16_t *pSymbol_re,
- int16_t *pSymbol_old_re,
- ivas_cell_dim_t *pCell_dims,
- BSTR_ENC_HANDLE hMetaData,
+ ivas_arith_t *pArith_re,
+ ivas_arith_t *pArith_re_diff,
+ const int16_t *pDo_diff,
+ const int16_t nB,
+ int16_t *pSymbol_re,
+ int16_t *pSymbol_old_re,
+ ivas_cell_dim_t *pCell_dims,
+ BSTR_ENC_HANDLE hMetaData,
const int16_t any_diff ,
const int16_t wc_strat_arith
);
@@ -4905,7 +5114,7 @@ ivas_error ivas_masa_enc_open(
);
void ivas_masa_enc_close(
- MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */
+ MASA_ENCODER_HANDLE *hMasa /* i/o: MASA metadata structure */
);
void ivas_masa_enc_reconfigure(
@@ -4926,6 +5135,16 @@ ivas_error ivas_masa_encode(
const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t Opt_DTX_ON, /* i : DTX on flag */
const int16_t element_mode /* i : element mode */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const ISM_MODE ism_mode, /* i : ISM format mode */
+ const int16_t nchan_ism, /* i : number of ISM channels */
+ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata handle */
+ const int16_t idx_separated_object, /* i : index of the separated object */
+ OMASA_ENC_HANDLE hOMasa, /* i : OMASA encoder handle */
+ const int16_t ism_imp, /* i : importance of separated object */
+ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */
+#endif
);
void ivas_masa_estimate_energy(
@@ -4940,19 +5159,109 @@ ivas_error ivas_masa_enc_config(
);
void ivas_masa_set_elements(
- const int32_t ivas_total_brate, /* i : codec total bitrate */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t mc_mode, /* i : MC format mode */
const int16_t nchan_transport, /* i : number of MASA input/transport channels */
IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
int16_t *element_mode, /* o : element mode */
int16_t *nSCE, /* o : number of SCEs */
int16_t *nCPE /* o : number of CPEs */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t ivas_format, /* i : IVAS format */
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int32_t ism_total_brate /* i : initial ISM total bitrate */
+#endif
+);
+
+#ifdef MASA_AND_OBJECTS
+/*! r: valid or not 1/0 */
+int16_t valid_ratio_index(
+ int16_t index, /* i : index to be checked */
+ const int16_t K, /* i : L1 norm to check against */
+ const int16_t len /* i : vector length */
+);
+
+void reconstruct_ism_ratios(
+ int16_t *ratio_ism_idx,
+ const int16_t nchan_ism,
+ const float step,
+ float *q_energy_ratio_ism
+);
+
+void distribute_evenly_ism(
+ int16_t *idx,
+ const int16_t K,
+ const int16_t nchan_ism
+);
+
+int16_t ivas_qmetadata_DecodeExtendedGR(
+ uint16_t* bitstream,
+ int16_t* index,
+ const int16_t alph_size,
+ const int16_t gr_param
+);
+
+int16_t ivas_qmetadata_encode_extended_gr_length(
+ const uint16_t value,
+ const uint16_t alphabet_size,
+ const int16_t gr_param);
+
+void ivas_qmetadata_encode_extended_gr(
+ BSTR_ENC_HANDLE hMetaData, /* i/o: q_metadata handle */
+ const uint16_t value, /* i : value to be encoded */
+ const uint16_t alphabet_size, /* i : alphabet size */
+ const int16_t gr_param); /* i : GR order */
+
+/*! r: CPE bitrate value */
+int32_t calculate_cpe_brate_MASA_ISM(
+ const ISM_MODE ism_mode, /* i : ism mode */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t nchan_ism /* i : number of objects */
+);
+
+void ivas_merge_masa_metadata(
+ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */
+ OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */
+);
+
+void ivas_masa_combine_directions(
+ MASA_ENCODER_HANDLE hMasa /* i/o: MASA encoder handle */
+);
+
+/*!r : number of bits for ISM ratio index */
+int16_t bits_index_ism_ratio(
+ const int16_t nchan_ism /* i : number of objects */
+);
+
+void calculate_nbits_meta(
+ const int16_t nchan_ism,
+ float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ const int16_t numSf,
+ const int16_t numCodingBands,
+ int16_t* bits_ism,
+ const int16_t idx_sep_obj,
+ const int16_t ism_imp
+);
+
+/*! r: limitation flag */
+int16_t calculate_brate_limit_flag(
+ const int16_t ism_imp[], /* i : ISM importance flags */
+ const int16_t nchan_ism /* i : number of objects */
);
+void ivas_get_stereo_panning_gains(
+ const float aziDeg,
+ const float eleDeg,
+ float panningGains[2]
+);
+#endif
+
void ivas_masa_set_coding_config(
MASA_CODEC_CONFIG* config, /* i/o: MASA coding config structure */
int16_t* band_mapping, /* o : Band mapping used */
- const int32_t ivas_total_brate, /* i : codec total bitrate */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t nchan_transport, /* i : number of transport channel (mono/stereo) */
const uint8_t isMcMasa /* i : toggle for selecting McMASA specific config */
);
@@ -5020,7 +5329,6 @@ void ivas_masa_prerender(
#endif
);
-
void ivas_spar_param_to_masa_param_mapping(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */
@@ -5171,6 +5479,10 @@ ivas_error vbap_init_data(
const float *speaker_node_azi_deg, /* i : vector of speaker node azimuths (positive left) */
const float *speaker_node_ele_deg, /* i : vector of speaker node elevations (positive up) */
const int16_t num_speaker_nodes /* i : number of speaker nodes in the set */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const IVAS_FORMAT ivas_format /* i : IVAS format */
+#endif
);
void vbap_free_data(
@@ -5182,6 +5494,10 @@ void vbap_determine_gains(
float *gains, /* o : gain vector for speaker nodes for given direction */
const int16_t azi_deg, /* i : azimuth in degrees for panning direction (positive left) */
const int16_t ele_deg /* i : elevation in degrees for panning direction (positive up) */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t use_object_mode /* i : select between object mode panning and spatial mode panning */
+#endif
);
void v_sort_ind(
@@ -5283,7 +5599,7 @@ void ivas_mcmasa_set_separate_channel_mode(
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 int32_t ivas_total_brate, /* i : IVAS 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 */
@@ -5372,6 +5688,7 @@ void ivas_lfe_synth_with_filters(
);
+#ifdef FIX_572_LFE_LPF_ENC
/*----------------------------------------------------------------------------------*
* LFE encoder low pass filter prototypes
*----------------------------------------------------------------------------------*/
@@ -5390,6 +5707,7 @@ void ivas_lfe_lpf_enc_apply(
float data_lfe_ch[], /* i/o: LFE signal */
const int16_t input_frame /* i : input frame length per channel */
);
+#endif
/*----------------------------------------------------------------------------------*
@@ -5462,6 +5780,189 @@ void ivas_filter_process(
);
+#ifdef MASA_AND_OBJECTS
+/*----------------------------------------------------------------------------------*
+* OMASA prototypes
+*---------------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_enc_open(
+ Encoder_Struct* st_ivas /* i/o: IVAS encoder handle */
+);
+
+void ivas_omasa_enc_close(
+ OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
+);
+
+ivas_error ivas_omasa_enc_config(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
+);
+
+ivas_error ivas_omasa_dec_config(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+);
+
+void ivas_omasa_set_config(
+ OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
+ MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */
+ const int32_t input_Fs, /* i : Input sample rate */
+ const ISM_MODE ism_mode /* i : ISM mode */
+);
+
+void ivas_omasa_enc(
+ OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
+ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */
+ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */
+ float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */
+ const int16_t input_frame, /* i : Input frame size */
+ const int16_t nchan_transport, /* i : Number of transport channels */
+ const int16_t nchan_ism, /* i : Number of objects for parameter analysis*/
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ float data_separated_object[L_FRAME48k], /* o : Separated object audio signal */
+ int16_t* idx_separated_object /* o : Index of the separated object */
+);
+
+void ivas_set_surplus_brate_enc(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
+#ifdef DEBUG_MODE_INFO
+ ,
+ const int16_t *nb_bits_metadata /* i : number of metadata bits */
+#endif
+);
+
+void ivas_set_surplus_brate_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ int32_t *ism_total_brate /* i : ISM total bitrate */
+);
+
+void set_ism_importance_interformat(
+ const int32_t ism_total_brate, /* i/o: ISms total bitrate */
+ const int16_t nchan_transport, /* i : number of transported channels */
+ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
+ SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
+ const float lp_noise_CPE, /* i : LP filtered total noise estimation */
+ int16_t ism_imp[] /* o : ISM importance flags */
+);
+
+#ifdef MASA_AND_OBJECTS
+/*! r: flag for using less bitrate for objects in OMASA */
+int16_t ivas_omasa_ener_brate(
+ const int16_t nchan_ism, /* i : number of ISMs */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ float data_f[][L_FRAME48k], /* i : Input / transport audio signals */
+ const int16_t input_frame /* i : Input frame size */
+);
+#endif
+
+/*! r: adjusted bitrate */
+int32_t ivas_interformat_brate(
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int16_t nchan_ism, /* i : number of ISM channels */
+ const int32_t element_brate, /* i : element bitrate */
+ const int16_t ism_imp, /* i : ISM importance flag */
+ const int16_t limit_flag /* i : flag to limit the bitrate increase */
+);
+
+void ivas_combined_format_brate_sanity(
+ const int32_t element_brate, /* i : element bitrate */
+ const int16_t core, /* i : core */
+ int32_t *core_brate, /* i/o: core bitrate */
+ int16_t *diff_nBits /* o : number of differential bits */
+);
+
+ISM_MODE ivas_omasa_ism_mode_select(
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const int16_t nchan_ism /* i : number of input ISM's */
+);
+
+void ivas_set_omasa_TC(
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ const int16_t nchan_ism, /* i : number of input ISMs */
+ int16_t *nSCE, /* o : number of SCEs */
+ int16_t *nCPE /* o : number of CPEs */
+);
+
+void ivas_merge_masa_transports(
+ float data_in_f1[][L_FRAME48k], /* i : Transport audio signals 1 */
+ float data_in_f2[][L_FRAME48k], /* i : Transport audio signals 2 */
+ float data_out_f[][L_FRAME48k], /* o : Merged transport audio signals */
+ const int16_t input_frame, /* i : Input frame size */
+ const int16_t num_transport_channels /* i : Number of transport audio signals */
+);
+
+ivas_error ivas_masa_ism_data_open(
+ Decoder_Struct* st_ivas /* i/o: IVAS decoder handle */
+);
+
+void ivas_masa_ism_data_close(
+ MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle */
+);
+
+ivas_error ivas_omasa_ism_metadata_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int32_t ism_total_brate, /* i : ISM total bitrate */
+ int16_t *nchan_ism, /* o : number of ISM separated channels */
+ int16_t *nchan_transport_ism, /* o : number of ISM TCs */
+ const int16_t dirac_bs_md_write_idx, /* i : DirAC bitstream write index */
+ int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */
+);
+
+ivas_error ivas_omasa_dirac_td_binaural(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float output[][L_FRAME48k], /* o : output synthesis signal */
+ const int16_t output_frame /* i : output frame length per channel */
+);
+
+void ivas_omasa_dirac_rend(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float output[][L_FRAME48k], /* o : output synthesis signal */
+ const int16_t output_frame /* i : output frame length per channel */
+);
+
+void preProcessStereoTransportsForMovedObjects(
+ Decoder_Struct* st_ivas,
+ float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
+ float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
+ const int16_t nBins,
+ const int16_t subframe
+);
+
+ivas_error ivas_masa_ism_separate_object_renderer_open(
+ Decoder_Struct* st_ivas /* i/o: IVAS decoder structure */
+);
+
+void ivas_masa_ism_separate_object_render(
+ Decoder_Struct* st_ivas, /* i/o: IVAS decoder structure */
+ float input_f[][L_FRAME48k], /* i : separated object signal */
+ float output_f[][L_FRAME48k], /* i/o: output signals */
+ const int16_t output_frame /* i : output frame length per channel */
+);
+
+void ivas_masa_ism_set_edited_objects(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+);
+
+void encode_masa_to_total(
+ IVAS_QMETADATA_HANDLE hQMetaData,
+ BSTR_ENC_HANDLE hMetaData,
+ const int16_t low_bitrate_mode,
+ const int16_t nbands,
+ const int16_t nblocks
+);
+
+void decode_masa_to_total(
+ uint16_t* bit_stream,
+ int16_t* index,
+ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ const int16_t nbands,
+ const int16_t nblocks
+);
+
+void modify_masa_energy_ratios(
+ IVAS_QMETADATA_HANDLE hQMetaData
+);
+
+#endif
+
/*----------------------------------------------------------------------------------*
* TD Binaural Object renderer
*----------------------------------------------------------------------------------*/
diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c
index 5677a3cc9b48b95616b71944fc1583ce2ae16e89..a131509ea1ec18c18630518f7a4835e4fd276685 100644
--- a/lib_com/ivas_rom_com.c
+++ b/lib_com/ivas_rom_com.c
@@ -2824,6 +2824,75 @@ const float McMASA_LFEGain_vectors[64] =
-2.14f, 0.26f, 0.84f, 1.02f
};
+#ifdef MASA_AND_OBJECTS
+/*----------------------------------------------------------------------------------*
+ * OMASA ROM tables
+ *----------------------------------------------------------------------------------*/
+
+const int32_t sep_object_brate[][MAX_NUM_OBJECTS] =
+{
+ {0, 0, 0, 0}, /* 13k2 */
+ {0, 0, 0, 0}, /* 16k4 */
+ {9600, 0, 0, 0}, /* 24k4 */
+ {IVAS_13k2, 0, 0, 0}, /* 32k */
+ {16000, 11000, 0, 0}, /* 48k */
+ {16000, 11700, 0, 0}, /* 64k */
+ {20000, 16000, 0, 0}, /* 80k */
+ {IVAS_32k, 20000, 20000, 0}, /* 96k */
+ {IVAS_32k, IVAS_24k4, 24000, 24000}, /* 128k */
+ {IVAS_48k, IVAS_32k, IVAS_24k4, 24000}, /* 160k */
+ {IVAS_64k, IVAS_48k, IVAS_32k, IVAS_24k4}, /* 192k */
+ {IVAS_96k, IVAS_64k, IVAS_48k, IVAS_32k}, /* 256k */
+ {IVAS_128k, IVAS_80k, IVAS_64k, IVAS_48k}, /* 384k */
+ {IVAS_128k, IVAS_96k, IVAS_80k, IVAS_64k} /* 512k */
+};
+
+/* column wise DCT matrices for 4 5, and 8 dim */
+const float dct4[4*4] =
+{
+ 0.5000f, 0.6533f, 0.5000f, 0.2706f,
+ 0.5000f, 0.2706f, -0.5000f, -0.6533f,
+ 0.5000f, -0.2706f, -0.5000f, 0.6533f,
+ 0.5000f, -0.6533f, 0.5000f, -0.2706f
+};
+
+const float dct5[5*5] =
+{
+ 0.4472f, 0.6015f, 0.5117f, 0.3717f, 0.1954f,
+ 0.4472f, 0.3717f, -0.1954f, -0.6015f, -0.5117f,
+ 0.4472f, 0.0000f, -0.6325f, -0.0000f, 0.6325f,
+ 0.4472f, -0.3717f, -0.1954f, 0.6015f, -0.5117f,
+ 0.4472f, -0.6015f, 0.5117f, -0.3717f, 0.1954f
+};
+
+const float dct8[8*8] =
+{
+ 0.3536f, 0.4904f, 0.4619f, 0.4157f, 0.3536f, 0.2778f, 0.1913f, 0.0975f,
+ 0.3536f, 0.4157f, 0.1913f, -0.0975f, -0.3536f, -0.4904f, -0.4619f, -0.2778f,
+ 0.3536f, 0.2778f, -0.1913f, -0.4904f, -0.3536f, 0.0975f, 0.4619f, 0.4157f,
+ 0.3536f, 0.0975f, -0.4619f, -0.2778f, 0.3536f, 0.4157f, -0.1913f, -0.4904f,
+ 0.3536f, -0.0975f, -0.4619f, 0.2778f, 0.3536f, -0.4157f, -0.1913f, 0.4904f,
+ 0.3536f, -0.2778f, -0.1913f, 0.4904f, -0.3536f, -0.0975f, 0.4619f, -0.4157f,
+ 0.3536f, -0.4157f, 0.1913f, 0.0975f, -0.3536f, 0.4904f, -0.4619f, 0.2778f,
+ 0.3536f, -0.4904f, 0.4619f, -0.4157f, 0.3536f, -0.2778f, 0.1913f, -0.0975f
+};
+
+const float dct12[12*12]=
+{
+ 0.2887f, 0.4048f, 0.3943f, 0.3772f, 0.3536f, 0.3239f, 0.2887f, 0.2485f, 0.2041f, 0.1562f, 0.1057f, 0.0533f,
+ 0.2887f, 0.3772f, 0.2887f, 0.1562f, 0.0000f, -0.1562f, -0.2887f, -0.3772f, -0.4082f, -0.3772f, -0.2887f, -0.1562f,
+ 0.2887f, 0.3239f, 0.1057f, -0.1562f, -0.3536f, -0.4048f, -0.2887f, -0.0533f, 0.2041f, 0.3772f, 0.3943f, 0.2485f,
+ 0.2887f, 0.2485f, -0.1057f, -0.3772f, -0.3536f, -0.0533f, 0.2887f, 0.4048f, 0.2041f, -0.1562f, -0.3943f, -0.3239f,
+ 0.2887f, 0.1562f, -0.2887f, -0.3772f, -0.0000f, 0.3772f, 0.2887f, -0.1562f, -0.4082f, -0.1562f, 0.2887f, 0.3772f,
+ 0.2887f, 0.0533f, -0.3943f, -0.1562f, 0.3536f, 0.2485f, -0.2887f, -0.3239f, 0.2041f, 0.3772f, -0.1057f, -0.4048f,
+ 0.2887f, -0.0533f, -0.3943f, 0.1562f, 0.3536f, -0.2485f, -0.2887f, 0.3239f, 0.2041f, -0.3772f, -0.1057f, 0.4048f,
+ 0.2887f, -0.1562f, -0.2887f, 0.3772f, 0.0000f, -0.3772f, 0.2887f, 0.1562f, -0.4082f, 0.1562f, 0.2887f, -0.3772f,
+ 0.2887f, -0.2485f, -0.1057f, 0.3772f, -0.3536f, 0.0533f, 0.2887f, -0.4048f, 0.2041f, 0.1562f, -0.3943f, 0.3239f,
+ 0.2887f, -0.3239f, 0.1057f, 0.1562f, -0.3536f, 0.4048f, -0.2887f, 0.0533f, 0.2041f, -0.3772f, 0.3943f, -0.2485f,
+ 0.2887f, -0.3772f, 0.2887f, -0.1562f, -0.0000f, 0.1562f, -0.2887f, 0.3772f, -0.4082f, 0.3772f, -0.2887f, 0.1562f,
+ 0.2887f, -0.4048f, 0.3943f, -0.3772f, 0.3536f, -0.3239f, 0.2887f, -0.2485f, 0.2041f, -0.1562f, 0.1057f, -0.0533f
+};
+#endif
/*----------------------------------------------------------------------------------*
* ISM ROM tables
diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h
index 8dc958e06c9a0e3ff3c3c37add4c722a0a719888..15fbd2048d8219f892126733b72b603a2e16418c 100644
--- a/lib_com/ivas_rom_com.h
+++ b/lib_com/ivas_rom_com.h
@@ -260,7 +260,6 @@ extern const uint16_t ivas_param_mc_sym_freq_icc_combined_48_16bits[PARAM_MC_SZ_
extern const uint16_t ivas_param_mc_cum_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER];
extern const uint16_t ivas_param_mc_sym_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER - 1];
-
/*----------------------------------------------------------------------------------*
* Parametric Upmix MC ROM tables
*----------------------------------------------------------------------------------*/
@@ -326,6 +325,18 @@ extern const float cb_azi_chan[];
extern const float McMASA_LFEGain_vectors[64];
+#ifdef MASA_AND_OBJECTS
+/*----------------------------------------------------------------------------------*
+ * MASA and ISM (OMASA) combined format ROM tables
+ *----------------------------------------------------------------------------------*/
+
+extern const int32_t sep_object_brate[][MAX_NUM_OBJECTS];
+extern const float dct4[];
+extern const float dct5[];
+extern const float dct8[];
+extern const float dct12[];
+#endif
+
/*----------------------------------------------------------------------------------*
* ISM ROM tables
*----------------------------------------------------------------------------------*/
@@ -339,7 +350,6 @@ extern const float ism_elevation_borders[4];
extern const int16_t Param_ISM_band_grouping[MAX_PARAM_ISM_NBANDS + 1];
-
/*----------------------------------------------------------------------------------*
* LFE coding ROM tables
*----------------------------------------------------------------------------------*/
diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h
index 6d2ed4c4e961dc316964a7b9b0791d6e88a32456..46c58b9bb2b3e0e56e2fbd6ede7edf8b239e66cc 100644
--- a/lib_com/ivas_stat_com.h
+++ b/lib_com/ivas_stat_com.h
@@ -81,6 +81,14 @@ typedef struct
int16_t ism_md_inc_diff_cnt; /* counter of continuous frames where MD are transmitted in inactive segments when MD significantly changes */
float last_true_radius; /* last true Q radius value */
+#ifdef MASA_AND_OBJECTS
+ int16_t ism_imp; /* ISM importance flag */
+ int16_t ism_md_null_flag;
+ int16_t ism_md_lowrate_flag;
+ float q_azimuth_old;
+ float q_elevation_old;
+#endif
+
} ISM_METADATA_FRAME, *ISM_METADATA_HANDLE;
@@ -169,8 +177,10 @@ typedef struct ivas_param_ism_data_structure
int16_t noisy_speech_buffer[PARAM_ISM_HYS_BUF_SIZE];
int16_t flag_equal_energy;
+#ifdef FIX_549_DMX_GAIN
float last_dmx_gain;
float last_cardioid_left[MAX_NUM_OBJECTS];
+#endif
} PARAM_ISM_CONFIG_DATA, *PARAM_ISM_CONFIG_HANDLE;
@@ -442,6 +452,16 @@ typedef struct ivas_masa_common_spatial_meta_struct
} MASA_COMMON_SPATIAL_META;
+#ifdef MASA_AND_OBJECTS
+typedef struct ivas_omasa_meta_struct
+{
+ uint8_t num_dirs;
+ MASA_DIRECTIONAL_SPATIAL_META directional_meta[MASA_MAXIMUM_DIRECTIONS];
+ MASA_COMMON_SPATIAL_META common_meta;
+
+} OMASA_SPATIAL_META, *OMASA_SPATIAL_META_HANDLE;
+#endif
+
typedef struct ivas_masa_metadata_frame_struct
{
MASA_DECRIPTIVE_META descriptive_meta;
@@ -551,6 +571,9 @@ typedef struct ivas_masa_qmetadata_frame_struct
int16_t ec_flag;
float dir_comp_ratio;
uint8_t is_masa_ivas_format;
+#ifdef MASA_AND_OBJECTS
+ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* TODO Nokia: This should be moved to some other place and reserved only when needed. */
+#endif
} IVAS_QMETADATA, *IVAS_QMETADATA_HANDLE;
diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c
index dee56c5dff17f6b34fb245fcf8beb729603e6b09..823c1b194458b3fcc6cf4c424997ed104b3b3250 100644
--- a/lib_com/ivas_stereo_td_bit_alloc.c
+++ b/lib_com/ivas_stereo_td_bit_alloc.c
@@ -74,6 +74,10 @@
*-------------------------------------------------------------------*/
void tdm_bit_alloc(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i: ISM mode in combined format */
+#endif
const int32_t element_brate_wo_meta, /* i : element bitrate without metadata */
const int16_t tdm_lp_reuse_flag, /* i : LPC reusage flag */
int32_t *total_brate_pri, /* o : Allocated primary channel bitrate */
@@ -136,7 +140,11 @@ void tdm_bit_alloc(
*total_brate_sec = tdm_bit_allc_tbl[idx][coder_type];
/* secondary channel bitrate allocation based on the energy scaling ratio */
+#ifdef MASA_AND_OBJECTS
+ if ( ( ( ivas_format != MASA_ISM_FORMAT || ism_mode == ISM_MODE_NONE ) && ( ( coder_type != UNVOICED ) || tdm_LRTD_flag == 1 ) ) || ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE && coder_type > UNVOICED ) )
+#else
if ( ( coder_type != UNVOICED ) || tdm_LRTD_flag == 1 )
+#endif
{
bit_rate_diff = (float) ( element_brate_wo_meta - 2 * *total_brate_sec );
@@ -416,7 +424,6 @@ void tdm_bit_alloc(
*total_brate_sec += 100;
}
}
-
*total_brate_pri = element_brate_wo_meta - *total_brate_sec;
return;
diff --git a/lib_com/options.h b/lib_com/options.h
index b56d19f88d185996beb195a28f31bb0f52c12b87..1b47d0dd5cfabf5d8a5a9430f50e04962edb12e1 100644
--- a/lib_com/options.h
+++ b/lib_com/options.h
@@ -153,22 +153,41 @@
#define VLBR_20MS_MD /* Dlb: SBA VLBR 20ms Optimization*/
#define SBA_MODE_CLEANUP_2 /* Dlb : changes part of fix issue #523 for unused signaling bit in SBA SID*/
#define FIX_137_SID_MD_BITS /* Dlb: Fix issue #137 , SID bitrate mismatch correction */
+#define FIX_563_PARAMMC_LIMITER /* FhG: issue 563: fix ILD limiter when coming from silence w/o transient set */
+#define FIX_560_VAD_FLAG /* Eri: Issue 560 - VAD flag issue for unified stereo */
+#define FIX_549_DMX_GAIN /* FhG: issue 549: ParamISM output too quiet */
#define FIX_470_MASA_JBM_EXT /* Nokia: Issue 470, fix MASA EXT output with JBM */
+#define ISM_FB /* issue 556: change SWB to FB coding in 1ISM at 24.4 kbps */
+#define FIX_558_PLC_DISCONT /* FhG: issue 558: fix discontinuities in DFT Stereo when switching from TCX concealment to ACELP */
#define FIX_564 /* Nokia: Issue 564: Fix gains in JBM path for SBA with parametric binaural renderer */
+#define FIX_566_2DIR_MASA_384K /* Nokia: Issued 566: Bugfix in 384k MASA metadata encoding of second direction */
+#define FIX_568_ISM_BITRATE_SWITCHING /* Philips: Issue 568: Bugfix for renderer re-initialization by ISM and bitrate switching */
+#define FIX_565_SBA_BURST_IN_FEC /* VA: Issue 565: Fix noise burst during FEC, due to wrong total_brate initialization */
+#define FIX_562_ISM2_64KBPS /* VA: issue 562: fix ISM2 at 64kbps issue */
#define FIX_559_EXTL_IGF_MISMATCH /* VA: issue 559: fix mismatch between st->extl and st->igf observed as crash in PlanarSBA bitrate switching */
#define FIX_571_REVERB_NOT_ACTIVATED_ISM /* Philips: Issue 571: Reverb not activated for discrete and parametric ISM */
+#define FIX_572_LFE_LPF_ENC /* FhG: issue 572: always apply the low pass filter to the LFE channel */
#define FIX_QMETA_SID_5k2 /* Nokia: Issue 137: enable using full 5.2k bitrate in MASA SID */
+#define FIX_578_PARAMMC_ILD_BS /* FhG: Issue 578: transmitt also center ILD in band 0 when LFE is active in 3TC ParamMC */
+#define FIX_UNCLR_ISSUE /* VoiceAge: issue 574: Fix UNCLR mis-classifications in noisy speech stereo */
+#define FIX_TCX_LOWRATE_LIMITATION /* VA: issue 577: TCX bitrate limitation only when DEBUGGING is active */
+#define FIX_575_LOW_OVERLAP_PLC_RECOVERY /* FhG: Issue 575 fix for PLC and transistion to TCX5*/
#define FIX_550_FIRST_FRAME_ACCESS /* Eri: Issue 550: TD Object renderer: first frame accesses wrong transport channel offsets */
#define FIX_550_FIRST_FRAME_ACCESS_ALT /* Eri: Issue 550: Should be merged with FIX_550_FIRST_FRAME_ACCESS above, or accepted at the same time */
#define FIX_569_TD_FILTER_LENGTH /* Eri: Issue 569: If an HRTF binary file exceeds the SFX_SPAT_BIN_MAX_FILTER_LENGTH the decoder crashes. This truncates the filter when generated from the model. */
+#define ISM_FB_16k4 /* VA: Issue: 579: change BW from SWB to FB in NxISM conditions to match the EVS codec */
+#define FIX_580_PARAMMC_ENER_BURSTS /* FhG: issue 580: energy bursts due to ILD holding when energy relations change too much */
#define FIX_595_SHL_NOGLOB /* FhG: Issue 595: compilation with BASOP_NOGLOB disabled */
#define UPDATE_FASTCONV_SBA_FILTER /* Dlb: Issue 584: Update SBA CLDFB-Domain HRTFs */
#define FIX_570_SF_EXT_ORIENTATION
+#define FIX_593_STL_INCLUDE /* FhG: Issue 593: correct include of stl.h in lib_enc/ivas_stereo_eclvq_enc.c */
+#define FIX_583_CLANG_TRANS_DET /* FhG: Issue 583: clang left shift on ramp_up_flag in transient detector */
#define FIX_280_PLANAR_CP /* Dlb : fix issue 28 : remove planarCP=1 related code*/
#define CODE_CLEAN_UP_DIRAC /* Dlb : code clean up*/
#define COVARIANCE_MEMORY_OPT /* Dlb : Issue 231: define SPAR covariance buffers in stack instead of inter-frame heap */
#define NONBE_FIX_589_JBM_TC_OFFSETS /* FhG: issue 589: wrong offset into the TC buffers is used in some rendering paths in the JBM main rendering function */
#define FIX_MEM_REALLOC_IND_LIST /* VA: issue 601: failure of the automatic memory re-allocation mechanism when ind_list[] buffer is depleted in MASA mode with 2 TC*/
+#define FIX_581_CLANG_OFFSET_TO_NULL /* FhG: issue 581: fix CLANG error about applying an offset to a NULL pointer */
#define JBM_PARAMUPMIX /* Dlb: Issue 471: Integrate the Multichannel Parametric Upmix into the JBM path */
#define FIX_582_INDEX_OUT_OF_BOUNDS_SNS_AVQ_DEC /* FhG: fix an undefined behaviour error in SNS AVQ decoding */
#define FIX_614_ADD_TO_NULL_PTR_DIRAC_SETUP /* FhG: Issue 614: prevent adding to a null pointer in dirac setup code */
@@ -179,6 +198,9 @@
#define NONBE_FIX_539_MASA_384K_CHIRP /* Nokia: issue 539, puts the normalization of the energy ratios at the correct place, affect MASA 384k only */
/* Fixes for bugs found during split rendering contribution development */
+#define REND_STATIC_MEM_OPT /* Dlb: Static memory optimisation for external renderer */
+#define EULER2QUAT_FIX /* Dlb: Fix for Euler2Quat()/Quat2EulerDegree functions */
+#define SBA_CREND_ROT_OPT /* Dlb: Optimisation for rotateFrameSba() used for SHD rotations in external renderer */
#define TD_TDREND_FIX_NULLPTR_ACCESS /* FhG: avoid nullptr access in ivas_rend_TDObjRendOpen */
#define TD_REND_FIX_DIV_BY_ZERO /* FhG: avoid division by zero in sincResample fn */
#define RENAME_GWLPR /* FhG: Rename clashing symbol */
@@ -190,7 +212,15 @@
#define FIX_615_UBSAN_SPAR_TO_DIRAC /*Dlb : Fix for UBSAN issue 615*/
/* ################## End BE DEVELOPMENT switches ######################### */
-
+#define MASA_AND_OBJECTS /* Nokia: Combination of MASA and objects */
+#ifdef MASA_AND_OBJECTS
+#define MASAISM_EDIT_OBJECTS /* Nokia: Temporary command line editing of object directions in the decoder */
+#define FIX_356_ISM_METADATA_SYNC_OMASA // temp. fix
+#define OMASA_BRSW_MONO_FIX /* Nokia: fix renderer config under rateswitching and MONO output */
+#define OMASA_FIX_LOW_FS /* Nokia: fixes related to lower input signal sampling rates */
+#define OMASA_BIT_BUFF_SZ /* Nokia: increase bitstream index buffer initial size */
+#define OMASA_EXT_OUTPUT /* VA: support of EXT output configuration for OMASA DISC mode */
+#endif
/* #################### Start NON-BE CR switches ########################## */
/* any switch which is non-be wrt operation points tested in selection */
diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c
index 0a46a263cb79565695432cb97a6fe30ebddd9ace..2a49ff3b1fe9b50f286b1c23bd734bbb39a33bcd 100644
--- a/lib_dec/FEC.c
+++ b/lib_dec/FEC.c
@@ -331,7 +331,11 @@ void FEC_exc_estim(
/*-----------------------------------------------------------------*
* Replicate the last spectrum in case the last good frame was coded by GSC
*-----------------------------------------------------------------*/
+#ifndef FIX_565_SBA_BURST_IN_FEC
+ if ( ( st->last_coder_type == AUDIO || st->last_good == INACTIVE_CLAS ) && st->total_brate <= ACELP_24k40 && !st->Opt_AMR_WB )
+#else
if ( ( st->last_coder_type == AUDIO || st->last_good == INACTIVE_CLAS ) && st->total_brate <= MAX_GSC_INACTIVE_BRATE && !st->Opt_AMR_WB )
+#endif
{
/* Replication of the last spectrum, with a slight downscaling of its dynamic */
st->GSC_noisy_speech = st->Last_GSC_noisy_speech_flag;
@@ -403,7 +407,11 @@ void FEC_exc_estim(
/*-----------------------------------------------------------------*
* Total excitation
*-----------------------------------------------------------------*/
+#ifndef FIX_565_SBA_BURST_IN_FEC
+ if ( ( st->last_coder_type == AUDIO || st->last_good == INACTIVE_CLAS ) && st->total_brate <= ACELP_24k40 && !st->Opt_AMR_WB )
+#else
if ( ( st->last_coder_type == AUDIO || st->last_good == INACTIVE_CLAS ) && st->total_brate <= MAX_GSC_INACTIVE_BRATE && !st->Opt_AMR_WB )
+#endif
{
/* For GSC - the excitation is already computed */
mvr2r( exc, exc2, st->L_frame );
diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c
index cffb6a1092ccf09839e6d7393126cb89a7ee3604..dd10cef29324326de7e73a828b35889ae317853a 100644
--- a/lib_dec/dec_tcx.c
+++ b/lib_dec/dec_tcx.c
@@ -377,7 +377,11 @@ void IMDCT(
TCX_MDCT_Inverse( x + w * L_spec_TCX5, win, L_ola, L_win - L_ola, L_ola, st->element_mode );
}
+#ifndef FIX_575_LOW_OVERLAP_PLC_RECOVERY
+ tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core_bfi, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale );
+#else
tcx_windowing_synthesis_current_frame( win, tcx_aldo_window_2, tcx_mdct_window_half, tcx_mdct_window_minimum, L_ola, tcx_mdct_window_half_length, tcx_mdct_window_min_length, ( w > 0 ) ? 0 : left_rect, ( w > 0 ) || ( w == 0 && index == 2 ) ? MIN_OVERLAP : hTcxCfg->tcx_last_overlap_mode, acelp_zir, hTcxDec->old_syn_Overl, syn_Overl_TDAC, st->old_Aq_12_8, tcx_mdct_window_trans, L_win, tcx_offset < 0 ? -tcx_offset : 0, ( w > 0 ) || ( frame_cnt > 0 ) ? 1 : st->last_core, ( w > 0 ) || ( frame_cnt > 0 ) ? 0 : st->last_is_cng, fullbandScale );
+#endif
if ( w > 0 )
{
@@ -394,11 +398,13 @@ void IMDCT(
/* To assure that no garbage values are passed to overlap */
set_zero( xn_buf + L_frame + tcx_offset + ( L_ola >> 1 ), overlap - tcx_offset - ( L_ola >> 1 ) );
+#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY
if ( st->prev_bfi && frame_cnt == 0 && st->last_core != st->last_core_bfi && st->last_core_bfi == ACELP_CORE )
{
tcx_windowing_synthesis_past_frame( old_syn_overl, tcx_aldo_window_1_trunc, tcx_mdct_window_half, tcx_mdct_window_minimum, overlap, tcx_mdct_window_half_length, tcx_mdct_window_min_length, hTcxCfg->tcx_last_overlap_mode );
v_add( xn_buf, old_syn_overl, xn_buf, overlap );
}
+#endif
}
else if ( !bfi && ( frame_cnt == 0 ) && ( hTcxCfg->tcx_curr_overlap_mode == FULL_OVERLAP ) )
@@ -1246,6 +1252,7 @@ void decoder_tcx_noisefilling(
if ( ( frame_cnt == 0 ) && ( L_frameTCX == hTcxDec->L_frameTCX >> 1 ) && ( st->tcxonly ) && ( !st->tonal_mdct_plc_active ) && ( st->nbLostCmpt == 1 ) && ( hTcxCfg->tcx_last_overlap_mode != FULL_OVERLAP ) && ( hTcxCfg->tcx_curr_overlap_mode != FULL_OVERLAP ) )
{
E_2ndlast = E_last = EPSILON;
+#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY
if ( st->element_mode > EVS_MONO )
{
for ( i = 0; i < L_frameTCX; i = i + 2 )
@@ -1262,11 +1269,19 @@ void decoder_tcx_noisefilling(
E_last += st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] * st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
}
}
+#else
+ for ( i = 0; i < infoIGFStartLine; i = i + 2 )
+ {
+ E_2ndlast += st->hTonalMDCTConc->lastBlockData.spectralData[i] * st->hTonalMDCTConc->lastBlockData.spectralData[i];
+ E_last += st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] * st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
+ }
+#endif
tmp2 = E_2ndlast / E_last;
/* replace higher energy TCX5 frame by lower one to avoid energy fluctuation */
if ( tmp2 > 2 )
{
+#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY
if ( st->element_mode > EVS_MONO )
{
for ( i = 0; i < L_frameTCX; i = i + 2 )
@@ -1281,9 +1296,16 @@ void decoder_tcx_noisefilling(
st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
}
}
+#else
+ for ( i = 0; i < infoIGFStartLine; i = i + 2 )
+ {
+ st->hTonalMDCTConc->lastBlockData.spectralData[i] = st->hTonalMDCTConc->lastBlockData.spectralData[i + 1];
+ }
+#endif
}
else if ( tmp2 < 0.5 )
{
+#ifdef FIX_575_LOW_OVERLAP_PLC_RECOVERY
if ( st->element_mode > EVS_MONO )
{
for ( i = 0; i < L_frameTCX; i = i + 2 )
@@ -1298,6 +1320,12 @@ void decoder_tcx_noisefilling(
st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
}
}
+#else
+ for ( i = 0; i < infoIGFStartLine; i = i + 2 )
+ {
+ st->hTonalMDCTConc->lastBlockData.spectralData[i + 1] = st->hTonalMDCTConc->lastBlockData.spectralData[i];
+ }
+#endif
}
}
diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c
index 5ed7aa92c4b33f7212c99d5fa896876c43b6b8e6..1244f977936891d9b449612dd6e93023a71c4fdb 100644
--- a/lib_dec/gs_dec.c
+++ b/lib_dec/gs_dec.c
@@ -104,7 +104,11 @@ void decod_audio(
}
/* safety check in case of bit errors */
+#ifdef ISM_FB_16k4
if ( st->GSC_noisy_speech && st->bwidth < SWB && st->GSC_IVAS_mode == 0 )
+#else
+ if ( st->GSC_noisy_speech && st->bwidth != SWB && st->GSC_IVAS_mode == 0 )
+#endif
{
st->BER_detect = 1;
st->GSC_noisy_speech = 0;
diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c
index 0f644b1d6fb013ded9a28c07980d5b5832256ea0..bb0268e98010658765660826e3786b61fbc94331 100644
--- a/lib_dec/ivas_core_dec.c
+++ b/lib_dec/ivas_core_dec.c
@@ -274,6 +274,17 @@ ivas_error ivas_core_dec(
}
}
+#ifdef MASA_AND_OBJECTS
+ /*------------------------------------------------------------------*
+ * Sanity check in combined format coding
+ *-----------------------------------------------------------------*/
+
+ if ( hCPE != NULL && hCPE->element_mode == IVAS_CPE_DFT && hCPE->brate_surplus > 0 )
+ {
+ ivas_combined_format_brate_sanity( hCPE->element_brate, sts[0]->core, &( sts[0]->core_brate ), &tmps );
+ }
+#endif
+
/*------------------------------------------------------------------*
* Core Decoding
*-----------------------------------------------------------------*/
diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c
index 9096843e9c6c6b3fccdba1c51df0ff9ee7a368ad..365101b8bf7d4248d871f46047b9b67eb155c29e 100644
--- a/lib_dec/ivas_cpe_dec.c
+++ b/lib_dec/ivas_cpe_dec.c
@@ -52,6 +52,10 @@
static void read_stereo_mode_and_bwidth( CPE_DEC_HANDLE hCPE, const Decoder_Struct *st_ivas );
+#ifdef MASA_AND_OBJECTS
+static void stereo_mode_combined_format_dec( const Decoder_Struct *st_ivas, CPE_DEC_HANDLE hCPE );
+#endif
+
/*--------------------------------------------------------------------------*
* ivas_cpe_dec()
@@ -77,6 +81,10 @@ ivas_error ivas_cpe_dec(
Decoder_State **sts;
int32_t ivas_total_brate;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t cpe_brate;
+ int32_t element_brate_ref;
+#endif
error = IVAS_ERR_OK;
@@ -93,10 +101,18 @@ ivas_error ivas_cpe_dec(
sts[0]->BER_detect |= st_ivas->BER_detect;
sts[1]->BER_detect |= st_ivas->BER_detect;
+#ifdef MASA_AND_OBJECTS
+ element_brate_ref = hCPE->element_brate;
+#endif
+
/*------------------------------------------------------------------*
* Read stereo technology info & audio bandwidth
*-----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ stereo_mode_combined_format_dec( st_ivas, hCPE );
+#endif
+
read_stereo_mode_and_bwidth( hCPE, st_ivas );
/*----------------------------------------------------------------*
@@ -162,7 +178,18 @@ ivas_error ivas_cpe_dec(
{
if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_5k2 )
{
- stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, (int32_t) ( 0.7f * st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+ }
+ else
+ {
+#endif
+ stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
}
else
{
@@ -218,7 +245,18 @@ ivas_error ivas_cpe_dec(
/* read DFT Stereo side info */
nb_bits = (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal );
- sts[1]->bit_stream = sts[0]->bit_stream + ivas_total_brate / FRAMES_PER_SEC - 1 - nb_bits_metadata;
+#ifdef MASA_AND_OBJECTS
+ cpe_brate = st_ivas->hCPE[0]->element_brate;
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ sts[1]->bit_stream = sts[0]->bit_stream + cpe_brate / FRAMES_PER_SEC - 1 - nb_bits_metadata;
+ sts[1]->bit_stream += hCPE->brate_surplus / FRAMES_PER_SEC;
+ }
+ else
+#endif
+ {
+ sts[1]->bit_stream = sts[0]->bit_stream + ivas_total_brate / FRAMES_PER_SEC - 1 - nb_bits_metadata;
+ }
if ( ivas_total_brate == IVAS_SID_5k2 )
{
@@ -226,7 +264,11 @@ ivas_error ivas_cpe_dec(
sts[1]->bit_stream -= SID_FORMAT_NBITS;
}
+#ifdef MASA_AND_OBJECTS
+ if ( ( ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) || ( st_ivas->ivas_format == MASA_ISM_FORMAT && cpe_brate < MASA_STEREO_MIN_BITRATE ) ) && ivas_total_brate > IVAS_SID_5k2 )
+#else
if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 )
+#endif
{
sts[0]->total_brate = hCPE->element_brate; /* Only mono downmix was transmitted in this case */
}
@@ -237,6 +279,14 @@ ivas_error ivas_cpe_dec(
/* subtract metadata bitbudget */
sts[0]->total_brate -= ( nb_bits_metadata * FRAMES_PER_SEC );
+
+#ifdef MASA_AND_OBJECTS
+ /* subtract bit-rate for combined format coding */
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ sts[0]->total_brate += hCPE->brate_surplus;
+ }
+#endif
}
else
{
@@ -248,6 +298,9 @@ ivas_error ivas_cpe_dec(
/* signal bitrate for BW selection in the SCh */
sts[0]->bits_frame_channel = 0;
sts[1]->bits_frame_channel = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC );
+#ifdef MASA_AND_OBJECTS
+ sts[1]->bits_frame_channel += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
+#endif
if ( st_ivas->hQMetaData != NULL )
{
sts[1]->bits_frame_channel -= st_ivas->hQMetaData->metadata_max_bits;
@@ -255,6 +308,16 @@ ivas_error ivas_cpe_dec(
}
else if ( hCPE->element_mode == IVAS_CPE_MDCT )
{
+#ifdef MASA_AND_OBJECTS
+ /* compute bit-rate surplus per channel in combined format coding */
+ int32_t brate_surplus[CPE_CHANNELS];
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ brate_surplus[0] = ( ( hCPE->brate_surplus / FRAMES_PER_SEC ) >> 1 ) * FRAMES_PER_SEC;
+ brate_surplus[1] = hCPE->brate_surplus - brate_surplus[0];
+ }
+#endif
+
if ( is_DTXrate( ivas_total_brate ) == 1 && ( sts[0]->first_CNG == 0 || sts[1]->first_CNG == 0 ) )
{
if ( ( error = initMdctStereoDtxData( hCPE ) ) != IVAS_ERR_OK )
@@ -279,6 +342,15 @@ ivas_error ivas_cpe_dec(
}
sts[n]->bits_frame_nominal = (int16_t) ( sts[n]->total_brate / FRAMES_PER_SEC );
sts[n]->bits_frame_channel = (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) / n_channels );
+
+#ifdef MASA_AND_OBJECTS
+ /* subtract bit-rate for combined format coding */
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ sts[n]->bits_frame_channel += (int16_t) ( brate_surplus[n] / FRAMES_PER_SEC );
+ sts[n]->total_brate += brate_surplus[n];
+ }
+#endif
}
if ( !st_ivas->hMCT )
@@ -343,7 +415,12 @@ ivas_error ivas_cpe_dec(
{
if ( !st_ivas->bfi )
{
- tdm_configure_dec( hCPE, &tdm_ratio_idx, nb_bits_metadata );
+ tdm_configure_dec(
+#ifdef MASA_AND_OBJECTS
+ st_ivas->ivas_format,
+ st_ivas->ism_mode,
+#endif
+ hCPE, &tdm_ratio_idx, nb_bits_metadata );
sts[1]->bit_stream = sts[0]->bit_stream + ( sts[0]->total_brate / FRAMES_PER_SEC );
}
@@ -489,6 +566,13 @@ ivas_error ivas_cpe_dec(
hCPE->last_element_brate = hCPE->element_brate;
hCPE->last_element_mode = hCPE->element_mode;
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ hCPE->element_brate = element_brate_ref;
+ }
+#endif
+
if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD )
{
stereo_cng_dec_update( hCPE, ivas_total_brate );
@@ -517,9 +601,15 @@ ivas_error ivas_cpe_dec(
{
dbgwrite( output[j], sizeof( float ), output_frame, 1, fname( debug_dir, "output.cpe", j, cpe_id, DEC ) );
}
- tmpF = 0;
- dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.sce", 0, cpe_id, DEC ) );
- dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, cpe_id, DEC ) );
+
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format != MASA_ISM_FORMAT )
+ {
+ tmpF = 0;
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.sce", 0, cpe_id, DEC ) );
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, cpe_id, DEC ) );
+ }
+#endif
}
}
#endif
@@ -546,6 +636,9 @@ ivas_error create_cpe_dec(
Decoder_State *st;
int32_t output_Fs;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t cpe_brate;
+#endif
error = IVAS_ERR_OK;
@@ -584,7 +677,11 @@ ivas_error create_cpe_dec(
hCPE->lt_es_em = 0.0f;
/* Note: nchan_out is considered to be related to the structure. This is nchan_out for CPE and for MASA_format is always 2. */
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->ivas_format == MC_FORMAT )
+#else
if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MC_FORMAT )
+#endif
{
hCPE->nchan_out = CPE_CHANNELS;
}
@@ -593,7 +690,22 @@ ivas_error create_cpe_dec(
hCPE->nchan_out = min( CPE_CHANNELS, st_ivas->hDecoderConfig->nchan_out );
}
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ cpe_brate = element_brate;
+ }
+ else
+ {
+ cpe_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ }
+
+ if ( ( ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE ) ||
+ ( st_ivas->ivas_format == MASA_ISM_FORMAT && cpe_brate < MASA_STEREO_MIN_BITRATE ) ) &&
+ st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 )
+#else
if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 )
+#endif
{
hCPE->nchan_out = 1;
}
@@ -604,14 +716,23 @@ ivas_error create_cpe_dec(
set_f( hCPE->prev_synth[n], 0, NS2SA( output_Fs, IVAS_DEC_DELAY_NS - STEREO_DFT32MS_OVL_NS ) );
}
+#ifdef MASA_AND_OBJECTS
+ hCPE->brate_surplus = 0;
+#endif
+
/*-----------------------------------------------------------------*
* DFT stereo I/O Buffers: allocate and initialize
*-----------------------------------------------------------------*/
for ( i = 0; i < CPE_CHANNELS; i++ )
{
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == STEREO_FORMAT || st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ||
+ ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) || st_ivas->sba_dirac_stereo_flag )
+#else
if ( st_ivas->ivas_format == STEREO_FORMAT || st_ivas->ivas_format == MASA_FORMAT ||
( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) || st_ivas->sba_dirac_stereo_flag )
+#endif
{
if ( ( hCPE->input_mem[i] = (float *) malloc( sizeof( float ) * NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ) ) ) == NULL )
{
@@ -1022,3 +1143,48 @@ static void read_stereo_mode_and_bwidth(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------------
+ * stereo_mode_combined_format_dec()
+ *
+ * Set stereo format in a combined format
+ *-------------------------------------------------------------------------*/
+
+static void stereo_mode_combined_format_dec(
+ const Decoder_Struct *st_ivas, /* i : decoder main structure */
+ CPE_DEC_HANDLE hCPE /* i/o: CPE handle */
+)
+{
+ int32_t element_brate_ref;
+
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ element_brate_ref = hCPE->element_brate;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC &&
+ ( ( st_ivas->nchan_ism == 3 && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_96k ) ||
+ ( st_ivas->nchan_ism == 4 && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_128k ) ) )
+ {
+ /* read OMASA stereo mode signalling */
+ if ( get_next_indice( hCPE->hCoreCoder[0], NBITS_ELEMENT_MODE ) )
+ {
+ hCPE->element_mode = IVAS_CPE_MDCT;
+ }
+ else
+ {
+ hCPE->element_mode = IVAS_CPE_DFT;
+ }
+
+ if ( hCPE->element_mode == IVAS_CPE_MDCT )
+ {
+ hCPE->element_brate = IVAS_64k;
+ hCPE->brate_surplus -= ( hCPE->element_brate - element_brate_ref );
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c
index 5ca878a00ec58382864b493b2665782dbb4f20a9..facefc96cd9b465d0c8aa78f92ce57f35d629806 100644
--- a/lib_dec/ivas_dec.c
+++ b/lib_dec/ivas_dec.c
@@ -65,7 +65,11 @@ ivas_error ivas_dec(
float output[MAX_OUTPUT_CHANNELS][L_FRAME48k]; /* 'float' buffer for output synthesis, MAX_OUTPUT_CHANNELS channels */
int16_t nchan_remapped;
float output_lfe_ch[L_FRAME48k];
+#ifdef MASA_AND_OBJECTS
+ int16_t nb_bits_metadata[MAX_SCE + 1];
+#else
int16_t nb_bits_metadata[MAX_SCE];
+#endif
int32_t output_Fs, ivas_total_brate;
AUDIO_CONFIG output_config;
float pan_left, pan_right;
@@ -74,6 +78,9 @@ ivas_error ivas_dec(
#ifdef VLBR_20MS_MD
int16_t num_md_sub_frames;
#endif
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
@@ -445,7 +452,7 @@ ivas_error ivas_dec(
{
#ifdef FIX_564
/* loudness correction */
- ivas_dirac_dec_binaural_sba_gain( output, nchan_remapped, output_frame );
+ ivas_dirac_dec_binaural_gain( output, nchan_remapped, output_frame );
#else
float gain;
@@ -489,6 +496,122 @@ ivas_error ivas_dec(
ivas_sba_upmixer_renderer( st_ivas, output, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */
}
}
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: Check here for p_output vs. output and possibly also metadata indices
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ int16_t nchan_ism, nchan_transport_ism;
+ int16_t dirac_bs_md_write_idx;
+
+ st = st_ivas->hCPE[0]->hCoreCoder[0];
+ set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+
+ /* Set the number of objects for the parametric rendering */
+ dirac_bs_md_write_idx = 0;
+ if ( st_ivas->hDirAC != NULL )
+ {
+ st_ivas->hDirAC->numIsmDirections = 0;
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ st_ivas->hDirAC->numIsmDirections = st_ivas->nchan_ism;
+ }
+
+ dirac_bs_md_write_idx = st_ivas->hDirAC->dirac_bs_md_write_idx; /* Store the write-index for this frame */
+ }
+
+ /* MASA metadata decoding */
+ if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Configuration of combined-format bit-budget distribution */
+ ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate );
+
+ st->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] );
+
+ /* set ISM parameters and decode ISM metadata in OMASA format */
+ if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* decode ISM channels */
+ for ( n = 0; n < nchan_transport_ism; n++ )
+ {
+ if ( ( error = ivas_sce_dec( st_ivas, n, &output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* decode MASA channels */
+ if ( ( error = ivas_cpe_dec( st_ivas, 0, output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->hCPE[0]->nchan_out == 1 )
+ {
+ mvr2r( output[0], output[1], output_frame ); /* Copy mono signal to stereo output channels */
+ }
+
+ /* HP filtering */
+ for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ )
+ {
+ hp20( output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs );
+ }
+
+ /* Set edited object positions, if editing enabled */
+ ivas_masa_ism_set_edited_objects( st_ivas );
+
+ /* Rendering */
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
+ {
+ if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, output, output_frame ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, output, st_ivas->nchan_transport );
+ }
+ }
+ else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
+ {
+ ivas_mono_downmix_render_passive( st_ivas, output, output_frame );
+ }
+ else if ( st_ivas->renderer_type == RENDERER_DIRAC )
+ {
+ ivas_omasa_dirac_rend( st_ivas, output, output_frame );
+ }
+
+#ifdef OMASA_EXT_OUTPUT
+ if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL )
+ {
+ /* sanity check in case of bitrate switching */
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" );
+ }
+
+ /* in case of external rendering, rearrange the channels order */
+ mvr2r( output[0], output[MAX_OUTPUT_CHANNELS - 2], output_frame );
+ mvr2r( output[1], output[MAX_OUTPUT_CHANNELS - 1], output_frame );
+
+ for ( n = 0; n < nchan_transport_ism; n++ )
+ {
+ mvr2r( output[st_ivas->nchan_transport + n], output[n], output_frame );
+ }
+ mvr2r( output[MAX_OUTPUT_CHANNELS - 2], output[n], output_frame );
+ mvr2r( output[MAX_OUTPUT_CHANNELS - 1], output[++n], output_frame );
+ }
+#endif
+ }
+#endif
else if ( st_ivas->ivas_format == MC_FORMAT )
{
st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0];
@@ -897,6 +1020,10 @@ ivas_error ivas_dec(
st_ivas->ini_active_frame++;
}
+#ifdef MASA_AND_OBJECTS
+ st_ivas->last_ivas_format = st_ivas->ivas_format;
+#endif
+
#ifdef DEBUG_MODE_INFO
dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" );
dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" );
diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c
index 766f4ff08fe05ea389e53845c393a6b5fda5f734..ef2ec470a229755eec2adec1f4456906b027f411 100644
--- a/lib_dec/ivas_dirac_dec.c
+++ b/lib_dec/ivas_dirac_dec.c
@@ -51,69 +51,206 @@
* Local function prototypes
*-----------------------------------------------------------------------*/
-static ivas_error ivas_dirac_dec_config_internal(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const DIRAC_CONFIG_FLAG flag_config_inp /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
+static ivas_error ivas_dirac_alloc_mem( DIRAC_DEC_HANDLE hDirAC, const RENDERER_TYPE renderer_type, DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem, const int16_t hodirac_flag );
+
+static void ivas_dirac_free_mem( DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem );
+
+static void initDiffuseResponses( float *diffuse_response_function, const int16_t num_channels, AUDIO_CONFIG output_config, IVAS_OUTPUT_SETUP hOutSetup, const int16_t ambisonics_order, const IVAS_FORMAT ivas_format, int16_t *num_ele_spk_no_diffuse_rendering, AUDIO_CONFIG transport_config );
+
+static void computeIntensityVector_dec( float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], const int16_t num_frequency_bands, float *intensity_real_x, float *intensity_real_y, float *intensity_real_z );
+
+static void protoSignalComputation_shd( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_direct_buffer_f, float *proto_diffuse_buffer_f, float *reference_power, const int16_t slot_index, const int16_t num_inputs, const int16_t num_outputs_diff, const int16_t num_freq_bands, float *p_Rmat );
+
+static void protoSignalComputation1( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands );
+
+static void protoSignalComputation2( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t isloudspeaker, const int16_t slot_index, const int16_t num_freq_bands, MASA_STEREO_TYPE_DETECT *stereo_type_detect );
+
+static void protoSignalComputation4( float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float *proto_frame_f, float *proto_direct_buffer_f, float *reference_power, float *proto_power_smooth, const int16_t slot_index, const int16_t num_outputs_diff, const int16_t num_freq_bands, const float *mtx_hoa_decoder, const int16_t nchan_transport, const int16_t *sba_map_tc_ind );
+
+static void ivas_dirac_dec_compute_diffuse_proto( DIRAC_DEC_HANDLE hDirAC, const int16_t slot_idx );
+
+static void computeDirectionAngles( float *intensity_real_x, float *intensity_real_y, float *intensity_real_z, const int16_t num_frequency_bands, int16_t *azimuth, int16_t *elevation );
+
+static void ivas_masa_init_stereotype_detection( MASA_STEREO_TYPE_DETECT *stereo_type_detect );
+
+static void ivas_masa_stereotype_detection( MASA_STEREO_TYPE_DETECT *stereo_type_detect );
+
+static void ivas_lfe_synth_with_cldfb( MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth, float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float RealBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], float ImagBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], const int16_t slot_index, const int16_t subframe_index, const int16_t nchan_transport );
+
+static void rotateAziEle_DirAC( int16_t *azi, int16_t *ele, const int16_t band1, const int16_t band2, const float *p_Rmat );
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_open()
+ *
+ * Open decoder DirAC handle
+ *-------------------------------------------------------------------------*/
+
+ivas_error ivas_dirac_dec_open(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
- DIRAC_DEC_HANDLE hDirAC;
ivas_error error;
- DIRAC_CONFIG_FLAG flag_config;
- flag_config = ( flag_config_inp == DIRAC_RECONFIGURE_MODE ) ? DIRAC_RECONFIGURE : flag_config_inp;
error = IVAS_ERR_OK;
- hDirAC = NULL;
-
- if ( flag_config == DIRAC_RECONFIGURE )
+ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
{
- hDirAC = st_ivas->hDirAC;
+ return error;
}
- else if ( flag_config == DIRAC_OPEN )
+
+ return error;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_allocate_parameters()
+ *
+ * Allocate and initialize DirAC parameters
+ *-------------------------------------------------------------------------*/
+
+ivas_error ivas_dirac_allocate_parameters(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
+ const int16_t params_flag /* i : set of parameters flag */
+)
+{
+ int16_t i;
+
+ if ( params_flag == 1 )
{
- /*-----------------------------------------------------------------*
- * prepare library opening
- *-----------------------------------------------------------------*/
+ if ( ( hDirAC->azimuth = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
- if ( ( hDirAC = (DIRAC_DEC_HANDLE) malloc( sizeof( DIRAC_DEC_DATA ) ) ) == NULL )
+ if ( ( hDirAC->elevation = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- if ( ( hDirAC->hConfig = (DIRAC_CONFIG_DATA_HANDLE) malloc( sizeof( DIRAC_CONFIG_DATA ) ) ) == NULL )
+ if ( ( hDirAC->diffuseness_vector = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
{
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC Config\n" ) );
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- hDirAC->hParamIsm = NULL;
- hDirAC->hParamIsmRendering = NULL;
- st_ivas->hDirAC = hDirAC;
- }
+ if ( ( hDirAC->energy_ratio1 = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ if ( ( hDirAC->spreadCoherence = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
- /*-----------------------------------------------------------------*
- * DirAC main configuration
- *-----------------------------------------------------------------*/
+ if ( ( hDirAC->surroundingCoherence = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
- if ( ( error = ivas_dirac_config( (void *) st_ivas, DEC ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
+ {
+ if ( ( hDirAC->azimuth[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_s( hDirAC->azimuth[i], 0, hDirAC->num_freq_bands );
- if ( flag_config == DIRAC_OPEN )
+ if ( ( hDirAC->elevation[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_s( hDirAC->elevation[i], 0, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->diffuseness_vector[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->diffuseness_vector[i], 1.0f, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->energy_ratio1[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->energy_ratio1[i], 0.0f, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->spreadCoherence[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->spreadCoherence[i], 0.0f, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->surroundingCoherence[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->surroundingCoherence[i], 0.0f, hDirAC->num_freq_bands );
+ }
+ }
+ else if ( params_flag == 2 )
{
- hDirAC->spar_to_dirac_write_idx = st_ivas->ivas_format == SBA_FORMAT ? DELAY_DIRAC_PARAM_DEC_SFR : 0;
- hDirAC->dithering_seed = DIRAC_DITH_SEED;
- st_ivas->hDirAC = hDirAC;
+ if ( ( hDirAC->azimuth2 = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+
+ if ( ( hDirAC->elevation2 = (int16_t **) malloc( hDirAC->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+
+ if ( ( hDirAC->energy_ratio2 = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+
+ if ( ( hDirAC->spreadCoherence2 = (float **) malloc( hDirAC->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
+ {
+ if ( ( hDirAC->azimuth2[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_s( hDirAC->azimuth2[i], 0, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->elevation2[i] = (int16_t *) malloc( hDirAC->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_s( hDirAC->elevation2[i], 0, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->energy_ratio2[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->energy_ratio2[i], 0.0f, hDirAC->num_freq_bands );
+
+ if ( ( hDirAC->spreadCoherence2[i] = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
+ }
+ set_f( hDirAC->spreadCoherence2[i], 0.0f, hDirAC->num_freq_bands );
+ }
}
- return error;
+ return IVAS_ERR_OK;
}
-static ivas_error ivas_dirac_rend_config(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const DIRAC_CONFIG_FLAG flag_config_inp, /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
- const int16_t dec_param_estim_old )
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_config()
+ *
+ * Open or reconfigure decoder DirAC/MASA handle
+ *-------------------------------------------------------------------------*/
+
+ivas_error ivas_dirac_dec_config(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const DIRAC_CONFIG_FLAG flag_config_inp /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
+)
{
DIRAC_DEC_HANDLE hDirAC;
int16_t nchan_out_woLFE;
@@ -125,30 +262,27 @@ static ivas_error ivas_dirac_rend_config(
float *proto_frame_f_old;
int16_t proto_signal_decorr_on_old;
uint16_t i, j, k;
+ int16_t dec_param_estim_old;
float ls_azimuth[MAX_OUTPUT_CHANNELS];
float ls_elevation[MAX_OUTPUT_CHANNELS];
int32_t output_Fs, ivas_total_brate;
ivas_error error;
int16_t nchan_transport_orig;
int16_t hodirac_flag;
+ int16_t map_idx;
DIRAC_CONFIG_FLAG flag_config;
- DIRAC_REND_HANDLE hDirACRend;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
flag_config = ( flag_config_inp == DIRAC_RECONFIGURE_MODE ) ? DIRAC_RECONFIGURE : flag_config_inp;
error = IVAS_ERR_OK;
- hDirACRend = NULL;
+ hDirAC = NULL;
output_Fs = st_ivas->hDecoderConfig->output_Fs;
ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
hodirac_flag = ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order );
- hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
-
if ( flag_config == DIRAC_RECONFIGURE )
{
- hDirACRend = st_ivas->hDirACRend;
+ hDirAC = st_ivas->hDirAC;
}
else if ( flag_config == DIRAC_OPEN )
{
@@ -156,21 +290,29 @@ static ivas_error ivas_dirac_rend_config(
* prepare library opening
*-----------------------------------------------------------------*/
- if ( ( hDirACRend = (DIRAC_REND_HANDLE) malloc( sizeof( DIRAC_REND_DATA ) ) ) == NULL )
+ if ( ( hDirAC = (DIRAC_DEC_HANDLE) malloc( sizeof( DIRAC_DEC_DATA ) ) ) == NULL )
{
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC renderer\n" ) );
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
+ if ( ( hDirAC->hConfig = (DIRAC_CONFIG_DATA_HANDLE) malloc( sizeof( DIRAC_CONFIG_DATA ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC Config\n" ) );
+ }
nchan_transport_old = 0;
+ hDirAC->hParamIsm = NULL;
+ hDirAC->hParamIsmRendering = NULL;
+ st_ivas->hDirAC = hDirAC;
}
+ dec_param_estim_old = ( flag_config == DIRAC_RECONFIGURE ) ? hDirAC->hConfig->dec_param_estim : FALSE;
nchan_transport_old = 0;
num_outputs_dir_old = 0;
num_outputs_diff_old = 0;
num_protos_diff_old = 0;
nchan_transport_orig = st_ivas->nchan_transport;
- if ( st_ivas->ivas_format == SBA_FORMAT )
+ if ( st_ivas->ivas_format == SBA_FORMAT && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
{
st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate );
}
@@ -187,40 +329,58 @@ static ivas_error ivas_dirac_rend_config(
ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3 );
}
+ /*-----------------------------------------------------------------*
+ * DirAC main configuration
+ *-----------------------------------------------------------------*/
+
+ if ( ( error = ivas_dirac_config( (void *) st_ivas, DEC ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
/*-----------------------------------------------------------------*
* output setup: for parametric binaural renderer, use output setup, otherwise internal setup
*-----------------------------------------------------------------*/
- hDirACRend->hOutSetup = st_ivas->hIntSetup;
- nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ hDirAC->hOutSetup = st_ivas->hOutSetup;
+
+ hDirAC->hConfig->dec_param_estim = FALSE;
+ }
+ else
+ {
+ hDirAC->hOutSetup = st_ivas->hIntSetup;
+ }
+ nchan_out_woLFE = hDirAC->hOutSetup.nchan_out_woLFE;
- if ( hDirACRend->hOutSetup.ls_azimuth != NULL && hDirACRend->hOutSetup.ls_elevation != NULL )
+ if ( hDirAC->hOutSetup.ls_azimuth != NULL && hDirAC->hOutSetup.ls_elevation != NULL )
{
- mvr2r( hDirACRend->hOutSetup.ls_azimuth, ls_azimuth, nchan_out_woLFE );
- mvr2r( hDirACRend->hOutSetup.ls_elevation, ls_elevation, nchan_out_woLFE );
+ mvr2r( hDirAC->hOutSetup.ls_azimuth, ls_azimuth, nchan_out_woLFE );
+ mvr2r( hDirAC->hOutSetup.ls_elevation, ls_elevation, nchan_out_woLFE );
}
- if ( hDirACRend->hOutSetup.ambisonics_order == -1 )
+ if ( hDirAC->hOutSetup.ambisonics_order == -1 )
{
- hDirACRend->hOutSetup.ambisonics_order = SBA_HOA3_ORDER; /* Order 3 is used by default in DirAC for SHD processing */
- if ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_MONO || hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_STEREO )
+ hDirAC->hOutSetup.ambisonics_order = SBA_HOA3_ORDER; /* Order 3 is used by default in DirAC for SHD processing */
+ if ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_MONO || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_STEREO )
{
- hDirACRend->hOutSetup.ambisonics_order = SBA_FOA_ORDER;
+ hDirAC->hOutSetup.ambisonics_order = SBA_FOA_ORDER;
}
}
- else if ( hDirACRend->hOutSetup.ambisonics_order >= SBA_FOA_ORDER )
+ else if ( hDirAC->hOutSetup.ambisonics_order >= SBA_FOA_ORDER )
{
mvr2r( ls_azimuth_4d4, ls_azimuth, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS );
mvr2r( ls_elevation_4d4, ls_elevation, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS );
}
- if ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1 || hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_7_1 || hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 || hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 || hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 || ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) )
+ if ( hDirAC->hOutSetup.separateChannelEnabled && ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1 || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1 || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 || ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) )
{
/* Remove the channel of the separated signal from the output setup of the spatial synthesis */
- hDirACRend->hOutSetup.nchan_out_woLFE--;
- nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
- mvr2r( &ls_azimuth[hDirACRend->hOutSetup.separateChannelIndex + 1], &ls_azimuth[hDirACRend->hOutSetup.separateChannelIndex], nchan_out_woLFE - hDirACRend->hOutSetup.separateChannelIndex );
- mvr2r( &ls_elevation[hDirACRend->hOutSetup.separateChannelIndex + 1], &ls_elevation[hDirACRend->hOutSetup.separateChannelIndex], nchan_out_woLFE - hDirACRend->hOutSetup.separateChannelIndex );
+ hDirAC->hOutSetup.nchan_out_woLFE--;
+ nchan_out_woLFE = hDirAC->hOutSetup.nchan_out_woLFE;
+ mvr2r( &ls_azimuth[hDirAC->hOutSetup.separateChannelIndex + 1], &ls_azimuth[hDirAC->hOutSetup.separateChannelIndex], nchan_out_woLFE - hDirAC->hOutSetup.separateChannelIndex );
+ mvr2r( &ls_elevation[hDirAC->hOutSetup.separateChannelIndex + 1], &ls_elevation[hDirAC->hOutSetup.separateChannelIndex], nchan_out_woLFE - hDirAC->hOutSetup.separateChannelIndex );
}
/*-----------------------------------------------------------------*
@@ -229,64 +389,114 @@ static ivas_error ivas_dirac_rend_config(
st_ivas->nchan_transport = nchan_transport_orig;
- if ( nchan_transport_orig > 2 && hDirACRend->hOutSetup.is_loudspeaker_setup && st_ivas->renderer_type == RENDERER_DIRAC && !hodirac_flag )
+ if ( flag_config == DIRAC_OPEN )
+ {
+ hDirAC->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );
+ set_s( hDirAC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set_s( hDirAC->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
+ hDirAC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
+ hDirAC->subframes_rendered = 0;
+ hDirAC->slots_rendered = 0;
+ hDirAC->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ }
+
+ if ( st_ivas->ivas_format == SBA_FORMAT && flag_config == DIRAC_RECONFIGURE && ( ( ivas_total_brate > IVAS_256k && st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_256k ) || ( ivas_total_brate <= IVAS_256k && st_ivas->hDecoderConfig->last_ivas_total_brate > IVAS_256k ) ) )
+ {
+ if ( st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k && hDirAC->azimuth2 == NULL )
+ {
+ if ( ( error = ivas_dirac_allocate_parameters( hDirAC, 2 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->hDecoderConfig->ivas_total_brate <= IVAS_256k && hDirAC->azimuth2 != NULL )
+ {
+ ivas_dirac_deallocate_parameters( hDirAC, 2 );
+ }
+ }
+
+ /* band config needed only for SPAR with FOA output */
+ if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA && st_ivas->ivas_format == SBA_FORMAT && !hodirac_flag )
+ {
+ return IVAS_ERR_OK;
+ }
+
+ if ( nchan_transport_orig > 2 && hDirAC->hOutSetup.is_loudspeaker_setup && st_ivas->renderer_type == RENDERER_DIRAC && !hodirac_flag )
+ {
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_PSD_LS;
+ hDirAC->panningConf = DIRAC_PANNING_VBAP;
+ }
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
- hDirACRend->synthesisConf = DIRAC_SYNTHESIS_PSD_LS;
- hDirACRend->panningConf = DIRAC_PANNING_VBAP;
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_PSD_LS;
+ hDirAC->panningConf = DIRAC_PANNING_VBAP;
}
- else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_MONO )
+ else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirAC->hOutSetup.output_config == AUDIO_CONFIG_MONO )
{
- hDirACRend->synthesisConf = DIRAC_SYNTHESIS_MONO;
- hDirACRend->panningConf = DIRAC_PANNING_HOA3;
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_MONO;
+ hDirAC->panningConf = DIRAC_PANNING_HOA3;
nchan_out_woLFE = 1;
}
- else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirACRend->hOutSetup.is_loudspeaker_setup )
+#ifdef MASA_AND_OBJECTS
+ else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirAC->hOutSetup.is_loudspeaker_setup )
+#else
+ else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirAC->hOutSetup.is_loudspeaker_setup )
+#endif
{
- hDirACRend->synthesisConf = DIRAC_SYNTHESIS_PSD_LS;
- hDirACRend->panningConf = DIRAC_PANNING_VBAP;
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_PSD_LS;
+ hDirAC->panningConf = DIRAC_PANNING_VBAP;
}
- else if ( st_ivas->ivas_format == MASA_FORMAT && !hDirACRend->hOutSetup.is_loudspeaker_setup && st_ivas->nchan_transport > 1 )
+#ifdef MASA_AND_OBJECTS
+ else if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && !hDirAC->hOutSetup.is_loudspeaker_setup && st_ivas->nchan_transport > 1 )
+#else
+ else if ( st_ivas->ivas_format == MASA_FORMAT && !hDirAC->hOutSetup.is_loudspeaker_setup && st_ivas->nchan_transport > 1 )
+#endif
{
- hDirACRend->synthesisConf = DIRAC_SYNTHESIS_PSD_SHD;
- hDirACRend->panningConf = DIRAC_PANNING_HOA3;
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_PSD_SHD;
+ hDirAC->panningConf = DIRAC_PANNING_HOA3;
}
else
{
- hDirACRend->synthesisConf = DIRAC_SYNTHESIS_GAIN_SHD;
- hDirACRend->panningConf = DIRAC_PANNING_HOA3;
+ hDirAC->synthesisConf = DIRAC_SYNTHESIS_GAIN_SHD;
+ hDirAC->panningConf = DIRAC_PANNING_HOA3;
}
if ( flag_config == DIRAC_OPEN )
{
- if ( ( hDirACRend->frequency_axis = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
+ hDirAC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
+ if ( ( hDirAC->frequency_axis = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- set_f( hDirACRend->frequency_axis, 0.0f, hSpatParamRendCom->num_freq_bands );
+ set_f( hDirAC->frequency_axis, 0.0f, hDirAC->num_freq_bands );
- ivas_dirac_dec_get_frequency_axis( hDirACRend->frequency_axis, output_Fs, hSpatParamRendCom->num_freq_bands );
+ ivas_dirac_dec_get_frequency_axis( hDirAC->frequency_axis, output_Fs, hDirAC->num_freq_bands );
}
- if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirACRend->panningConf == DIRAC_PANNING_HOA3 && nchan_transport == 2 )
+ if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->mc_mode == MC_MODE_MCMASA ) && hDirAC->panningConf == DIRAC_PANNING_HOA3 && nchan_transport == 2 )
{
- if ( ( flag_config == DIRAC_RECONFIGURE && hDirACRend->masa_stereo_type_detect == NULL ) || flag_config == DIRAC_OPEN )
+ if ( ( flag_config == DIRAC_RECONFIGURE && hDirAC->masa_stereo_type_detect == NULL ) || flag_config == DIRAC_OPEN )
{
- if ( ( hDirACRend->masa_stereo_type_detect = (MASA_STEREO_TYPE_DETECT *) malloc( sizeof( MASA_STEREO_TYPE_DETECT ) ) ) == NULL )
+ if ( ( hDirAC->masa_stereo_type_detect = (MASA_STEREO_TYPE_DETECT *) malloc( sizeof( MASA_STEREO_TYPE_DETECT ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- ivas_masa_init_stereotype_detection( hDirACRend->masa_stereo_type_detect );
+ ivas_masa_init_stereotype_detection( hDirAC->masa_stereo_type_detect );
}
else
{
- if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->masa_stereo_type_detect != NULL )
+ if ( flag_config == DIRAC_RECONFIGURE && hDirAC->masa_stereo_type_detect != NULL )
{
- free( hDirACRend->masa_stereo_type_detect );
+ free( hDirAC->masa_stereo_type_detect );
}
- hDirACRend->masa_stereo_type_detect = NULL;
+ hDirAC->masa_stereo_type_detect = NULL;
}
+#ifdef MASA_AND_OBJECTS
+ hDirAC->numIsmDirections = 0; /* By default, no ism directions, set correct number runtime when needed */
+#endif
+
/*-----------------------------------------------------------------*
* (re)configure sub-modules
*-----------------------------------------------------------------*/
@@ -294,39 +504,45 @@ static ivas_error ivas_dirac_rend_config(
/* prototype signal computation */
if ( flag_config == DIRAC_RECONFIGURE )
{
- num_outputs_dir_old = hDirACRend->num_outputs_dir;
- num_outputs_diff_old = hDirACRend->num_outputs_diff;
- num_protos_diff_old = hDirACRend->num_protos_diff;
+ num_outputs_dir_old = hDirAC->num_outputs_dir;
+ num_outputs_diff_old = hDirAC->num_outputs_diff;
+ num_protos_diff_old = hDirAC->num_protos_diff;
}
/* allocate output setup related arrays */
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ /* Two channels in parametric binaural rendering */
+ hDirAC->num_outputs_diff = 2;
+ hDirAC->num_outputs_dir = 2;
+ }
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
{
/* Directional and diffuses components in output LS format */
- hDirACRend->num_outputs_diff = nchan_out_woLFE;
- hDirACRend->num_outputs_dir = nchan_out_woLFE;
+ hDirAC->num_outputs_diff = nchan_out_woLFE;
+ hDirAC->num_outputs_dir = nchan_out_woLFE;
}
- else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
/* Directional and diffuses components in SHD */
/* Diffuseness components up to 1st order */
- hDirACRend->num_outputs_diff = ( min( hDirACRend->hOutSetup.ambisonics_order, 1 ) + 1 ) * ( min( hDirACRend->hOutSetup.ambisonics_order, 1 ) + 1 );
- if ( ( st_ivas->ivas_format == SBA_FORMAT ) && ( ivas_total_brate >= IVAS_96k ) && ( hDirACRend->hOutSetup.ambisonics_order > 1 ) && ( nchan_transport < 4 ) )
+ hDirAC->num_outputs_diff = ( min( hDirAC->hOutSetup.ambisonics_order, 1 ) + 1 ) * ( min( hDirAC->hOutSetup.ambisonics_order, 1 ) + 1 );
+ if ( ( st_ivas->ivas_format == SBA_FORMAT ) && ( ivas_total_brate >= IVAS_96k ) && ( hDirAC->hOutSetup.ambisonics_order > 1 ) && ( nchan_transport < 4 ) )
{
- hDirACRend->num_outputs_diff += 2; /* Add 2nd-order planar components for HRs */
+ hDirAC->num_outputs_diff += 2; /* Add 2nd-order planar components for HRs */
}
- hDirACRend->num_outputs_dir = ivas_sba_get_nchan( hDirACRend->hOutSetup.ambisonics_order, 0 );
+ hDirAC->num_outputs_dir = ivas_sba_get_nchan( hDirAC->hOutSetup.ambisonics_order, 0 );
}
- else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
{
- hDirACRend->num_outputs_diff = DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS;
- hDirACRend->num_outputs_dir = nchan_out_woLFE;
+ hDirAC->num_outputs_diff = DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS;
+ hDirAC->num_outputs_dir = nchan_out_woLFE;
}
- else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
- hDirACRend->num_outputs_diff = 1; /* There is one output channel in mono */
- hDirACRend->num_outputs_dir = 2; /* Two channels are pre-rendered for stereo type detection */
+ hDirAC->num_outputs_diff = 1; /* There is one output channel in mono */
+ hDirAC->num_outputs_dir = 2; /* Two channels are pre-rendered for stereo type detection */
}
else
{
@@ -335,135 +551,154 @@ static ivas_error ivas_dirac_rend_config(
if ( flag_config == DIRAC_OPEN )
{
- num_outputs_dir_old = hDirACRend->num_outputs_dir;
- if ( ( hDirACRend->proto_index_dir = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_dir ) ) == NULL )
+ num_outputs_dir_old = hDirAC->num_outputs_dir;
+ if ( ( hDirAC->proto_index_dir = (int16_t *) malloc( sizeof( int16_t ) * hDirAC->num_outputs_dir ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- num_outputs_diff_old = hDirACRend->num_outputs_diff;
- if ( ( hDirACRend->proto_index_diff = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_diff ) ) == NULL )
+ num_outputs_diff_old = hDirAC->num_outputs_diff;
+ if ( ( hDirAC->proto_index_diff = (int16_t *) malloc( sizeof( int16_t ) * hDirAC->num_outputs_diff ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- if ( hDirACRend->num_outputs_dir != num_outputs_dir_old && flag_config == DIRAC_RECONFIGURE )
+ if ( hDirAC->num_outputs_dir != num_outputs_dir_old && flag_config == DIRAC_RECONFIGURE )
{
- free( hDirACRend->proto_index_dir );
- if ( ( hDirACRend->proto_index_dir = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_dir ) ) == NULL )
+ free( hDirAC->proto_index_dir );
+ if ( ( hDirAC->proto_index_dir = (int16_t *) malloc( sizeof( int16_t ) * hDirAC->num_outputs_dir ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- set_s( hDirACRend->proto_index_dir, 0, hDirACRend->num_outputs_dir );
+ set_s( hDirAC->proto_index_dir, 0, hDirAC->num_outputs_dir );
- if ( hDirACRend->num_outputs_diff != num_outputs_diff_old && flag_config == DIRAC_RECONFIGURE )
+ if ( hDirAC->num_outputs_diff != num_outputs_diff_old && flag_config == DIRAC_RECONFIGURE )
{
- free( hDirACRend->proto_index_diff );
- if ( ( hDirACRend->proto_index_diff = (int16_t *) malloc( sizeof( int16_t ) * hDirACRend->num_outputs_diff ) ) == NULL )
+ free( hDirAC->proto_index_diff );
+ if ( ( hDirAC->proto_index_diff = (int16_t *) malloc( sizeof( int16_t ) * hDirAC->num_outputs_diff ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- set_s( hDirACRend->proto_index_diff, 0, hDirACRend->num_outputs_diff );
+ set_s( hDirAC->proto_index_diff, 0, hDirAC->num_outputs_diff );
- hDirACRend->sba_map_tc = sba_map_tc;
+ hDirAC->sba_map_tc = sba_map_tc;
if ( st_ivas->ivas_format == SBA_FORMAT )
{
if ( st_ivas->sba_order > SBA_FOA_ORDER && ivas_total_brate >= IVAS_512k )
{
- hDirACRend->sba_map_tc = sba_map_tc_512;
+ hDirAC->sba_map_tc = sba_map_tc_512;
}
}
if ( nchan_transport == 1 )
{
- hDirACRend->num_protos_ambi = 1;
- hDirACRend->num_protos_dir = 1;
- hDirACRend->num_protos_diff = 1;
+ hDirAC->num_protos_ambi = 1;
+ hDirAC->num_protos_dir = 1;
+ hDirAC->num_protos_diff = 1;
+
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ hDirAC->num_protos_dir = 2;
+ hDirAC->num_protos_diff = 2;
+ hDirAC->proto_index_dir[0] = 0;
+ hDirAC->proto_index_dir[1] = 1;
+ hDirAC->proto_index_diff[0] = 0;
+ hDirAC->proto_index_diff[1] = 1;
+ }
}
else if ( nchan_transport == 2 )
{
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- hDirACRend->num_protos_ambi = 2;
- hDirACRend->num_protos_diff = 1;
- hDirACRend->num_protos_dir = 2;
- hDirACRend->proto_index_dir[1] = 1;
+ hDirAC->num_protos_ambi = 2;
+ hDirAC->num_protos_diff = 1;
+ hDirAC->num_protos_dir = 2;
+ hDirAC->proto_index_dir[1] = 1;
}
- else if ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_MONO )
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ hDirAC->num_protos_dir = 2;
+ hDirAC->num_protos_diff = 2;
+ hDirAC->proto_index_dir[0] = 0;
+ hDirAC->proto_index_dir[1] = 1;
+ hDirAC->proto_index_diff[0] = 0;
+ hDirAC->proto_index_diff[1] = 1;
+ }
+ else if ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_MONO )
{
/* Following the foa rendering for code compatibility */
- hDirACRend->num_protos_ambi = 2;
- hDirACRend->num_protos_dir = 2;
- hDirACRend->num_protos_diff = 3;
- hDirACRend->proto_index_dir[0] = 0;
- hDirACRend->proto_index_diff[0] = 0;
+ hDirAC->num_protos_ambi = 2;
+ hDirAC->num_protos_dir = 2;
+ hDirAC->num_protos_diff = 3;
+ hDirAC->proto_index_dir[0] = 0;
+ hDirAC->proto_index_diff[0] = 0;
}
else
{
- hDirACRend->num_protos_ambi = 2;
- hDirACRend->num_protos_diff = 3;
+ hDirAC->num_protos_ambi = 2;
+ hDirAC->num_protos_diff = 3;
- for ( k = 0; k < hDirACRend->num_outputs_diff; k++ )
+ for ( k = 0; k < hDirAC->num_outputs_diff; k++ )
{
if ( ls_azimuth[k] > 0.0f )
{
- hDirACRend->proto_index_diff[k] = 1;
+ hDirAC->proto_index_diff[k] = 1;
}
else if ( ls_azimuth[k] < 0.0f )
{
- hDirACRend->proto_index_diff[k] = 2;
+ hDirAC->proto_index_diff[k] = 2;
}
else
{
- hDirACRend->proto_index_diff[k] = 0;
+ hDirAC->proto_index_diff[k] = 0;
}
}
- if ( hDirACRend->hOutSetup.is_loudspeaker_setup )
+ if ( hDirAC->hOutSetup.is_loudspeaker_setup )
{
- hDirACRend->num_protos_dir = 3;
- mvs2s( hDirACRend->proto_index_diff, hDirACRend->proto_index_dir, nchan_out_woLFE );
+ hDirAC->num_protos_dir = 3;
+ mvs2s( hDirAC->proto_index_diff, hDirAC->proto_index_dir, nchan_out_woLFE );
}
else
{
- hDirACRend->num_protos_dir = 2;
- hDirACRend->proto_index_dir[1] = 1;
+ hDirAC->num_protos_dir = 2;
+ hDirAC->proto_index_dir[1] = 1;
}
}
}
else /* nchan_transport > 2 */
{
- hDirACRend->num_protos_ambi = 4;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
+ hDirAC->num_protos_ambi = 4;
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
{
- hDirACRend->num_protos_diff = hDirACRend->num_outputs_diff;
- for ( k = 0; k < hDirACRend->num_outputs_diff; k++ )
+ hDirAC->num_protos_diff = hDirAC->num_outputs_diff;
+ for ( k = 0; k < hDirAC->num_outputs_diff; k++ )
{
- hDirACRend->proto_index_diff[k] = k;
+ hDirAC->proto_index_diff[k] = k;
}
- hDirACRend->num_protos_dir = hDirACRend->num_outputs_dir;
- for ( k = 0; k < hDirACRend->num_outputs_dir; k++ )
+ hDirAC->num_protos_dir = hDirAC->num_outputs_dir;
+ for ( k = 0; k < hDirAC->num_outputs_dir; k++ )
{
- hDirACRend->proto_index_dir[k] = k;
+ hDirAC->proto_index_dir[k] = k;
}
}
else
{
- hDirACRend->num_protos_diff = 1;
- hDirACRend->num_protos_dir = nchan_transport;
- if ( ( st_ivas->sba_planar ) && ( !( st_ivas->ivas_format == SBA_FORMAT ) ) ) // Todo Dolby/FhG refactor: Is this ever true?
+ hDirAC->num_protos_diff = 1;
+ hDirAC->num_protos_dir = nchan_transport;
+ if ( ( st_ivas->sba_planar ) && ( !( st_ivas->ivas_format == SBA_FORMAT ) ) )
{
- hDirACRend->num_protos_dir++;
+ hDirAC->num_protos_dir++;
}
- for ( k = 0; k < min( hDirACRend->num_outputs_dir, hDirACRend->num_protos_dir ); k++ )
+ for ( k = 0; k < min( hDirAC->num_outputs_dir, hDirAC->num_protos_dir ); k++ )
{
- if ( hDirACRend->sba_map_tc[k] < hDirACRend->num_outputs_dir )
+ if ( hDirAC->sba_map_tc[k] < hDirAC->num_outputs_dir )
{
- hDirACRend->proto_index_dir[hDirACRend->sba_map_tc[k]] = k;
+ hDirAC->proto_index_dir[hDirAC->sba_map_tc[k]] = k;
}
}
}
@@ -472,61 +707,61 @@ static ivas_error ivas_dirac_rend_config(
/* direct/diffuse responses */
if ( flag_config == DIRAC_OPEN )
{
- if ( ( hDirACRend->diffuse_response_function = (float *) malloc( sizeof( float ) * hDirACRend->num_outputs_dir ) ) == NULL )
+ if ( ( hDirAC->diffuse_response_function = (float *) malloc( sizeof( float ) * hDirAC->num_outputs_dir ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
/* reallocate static memory */
- else if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->num_outputs_dir != num_outputs_dir_old )
+ else if ( flag_config == DIRAC_RECONFIGURE && hDirAC->num_outputs_dir != num_outputs_dir_old )
{
- free( hDirACRend->diffuse_response_function );
- hDirACRend->diffuse_response_function = NULL;
- if ( ( hDirACRend->diffuse_response_function = (float *) malloc( sizeof( float ) * hDirACRend->num_outputs_dir ) ) == NULL )
+ free( hDirAC->diffuse_response_function );
+ hDirAC->diffuse_response_function = NULL;
+ if ( ( hDirAC->diffuse_response_function = (float *) malloc( sizeof( float ) * hDirAC->num_outputs_dir ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- if ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) || ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) || ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO ) )
+ if ( ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) || ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) || ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO ) )
{
- initDiffuseResponses( hDirACRend->diffuse_response_function, nchan_out_woLFE, hDirACRend->hOutSetup.output_config,
- hDirACRend->hOutSetup, hDirACRend->hOutSetup.ambisonics_order, st_ivas->ivas_format, &hDirACRend->num_ele_spk_no_diffuse_rendering, st_ivas->transport_config );
+ initDiffuseResponses( hDirAC->diffuse_response_function, nchan_out_woLFE, hDirAC->hOutSetup.output_config,
+ hDirAC->hOutSetup, hDirAC->hOutSetup.ambisonics_order, st_ivas->ivas_format, &hDirAC->num_ele_spk_no_diffuse_rendering, st_ivas->transport_config );
}
else
{
- initDiffuseResponses( hDirACRend->diffuse_response_function, hDirACRend->num_outputs_dir, AUDIO_CONFIG_FOA,
- hDirACRend->hOutSetup, hDirACRend->hOutSetup.ambisonics_order, st_ivas->ivas_format, &hDirACRend->num_ele_spk_no_diffuse_rendering, AUDIO_CONFIG_INVALID );
+ initDiffuseResponses( hDirAC->diffuse_response_function, hDirAC->num_outputs_dir, AUDIO_CONFIG_FOA,
+ hDirAC->hOutSetup, hDirAC->hOutSetup.ambisonics_order, st_ivas->ivas_format, &hDirAC->num_ele_spk_no_diffuse_rendering, AUDIO_CONFIG_INVALID );
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
{
if ( flag_config == DIRAC_OPEN )
{
- if ( ( hDirACRend->hoa_encoder = (float *) malloc( nchan_out_woLFE * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ if ( ( hDirAC->hoa_encoder = (float *) malloc( nchan_out_woLFE * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- else if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->hoa_encoder && ( hDirACRend->num_outputs_diff != num_outputs_diff_old ) )
+ else if ( flag_config == DIRAC_RECONFIGURE && hDirAC->hoa_encoder && ( hDirAC->num_outputs_diff != num_outputs_diff_old ) )
{
- free( hDirACRend->hoa_encoder );
- hDirACRend->hoa_encoder = NULL;
- if ( ( hDirACRend->hoa_encoder = (float *) malloc( nchan_out_woLFE * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ free( hDirAC->hoa_encoder );
+ hDirAC->hoa_encoder = NULL;
+ if ( ( hDirAC->hoa_encoder = (float *) malloc( nchan_out_woLFE * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- set_f( hDirACRend->hoa_encoder, 0.0f, nchan_out_woLFE * hDirACRend->num_outputs_diff );
- compute_hoa_encoder_mtx( ls_azimuth, ls_elevation, hDirACRend->hoa_encoder, hDirACRend->num_outputs_diff, hDirACRend->hOutSetup.ambisonics_order );
+ set_f( hDirAC->hoa_encoder, 0.0f, nchan_out_woLFE * hDirAC->num_outputs_diff );
+ compute_hoa_encoder_mtx( ls_azimuth, ls_elevation, hDirAC->hoa_encoder, hDirAC->num_outputs_diff, hDirAC->hOutSetup.ambisonics_order );
}
else
{
- if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->hoa_encoder )
+ if ( flag_config == DIRAC_RECONFIGURE && hDirAC->hoa_encoder )
{
- free( hDirACRend->hoa_encoder );
+ free( hDirAC->hoa_encoder );
}
- hDirACRend->hoa_encoder = NULL;
+ hDirAC->hoa_encoder = NULL;
}
/* VBAP */
@@ -535,25 +770,32 @@ static ivas_error ivas_dirac_rend_config(
st_ivas->hVBAPdata = NULL;
}
- if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP )
+ if ( hDirAC->panningConf == DIRAC_PANNING_VBAP )
{
if ( flag_config == DIRAC_RECONFIGURE && st_ivas->hVBAPdata != NULL )
{
vbap_free_data( &( st_ivas->hVBAPdata ) );
}
+#ifdef MASA_AND_OBJECTS
+ if ( ( error = vbap_init_data( &( st_ivas->hVBAPdata ), ls_azimuth, ls_elevation, nchan_out_woLFE, st_ivas->ivas_format ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#else
if ( ( error = vbap_init_data( &( st_ivas->hVBAPdata ), ls_azimuth, ls_elevation, nchan_out_woLFE ) ) != IVAS_ERR_OK )
{
return error;
}
+#endif
}
- else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
if ( flag_config == DIRAC_RECONFIGURE && st_ivas->hVBAPdata != NULL )
{
vbap_free_data( &( st_ivas->hVBAPdata ) );
}
- hDirACRend->hoa_decoder = NULL;
+ hDirAC->hoa_decoder = NULL;
}
else if ( flag_config == DIRAC_RECONFIGURE && st_ivas->hVBAPdata != NULL )
{
@@ -563,67 +805,67 @@ static ivas_error ivas_dirac_rend_config(
/* HOA panning/dec */
if ( flag_config == DIRAC_OPEN )
{
- hDirACRend->hoa_decoder = NULL;
- if ( ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 ) || st_ivas->ivas_format == SBA_FORMAT || ( nchan_transport > 2 ) )
+ hDirAC->hoa_decoder = NULL;
+ if ( ( hDirAC->panningConf == DIRAC_PANNING_HOA3 ) || st_ivas->ivas_format == SBA_FORMAT || ( nchan_transport > 2 ) )
{
- if ( hDirACRend->hOutSetup.is_loudspeaker_setup )
+ if ( hDirAC->hOutSetup.is_loudspeaker_setup )
{
if ( st_ivas->hoa_dec_mtx != NULL )
{
free( st_ivas->hoa_dec_mtx );
st_ivas->hoa_dec_mtx = NULL;
}
- if ( ( error = ivas_sba_get_hoa_dec_matrix( hDirACRend->hOutSetup, &st_ivas->hoa_dec_mtx, hDirACRend->hOutSetup.ambisonics_order ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_sba_get_hoa_dec_matrix( hDirAC->hOutSetup, &st_ivas->hoa_dec_mtx, hDirAC->hOutSetup.ambisonics_order ) ) != IVAS_ERR_OK )
{
return error;
}
- hDirACRend->hoa_decoder = st_ivas->hoa_dec_mtx;
+ hDirAC->hoa_decoder = st_ivas->hoa_dec_mtx;
}
}
}
/* decorrelation */
- proto_signal_decorr_on_old = ( flag_config == DIRAC_RECONFIGURE ) ? hDirACRend->proto_signal_decorr_on : 0;
- hDirACRend->proto_signal_decorr_on = 1;
- if ( ( nchan_transport > 2 ) && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) )
+ proto_signal_decorr_on_old = ( flag_config == DIRAC_RECONFIGURE ) ? hDirAC->proto_signal_decorr_on : 0;
+ hDirAC->proto_signal_decorr_on = 1;
+ if ( ( nchan_transport > 2 ) && ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS ) )
{
/*switch off decorrelation for 4 transport channels*/
- hDirACRend->proto_signal_decorr_on = 0;
+ hDirAC->proto_signal_decorr_on = 0;
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
- hDirACRend->proto_signal_decorr_on = 0;
+ hDirAC->proto_signal_decorr_on = 0;
}
- if ( ( flag_config == DIRAC_OPEN && hDirACRend->proto_signal_decorr_on ) || ( flag_config == DIRAC_RECONFIGURE && ( hDirACRend->proto_signal_decorr_on && !proto_signal_decorr_on_old ) ) )
+ if ( ( flag_config == DIRAC_OPEN && hDirAC->proto_signal_decorr_on ) || ( flag_config == DIRAC_RECONFIGURE && ( hDirAC->proto_signal_decorr_on && !proto_signal_decorr_on_old ) ) )
{
- if ( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ),
- &( hDirACRend->h_freq_domain_decorr_ap_state ),
- hSpatParamRendCom->num_freq_bands,
- hDirACRend->num_outputs_diff,
- hDirACRend->num_protos_diff,
- hDirACRend->synthesisConf,
- hDirACRend->frequency_axis,
+ if ( ( error = ivas_dirac_dec_decorr_open( &( hDirAC->h_freq_domain_decorr_ap_params ),
+ &( hDirAC->h_freq_domain_decorr_ap_state ),
+ hDirAC->num_freq_bands,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff,
+ hDirAC->synthesisConf,
+ hDirAC->frequency_axis,
nchan_transport > 2 ? 4 : nchan_transport,
output_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
}
- else if ( flag_config == DIRAC_RECONFIGURE && ( !hDirACRend->proto_signal_decorr_on && proto_signal_decorr_on_old ) )
+ else if ( flag_config == DIRAC_RECONFIGURE && ( !hDirAC->proto_signal_decorr_on && proto_signal_decorr_on_old ) )
{
- ivas_dirac_dec_decorr_close( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state );
+ ivas_dirac_dec_decorr_close( &hDirAC->h_freq_domain_decorr_ap_params, &hDirAC->h_freq_domain_decorr_ap_state );
}
- else if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->proto_signal_decorr_on && proto_signal_decorr_on_old )
+ else if ( flag_config == DIRAC_RECONFIGURE && hDirAC->proto_signal_decorr_on && proto_signal_decorr_on_old )
{
- if ( nchan_transport != nchan_transport_old || hDirACRend->num_outputs_diff != num_outputs_diff_old || flag_config_inp == DIRAC_RECONFIGURE_MODE )
+ if ( nchan_transport != nchan_transport_old || hDirAC->num_outputs_diff != num_outputs_diff_old || flag_config_inp == DIRAC_RECONFIGURE_MODE )
{
/* close and reopen the decorrelator */
- ivas_dirac_dec_decorr_close( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state );
+ ivas_dirac_dec_decorr_close( &hDirAC->h_freq_domain_decorr_ap_params, &hDirAC->h_freq_domain_decorr_ap_state );
- if ( ( error = ivas_dirac_dec_decorr_open( &( hDirACRend->h_freq_domain_decorr_ap_params ), &( hDirACRend->h_freq_domain_decorr_ap_state ), hSpatParamRendCom->num_freq_bands, hDirACRend->num_outputs_diff,
- hDirACRend->num_protos_diff, hDirACRend->synthesisConf, hDirACRend->frequency_axis, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_decorr_open( &( hDirAC->h_freq_domain_decorr_ap_params ), &( hDirAC->h_freq_domain_decorr_ap_state ), hDirAC->num_freq_bands, hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff, hDirAC->synthesisConf, hDirAC->frequency_axis, nchan_transport > 2 ? 4 : nchan_transport, output_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -633,54 +875,54 @@ static ivas_error ivas_dirac_rend_config(
/* output synthesis */
if ( flag_config == DIRAC_OPEN )
{
- if ( ( ivas_dirac_dec_output_synthesis_open( hSpatParamRendCom, hDirACRend, st_ivas->renderer_type, nchan_transport, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK )
+ if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK )
{
return error;
}
- hDirACRend->h_output_synthesis_psd_params.use_onset_filters = hDirACRend->proto_signal_decorr_on;
+ hDirAC->h_output_synthesis_psd_params.use_onset_filters = hDirAC->proto_signal_decorr_on;
}
- else if ( ( flag_config == DIRAC_RECONFIGURE ) && ( ( nchan_transport != nchan_transport_old ) || ( hDirACRend->num_outputs_diff != num_outputs_diff_old ) ) )
+ else if ( ( flag_config == DIRAC_RECONFIGURE ) && ( ( nchan_transport != nchan_transport_old ) || ( hDirAC->num_outputs_diff != num_outputs_diff_old ) ) )
{
- ivas_dirac_dec_output_synthesis_close( hDirACRend );
+ ivas_dirac_dec_output_synthesis_close( hDirAC );
- if ( ( ivas_dirac_dec_output_synthesis_open( hSpatParamRendCom, hDirACRend, st_ivas->renderer_type, nchan_transport, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK )
+ if ( ( ivas_dirac_dec_output_synthesis_open( hDirAC, st_ivas->renderer_type, nchan_transport, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK )
{
return error;
}
- hDirACRend->h_output_synthesis_psd_params.use_onset_filters = hDirACRend->proto_signal_decorr_on;
+ hDirAC->h_output_synthesis_psd_params.use_onset_filters = hDirAC->proto_signal_decorr_on;
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- hDirACRend->h_output_synthesis_psd_params.use_onset_filters = 0;
+ hDirAC->h_output_synthesis_psd_params.use_onset_filters = 0;
}
/*-----------------------------------------------------------------*
* memory allocation
*-----------------------------------------------------------------*/
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->proto_frame_f )
+ if ( flag_config == DIRAC_RECONFIGURE && hDirAC->proto_frame_f )
{
- free( hDirACRend->proto_frame_f );
+ free( hDirAC->proto_frame_f );
}
- hDirACRend->proto_frame_f = NULL;
+ hDirAC->proto_frame_f = NULL;
}
else
{
- if ( flag_config == DIRAC_OPEN || ( flag_config == DIRAC_RECONFIGURE && hDirACRend->proto_frame_f == NULL ) )
+ if ( flag_config == DIRAC_OPEN || ( flag_config == DIRAC_RECONFIGURE && hDirAC->proto_frame_f == NULL ) )
{
- if ( ( hDirACRend->proto_frame_f = (float *) malloc( sizeof( float ) * 2 * hDirACRend->num_protos_diff * hSpatParamRendCom->num_freq_bands ) ) == NULL )
+ if ( ( hDirAC->proto_frame_f = (float *) malloc( sizeof( float ) * 2 * hDirAC->num_protos_diff * hDirAC->num_freq_bands ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- else if ( flag_config == DIRAC_RECONFIGURE && ( hDirACRend->num_protos_diff != num_protos_diff_old ) )
+ else if ( flag_config == DIRAC_RECONFIGURE && ( hDirAC->num_protos_diff != num_protos_diff_old ) )
{
- proto_frame_f_old = hDirACRend->proto_frame_f;
+ proto_frame_f_old = hDirAC->proto_frame_f;
free( proto_frame_f_old );
- if ( ( hDirACRend->proto_frame_f = (float *) malloc( sizeof( float ) * 2 * hDirACRend->num_protos_diff * hSpatParamRendCom->num_freq_bands ) ) == NULL )
+ if ( ( hDirAC->proto_frame_f = (float *) malloc( sizeof( float ) * 2 * hDirAC->num_protos_diff * hDirAC->num_freq_bands ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
@@ -690,31 +932,31 @@ static ivas_error ivas_dirac_rend_config(
if ( flag_config == DIRAC_OPEN )
{
- hDirACRend->buffer_energy = NULL;
+ hDirAC->buffer_energy = NULL;
}
if ( ( flag_config == DIRAC_OPEN && hDirAC->hConfig->dec_param_estim == TRUE ) || ( flag_config == DIRAC_RECONFIGURE && ( hDirAC->hConfig->dec_param_estim == TRUE && dec_param_estim_old == FALSE ) ) )
{
- hDirACRend->index_buffer_intensity = 0;
+ hDirAC->index_buffer_intensity = 0;
for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
{
for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
{
- if ( ( hDirACRend->buffer_intensity_real[i][j] = (float *) malloc( CLDFB_NO_CHANNELS_MAX * sizeof( float ) ) ) == NULL )
+ if ( ( hDirAC->buffer_intensity_real[i][j] = (float *) malloc( CLDFB_NO_CHANNELS_MAX * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- set_f( hDirACRend->buffer_intensity_real[i][j], 0.0f, CLDFB_NO_CHANNELS_MAX );
+ set_f( hDirAC->buffer_intensity_real[i][j], 0.0f, CLDFB_NO_CHANNELS_MAX );
}
}
- if ( hDirACRend->buffer_energy == NULL )
+ if ( hDirAC->buffer_energy == NULL )
{
- if ( ( hDirACRend->buffer_energy = (float *) malloc( DIRAC_NO_COL_AVG_DIFF * CLDFB_NO_CHANNELS_MAX * sizeof( float ) ) ) == NULL )
+ if ( ( hDirAC->buffer_energy = (float *) malloc( DIRAC_NO_COL_AVG_DIFF * CLDFB_NO_CHANNELS_MAX * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
}
- set_f( hDirACRend->buffer_energy, 0.0f, DIRAC_NO_COL_AVG_DIFF * CLDFB_NO_CHANNELS_MAX );
+ set_f( hDirAC->buffer_energy, 0.0f, DIRAC_NO_COL_AVG_DIFF * CLDFB_NO_CHANNELS_MAX );
}
else if ( ( flag_config == DIRAC_OPEN && hDirAC->hConfig->dec_param_estim == FALSE ) || ( flag_config == DIRAC_RECONFIGURE && ( hDirAC->hConfig->dec_param_estim == FALSE && dec_param_estim_old == TRUE ) ) )
{
@@ -722,228 +964,132 @@ static ivas_error ivas_dirac_rend_config(
{
for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
{
- if ( flag_config == DIRAC_RECONFIGURE && hDirACRend->buffer_intensity_real[i][j] )
+ if ( flag_config == DIRAC_RECONFIGURE && hDirAC->buffer_intensity_real[i][j] )
{
- free( hDirACRend->buffer_intensity_real[i][j] );
+ free( hDirAC->buffer_intensity_real[i][j] );
}
- hDirACRend->buffer_intensity_real[i][j] = NULL;
+ hDirAC->buffer_intensity_real[i][j] = NULL;
}
}
- if ( hDirACRend->buffer_energy != NULL )
+ if ( hDirAC->buffer_energy != NULL )
{
- free( hDirACRend->buffer_energy );
- hDirACRend->buffer_energy = NULL;
+ free( hDirAC->buffer_energy );
+ hDirAC->buffer_energy = NULL;
}
}
/* output synthesis */
- ivas_dirac_dec_output_synthesis_init( hSpatParamRendCom, hDirACRend, nchan_out_woLFE, hodirac_flag );
+ ivas_dirac_dec_output_synthesis_init( hDirAC, nchan_out_woLFE, hodirac_flag );
/* Allocate stack memory */
if ( flag_config != DIRAC_OPEN )
{
- ivas_dirac_free_mem( &( hDirACRend->stack_mem ) );
+ ivas_dirac_free_mem( &( hDirAC->stack_mem ) );
}
- if ( ( error = ivas_dirac_alloc_mem( hDirACRend, st_ivas->renderer_type, hSpatParamRendCom->num_freq_bands, &( hDirACRend->stack_mem ), hodirac_flag ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_alloc_mem( hDirAC, st_ivas->renderer_type, &( hDirAC->stack_mem ), hodirac_flag ) ) != IVAS_ERR_OK )
{
return error;
}
+ mvs2s( DirAC_block_grouping, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
+
if ( flag_config == DIRAC_OPEN )
{
- st_ivas->hDirACRend = hDirACRend;
- }
-
- return error;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_dec_config()
- *
- * Open or reconfigure decoder DirAC/MASA handle
- *-------------------------------------------------------------------------*/
+ hDirAC->dirac_md_buffer_length = 0;
+ hDirAC->dirac_bs_md_write_idx = 0;
+ hDirAC->dirac_read_idx = 0;
+ hDirAC->spar_to_dirac_write_idx = 0;
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA )
+ {
+ hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
-ivas_error ivas_dirac_dec_config(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const DIRAC_CONFIG_FLAG flag_config_inp /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
-)
-{
- ivas_error error;
- int32_t output_Fs;
- int16_t hodirac_flag;
- int16_t sparfoa_flag;
- DIRAC_CONFIG_FLAG dec_config_flag;
- DIRAC_CONFIG_FLAG rend_config_flag;
- DIRAC_CONFIG_FLAG common_rend_config_flag;
- int16_t need_dirac_rend;
- int16_t need_parambin;
- int16_t dec_param_estim_old;
- int16_t dec_param_estim_new;
+ set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
+ for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
+ {
+ hDirAC->render_to_md_map[map_idx] = map_idx;
+ }
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT )
+#else
+ else if ( st_ivas->ivas_format == MASA_FORMAT )
+#endif
+ {
+ hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR;
+ hDirAC->dirac_bs_md_write_idx = DELAY_MASA_PARAM_DEC_SFR;
- error = IVAS_ERR_OK;
+ set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
+ for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
+ {
+ hDirAC->render_to_md_map[map_idx] = map_idx;
+ }
+ }
+ else
+ {
+ int16_t num_slots_in_subfr;
+ num_slots_in_subfr = hDirAC->hConfig->dec_param_estim ? CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES : 1;
+ hDirAC->dirac_md_buffer_length = ( MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_DIRAC_PARAM_DEC_SFR );
+ hDirAC->dirac_bs_md_write_idx = DELAY_DIRAC_PARAM_DEC_SFR;
+ hDirAC->spar_to_dirac_write_idx = DELAY_DIRAC_PARAM_DEC_SFR;
+ hDirAC->dirac_read_idx = 0;
+ hDirAC->dirac_estimator_idx = 0;
+
+ set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
+ for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS * num_slots_in_subfr; map_idx++ )
+ {
+ hDirAC->render_to_md_map[map_idx] = hDirAC->dirac_read_idx + map_idx / num_slots_in_subfr;
+ }
+ }
- /* Solve and setup flags for inits */
- dec_config_flag = ( flag_config_inp == DIRAC_RECONFIGURE_MODE ) ? DIRAC_RECONFIGURE : flag_config_inp;
+ if ( ( error = ivas_dirac_allocate_parameters( hDirAC, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
- output_Fs = st_ivas->hDecoderConfig->output_Fs;
- hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order );
- dec_param_estim_old = ( dec_config_flag == DIRAC_RECONFIGURE ) ? st_ivas->hDirAC->hConfig->dec_param_estim : FALSE;
-
-
- sparfoa_flag = 0;
- if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA && st_ivas->ivas_format == SBA_FORMAT && !hodirac_flag )
- {
- sparfoa_flag = 1;
- }
-
- if ( ( error = ivas_dirac_dec_config_internal( st_ivas, dec_config_flag ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- /* This is required for parambin */
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
- {
- st_ivas->hDirAC->hConfig->dec_param_estim = FALSE;
- }
-
- dec_param_estim_new = st_ivas->hDirAC->hConfig->dec_param_estim;
-
- /* Setup renderers and meta */
- /* First, free everything if in reconfig and not the active renderer */
- need_parambin = 0;
- switch ( st_ivas->renderer_type )
- {
- case RENDERER_BINAURAL_PARAMETRIC:
- case RENDERER_BINAURAL_PARAMETRIC_ROOM:
- case RENDERER_STEREO_PARAMETRIC:
- need_parambin = 1;
- break;
- default:
- need_parambin = 0;
- }
-
- if ( !need_parambin )
- {
- ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
- }
-
- need_dirac_rend = 0;
- switch ( st_ivas->renderer_type )
- {
- case RENDERER_DIRAC:
- case RENDERER_BINAURAL_FASTCONV:
- case RENDERER_BINAURAL_FASTCONV_ROOM:
- case RENDERER_SBA_LINEAR_ENC:
- case RENDERER_SBA_LINEAR_DEC:
- need_dirac_rend = 1;
- break;
- default:
- need_dirac_rend = 0;
- }
-
- if ( !need_dirac_rend )
- {
- ivas_dirac_rend_close( &st_ivas->hDirACRend );
- }
-
- if ( !sparfoa_flag )
- {
- common_rend_config_flag = st_ivas->hSpatParamRendCom == NULL ? DIRAC_OPEN : flag_config_inp;
- if ( ( error = ivas_spat_hSpatParamRendCom_config( &st_ivas->hSpatParamRendCom, common_rend_config_flag, dec_param_estim_new,
- st_ivas->ivas_format, st_ivas->mc_mode, output_Fs, hodirac_flag ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- if ( need_dirac_rend )
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ) )
+#else
+ if ( st_ivas->ivas_format == MASA_FORMAT || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_256k ) )
+#endif
{
- rend_config_flag = st_ivas->hDirACRend == NULL ? DIRAC_OPEN : flag_config_inp;
- if ( ( error = ivas_dirac_rend_config( st_ivas, rend_config_flag, dec_param_estim_old ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_allocate_parameters( hDirAC, 2 ) ) != IVAS_ERR_OK )
{
return error;
}
}
-
- if ( need_parambin )
+ else
{
- if ( st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
- {
- if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
-
- if ( st_ivas->hDiracDecBin == NULL )
- {
- if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else
- {
- /* This is required to keep BE in rate switching. This probably means that 1TC and 2TC MASA perform differently. */
- if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params != NULL && !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nSCE > 0 ) )
- {
- ivas_dirac_dec_decorr_close( &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state );
- }
-
- if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ hDirAC->azimuth2 = NULL;
+ hDirAC->elevation2 = NULL;
+ hDirAC->energy_ratio2 = NULL;
+ hDirAC->spreadCoherence2 = NULL;
+ }
- if ( !st_ivas->hDiracDecBin->useTdDecorr )
- {
- if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params == NULL )
- {
- float frequency_axis[CLDFB_NO_CHANNELS_MAX];
- ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands );
- if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ),
- &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ),
- st_ivas->hSpatParamRendCom->num_freq_bands,
- BINAURAL_CHANNELS,
- BINAURAL_CHANNELS,
- DIRAC_SYNTHESIS_PSD_LS,
- frequency_axis,
- BINAURAL_CHANNELS,
- st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- }
+ hDirAC->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */
- st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
- }
- }
+ hDirAC->dithering_seed = DIRAC_DITH_SEED;
+ st_ivas->hDirAC = hDirAC;
}
- /* Allocate transport channel buffers for SBA format when in JBM */
- if ( dec_config_flag == DIRAC_OPEN )
+ /* allocate transport channels*/
+ if ( flag_config == DIRAC_OPEN )
{
if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL )
{
if ( st_ivas->ivas_format == SBA_FORMAT )
{
int16_t nchan_to_allocate;
- int16_t nchan_transport;
-
- nchan_transport = st_ivas->nchan_transport;
nchan_to_allocate = nchan_transport;
- if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
+ if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
{
nchan_to_allocate++; /* we need a channel for the CNG in this case*/
}
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
nchan_to_allocate = 2 * BINAURAL_CHANNELS;
}
- if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, st_ivas->hSpatParamRendCom->slot_size ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, hDirAC->slot_size ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -962,8 +1108,10 @@ ivas_error ivas_dirac_dec_config(
*------------------------------------------------------------------------*/
void ivas_dirac_dec_close(
- DIRAC_DEC_HANDLE *hDirAC_out )
+ DIRAC_DEC_HANDLE *hDirAC_out /* i/o: decoder DirAC handle */
+)
{
+ int16_t i, j;
DIRAC_DEC_HANDLE hDirAC;
if ( hDirAC_out == NULL || *hDirAC_out == NULL )
@@ -980,6 +1128,86 @@ void ivas_dirac_dec_close(
hDirAC->hConfig = NULL;
}
+ /* close Output synthesis sub-module */
+ ivas_dirac_dec_output_synthesis_close( hDirAC );
+
+ /* close Decorrelator sub-module */
+ if ( hDirAC->proto_signal_decorr_on )
+ {
+ ivas_dirac_dec_decorr_close( &hDirAC->h_freq_domain_decorr_ap_params, &hDirAC->h_freq_domain_decorr_ap_state );
+ }
+
+ /* Params */
+
+ /* free frequency axis buffer */
+ if ( hDirAC->frequency_axis != NULL )
+ {
+ free( hDirAC->frequency_axis );
+ hDirAC->frequency_axis = NULL;
+ }
+
+ if ( hDirAC->diffuse_response_function != NULL )
+ {
+ free( hDirAC->diffuse_response_function );
+ hDirAC->diffuse_response_function = NULL;
+ }
+
+ if ( hDirAC->hoa_encoder != NULL )
+ {
+ free( hDirAC->hoa_encoder );
+ hDirAC->hoa_encoder = NULL;
+ }
+
+ /* prototype indexing */
+ if ( hDirAC->proto_index_dir != NULL )
+ {
+ free( hDirAC->proto_index_dir );
+ hDirAC->proto_index_dir = NULL;
+ }
+
+ if ( hDirAC->proto_index_diff != NULL )
+ {
+ free( hDirAC->proto_index_diff );
+ hDirAC->proto_index_dir = NULL;
+ }
+
+ /* States */
+
+ /* free prototype signal buffers */
+ if ( hDirAC->proto_frame_f != NULL )
+ {
+ free( hDirAC->proto_frame_f );
+ hDirAC->proto_frame_f = NULL;
+ }
+
+ for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
+ {
+ for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
+ {
+ if ( hDirAC->buffer_intensity_real[i][j] != NULL )
+ {
+ free( hDirAC->buffer_intensity_real[i][j] );
+ hDirAC->buffer_intensity_real[i][j] = NULL;
+ }
+ }
+ }
+ if ( hDirAC->buffer_energy != NULL )
+ {
+ free( hDirAC->buffer_energy );
+ hDirAC->buffer_energy = NULL;
+ }
+
+ ivas_dirac_deallocate_parameters( hDirAC, 1 );
+ ivas_dirac_deallocate_parameters( hDirAC, 2 );
+
+ if ( hDirAC->masa_stereo_type_detect != NULL )
+ {
+ free( hDirAC->masa_stereo_type_detect );
+ hDirAC->masa_stereo_type_detect = NULL;
+ }
+
+ ivas_dirac_free_mem( &( hDirAC->stack_mem ) );
+
free( *hDirAC_out );
*hDirAC_out = NULL;
@@ -988,557 +1216,2019 @@ void ivas_dirac_dec_close(
/*-------------------------------------------------------------------------
- * ivas_dirac_dec_read_BS()
+ * ivas_dirac_deallocate_parameters()
*
- * Read DirAC parameters from the bitstream
- *------------------------------------------------------------------------*/
+ * Deallocate DirAC parameters
+ *-------------------------------------------------------------------------*/
-void ivas_dirac_dec_read_BS(
- const int32_t ivas_total_brate, /* i : IVAS total bitrate */
- Decoder_State *st, /* i/o: decoder state structure */
- DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial rendering data handle */
- IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata */
- int16_t *nb_bits, /* o : number of bits read */
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */
+void ivas_dirac_deallocate_parameters(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
+ const int16_t params_flag /* i : set of parameters flag */
)
{
- int16_t i, j, b, dir, orig_dirac_bands;
- int16_t next_bit_pos_orig;
- *nb_bits = 0;
- if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 )
- {
- next_bit_pos_orig = st->next_bit_pos;
- st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 );
-
- /* 1 bit flag for signaling metadata to read */
- b = st->bit_stream[( st->next_bit_pos )--];
- ( *nb_bits )++;
+ int16_t i;
- if ( b == 1 ) /* WB 4TCs condition, no other metadata to read*/
+ if ( params_flag == 1 )
+ {
+ if ( hDirAC->azimuth != NULL )
{
- orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
+ {
+ if ( hDirAC->azimuth[i] != NULL )
+ {
+ free( hDirAC->azimuth[i] );
+ hDirAC->azimuth[i] = NULL;
+ }
+ }
- hQMetaData->sba_inactive_mode = 1;
+ free( hDirAC->azimuth );
+ hDirAC->azimuth = NULL;
+ }
- /* if we start with a SID frame, we need to init the azi/ele arrays.*/
- if ( st->ini_frame == 0 )
+ if ( hDirAC->elevation != NULL )
+ {
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
+ if ( hDirAC->elevation[i] != NULL )
{
- set_zero( hQMetaData->q_direction[0].band_data[b].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
- set_zero( hQMetaData->q_direction[0].band_data[b].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
+ free( hDirAC->elevation[i] );
+ hDirAC->elevation[i] = NULL;
}
}
- *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT );
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ free( hDirAC->elevation );
+ hDirAC->elevation = NULL;
+ }
+
+ if ( hDirAC->energy_ratio1 != NULL )
+ {
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
+ if ( hDirAC->energy_ratio1[i] != NULL )
+ {
+ free( hDirAC->energy_ratio1[i] );
+ hDirAC->energy_ratio1[i] = NULL;
+ }
}
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ free( hDirAC->energy_ratio1 );
+ hDirAC->energy_ratio1 = NULL;
+ }
+
+ if ( hDirAC->diffuseness_vector != NULL )
+ {
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- for ( j = orig_dirac_bands - 2; j >= 0; j-- )
+ if ( hDirAC->diffuseness_vector[i] != NULL )
{
- hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
- hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
- hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
+ free( hDirAC->diffuseness_vector[i] );
+ hDirAC->diffuseness_vector[i] = NULL;
}
}
- hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
+ free( hDirAC->diffuseness_vector );
+ hDirAC->diffuseness_vector = NULL;
}
- else
+
+ if ( hDirAC->spreadCoherence != NULL )
{
- hQMetaData->sba_inactive_mode = 0;
- hQMetaData->is_masa_ivas_format = 0;
- if ( hQMetaData->useLowerRes )
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- hQMetaData->q_direction[0].cfg.nblocks = 1;
+ if ( hDirAC->spreadCoherence[i] != NULL )
+ {
+ free( hDirAC->spreadCoherence[i] );
+ hDirAC->spreadCoherence[i] = NULL;
+ }
}
- else
+ free( hDirAC->spreadCoherence );
+ hDirAC->spreadCoherence = NULL;
+ }
+
+ if ( hDirAC->surroundingCoherence != NULL )
+ {
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- hQMetaData->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
+ if ( hDirAC->surroundingCoherence[i] != NULL )
+ {
+ free( hDirAC->surroundingCoherence[i] );
+ hDirAC->surroundingCoherence[i] = NULL;
+ }
}
-
- *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), hodirac_flag );
+ free( hDirAC->surroundingCoherence );
+ hDirAC->surroundingCoherence = NULL;
}
-
-#ifdef DEBUGGING
- assert( *nb_bits >= 0 );
-#endif
-
- st->next_bit_pos = next_bit_pos_orig;
}
- else if ( !st->bfi && ivas_total_brate == IVAS_SID_5k2 )
+ else if ( params_flag == 2 )
{
- next_bit_pos_orig = st->next_bit_pos;
-
- /* subtract mode signaling bits, since bitstream was moved after mode reading */
- st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS );
-#ifndef SBA_MODE_CLEANUP_2
- /* 1 bit flag for SPAR/DirAC, already read in read format function */
-#else
- /* 1 bit flag for signaling metadata to read */
-#endif
- b = st->bit_stream[( st->next_bit_pos )--];
- ( *nb_bits )++;
- hQMetaData->sba_inactive_mode = 1;
- orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
-
- /* if we start with a SID frame, we need to init the azi/ele arrays.*/
- if ( st->ini_frame == 0 )
+ if ( hDirAC->azimuth2 != NULL )
{
- for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- for ( b = 0; b < hQMetaData->q_direction[dir].cfg.nbands; b++ )
+ if ( hDirAC->azimuth2[i] != NULL )
{
- set_zero( hQMetaData->q_direction[dir].band_data[b].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
- set_zero( hQMetaData->q_direction[dir].band_data[b].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
+ free( hDirAC->azimuth2[i] );
+ hDirAC->azimuth2[i] = NULL;
}
}
+ free( hDirAC->azimuth2 );
+ hDirAC->azimuth2 = NULL;
}
- *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT );
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ if ( hDirAC->elevation2 != NULL )
{
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
- hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
+ {
+ if ( hDirAC->elevation2[i] != NULL )
+ {
+ free( hDirAC->elevation2[i] );
+ hDirAC->elevation2[i] = NULL;
+ }
+ }
+ free( hDirAC->elevation2 );
+ hDirAC->elevation2 = NULL;
}
- for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+
+ if ( hDirAC->energy_ratio2 != NULL )
{
- for ( j = orig_dirac_bands - 2; j >= 0; j-- )
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
{
- hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
- hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
- hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
+ if ( hDirAC->energy_ratio2[i] != NULL )
+ {
+ free( hDirAC->energy_ratio2[i] );
+ hDirAC->energy_ratio2[i] = NULL;
+ }
}
+ free( hDirAC->energy_ratio2 );
+ hDirAC->energy_ratio2 = NULL;
}
- hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
-
- st->next_bit_pos = next_bit_pos_orig;
- }
-
- if ( hDirAC != NULL && hSpatParamRendCom != NULL )
- {
- ivas_qmetadata_to_dirac( hQMetaData, hDirAC, NULL, hSpatParamRendCom, ivas_total_brate, SBA_FORMAT, hodirac_flag, dirac_to_spar_md_bands );
+ if ( hDirAC->spreadCoherence2 != NULL )
+ {
+ for ( i = 0; i < hDirAC->dirac_md_buffer_length; i++ )
+ {
+ if ( hDirAC->spreadCoherence2[i] != NULL )
+ {
+ free( hDirAC->spreadCoherence2[i] );
+ hDirAC->spreadCoherence2[i] = NULL;
+ }
+ }
+ free( hDirAC->spreadCoherence2 );
+ hDirAC->spreadCoherence2 = NULL;
+ }
}
return;
}
-/*-----------------------------------------------------------------------*
- * ivas_qmetadata_to_dirac()
+/*-------------------------------------------------------------------------
+ * ivas_dirac_alloc_mem()
*
- * Copy qmetedata to DirAC parameters for rendering
- *-----------------------------------------------------------------------*/
+ * Allocate stack memory for DirAC renderer
+ *------------------------------------------------------------------------*/
-void ivas_qmetadata_to_dirac(
- const IVAS_QMETADATA_HANDLE hQMetaData, /* i : frame of MASA q_metadata */
- DIRAC_DEC_HANDLE hDirAC, /* i : DirAC decoder structure */
- MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- const int32_t ivas_total_brate, /* i : IVAS total bitrate */
- const IVAS_FORMAT ivas_format, /* i : IVAS format */
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */
-)
+static ivas_error ivas_dirac_alloc_mem(
+ DIRAC_DEC_HANDLE hDirAC,
+ const RENDERER_TYPE renderer_type,
+ DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem,
+ const int16_t hodirac_flag )
{
- int16_t block, band;
- int16_t *seed_ptr;
- int16_t band_start, band_end, diff_idx;
- float diffuseness;
- int16_t b, ele, azi;
- float azimuth, elevation;
- IVAS_QDIRECTION *q_direction;
- int16_t *band_mapping;
- int16_t *band_grouping;
- int16_t start_band;
- int16_t nbands = 0;
- int16_t nblocks = 0;
- int16_t qBand_idx;
- int16_t idx_sec = 0;
- int16_t no_secs = 1;
+ int16_t num_freq_bands, num_freq_bands_diff, size;
+ int16_t size_ho;
+ int16_t size_pf;
+ int16_t num_outputs_dir, num_outputs_diff;
+ int16_t num_protos_dir;
- q_direction = &( hQMetaData->q_direction[0] );
- hSpatParamRendCom->numSimultaneousDirections = hQMetaData->no_directions;
+ num_protos_dir = hDirAC->num_protos_dir;
- if ( hMasa != NULL && ivas_total_brate > IVAS_SID_5k2 )
- {
- int16_t meta_write_index;
- band_mapping = hMasa->data.band_mapping;
-
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
- {
- meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + block ) % hSpatParamRendCom->dirac_md_buffer_length;
+ num_freq_bands = hDirAC->num_freq_bands;
+ num_freq_bands_diff = hDirAC->h_output_synthesis_psd_params.max_band_decorr;
- for ( band = 0; band < hMasa->config.numCodingBands; ++band )
- {
- for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
- {
- hSpatParamRendCom->azimuth[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block];
- hSpatParamRendCom->elevation[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block];
- hSpatParamRendCom->energy_ratio1[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block];
- hSpatParamRendCom->diffuseness_vector[meta_write_index][b] = 1.0f - q_direction->band_data[band].energy_ratio[block];
+ num_outputs_dir = hDirAC->num_outputs_dir;
+ num_outputs_diff = hDirAC->num_outputs_diff;
- if ( q_direction->coherence_band_data != NULL )
- {
- hSpatParamRendCom->spreadCoherence[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f;
- }
- else
- {
- hSpatParamRendCom->spreadCoherence[meta_write_index][b] = 0.0f;
- }
+ size = num_freq_bands * num_outputs_dir;
+ if ( hodirac_flag )
+ {
+ size_ho = size * DIRAC_HO_NUMSECTORS;
+ size_pf = num_freq_bands * DIRAC_HO_NUMSECTORS;
+ }
+ else
+ {
+ size_ho = size;
+ size_pf = num_freq_bands;
+ }
- if ( hQMetaData->surcoh_band_data != NULL )
- {
- hSpatParamRendCom->surroundingCoherence[meta_write_index][b] = hQMetaData->surcoh_band_data[band].surround_coherence[block] / 255.0f;
- }
- else
- {
- hSpatParamRendCom->surroundingCoherence[meta_write_index][b] = 0.0f;
- }
- }
- }
+ /* PSD related buffers */
+ hDirAC_mem->cy_auto_dir_smooth = NULL;
+ hDirAC_mem->proto_power_smooth = NULL;
+ hDirAC_mem->proto_power_diff_smooth = NULL;
+ hDirAC_mem->direct_responses_square = NULL;
+ hDirAC_mem->frame_dec_f = NULL;
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ if ( ( hDirAC_mem->cy_auto_dir_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
+ set_zero( hDirAC_mem->cy_auto_dir_smooth, size );
- if ( hQMetaData->no_directions == 2 )
+ if ( ( hDirAC_mem->proto_power_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
{
- q_direction = &( hQMetaData->q_direction[1] );
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
- {
- meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + block ) % hSpatParamRendCom->dirac_md_buffer_length;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->proto_power_smooth, size );
- for ( band = 0; band < hMasa->config.numCodingBands; ++band )
- {
- for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
- {
- hSpatParamRendCom->azimuth2[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block];
- hSpatParamRendCom->elevation2[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block];
- hSpatParamRendCom->energy_ratio2[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block];
- hSpatParamRendCom->diffuseness_vector[meta_write_index][b] -= q_direction->band_data[band].energy_ratio[block];
+ if ( ( hDirAC_mem->proto_power_diff_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->proto_power_diff_smooth, size );
- if ( q_direction->coherence_band_data != NULL )
- {
- hSpatParamRendCom->spreadCoherence2[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f;
- }
- else
- {
- hSpatParamRendCom->spreadCoherence2[meta_write_index][b] = 0.0f;
- }
- }
- }
- }
+ if ( ( hDirAC_mem->direct_responses_square = (float *) malloc( sizeof( float ) * size ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
- else if ( hSpatParamRendCom->azimuth2 != NULL && hSpatParamRendCom->elevation2 != NULL && hSpatParamRendCom->energy_ratio2 != NULL && hSpatParamRendCom->spreadCoherence2 != NULL )
+ set_zero( hDirAC_mem->direct_responses_square, size );
+ if ( hDirAC->proto_signal_decorr_on && ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC ) )
{
- /* zero out old dir2 data */
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
+ if ( ( hDirAC_mem->frame_dec_f = (float *) malloc( sizeof( float ) * 2 * num_outputs_diff * num_freq_bands ) ) == NULL )
{
- meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + block ) % hSpatParamRendCom->dirac_md_buffer_length;
- set_s( hSpatParamRendCom->azimuth2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands );
- set_s( hSpatParamRendCom->elevation2[meta_write_index], 0, hSpatParamRendCom->num_freq_bands );
- set_zero( hSpatParamRendCom->energy_ratio2[meta_write_index], hSpatParamRendCom->num_freq_bands );
- set_zero( hSpatParamRendCom->spreadCoherence2[meta_write_index], hSpatParamRendCom->num_freq_bands );
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
}
}
- else /* SBA mode/SID/Zero frame*/
+ hDirAC->h_output_synthesis_psd_state.proto_power_smooth = hDirAC_mem->proto_power_smooth;
+ hDirAC->h_output_synthesis_psd_state.proto_power_diff_smooth = hDirAC_mem->proto_power_diff_smooth;
+ hDirAC->h_output_synthesis_psd_state.cy_auto_dir_smooth = hDirAC_mem->cy_auto_dir_smooth;
+ hDirAC->h_output_synthesis_psd_state.direct_responses_square = hDirAC_mem->direct_responses_square;
+
+ /* Target and smoothed nrg factors/gains */
+ if ( ( hDirAC_mem->cy_cross_dir_smooth = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL )
{
- int16_t tmp_write_idx_param_band;
- int16_t tmp_write_idx_band;
- float diffuseness_sec = 0.f;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->cy_cross_dir_smooth, size );
- /* ungroup */
- seed_ptr = &hDirAC->dithering_seed;
- nblocks = q_direction->cfg.nblocks;
- nbands = hDirAC->band_grouping[hDirAC->hConfig->nbands];
- band_grouping = hDirAC->band_grouping;
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ if ( ( hDirAC_mem->cy_auto_diff_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->cy_auto_diff_smooth, size );
+ }
+ else
+ {
+ if ( ( hDirAC_mem->cy_auto_diff_smooth = (float *) malloc( sizeof( float ) * num_outputs_diff * num_freq_bands_diff ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->cy_auto_diff_smooth, num_outputs_diff * num_freq_bands_diff );
+ }
+ hDirAC->h_output_synthesis_psd_state.cy_cross_dir_smooth = hDirAC_mem->cy_cross_dir_smooth;
+ hDirAC->h_output_synthesis_psd_state.cy_auto_diff_smooth = hDirAC_mem->cy_auto_diff_smooth;
- if ( ivas_total_brate <= IVAS_SID_5k2 && ivas_format != SBA_FORMAT )
+ /*Responses (gains/factors)*/
+ if ( ( hDirAC_mem->direct_responses = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ set_zero( hDirAC_mem->direct_responses, size );
+
+
+ hDirAC->h_output_synthesis_psd_state.direct_responses = hDirAC_mem->direct_responses;
+
+ /* Prototypes */
+ hDirAC_mem->proto_direct_buffer_f = NULL;
+ hDirAC_mem->proto_diffuse_buffer_f = NULL;
+ if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( hDirAC_mem->proto_direct_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_protos_dir * num_freq_bands ) ) == NULL )
{
- /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/
- start_band = 0;
- hDirAC->hConfig->nbands = 5;
- ivas_dirac_config_bands( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, NULL, 0, 0, NULL );
- nbands = 5;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
- else
+
+ if ( hDirAC->proto_signal_decorr_on )
{
- start_band = hDirAC->hConfig->enc_param_start_band;
- if ( ivas_format == SBA_FORMAT )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
{
- hDirAC->hConfig->nbands = IVAS_MAX_NUM_BANDS;
+ if ( ( hDirAC_mem->proto_diffuse_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * size ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
}
else
{
- hDirAC->hConfig->nbands = q_direction->cfg.nbands;
+ if ( ( hDirAC_mem->proto_diffuse_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_outputs_diff * num_freq_bands ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
}
+ }
+ }
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f = hDirAC_mem->proto_direct_buffer_f;
+ hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f = hDirAC_mem->proto_diffuse_buffer_f;
- ivas_dirac_config_bands( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hDirAC->hConfig->enc_param_start_band, hDirAC->hFbMdft );
+ /* Gains/power factors*/
+ hDirAC_mem->direct_power_factor = NULL;
+ hDirAC_mem->diffuse_power_factor = NULL;
- nbands = hDirAC->hConfig->nbands;
- if ( hQMetaData->q_direction[0].cfg.nblocks == 0 )
- {
- /* No transmission -> no copy from qmetadata buffers*/
- nbands = start_band;
- }
+ if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( hDirAC_mem->direct_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
-
- /* Low-Bands with no spatial data transmitted, analysis at decoder side */
- for ( band = 0; band < start_band; band++ )
+ if ( ( hDirAC_mem->diffuse_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL )
{
- band_start = band_grouping[band];
- band_end = band_grouping[band + 1];
- tmp_write_idx_param_band = hSpatParamRendCom->dirac_bs_md_write_idx;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ }
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ hDirAC->h_output_synthesis_psd_state.direct_power_factor = hDirAC_mem->direct_power_factor;
+ hDirAC->h_output_synthesis_psd_state.diffuse_power_factor = hDirAC_mem->diffuse_power_factor;
+
+ hDirAC_mem->reference_power = NULL;
+ hDirAC_mem->onset_filter = NULL;
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( hDirAC_mem->reference_power = (float *) malloc( sizeof( float ) * 2 * num_freq_bands ) ) == NULL )
{
- for ( b = band_start; b < band_end; b++ )
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ if ( hDirAC->proto_signal_decorr_on )
+ {
+ if ( ( hDirAC_mem->onset_filter = (float *) malloc( sizeof( float ) * num_outputs_diff * num_freq_bands ) ) == NULL )
{
- tmp_write_idx_band = tmp_write_idx_param_band;
- hSpatParamRendCom->spreadCoherence[block][b] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[block][b] = 0.0f;
-
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = 0;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = 0;
- hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = 0.f;
-
- hSpatParamRendCom->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
- hSpatParamRendCom->energy_ratio1[tmp_write_idx_band][b] = 0;
- tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
}
}
}
-
- /* Bands with spatial data transmitted */
- if ( hodirac_flag )
+ }
+ else
+ {
+ if ( num_protos_dir > 2 )
{
- no_secs = DIRAC_HO_NUMSECTORS;
+ if ( ( hDirAC_mem->reference_power = (float *) malloc( sizeof( float ) * 5 * num_freq_bands ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
}
- for ( idx_sec = 0; idx_sec < no_secs; idx_sec++ )
+ if ( hDirAC->proto_signal_decorr_on )
{
- for ( band = start_band; band < nbands; band++ )
+ if ( ( hDirAC_mem->onset_filter = (float *) malloc( sizeof( float ) * 2 * num_freq_bands ) ) == NULL )
{
- band_start = band_grouping[band];
- band_end = band_grouping[band + 1];
- tmp_write_idx_param_band = hSpatParamRendCom->dirac_bs_md_write_idx;
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
+ }
+ }
+ }
- if ( ivas_format == SBA_FORMAT )
- {
- qBand_idx = dirac_to_spar_md_bands[band] - start_band;
- }
- else
- {
- qBand_idx = band;
- }
- diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0];
-#ifdef DEBUG_MODE_DIRAC
- dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" );
-#endif
- diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0];
+ return IVAS_ERR_OK;
+}
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
- {
- int16_t block_qmetadata;
- block_qmetadata = min( block, nblocks - 1 );
- block_qmetadata = max( block_qmetadata, 0 );
+static void ivas_dirac_free_mem(
+ DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem )
+{
+ if ( hDirAC_mem->cy_auto_dir_smooth != NULL )
+ {
+ free( hDirAC_mem->cy_auto_dir_smooth );
+ }
+ if ( hDirAC_mem->proto_power_smooth != NULL )
+ {
+ free( hDirAC_mem->proto_power_smooth );
+ }
+ if ( hDirAC_mem->proto_power_diff_smooth != NULL )
+ {
+ free( hDirAC_mem->proto_power_diff_smooth );
+ }
+ if ( hDirAC_mem->direct_responses_square != NULL )
+ {
+ free( hDirAC_mem->direct_responses_square );
+ }
+ if ( hDirAC_mem->frame_dec_f != NULL )
+ {
+ free( hDirAC_mem->frame_dec_f );
+ }
+ if ( hDirAC_mem->cy_cross_dir_smooth != NULL )
+ {
+ free( hDirAC_mem->cy_cross_dir_smooth );
+ }
+ if ( hDirAC_mem->cy_auto_diff_smooth != NULL )
+ {
+ free( hDirAC_mem->cy_auto_diff_smooth );
+ }
+ if ( hDirAC_mem->direct_responses != NULL )
+ {
+ free( hDirAC_mem->direct_responses );
+ }
+ if ( hDirAC_mem->proto_direct_buffer_f != NULL )
+ {
+ free( hDirAC_mem->proto_direct_buffer_f );
+ }
+ if ( hDirAC_mem->proto_diffuse_buffer_f != NULL )
+ {
+ free( hDirAC_mem->proto_diffuse_buffer_f );
+ }
+ if ( hDirAC_mem->direct_power_factor != NULL )
+ {
+ free( hDirAC_mem->direct_power_factor );
+ }
+ if ( hDirAC_mem->diffuse_power_factor != NULL )
+ {
+ free( hDirAC_mem->diffuse_power_factor );
+ }
+ if ( hDirAC_mem->reference_power != NULL )
+ {
+ free( hDirAC_mem->reference_power );
+ }
+ if ( hDirAC_mem->onset_filter != NULL )
+ {
+ free( hDirAC_mem->onset_filter );
+ }
- if ( q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] < 0.f )
- {
- q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] += 360.f;
- }
+ return;
+}
- if ( hMasa == NULL && hodirac_flag )
- {
- azimuth = q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata];
- elevation = q_direction[idx_sec].band_data[qBand_idx].elevation[block_qmetadata];
- diffuseness = 1.f - q_direction[0].band_data[qBand_idx].energy_ratio[block_qmetadata];
- diffuseness_sec = q_direction[1].band_data[qBand_idx].energy_ratio[block_qmetadata];
- assert( diffuseness_sec < 1.0001f && diffuseness_sec > -0.0001f );
- }
- else
- {
- azimuth = q_direction->band_data[qBand_idx].azimuth[block_qmetadata];
- elevation = q_direction->band_data[qBand_idx].elevation[block_qmetadata];
- }
- for ( b = band_start; b < band_end; b++ )
- {
- tmp_write_idx_band = tmp_write_idx_param_band;
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_read_BS()
+ *
+ * Read DirAC parameters from the bitstream
+ *------------------------------------------------------------------------*/
- if ( hodirac_flag )
- {
- azi = (int16_t) ( azimuth + 0.5f );
- ele = (int16_t) ( elevation + 0.5f );
- }
- else
- {
- azi = (int16_t) ( azimuth + rand_triangular_signed( seed_ptr ) * dirac_dithering_azi_scale[diff_idx] + 0.5f );
- ele = (int16_t) ( elevation + rand_triangular_signed( seed_ptr ) * dirac_dithering_ele_scale[diff_idx] + 0.5f );
- /* limit the elevation to [-90, 90] */
- ele = min( 90, ele );
- ele = max( -90, ele );
- }
+void ivas_dirac_dec_read_BS(
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ Decoder_State *st, /* i/o: decoder state structure */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: decoder DirAC handle */
+ IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata */
+ int16_t *nb_bits, /* o : number of bits read */
+ const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
+ int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */
+)
+{
+ int16_t i, j, b, dir, orig_dirac_bands;
+ int16_t next_bit_pos_orig;
+ *nb_bits = 0;
+ if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 )
+ {
+ next_bit_pos_orig = st->next_bit_pos;
+ st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 );
- if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL )
- {
- hSpatParamRendCom->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f;
- }
- else
- {
- hSpatParamRendCom->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
- }
+ /* 1 bit flag for signaling metadata to read */
+ b = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits )++;
- if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL )
- {
- hSpatParamRendCom->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f;
- }
- else
- {
- hSpatParamRendCom->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
- }
+ if ( b == 1 ) /* WB 4TCs condition, no other metadata to read*/
+ {
+ orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
- hSpatParamRendCom->energy_ratio1[tmp_write_idx_band][b] = q_direction->band_data[qBand_idx].energy_ratio[0];
+ hQMetaData->sba_inactive_mode = 1;
- hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness;
+ /* if we start with a SID frame, we need to init the azi/ele arrays.*/
+ if ( st->ini_frame == 0 )
+ {
+ for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
+ {
+ set_zero( hQMetaData->q_direction[0].band_data[b].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
+ set_zero( hQMetaData->q_direction[0].band_data[b].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
+ }
+ }
+
+ *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT );
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
+ }
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ for ( j = orig_dirac_bands - 2; j >= 0; j-- )
+ {
+ hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
+ hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
+ hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
+ }
+ }
+
+ hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
+ }
+ else
+ {
+ hQMetaData->sba_inactive_mode = 0;
+ hQMetaData->is_masa_ivas_format = 0;
+ if ( hQMetaData->useLowerRes )
+ {
+ hQMetaData->q_direction[0].cfg.nblocks = 1;
+ }
+ else
+ {
+ hQMetaData->q_direction[0].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
+ }
+
+ *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), hodirac_flag );
+ }
+
+#ifdef DEBUGGING
+ assert( *nb_bits >= 0 );
+#endif
+
+ st->next_bit_pos = next_bit_pos_orig;
+ }
+ else if ( !st->bfi && ivas_total_brate == IVAS_SID_5k2 )
+ {
+ next_bit_pos_orig = st->next_bit_pos;
+
+ /* subtract mode signaling bits, since bitstream was moved after mode reading */
+ st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS );
+#ifndef SBA_MODE_CLEANUP_2
+ /* 1 bit flag for SPAR/DirAC, already read in read format function */
+#else
+ /* 1 bit flag for signaling metadata to read */
+#endif
+ b = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits )++;
+ hQMetaData->sba_inactive_mode = 1;
+ orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands;
+
+ /* if we start with a SID frame, we need to init the azi/ele arrays.*/
+ if ( st->ini_frame == 0 )
+ {
+ for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
+ {
+ for ( b = 0; b < hQMetaData->q_direction[dir].cfg.nbands; b++ )
+ {
+ set_zero( hQMetaData->q_direction[dir].band_data[b].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
+ set_zero( hQMetaData->q_direction[dir].band_data[b].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
+ }
+ }
+ }
+
+ *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT );
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0];
+ hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0];
+ }
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ for ( j = orig_dirac_bands - 2; j >= 0; j-- )
+ {
+ hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0];
+ hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0];
+ hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0];
+ }
+ }
+
+ hQMetaData->q_direction->cfg.nbands = orig_dirac_bands;
+
+ st->next_bit_pos = next_bit_pos_orig;
+ }
+
+ if ( hDirAC != NULL )
+ {
+ ivas_qmetadata_to_dirac( hQMetaData, hDirAC, NULL, ivas_total_brate, SBA_FORMAT, hodirac_flag, dirac_to_spar_md_bands );
+ }
+
+ return;
+}
+
+
+/*-----------------------------------------------------------------------*
+ * ivas_qmetadata_to_dirac()
+ *
+ * Copy qmetedata to DirAC parameters for rendering
+ *-----------------------------------------------------------------------*/
+
+void ivas_qmetadata_to_dirac(
+ const IVAS_QMETADATA_HANDLE hQMetaData, /* i : frame of MASA q_metadata */
+ DIRAC_DEC_HANDLE hDirAC, /* o : DirAC decoder structure */
+ MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ const IVAS_FORMAT ivas_format, /* i : IVAS format */
+ const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
+ int16_t *dirac_to_spar_md_bands /* o : DirAC->SPAR MD bands */
+)
+{
+ int16_t block, band;
+ int16_t *seed_ptr;
+ int16_t band_start, band_end, diff_idx;
+ float diffuseness;
+ int16_t b, ele, azi;
+ float azimuth, elevation;
+ IVAS_QDIRECTION *q_direction;
+ int16_t *band_mapping;
+ int16_t *band_grouping;
+ int16_t start_band;
+ int16_t nbands = 0;
+ int16_t nblocks = 0;
+ int16_t qBand_idx;
+ int16_t idx_sec = 0;
+ int16_t no_secs = 1;
+
+ q_direction = &( hQMetaData->q_direction[0] );
+#ifdef MASA_AND_OBJECTS
+ hDirAC->numParametricDirections = hQMetaData->no_directions;
+ hDirAC->numSimultaneousDirections = hDirAC->numParametricDirections + hDirAC->numIsmDirections;
+#else
+ hDirAC->numSimultaneousDirections = hQMetaData->no_directions;
+#endif
+
+ if ( hMasa != NULL && ivas_total_brate > IVAS_SID_5k2 )
+ {
+ int16_t meta_write_index;
+ band_mapping = hMasa->data.band_mapping;
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
+ {
+ meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length;
+
+ for ( band = 0; band < hMasa->config.numCodingBands; ++band )
+ {
+ for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
+ {
+ hDirAC->azimuth[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block];
+ hDirAC->elevation[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block];
+ hDirAC->energy_ratio1[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block];
+ hDirAC->diffuseness_vector[meta_write_index][b] = 1.0f - q_direction->band_data[band].energy_ratio[block];
+
+ if ( q_direction->coherence_band_data != NULL )
+ {
+ hDirAC->spreadCoherence[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f;
+ }
+ else
+ {
+ hDirAC->spreadCoherence[meta_write_index][b] = 0.0f;
+ }
+
+ if ( hQMetaData->surcoh_band_data != NULL )
+ {
+ hDirAC->surroundingCoherence[meta_write_index][b] = hQMetaData->surcoh_band_data[band].surround_coherence[block] / 255.0f;
+ }
+ else
+ {
+ hDirAC->surroundingCoherence[meta_write_index][b] = 0.0f;
+ }
+ }
+ }
+ }
+
+ if ( hQMetaData->no_directions == 2 )
+ {
+ q_direction = &( hQMetaData->q_direction[1] );
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
+ {
+ meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length;
+
+ for ( band = 0; band < hMasa->config.numCodingBands; ++band )
+ {
+ for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
+ {
+ hDirAC->azimuth2[meta_write_index][b] = (int16_t) q_direction->band_data[band].azimuth[block];
+ hDirAC->elevation2[meta_write_index][b] = (int16_t) q_direction->band_data[band].elevation[block];
+ hDirAC->energy_ratio2[meta_write_index][b] = q_direction->band_data[band].energy_ratio[block];
+ hDirAC->diffuseness_vector[meta_write_index][b] -= q_direction->band_data[band].energy_ratio[block];
+
+ if ( q_direction->coherence_band_data != NULL )
+ {
+ hDirAC->spreadCoherence2[meta_write_index][b] = q_direction->coherence_band_data[band].spread_coherence[block] / 255.0f;
+ }
+ else
+ {
+ hDirAC->spreadCoherence2[meta_write_index][b] = 0.0f;
+ }
+ }
+ }
+ }
+ }
+ else if ( hDirAC->azimuth2 != NULL && hDirAC->elevation2 != NULL && hDirAC->energy_ratio2 != NULL && hDirAC->spreadCoherence2 != NULL )
+ {
+ /* zero out old dir2 data */
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block )
+ {
+ meta_write_index = ( hDirAC->dirac_bs_md_write_idx + block ) % hDirAC->dirac_md_buffer_length;
+ set_s( hDirAC->azimuth2[meta_write_index], 0, hDirAC->num_freq_bands );
+ set_s( hDirAC->elevation2[meta_write_index], 0, hDirAC->num_freq_bands );
+ set_zero( hDirAC->energy_ratio2[meta_write_index], hDirAC->num_freq_bands );
+ set_zero( hDirAC->spreadCoherence2[meta_write_index], hDirAC->num_freq_bands );
+ }
+ }
+ }
+ else /* SBA mode/SID/Zero frame*/
+ {
+ int16_t tmp_write_idx_param_band;
+ int16_t tmp_write_idx_band;
+ float diffuseness_sec = 0.f;
+
+ /* ungroup */
+ seed_ptr = &hDirAC->dithering_seed;
+ nblocks = q_direction->cfg.nblocks;
+ nbands = hDirAC->band_grouping[hDirAC->hConfig->nbands];
+ band_grouping = hDirAC->band_grouping;
+
+ if ( ivas_total_brate <= IVAS_SID_5k2 && ivas_format != SBA_FORMAT )
+ {
+ /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/
+ start_band = 0;
+ hDirAC->hConfig->nbands = 5;
+ ivas_dirac_config_bands( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, NULL, 0, 0, NULL );
+ nbands = 5;
+ }
+ else
+ {
+ start_band = hDirAC->hConfig->enc_param_start_band;
+ if ( ivas_format == SBA_FORMAT )
+ {
+ hDirAC->hConfig->nbands = IVAS_MAX_NUM_BANDS;
+ }
+ else
+ {
+ hDirAC->hConfig->nbands = q_direction->cfg.nbands;
+ }
+
+ ivas_dirac_config_bands( hDirAC->band_grouping, hDirAC->hConfig->nbands, nbands, dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hDirAC->hConfig->enc_param_start_band, hDirAC->hFbMdft );
+
+ nbands = hDirAC->hConfig->nbands;
+ if ( hQMetaData->q_direction[0].cfg.nblocks == 0 )
+ {
+ /* No transmission -> no copy from qmetadata buffers*/
+ nbands = start_band;
+ }
+ }
+
+ /* Low-Bands with no spatial data transmitted, analysis at decoder side */
+ for ( band = 0; band < start_band; band++ )
+ {
+ band_start = band_grouping[band];
+ band_end = band_grouping[band + 1];
+ tmp_write_idx_param_band = hDirAC->dirac_bs_md_write_idx;
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ for ( b = band_start; b < band_end; b++ )
+ {
+ tmp_write_idx_band = tmp_write_idx_param_band;
+ hDirAC->spreadCoherence[block][b] = 0.0f;
+ hDirAC->surroundingCoherence[block][b] = 0.0f;
+
+ hDirAC->elevation[tmp_write_idx_band][b] = 0;
+ hDirAC->azimuth[tmp_write_idx_band][b] = 0;
+ hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f;
+
+ hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
+ hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
+ hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0;
+ tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length;
+ }
+ }
+ }
+
+ /* Bands with spatial data transmitted */
+ if ( hodirac_flag )
+ {
+ no_secs = DIRAC_HO_NUMSECTORS;
+ }
+
+ for ( idx_sec = 0; idx_sec < no_secs; idx_sec++ )
+ {
+ for ( band = start_band; band < nbands; band++ )
+ {
+ band_start = band_grouping[band];
+ band_end = band_grouping[band + 1];
+ tmp_write_idx_param_band = hDirAC->dirac_bs_md_write_idx;
+
+ if ( ivas_format == SBA_FORMAT )
+ {
+ qBand_idx = dirac_to_spar_md_bands[band] - start_band;
+ }
+ else
+ {
+ qBand_idx = band;
+ }
+ diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0];
+#ifdef DEBUG_MODE_DIRAC
+ dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" );
+#endif
+ diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0];
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ int16_t block_qmetadata;
+
+ block_qmetadata = min( block, nblocks - 1 );
+ block_qmetadata = max( block_qmetadata, 0 );
+
+ if ( q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] < 0.f )
+ {
+ q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata] += 360.f;
+ }
+
+ if ( hMasa == NULL && hodirac_flag )
+ {
+ azimuth = q_direction[idx_sec].band_data[qBand_idx].azimuth[block_qmetadata];
+ elevation = q_direction[idx_sec].band_data[qBand_idx].elevation[block_qmetadata];
+ diffuseness = 1.f - q_direction[0].band_data[qBand_idx].energy_ratio[block_qmetadata];
+ diffuseness_sec = q_direction[1].band_data[qBand_idx].energy_ratio[block_qmetadata];
+ assert( diffuseness_sec < 1.0001f && diffuseness_sec > -0.0001f );
+ }
+ else
+ {
+ azimuth = q_direction->band_data[qBand_idx].azimuth[block_qmetadata];
+ elevation = q_direction->band_data[qBand_idx].elevation[block_qmetadata];
+ }
+
+ for ( b = band_start; b < band_end; b++ )
+ {
+ tmp_write_idx_band = tmp_write_idx_param_band;
+
+ if ( hodirac_flag )
+ {
+ azi = (int16_t) ( azimuth + 0.5f );
+ ele = (int16_t) ( elevation + 0.5f );
+ }
+ else
+ {
+ azi = (int16_t) ( azimuth + rand_triangular_signed( seed_ptr ) * dirac_dithering_azi_scale[diff_idx] + 0.5f );
+ ele = (int16_t) ( elevation + rand_triangular_signed( seed_ptr ) * dirac_dithering_ele_scale[diff_idx] + 0.5f );
+ /* limit the elevation to [-90, 90] */
+ ele = min( 90, ele );
+ ele = max( -90, ele );
+ }
+
+ if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL )
+ {
+ hDirAC->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f;
+ }
+ else
+ {
+ hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
+ }
+
+ if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL )
+ {
+ hDirAC->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f;
+ }
+ else
+ {
+ hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
+ }
+
+ hDirAC->energy_ratio1[tmp_write_idx_band][b] = q_direction->band_data[qBand_idx].energy_ratio[0];
+
+ hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness;
+
+ if ( hodirac_flag )
+ {
+ if ( idx_sec == 0 )
+ {
+ hDirAC->elevation[tmp_write_idx_band][b] = ele;
+ hDirAC->azimuth[tmp_write_idx_band][b] = azi;
+ hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0.f; // not in use
+ }
+ else
+ {
+ assert( idx_sec == 1 );
+ hDirAC->elevation2[tmp_write_idx_band][b] = ele;
+ hDirAC->azimuth2[tmp_write_idx_band][b] = azi;
+ hDirAC->energy_ratio2[tmp_write_idx_band][b] = 1.f - diffuseness_sec;
+ }
+ }
+ else
+ {
+ hDirAC->elevation[tmp_write_idx_band][b] = ele;
+ hDirAC->azimuth[tmp_write_idx_band][b] = azi;
+ }
+ }
+ tmp_write_idx_param_band = ( tmp_write_idx_param_band + 1 ) % hDirAC->dirac_md_buffer_length;
+
+ } /* for ( block =...) */
+ } /* for ( band = ...) */
+ } /* for ( idx_sec = ...)*/
+
+ /* Bands not transmitted -> zeroed*/
+ for ( b = band_grouping[band]; b < hDirAC->num_freq_bands; b++ )
+ {
+ tmp_write_idx_band = hDirAC->dirac_bs_md_write_idx;
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+
+ hDirAC->spreadCoherence[block][b] = 0.0f;
+ hDirAC->surroundingCoherence[block][b] = 0.0f;
+ hDirAC->energy_ratio1[block][b] = 0;
+
+ hDirAC->elevation[tmp_write_idx_band][b] = 0;
+ hDirAC->azimuth[tmp_write_idx_band][b] = 0;
+ hDirAC->diffuseness_vector[tmp_write_idx_band][b] = 0.f;
+ hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
+ hDirAC->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
+ hDirAC->energy_ratio1[tmp_write_idx_band][b] = 0;
+ tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length;
+ }
+ }
+ }
+
+ /* update buffer write index */
+ hDirAC->dirac_bs_md_write_idx = ( hDirAC->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hDirAC->dirac_md_buffer_length;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_set_md_map()
+ *
+ * Set metadata index mapping for DirAC
+ *------------------------------------------------------------------------*/
+
+void ivas_dirac_dec_set_md_map(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int16_t nCldfbTs /* i : number of CLDFB time slots */
+)
+{
+ int16_t num_slots_in_subfr;
+ DIRAC_DEC_HANDLE hDirAC;
+
+ hDirAC = st_ivas->hDirAC;
+#ifdef DEBUGGING
+ assert( hDirAC );
+#endif
+
+ /* adapt subframes */
+ hDirAC->num_slots = nCldfbTs;
+ hDirAC->slots_rendered = 0;
+ num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES;
+ hDirAC->subframes_rendered = 0;
+
+ ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hDirAC->subframe_nbslots, &hDirAC->nb_subframes );
+
+ /* set mapping according to dirac_read_idx */
+
+ set_s( hDirAC->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
+
+#ifdef FIX_470_MASA_JBM_EXT
+ if ( st_ivas->ivas_format == MASA_FORMAT )
+ {
+ ivas_jbm_dec_get_md_map_even_spacing( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map );
+ }
+ else if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
+#else
+ if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
+#endif
+ {
+ ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map );
+ }
+ else
+ {
+ ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hDirAC->dirac_read_idx, hDirAC->dirac_md_buffer_length, hDirAC->render_to_md_map );
+ }
+
+ if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
+ {
+ float tmp;
+ int16_t sf_idx, slot_idx, slot_idx_abs;
+
+ slot_idx_abs = 0;
+ for ( sf_idx = 0; sf_idx < hDirAC->nb_subframes; sf_idx++ )
+ {
+ tmp = 0.0f;
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[sf_idx]; slot_idx++ )
+ {
+ tmp += (float) hDirAC->render_to_md_map[slot_idx_abs];
+ slot_idx_abs++;
+ }
+ hDirAC->render_to_md_map[sf_idx] = ( (int16_t) roundf( tmp / (float) hDirAC->subframe_nbslots[sf_idx] ) + hDirAC->dirac_read_idx ) % hDirAC->dirac_md_buffer_length;
+ }
+
+ set_s( &hDirAC->render_to_md_map[hDirAC->nb_subframes], 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME - hDirAC->nb_subframes );
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec()
+ *
+ * DirAC decoding process
+ *------------------------------------------------------------------------*/
+
+void ivas_dirac_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */
+ const int16_t nchan_transport /* i : number of transport channels */
+)
+{
+ int16_t subframe_idx;
+ float *output_f_local[MAX_OUTPUT_CHANNELS];
+ float cng_td_buffer[L_FRAME16k];
+ int16_t nchan_out, n, n_samples_sf;
+ nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
+
+ n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * st_ivas->hDirAC->slot_size;
+
+ for ( n = 0; n < nchan_out; n++ )
+ {
+ output_f_local[n] = &output_f[n][0];
+ }
+
+ for ( n = 0; n < nchan_transport; n++ )
+ {
+ st_ivas->hTcBuffer->tc[n] = output_f[n];
+ }
+
+ if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
+ {
+ Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0];
+ st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0];
+ generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna );
+ }
+
+ ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS );
+
+ for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ )
+ {
+ ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL );
+ for ( n = 0; n < nchan_out; n++ )
+ {
+ output_f_local[n] += n_samples_sf;
+ }
+ }
+
+ if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
+ {
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ }
+ else
+ {
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ }
+
+ for ( n = 0; n < nchan_transport; n++ )
+ {
+ st_ivas->hTcBuffer->tc[n] = NULL;
+ }
+
+ if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
+ {
+ st_ivas->hTcBuffer->tc[nchan_transport] = NULL;
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_render()
+ *
+ * DirAC decoding renderer process
+ *------------------------------------------------------------------------*/
+
+void ivas_dirac_dec_render(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */
+ uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */
+ uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */
+ float *output_f[] /* o : rendered time signal */
+)
+{
+ int16_t slots_to_render, first_sf, last_sf, subframe_idx;
+ uint16_t slot_size, n_samples_sf, ch, nchan_intern;
+ DIRAC_DEC_HANDLE hDirAC;
+ float *output_f_local[MAX_OUTPUT_CHANNELS];
+
+ hDirAC = st_ivas->hDirAC;
+
+ nchan_intern = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
+#ifdef DEBUGGING
+ assert( hDirAC );
+#endif
+ for ( ch = 0; ch < nchan_intern; ch++ )
+ {
+ output_f_local[ch] = output_f[ch];
+ }
+ slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
+
+ /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
+ slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size );
+ *nSamplesRendered = slots_to_render * slot_size;
+ first_sf = hDirAC->subframes_rendered;
+ last_sf = first_sf;
+
+ while ( slots_to_render > 0 )
+ {
+ slots_to_render -= hDirAC->subframe_nbslots[last_sf];
+ last_sf++;
+ }
+
+#ifdef DEBUGGING
+ assert( slots_to_render == 0 );
+#endif
+ for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
+ {
+ ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL );
+ n_samples_sf = hDirAC->subframe_nbslots[subframe_idx] * st_ivas->hDirAC->slot_size;
+ for ( ch = 0; ch < nchan_intern; ch++ )
+ {
+ output_f_local[ch] += n_samples_sf;
+ }
+ }
+
+ if ( hDirAC->slots_rendered == hDirAC->num_slots )
+ {
+ if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
+ {
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ }
+ else
+ {
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ }
+ }
+
+ *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec()
+ *
+ * DirAC decoding process
+ *------------------------------------------------------------------------*/
+
+void ivas_dirac_dec_render_sf(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX],
+ float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] )
+{
+ int16_t i, ch, idx_in, idx_lfe;
+ DIRAC_DEC_HANDLE hDirAC;
+ float dirEne;
+ float surCohEner;
+ float surCohRatio[CLDFB_NO_CHANNELS_MAX];
+ int16_t subframe_idx;
+ int16_t slot_idx, index_slot;
+ int16_t hodirac_flag;
+ float *p_Rmat;
+ int16_t slot_idx_start, slot_idx_start_cldfb_synth, md_idx;
+
+ /*CLDFB: last output channels reserved to LFT for CICPx*/
+ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#else
+ float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
+#endif
+#ifdef MASA_AND_OBJECTS
+ float Cldfb_RealBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; /* Todo Nokia: Temporary, to be removed once function calls have been refactored to accept another size */
+ float Cldfb_ImagBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; /* Todo Nokia: Temporary, to be removed once function calls have been refactored to accept another size */
+#endif
+ int16_t index, num_freq_bands;
+
+ /* local copies of azi, ele, diffuseness */
+ int16_t azimuth[CLDFB_NO_CHANNELS_MAX];
+ int16_t elevation[CLDFB_NO_CHANNELS_MAX];
+ float diffuseness_vector[CLDFB_NO_CHANNELS_MAX];
+
+ DIRAC_DEC_STACK_MEM DirAC_mem;
+ float *reference_power, *reference_power_smooth;
+ float *onset_filter, *onset_filter_subframe, *p_onset_filter = NULL;
+ uint16_t coherence_flag;
+
+ push_wmops( "ivas_dirac_dec_render" );
+
+ /* Initialize aux buffers */
+ hDirAC = st_ivas->hDirAC;
+
+ DirAC_mem = st_ivas->hDirAC->stack_mem;
+
+ reference_power = DirAC_mem.reference_power;
+ reference_power_smooth = DirAC_mem.reference_power + hDirAC->num_freq_bands;
+ onset_filter = DirAC_mem.onset_filter;
+#ifdef FIX_614_ADD_TO_NULL_PTR_DIRAC_SETUP
+ onset_filter_subframe = ( DirAC_mem.onset_filter == NULL ) ? NULL : DirAC_mem.onset_filter + hDirAC->num_freq_bands;
+#else
+ onset_filter_subframe = DirAC_mem.onset_filter + hDirAC->num_freq_bands;
+#endif
+
+ hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order );
+
+ if ( st_ivas->hQMetaData != NULL && st_ivas->ivas_format != SBA_FORMAT )
+ {
+ coherence_flag = st_ivas->hQMetaData->coherence_flag;
+ }
+ else
+ {
+ coherence_flag = 0;
+ }
+
+#ifdef DEBUG_MODE_DIRAC
+ {
+ int16_t n, tmp[IVAS_SPAR_MAX_CH * L_FRAME48k];
+ char file_name[50] = { 0 };
+ const int16_t output_frame = st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC;
+
+ for ( n = 0; n < nchan_transport; n++ )
+ {
+ for ( i = 0; i < output_frame; i++ )
+ {
+ tmp[nchan_transport * i + n] = (int16_t) ( output_f[n][i] + 0.5f );
+ }
+ }
+ sprintf( file_name, "./res/ivas_dirac_dec_DMX%d.%d.pcm", nchan_transport, (int16_t) ( output_frame * 0.05 ) );
+ dbgwrite( tmp, sizeof( int16_t ), nchan_transport * output_frame, 1, file_name );
+ }
+#endif
+
+ /* Subframe loop */
+ slot_idx_start = hDirAC->slots_rendered;
+ slot_idx_start_cldfb_synth = 0;
+
+ subframe_idx = hDirAC->subframes_rendered;
+ if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ {
+ md_idx = hDirAC->render_to_md_map[subframe_idx];
+ }
+ else
+ {
+ md_idx = hDirAC->render_to_md_map[slot_idx_start];
+ }
+ /* ToDo: Another workaround for self test BE */
+
+ /* copy parameters into local buffers*/
+ if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ {
+ mvs2s( hDirAC->azimuth[hDirAC->render_to_md_map[subframe_idx]], azimuth, hDirAC->num_freq_bands );
+ mvs2s( hDirAC->elevation[hDirAC->render_to_md_map[subframe_idx]], elevation, hDirAC->num_freq_bands );
+ mvr2r( hDirAC->diffuseness_vector[hDirAC->render_to_md_map[subframe_idx]], diffuseness_vector, hDirAC->num_freq_bands );
+ }
+ else
+ {
+ set_zero( diffuseness_vector, hDirAC->num_freq_bands );
+ }
+
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ set_zero( reference_power_smooth, hDirAC->num_freq_bands );
+ }
+ else
+ {
+ set_zero( onset_filter_subframe, hDirAC->num_freq_bands );
+ }
+
+ if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] )
+ {
+ p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0];
+
+ if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
+ {
+ num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
+ if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ {
+ rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hDirAC->num_freq_bands, p_Rmat );
+ }
+ }
+ }
+ else
+ {
+ p_Rmat = 0;
+ }
+
+ if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ {
+ /* compute response */
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ ivas_dirac_dec_compute_power_factors( hDirAC->num_freq_bands,
+ diffuseness_vector,
+ hDirAC->h_output_synthesis_psd_params.max_band_decorr,
+ hDirAC->h_output_synthesis_psd_state.direct_power_factor,
+ hDirAC->h_output_synthesis_psd_state.diffuse_power_factor );
+
+ if ( coherence_flag )
+ {
+ for ( i = 0; i < hDirAC->num_freq_bands; i++ )
+ {
+ dirEne = hDirAC->h_output_synthesis_psd_state.direct_power_factor[i];
+ surCohEner = hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] * hDirAC->surroundingCoherence[md_idx][i];
+ hDirAC->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner;
+ hDirAC->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner;
+
+ surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner );
+ }
+ }
+ else
+ {
+ set_zero( surCohRatio, hDirAC->num_freq_bands );
+ }
+ }
+ else
+ {
+ ivas_dirac_dec_compute_gain_factors( hDirAC->num_freq_bands,
+ hDirAC->diffuseness_vector[md_idx],
+ hDirAC->h_output_synthesis_psd_params.max_band_decorr,
+ hDirAC->h_output_synthesis_psd_state.direct_power_factor,
+ hDirAC->h_output_synthesis_psd_state.diffuse_power_factor );
+
+ if ( coherence_flag )
+ {
+ for ( i = 0; i < hDirAC->num_freq_bands; i++ )
+ {
+ surCohRatio[i] = hDirAC->surroundingCoherence[md_idx][i];
+ }
+ }
+ else
+ {
+ set_zero( surCohRatio, hDirAC->num_freq_bands );
+ }
+ }
+ if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 )
+ {
+ ivas_dirac_dec_compute_directional_responses( hDirAC,
+ st_ivas->hVBAPdata,
+ st_ivas->hMasa,
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hMasaIsmData,
+#endif
+ azimuth,
+ elevation,
+ md_idx,
+ surCohRatio,
+ st_ivas->hCombinedOrientationData->shd_rot_max_order,
+ p_Rmat,
+ hodirac_flag );
+ }
+ else
+ {
+ ivas_dirac_dec_compute_directional_responses( hDirAC,
+ st_ivas->hVBAPdata,
+ st_ivas->hMasa,
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hMasaIsmData,
+#endif
+ azimuth,
+ elevation,
+ md_idx,
+ surCohRatio,
+ 0,
+ NULL,
+ hodirac_flag );
+ }
+ }
+
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: This might need adjustments
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 )
+ {
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ index_slot = slot_idx_start + slot_idx;
+
+ /* CLDFB Analysis*/
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirAC->sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ),
+ Cldfb_RealBuffer_Temp[ch][slot_idx],
+ Cldfb_ImagBuffer_Temp[ch][slot_idx],
+ hDirAC->num_freq_bands,
+ st_ivas->cldfbAnaDec[ch] );
+ }
+ }
+
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_Temp, Cldfb_ImagBuffer_Temp, hDirAC->num_freq_bands, subframe_idx );
+ }
+ }
+#endif
+
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ index_slot = slot_idx_start + slot_idx;
+ if ( hDirAC->hConfig->dec_param_estim == TRUE )
+ {
+ md_idx = hDirAC->render_to_md_map[index_slot];
+ }
+ else
+ {
+ md_idx = hDirAC->render_to_md_map[subframe_idx];
+ }
+
+ if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ mvr2r( pppQMfFrame_ts_re[ch][slot_idx], Cldfb_RealBuffer[ch][0], hDirAC->num_freq_bands );
+ mvr2r( pppQMfFrame_ts_im[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands );
+ }
+ }
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: This might need adjustments
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 )
+ {
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ mvr2r( Cldfb_RealBuffer_Temp[ch][slot_idx], Cldfb_RealBuffer[ch][0], hDirAC->num_freq_bands );
+ mvr2r( Cldfb_ImagBuffer_Temp[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hDirAC->num_freq_bands );
+ }
+ }
+#endif
+ else
+ {
+ /* CLDFB Analysis*/
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirAC->sba_map_tc[ch]][hDirAC->num_freq_bands * index_slot] ),
+ Cldfb_RealBuffer[ch][0],
+ Cldfb_ImagBuffer[ch][0],
+ hDirAC->num_freq_bands,
+ st_ivas->cldfbAnaDec[ch] );
+ }
+ }
+
+ /* CNG in DirAC, extra CLDFB ana for CNA*/
+ if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
+ {
+ Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0];
+
+ generate_masking_noise_dirac( st->hFdCngDec->hFdCngCom,
+ st_ivas->cldfbAnaDec[1],
+ st_ivas->hTcBuffer->tc[1],
+ Cldfb_RealBuffer[1][0],
+ Cldfb_ImagBuffer[1][0],
+ index_slot,
+ st->cna_dirac_flag && st->flag_cna,
+ ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->cng_type == FD_CNG && st->cng_sba_flag );
+ }
+
+ /* LFE synthesis */
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled && !( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && hDirAC->hOutSetup.num_lfe == 0 ) )
+ {
+ ivas_lfe_synth_with_cldfb( st_ivas->hMasa->hMasaLfeSynth,
+ Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1],
+ slot_idx,
+ md_idx,
+ nchan_transport );
+ }
+
+ /*-----------------------------------------------------------------*
+ * protoype signal computation
+ *-----------------------------------------------------------------*/
+
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
+ {
+ protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f,
+ reference_power, slot_idx, nchan_transport,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_freq_bands,
+ p_Rmat );
+ }
+ else
+ {
+ protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f,
+ reference_power, slot_idx, nchan_transport,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_freq_bands,
+ 0 );
+ }
+ }
+ else if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ {
+ protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->proto_frame_f,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ reference_power, hDirAC->h_output_synthesis_psd_state.proto_power_smooth,
+ 0, slot_idx, hDirAC->num_freq_bands, hDirAC->masa_stereo_type_detect );
+ }
+ else
+ {
+ switch ( nchan_transport )
+ {
+ case 11:
+ case 8:
+ case 6:
+ case 4:
+ protoSignalComputation4( Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ hDirAC->proto_frame_f,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ reference_power,
+ hDirAC->h_output_synthesis_psd_state.proto_power_smooth,
+ slot_idx, hDirAC->num_outputs_diff,
+ hDirAC->num_freq_bands,
+ hDirAC->hoa_decoder,
+ nchan_transport,
+ hDirAC->sba_map_tc );
+ break;
+ case 2:
+ protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ hDirAC->proto_frame_f,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ reference_power,
+ hDirAC->h_output_synthesis_psd_state.proto_power_smooth,
+ hDirAC->hOutSetup.is_loudspeaker_setup,
+ slot_idx,
+ hDirAC->num_freq_bands,
+ hDirAC->masa_stereo_type_detect );
+ break;
+ case 1:
+ protoSignalComputation1( Cldfb_RealBuffer, Cldfb_ImagBuffer,
+ hDirAC->proto_frame_f,
+ hDirAC->h_output_synthesis_psd_state.proto_direct_buffer_f,
+ reference_power,
+ hDirAC->h_output_synthesis_psd_state.proto_power_smooth,
+ slot_idx,
+ hDirAC->num_protos_diff,
+ hDirAC->num_freq_bands );
+ break;
+ default:
+ return;
+ }
+ }
+
+
+ /*-----------------------------------------------------------------*
+ * Compute DirAC parameters at decoder side
+ *-----------------------------------------------------------------*/
+
+ if ( hDirAC->hConfig->dec_param_estim == TRUE )
+ {
+ mvs2s( &hDirAC->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], hDirAC->num_freq_bands - hDirAC->hConfig->enc_param_start_band );
+ mvs2s( &hDirAC->elevation[md_idx][hDirAC->hConfig->enc_param_start_band], &elevation[hDirAC->hConfig->enc_param_start_band], hDirAC->num_freq_bands - hDirAC->hConfig->enc_param_start_band );
+ if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
+ {
+ num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
+ rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hDirAC->num_freq_bands, p_Rmat );
+ }
+
+ hDirAC->index_buffer_intensity = ( hDirAC->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
+
+ index = hDirAC->index_buffer_intensity;
+
+ num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
+
+ computeIntensityVector_dec( Cldfb_RealBuffer,
+ Cldfb_ImagBuffer,
+ num_freq_bands,
+ hDirAC->buffer_intensity_real[0][index - 1],
+ hDirAC->buffer_intensity_real[1][index - 1],
+ hDirAC->buffer_intensity_real[2][index - 1] );
+
+ computeDirectionAngles( hDirAC->buffer_intensity_real[0][index - 1],
+ hDirAC->buffer_intensity_real[1][index - 1],
+ hDirAC->buffer_intensity_real[2][index - 1],
+ num_freq_bands,
+ azimuth,
+ elevation );
+
+ mvr2r( reference_power, &( hDirAC->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
+
+ computeDiffuseness( hDirAC->buffer_intensity_real, hDirAC->buffer_energy, num_freq_bands, hDirAC->diffuseness_vector[md_idx] );
+ }
+
+#ifdef DEBUG_MODE_DIRAC
+ {
+ static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL;
+
+
+ if ( fp_direction_vector == NULL )
+ fp_direction_vector = fopen( "./res/dbg_direction_vector_C_dec.bin", "wb" );
+ if ( fp_diffuseness == NULL )
+ fp_diffuseness = fopen( "./res/dbg_diffuseness_C_dec.bin", "wb" );
+ if ( fp_referencePower == NULL )
+ fp_referencePower = fopen( "./res/dbg_reference_power_C_dec.bin", "wb" );
+
+
+ for ( i = 0; i < hDirAC->num_freq_bands; i++ )
+ {
+ float radius_length;
+ float dv[3];
+
+ if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ {
+ radius_length = cos( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 );
+ dv[0] = radius_length * cos( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 );
+ dv[1] = radius_length * sin( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 );
+ dv[2] = sin( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 );
+
+ fwrite( dv, sizeof( float ), 3, fp_direction_vector );
+ fwrite( &( hDirAC->diffuseness_vector[0][i] ), sizeof( float ), 1, fp_diffuseness );
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ reference_power[i] = Cldfb_RealBuffer[0][0][i] * Cldfb_RealBuffer[0][0][i] + Cldfb_ImagBuffer[0][0][i] * Cldfb_ImagBuffer[0][0][i];
+ }
+ fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower );
+ }
+ else
+ {
+ radius_length = cos( hDirAC->elevation[index_slot][i] * PI_OVER_180 );
+ dv[0] = radius_length * cos( hDirAC->azimuth[index_slot][i] * PI_OVER_180 );
+ dv[1] = radius_length * sin( hDirAC->azimuth[index_slot][i] * PI_OVER_180 );
+ dv[2] = sin( hDirAC->elevation[index_slot][i] * PI_OVER_180 );
+
+ fwrite( dv, sizeof( float ), 3, fp_direction_vector );
+ fwrite( &( hDirAC->diffuseness_vector[index_slot][i] ), sizeof( float ), 1, fp_diffuseness );
+ fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower );
+ }
+ }
+ }
+#endif
+
+ /*-----------------------------------------------------------------*
+ * frequency domain decorrelation
+ *-----------------------------------------------------------------*/
+
+ if ( hDirAC->proto_signal_decorr_on == 1 )
+ {
+ /* decorrelate prototype frame */
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff,
+ hDirAC->synthesisConf,
+ nchan_transport,
+ hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff,
+ hDirAC->proto_index_diff,
+ hDirAC->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hDirAC->num_freq_bands * hDirAC->num_outputs_diff + 2 * hDirAC->num_freq_bands * min( 4, nchan_transport ),
+ onset_filter,
+ hDirAC->h_freq_domain_decorr_ap_params,
+ hDirAC->h_freq_domain_decorr_ap_state );
+
+ v_multc( onset_filter, 0.25f, onset_filter, hDirAC->num_freq_bands );
+ v_add( onset_filter, onset_filter_subframe, onset_filter_subframe, hDirAC->num_freq_bands );
+ p_onset_filter = onset_filter_subframe;
+ }
+ else
+ {
+ ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff,
+ hDirAC->synthesisConf,
+ nchan_transport,
+ hDirAC->proto_frame_f,
+ hDirAC->num_protos_diff,
+ hDirAC->proto_index_diff,
+ DirAC_mem.frame_dec_f,
+ onset_filter,
+ hDirAC->h_freq_domain_decorr_ap_params,
+ hDirAC->h_freq_domain_decorr_ap_state );
+
+ hDirAC->proto_frame_dec_f = DirAC_mem.frame_dec_f;
+ p_onset_filter = onset_filter;
+ }
+ }
+ else
+ {
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ set_f( onset_filter_subframe, 1.f, hDirAC->num_freq_bands );
+ p_onset_filter = onset_filter_subframe;
+ }
+ else
+ {
+ /* no frequency domain decorrelation: use prototype frame */
+ hDirAC->proto_frame_dec_f = hDirAC->proto_frame_f;
+ p_onset_filter = NULL;
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * output synthesis
+ *-----------------------------------------------------------------*/
+
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
+ {
+ /*Compute diffuse prototypes*/
+ ivas_dirac_dec_compute_diffuse_proto( hDirAC, slot_idx );
+ }
+
+ /*Compute PSDs*/
+ if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 )
+ {
+ ivas_dirac_dec_output_synthesis_process_slot( reference_power,
+ p_onset_filter,
+ azimuth,
+ elevation,
+ hDirAC->diffuseness_vector[md_idx],
+ hDirAC,
+ st_ivas->hCombinedOrientationData->shd_rot_max_order,
+ p_Rmat,
+ st_ivas->hVBAPdata,
+ hDirAC->hOutSetup,
+ nchan_transport,
+ md_idx,
+ hodirac_flag );
+ }
+ else
+ {
+ ivas_dirac_dec_output_synthesis_process_slot( reference_power,
+ p_onset_filter,
+ azimuth,
+ elevation,
+ hDirAC->diffuseness_vector[md_idx],
+ hDirAC,
+ 0,
+ 0,
+ st_ivas->hVBAPdata,
+ hDirAC->hOutSetup,
+ nchan_transport,
+ md_idx,
+ hodirac_flag );
+ }
+
+ if ( hDirAC->hConfig->dec_param_estim )
+ {
+ float fac = 1.0f / (float) hDirAC->subframe_nbslots[subframe_idx];
+ v_multc_acc( hDirAC->diffuseness_vector[md_idx], fac, diffuseness_vector, hDirAC->num_freq_bands );
+ }
+
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ v_add( reference_power, reference_power_smooth, reference_power_smooth, hDirAC->num_freq_bands );
+ }
+ }
+
+ ivas_dirac_dec_output_synthesis_get_interpolator( &hDirAC->h_output_synthesis_psd_params, hDirAC->subframe_nbslots[subframe_idx] );
+
+
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( Cldfb_RealBuffer,
+ Cldfb_ImagBuffer,
+ hDirAC,
+ nchan_transport,
+ hDirAC->subframe_nbslots[subframe_idx],
+ p_onset_filter,
+ diffuseness_vector,
+ hodirac_flag );
+ }
+ else
+ {
+ /* Determine encoding quality based additional smoothing factor */
+ float qualityBasedSmFactor = 1.0f;
+
+ if ( st_ivas->hMasa != NULL )
+ {
+ qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality;
+ qualityBasedSmFactor *= qualityBasedSmFactor;
+ }
+
+
+ ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer,
+ Cldfb_ImagBuffer,
+ hDirAC,
+ hDirAC->subframe_nbslots[subframe_idx],
+ diffuseness_vector,
+ reference_power_smooth,
+ qualityBasedSmFactor );
+ }
+
+ /*-----------------------------------------------------------------*
+ * CLDFB synthesis (and binaural rendering)
+ *-----------------------------------------------------------------*/
+
+ index_slot = slot_idx_start_cldfb_synth;
+
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
+ {
+ /* Perform binaural rendering */
+ ivas_binRenderer( st_ivas->hBinRenderer,
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ &st_ivas->splitBinRend.splitrend.multiBinPoseData,
+#endif
+ st_ivas->hCombinedOrientationData,
+ subframe_idx,
+ hDirAC->subframe_nbslots[subframe_idx],
+ Cldfb_RealBuffer_Binaural,
+ Cldfb_ImagBuffer_Binaural,
+ Cldfb_RealBuffer,
+ Cldfb_ImagBuffer );
- if ( hodirac_flag )
- {
- if ( idx_sec == 0 )
- {
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi;
- hSpatParamRendCom->energy_ratio1[tmp_write_idx_band][b] = 0.f; // not in use
- }
- else
- {
- assert( idx_sec == 1 );
- hSpatParamRendCom->elevation2[tmp_write_idx_band][b] = ele;
- hSpatParamRendCom->azimuth2[tmp_write_idx_band][b] = azi;
- hSpatParamRendCom->energy_ratio2[tmp_write_idx_band][b] = 1.f - diffuseness_sec;
- }
- }
- else
- {
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi;
- }
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ||
+ ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+ {
+ int16_t pos_idx;
+#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
+ for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
+#else
+ for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
+#endif
+ {
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
+ {
+ mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hDirAC->num_freq_bands );
+ mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hDirAC->num_freq_bands );
}
- tmp_write_idx_param_band = ( tmp_write_idx_param_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
+ }
+ }
+ }
+#endif
+ /* Inverse CLDFB*/
+ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
+ {
+ /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
+ float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
+ float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
- } /* for ( block =...) */
- } /* for ( band = ...) */
- } /* for ( idx_sec = ...)*/
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
+ {
+#ifdef SPLIT_REND_WITH_HEAD_ROT
+ RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i];
+ ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i];
+#else
+ RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i];
+ ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i];
+#endif
+ }
- /* Bands not transmitted -> zeroed*/
- for ( b = band_grouping[band]; b < hSpatParamRendCom->num_freq_bands; b++ )
+ cldfbSynthesis( RealBuffer,
+ ImagBuffer,
+ &( output_f[ch][index_slot * hDirAC->num_freq_bands] ),
+ hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx],
+ st_ivas->cldfbSynDec[ch] );
+ }
+ }
+ else if ( st_ivas->ivas_format == SBA_FORMAT )
+ {
+ for ( ch = 0; ch < hDirAC->hOutSetup.nchan_out_woLFE; ch++ )
+ {
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
+ {
+ mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hDirAC->num_freq_bands );
+ mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hDirAC->num_freq_bands );
+ }
+ }
+ }
+ else
+ {
+ float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
+ float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
+ int16_t outchannels;
+
+ idx_in = 0;
+ idx_lfe = 0;
+
+ outchannels = hDirAC->hOutSetup.nchan_out_woLFE + hDirAC->hOutSetup.num_lfe;
+ if ( hDirAC->hOutSetup.separateChannelEnabled && ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1 ||
+ hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1 ||
+ hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 ||
+ hDirAC->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 ||
+ hDirAC->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 ||
+ ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) )
{
- tmp_write_idx_band = hSpatParamRendCom->dirac_bs_md_write_idx;
+ outchannels++;
+ }
- for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ if ( hDirAC->hOutSetup.separateChannelEnabled && hDirAC->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM )
+ {
+ float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
+ float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
+ const int16_t subframe_start_sample = index_slot * hDirAC->num_freq_bands;
+ const int16_t num_samples_subframe = hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx];
+
+ /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */
+ mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe );
+ mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe );
+
+ for ( ch = 0; ch < outchannels; ch++ )
{
+ if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) )
+ {
+ /* Move the LFE channel to the correct place */
+ mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
+
+ if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) )
+ {
+ idx_lfe++;
+ }
+ }
+ else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) )
+ {
+ /* Move the separated channel to the correct place. Thus, the separated channel is
+ * combined with the synthesized channels here when there is a matching channel. */
+ mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
+ }
+ else
+ {
+ /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
+ {
+ RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
+ ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
+ }
+ cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] );
+
+ if ( !st_ivas->hLsSetupCustom->separate_ch_found )
+ {
+ /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel
+ * is combined with the synthesized channels here when there is no matching channel. */
+ v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
+ }
- hSpatParamRendCom->spreadCoherence[block][b] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[block][b] = 0.0f;
- hSpatParamRendCom->energy_ratio1[block][b] = 0;
+ idx_in++;
+ }
+ }
+ }
+ else
+ {
+ for ( ch = 0; ch < outchannels; ch++ )
+ {
+ if ( ( hDirAC->hOutSetup.num_lfe > 0 ) && ( hDirAC->hOutSetup.index_lfe[idx_lfe] == ch ) )
+ {
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirAC->hOutSetup.separateChannelEnabled )
+ {
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
+ {
+ RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i];
+ ImagBuffer[i] = Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i];
+ }
+ cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirAC->hOutSetup.nchan_out_woLFE + idx_lfe] );
+ }
+ else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirAC->hOutSetup.separateChannelEnabled )
+ {
+ /* LFE has been synthesized in the time domain, do nothing. */
+ }
+ else
+ {
+ set_zero( &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands );
+ }
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = 0;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = 0;
- hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = 0.f;
- hSpatParamRendCom->spreadCoherence[tmp_write_idx_band][b] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[tmp_write_idx_band][b] = 0.0f;
- hSpatParamRendCom->energy_ratio1[tmp_write_idx_band][b] = 0;
- tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
+ if ( idx_lfe < ( hDirAC->hOutSetup.num_lfe - 1 ) )
+ {
+ idx_lfe++;
+ }
+ }
+ else if ( ( hDirAC->hOutSetup.separateChannelEnabled ) && ( hDirAC->hOutSetup.separateChannelIndex == ch ) )
+ {
+ /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated
+ * channel is combined with the synthesized channels here. */
+ }
+ else
+ {
+ /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
+ {
+ RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
+ ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
+ }
+ cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hDirAC->num_freq_bands] ), hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] );
+ idx_in++;
+ }
}
}
}
+ hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe_idx];
+ hDirAC->subframes_rendered++;
- /* update buffer write index */
- hSpatParamRendCom->dirac_bs_md_write_idx = ( hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length;
+ pop_wmops();
return;
}
/*-------------------------------------------------------------------------
- * ivas_dirac_dec_set_md_map()
+ * compute_hoa_encoder_mtx()
+ *
*
- * Set metadata index mapping for DirAC
*------------------------------------------------------------------------*/
-void ivas_dirac_dec_set_md_map(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- const int16_t nCldfbTs /* i : number of CLDFB time slots */
-)
+void compute_hoa_encoder_mtx(
+ const float *azimuth,
+ const float *elevation,
+ float *response,
+ const int16_t num_responses,
+ const int16_t ambisonics_order )
{
- int16_t num_slots_in_subfr;
- DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
-
- hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
-#ifdef DEBUGGING
- assert( hDirAC );
- assert( hSpatParamRendCom );
-#endif
-
- /* adapt subframes */
- hSpatParamRendCom->num_slots = nCldfbTs;
- hSpatParamRendCom->slots_rendered = 0;
- num_slots_in_subfr = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES;
- hSpatParamRendCom->subframes_rendered = 0;
-
- ivas_jbm_dec_get_adapted_subframes( nCldfbTs, hSpatParamRendCom->subframe_nbslots, &hSpatParamRendCom->nb_subframes );
-
- /* set mapping according to dirac_read_idx */
-
- set_s( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
+ int16_t k, num_sh;
-#ifdef FIX_470_MASA_JBM_EXT
- if ( st_ivas->ivas_format == MASA_FORMAT )
- {
- ivas_jbm_dec_get_md_map_even_spacing( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hSpatParamRendCom->dirac_md_buffer_length, hSpatParamRendCom->render_to_md_map );
- }
- else if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
-#else
- if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
-#endif
- {
- ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, 0, hSpatParamRendCom->dirac_md_buffer_length, hSpatParamRendCom->render_to_md_map );
- }
- else
- {
- ivas_jbm_dec_get_md_map( DEFAULT_JBM_CLDFB_TIMESLOTS, nCldfbTs, num_slots_in_subfr, hSpatParamRendCom->dirac_read_idx, hSpatParamRendCom->dirac_md_buffer_length, hSpatParamRendCom->render_to_md_map );
- }
+ num_sh = ivas_sba_get_nchan( ambisonics_order, 0 );
- if ( hDirAC->hConfig == NULL || hDirAC->hConfig->dec_param_estim == 0 )
+ for ( k = 0; k < num_responses; k++ )
{
- float tmp;
- int16_t sf_idx, slot_idx, slot_idx_abs;
-
- slot_idx_abs = 0;
- for ( sf_idx = 0; sf_idx < hSpatParamRendCom->nb_subframes; sf_idx++ )
- {
- tmp = 0.0f;
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[sf_idx]; slot_idx++ )
- {
- tmp += (float) hSpatParamRendCom->render_to_md_map[slot_idx_abs];
- slot_idx_abs++;
- }
- hSpatParamRendCom->render_to_md_map[sf_idx] = ( (int16_t) roundf( tmp / (float) hSpatParamRendCom->subframe_nbslots[sf_idx] ) + hSpatParamRendCom->dirac_read_idx ) % hSpatParamRendCom->dirac_md_buffer_length;
- }
-
- set_s( &hSpatParamRendCom->render_to_md_map[hSpatParamRendCom->nb_subframes], 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME - hSpatParamRendCom->nb_subframes );
+ ivas_dirac_dec_get_response( (const int16_t) azimuth[k], (const int16_t) elevation[k], &response[k * num_sh], ambisonics_order );
}
return;
@@ -1546,966 +3236,1138 @@ void ivas_dirac_dec_set_md_map(
/*-------------------------------------------------------------------------
- * ivas_dirac_dec()
+ * ivas_dirac_dec_get_frequency_axis()
*
- * DirAC decoding process
+ * DirAC decoding initialization
*------------------------------------------------------------------------*/
-void ivas_dirac_dec(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */
- const int16_t nchan_transport /* i : number of transport channels */
-)
+void ivas_dirac_dec_get_frequency_axis(
+ float *frequency_axis,
+ const int32_t output_Fs,
+ const int16_t num_freq_bands )
{
- int16_t subframe_idx;
- float *output_f_local[MAX_OUTPUT_CHANNELS];
- float cng_td_buffer[L_FRAME16k];
- int16_t nchan_out, n, n_samples_sf;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
-
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
+ int16_t k;
+ float const_part;
- n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * hSpatParamRendCom->slot_size;
-
- for ( n = 0; n < nchan_out; n++ )
+ /* calc cldfb frequency axis */
+ const_part = (float) output_Fs / ( 2.0f * (float) num_freq_bands );
+ for ( k = 0; k < num_freq_bands; ++k )
{
- output_f_local[n] = &output_f[n][0];
+ frequency_axis[k] = ( (float) k + 0.5f ) * const_part;
}
- for ( n = 0; n < nchan_transport; n++ )
- {
- st_ivas->hTcBuffer->tc[n] = output_f[n];
- }
+ return;
+}
- if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
+
+/*-------------------------------------------------------------------------
+ * Local functions
+ *-------------------------------------------------------------------------*/
+
+static void initDiffuseResponses(
+ float *diffuse_response_function,
+ const int16_t num_channels,
+ AUDIO_CONFIG output_config,
+ IVAS_OUTPUT_SETUP hOutSetup,
+ const int16_t ambisonics_order,
+ const IVAS_FORMAT ivas_format,
+ int16_t *num_ele_spk_no_diffuse_rendering,
+ AUDIO_CONFIG transport_config )
+{
+ int16_t i, l, k, idx, num_horizontal_speakers;
+ *num_ele_spk_no_diffuse_rendering = 0;
+
+ if ( output_config == AUDIO_CONFIG_MONO )
{
- Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0];
- st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0];
- generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna );
+ diffuse_response_function[0] = 1.0f;
+ diffuse_response_function[1] = inv_sqrt( 3.0f );
}
+ else if ( !( output_config == AUDIO_CONFIG_FOA || output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_HOA3 ) )
+ {
+ /* set diffuse response function */
+ if ( ivas_format == MC_FORMAT && ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 ) && output_config == AUDIO_CONFIG_5_1_4 )
+ {
+ num_horizontal_speakers = num_channels - NUM_ELEVATED_SPEAKERS;
- ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS );
+ mvr2r( diffuse_response_CICP6, diffuse_response_function, num_horizontal_speakers );
+ set_zero( &diffuse_response_function[num_horizontal_speakers], NUM_ELEVATED_SPEAKERS );
+ *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
+ }
+ else if ( ivas_format == MC_FORMAT && ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 ) && output_config == AUDIO_CONFIG_7_1_4 )
+ {
+ num_horizontal_speakers = num_channels - NUM_ELEVATED_SPEAKERS;
- for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ )
- {
- ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL );
- for ( n = 0; n < nchan_out; n++ )
+ set_f( diffuse_response_function, sqrtf( 1.f / ( (float) num_horizontal_speakers ) ), num_horizontal_speakers );
+ set_zero( &diffuse_response_function[num_horizontal_speakers], NUM_ELEVATED_SPEAKERS );
+ *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT || ivas_format == MC_FORMAT ) && output_config == AUDIO_CONFIG_5_1 && num_channels == 5 )
+#else
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && output_config == AUDIO_CONFIG_5_1 && num_channels == 5 )
+#endif
+ {
+ mvr2r( diffuse_response_CICP6, diffuse_response_function, num_channels );
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_5_1_2 ) && ( num_channels == 7 ) )
+#else
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && output_config == AUDIO_CONFIG_5_1_2 && num_channels == 7 )
+#endif
+ {
+ mvr2r( diffuse_response_CICP14, diffuse_response_function, num_channels );
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_5_1_4 ) && ( num_channels == 9 ) )
+#else
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_5_1_4 ) && ( num_channels == 9 ) )
+#endif
+ {
+ mvr2r( diffuse_response_CICP16, diffuse_response_function, num_channels );
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_LS_CUSTOM ) )
+#else
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_LS_CUSTOM ) )
+#endif
{
- output_f_local[n] += n_samples_sf;
+ if ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 )
+ {
+ /* Detect loudspeakers with elevation */
+ for ( i = 0, num_horizontal_speakers = 0; i < num_channels; i++ )
+ {
+ if ( fabsf( hOutSetup.ls_elevation[i] ) <= 5.f )
+ {
+ num_horizontal_speakers++;
+ diffuse_response_function[i] = 1.f;
+ }
+ else
+ {
+ *num_ele_spk_no_diffuse_rendering += 1;
+ diffuse_response_function[i] = 0.f;
+ }
+ }
+ /* Diffuse only to horizontal plane if enough loudspeakers */
+ if ( num_horizontal_speakers > 2 )
+ {
+ for ( i = 0; i < num_channels; i++ )
+ {
+ diffuse_response_function[i] *= sqrtf( 1.f / (float) num_horizontal_speakers );
+ }
+ }
+ else
+ {
+ *num_ele_spk_no_diffuse_rendering = 0;
+ set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
+ }
+ }
+ else
+ {
+ set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
+ }
+ }
+ else
+ {
+ set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
}
- }
-
- if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
- {
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length;
}
else
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
- }
-
- for ( n = 0; n < nchan_transport; n++ )
- {
- st_ivas->hTcBuffer->tc[n] = NULL;
- }
-
- if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
- {
- st_ivas->hTcBuffer->tc[nchan_transport] = NULL;
+ idx = 0;
+ for ( l = 0; l <= ambisonics_order; l++ )
+ {
+ for ( k = 0; k < ( 2 * l + 1 ); k++ )
+ {
+ diffuse_response_function[idx++] = inv_sqrt( 2.0f * l + 1.0f );
+ }
+ }
}
return;
}
-/*-------------------------------------------------------------------------
- * ivas_dirac_dec_render()
- *
- * DirAC decoding renderer process
- *------------------------------------------------------------------------*/
-
-void ivas_dirac_dec_render(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
- const int16_t nchan_transport, /* i : number of transport channels */
- const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */
- uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */
- uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */
- float *output_f[] /* o : rendered time signal */
-)
+static void protoSignalComputation_shd(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float *proto_direct_buffer_f,
+ float *proto_diffuse_buffer_f,
+ float *reference_power,
+ const int16_t slot_index,
+ const int16_t num_inputs,
+ const int16_t num_outputs_diff,
+ const int16_t num_freq_bands,
+ float *p_Rmat )
{
- int16_t slots_to_render, first_sf, last_sf, subframe_idx;
- uint16_t slot_size, n_samples_sf, ch, nchan_intern;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
- float *output_f_local[MAX_OUTPUT_CHANNELS];
+ int16_t l, k;
+ float *p_proto_direct_buffer;
+ float *p_proto_diffuse_buffer;
+ int16_t Rmat_k[4];
+ float W_real, W_imag;
+ float Y_real, Y_imag;
+ float *p_k[4];
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
+ k = 0; /* to avoid compilation warning */
- nchan_intern = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
-#ifdef DEBUGGING
- assert( hSpatParamRendCom );
-#endif
- for ( ch = 0; ch < nchan_intern; ch++ )
+ p_proto_direct_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * num_inputs;
+ p_proto_diffuse_buffer = proto_diffuse_buffer_f + slot_index * 2 * num_freq_bands * num_outputs_diff;
+
+ if ( num_inputs == 1 )
{
- output_f_local[ch] = output_f[ch];
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ p_proto_direct_buffer[2 * l] = RealBuffer[0][0][l];
+ p_proto_direct_buffer[2 * l + 1] = ImagBuffer[0][0][l];
+ }
}
- slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
+ else if ( num_inputs == 2 )
+ {
+ if ( p_Rmat != 0 )
+ {
+ assert( num_inputs == 4 && "This code block should never be run with num_inputs != 4!" );
- /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
- slots_to_render = min( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered, nSamplesAsked / slot_size );
- *nSamplesRendered = slots_to_render * slot_size;
- first_sf = hSpatParamRendCom->subframes_rendered;
- last_sf = first_sf;
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ W_real = RealBuffer[0][0][l] + RealBuffer[1][0][l];
+ W_imag = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
- while ( slots_to_render > 0 )
- {
- slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
- last_sf++;
- }
+ Y_real = RealBuffer[0][0][l] - RealBuffer[1][0][l];
+ Y_imag = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
-#ifdef DEBUGGING
- assert( slots_to_render == 0 );
-#endif
- for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
- {
- ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL );
- n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size;
- for ( ch = 0; ch < nchan_intern; ch++ )
+ p_proto_direct_buffer[2 * l] = W_real;
+ p_proto_direct_buffer[2 * l + 1] = W_imag;
+ p_proto_direct_buffer[2 * num_freq_bands + 2 * l] = p_Rmat[0] * Y_real;
+ p_proto_direct_buffer[2 * num_freq_bands + 2 * l + 1] = p_Rmat[0] * Y_imag;
+ }
+ }
+ else
{
- output_f_local[ch] += n_samples_sf;
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ W_real = RealBuffer[0][0][l] + RealBuffer[1][0][l];
+ W_imag = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
+
+ p_proto_direct_buffer[2 * l] = W_real;
+ p_proto_direct_buffer[2 * l + 1] = W_imag;
+ {
+ p_proto_direct_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
+ p_proto_direct_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
+ }
+ }
}
}
-
- if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots )
+ else if ( num_inputs >= 4 )
{
- if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
+ p_k[0] = p_proto_direct_buffer;
+ p_k[1] = p_proto_direct_buffer + 2 * num_freq_bands;
+ p_k[2] = p_proto_direct_buffer + 4 * num_freq_bands;
+ p_k[3] = p_proto_direct_buffer + 6 * num_freq_bands;
+ Rmat_k[0] = 0;
+ Rmat_k[1] = 1;
+ Rmat_k[2] = 2;
+ Rmat_k[3] = 0;
+
+ if ( p_Rmat != 0 )
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ assert( num_inputs == 4 && "This code block should never be run with num_inputs != 4!" );
+
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ *( p_k[0] ) = RealBuffer[0][0][l];
+ reference_power[l + num_freq_bands] = *( p_k[0] ) * *( p_k[0] );
+ p_k[0]++;
+ *( p_k[0] ) = ImagBuffer[0][0][l];
+ reference_power[l + num_freq_bands] += *( p_k[0] ) * *( p_k[0] );
+ p_k[0]++;
+ reference_power[l] = 0.5f * reference_power[l + num_freq_bands];
+
+ for ( k = 1; k < 4; k++ )
+ {
+ *( p_k[k] ) = p_Rmat[3 * Rmat_k[k] + 1] * RealBuffer[1][0][l] + p_Rmat[3 * Rmat_k[k] + 2] * RealBuffer[2][0][l] + p_Rmat[3 * Rmat_k[k] + 0] * RealBuffer[3][0][l];
+ reference_power[l + ( k + 1 ) * num_freq_bands] = *( p_k[k] ) * *( p_k[k] );
+ p_k[k]++;
+ *( p_k[k] ) = p_Rmat[3 * Rmat_k[k] + 1] * ImagBuffer[1][0][l] + p_Rmat[3 * Rmat_k[k] + 2] * ImagBuffer[2][0][l] + p_Rmat[3 * Rmat_k[k] + 0] * ImagBuffer[3][0][l];
+ reference_power[l + ( k + 1 ) * num_freq_bands] += *( p_k[k] ) * *( p_k[k] );
+ p_k[k]++;
+ reference_power[l] += 0.5f * ( reference_power[l + ( k + 1 ) * num_freq_bands] );
+ }
+
+ for ( k = 1; k < 4; k++ )
+ {
+ RealBuffer[k][0][l] = p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l];
+ ImagBuffer[k][0][l] = p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1];
+ }
+ }
}
else
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ set_zero( reference_power, num_freq_bands );
+ for ( k = 0; k < 4; k++ )
+ {
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l] = RealBuffer[k][0][l];
+ p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1] = ImagBuffer[k][0][l];
+ reference_power[l + ( k + 1 ) * num_freq_bands] = RealBuffer[k][0][l] * RealBuffer[k][0][l] + ImagBuffer[k][0][l] * ImagBuffer[k][0][l];
+ reference_power[l] += 0.5f * ( reference_power[l + ( k + 1 ) * num_freq_bands] );
+ }
+ }
+ }
+
+ /* Additional transport channels = planar SBA components of degree higher than 1*/
+ for ( ; k < num_inputs; k++ )
+ {
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l] = RealBuffer[k][0][l];
+ p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1] = ImagBuffer[k][0][l];
+ }
}
}
- *nSamplesAvailable = ( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered ) * slot_size;
+
+ /*Copy direct to diffuse proto*/
+ mvr2r( p_proto_direct_buffer, p_proto_diffuse_buffer, 2 * num_freq_bands * min( num_outputs_diff, num_inputs ) );
+
+ if ( num_inputs == 1 )
+ {
+ /* Add comfort noise addition (CNA) to diffuse proto only*/
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ p_proto_diffuse_buffer[2 * l] += RealBuffer[1][0][l];
+ p_proto_diffuse_buffer[2 * l + 1] += ImagBuffer[1][0][l];
+ }
+ }
return;
}
-/*-------------------------------------------------------------------------
- * ivas_dirac_dec()
- *
- * DirAC decoding process
- *------------------------------------------------------------------------*/
-
-void ivas_dirac_dec_render_sf(
- Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
- float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */
- const int16_t nchan_transport, /* i : number of transport channels */
- float *pppQMfFrame_ts_re[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX],
- float *pppQMfFrame_ts_im[IVAS_MAX_FB_MIXER_IN_CH][CLDFB_NO_COL_MAX] )
+static void protoSignalComputation1(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float *proto_frame_f,
+ float *proto_direct_buffer_f,
+ float *reference_power,
+ float *proto_power_smooth,
+ const int16_t slot_index,
+ const int16_t num_outputs_diff,
+ const int16_t num_freq_bands )
{
- int16_t i, ch, idx_in, idx_lfe;
- DIRAC_DEC_HANDLE hDirAC;
- DIRAC_REND_HANDLE hDirACRend;
- float dirEne;
- float surCohEner;
- float surCohRatio[CLDFB_NO_CHANNELS_MAX];
- int16_t subframe_idx;
- int16_t slot_idx, index_slot;
- int16_t hodirac_flag;
- float *p_Rmat;
- int16_t slot_idx_start, slot_idx_start_cldfb_synth, md_idx;
+ int16_t l, k;
+ float *p_proto_buffer;
- /*CLDFB: last output channels reserved to LFT for CICPx*/
- float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
- float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
-#ifdef SPLIT_REND_WITH_HEAD_ROT
- float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
- float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
-#else
- float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
- float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
-#endif
+ p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands;
- int16_t index, num_freq_bands;
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ reference_power[l] = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ proto_power_smooth[l] += reference_power[l];
+ p_proto_buffer[2 * l] = RealBuffer[0][0][l];
+ p_proto_buffer[2 * l + 1] = ImagBuffer[0][0][l];
- /* local copies of azi, ele, diffuseness */
- int16_t azimuth[CLDFB_NO_CHANNELS_MAX];
- int16_t elevation[CLDFB_NO_CHANNELS_MAX];
- float diffuseness_vector[CLDFB_NO_CHANNELS_MAX];
+ for ( k = 0; k < num_outputs_diff; k++ )
+ {
+ proto_frame_f[2 * k * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
+ proto_frame_f[2 * k * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
+ }
+ }
- DIRAC_DEC_STACK_MEM DirAC_mem;
- float *reference_power, *reference_power_smooth;
- float *onset_filter, *onset_filter_subframe, *p_onset_filter = NULL;
- uint16_t coherence_flag;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
+ return;
+}
- push_wmops( "ivas_dirac_dec_render" );
- /* Initialize aux buffers */
- hDirAC = st_ivas->hDirAC;
- hDirACRend = st_ivas->hDirACRend;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
+static void protoSignalComputation2(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float *proto_frame_f,
+ float *proto_direct_buffer_f,
+ float *reference_power,
+ float *proto_power_smooth,
+ const int16_t isloudspeaker,
+ const int16_t slot_index,
+ const int16_t num_freq_bands,
+ MASA_STEREO_TYPE_DETECT *stereo_type_detect )
+{
+ int16_t l;
+ float *p_proto_buffer;
+ float Real_aux, Imag_aux;
- DirAC_mem = hDirACRend->stack_mem;
+ float left_bb_power, right_bb_power, total_bb_power, lr_bb_power;
+ float lr_total_bb_ratio;
+ float a, b;
- reference_power = DirAC_mem.reference_power;
- reference_power_smooth = DirAC_mem.reference_power + hSpatParamRendCom->num_freq_bands;
- onset_filter = DirAC_mem.onset_filter;
-#ifdef FIX_614_ADD_TO_NULL_PTR_DIRAC_SETUP
- onset_filter_subframe = ( DirAC_mem.onset_filter == NULL ) ? NULL : DirAC_mem.onset_filter + hSpatParamRendCom->num_freq_bands;
-#else
- onset_filter_subframe = DirAC_mem.onset_filter + hSpatParamRendCom->num_freq_bands;
-#endif
+ float left_hi_power, right_hi_power, total_hi_power, lr_hi_power;
+ float lr_total_hi_ratio;
+ float a2, b2;
- hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order );
+ float sum_power;
+ float sum_total_ratio[MASA_SUM_FREQ_RANGE_BINS];
+ float min_sum_total_ratio;
+ float min_sum_total_ratio_db;
- if ( st_ivas->hQMetaData != NULL && st_ivas->ivas_format != SBA_FORMAT )
+ float RealSubtract, ImagSubtract;
+
+ float interpolatorSpaced = 0.0f;
+ float interpolatorDmx = 1.0f;
+
+ int16_t dipole_freq_range[2];
+ float tempSpaced, tempDmx;
+
+ if ( isloudspeaker )
{
- coherence_flag = st_ivas->hQMetaData->coherence_flag;
+ p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 3;
+
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ float Left_power;
+ float Right_power;
+ Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
+ Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
+
+ Left_power = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ Right_power = RealBuffer[1][0][l] * RealBuffer[1][0][l] + ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
+
+ reference_power[l] = Left_power + Right_power;
+ proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
+
+ p_proto_buffer[2 * l] = Real_aux;
+ p_proto_buffer[2 * l + 1] = Imag_aux;
+ proto_power_smooth[l + num_freq_bands] += RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
+
+ proto_power_smooth[l + 2 * num_freq_bands] += RealBuffer[1][0][l] * RealBuffer[1][0][l];
+ proto_power_smooth[l + 2 * num_freq_bands] += ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
+ p_proto_buffer[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
+ p_proto_buffer[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
+
+ proto_frame_f[2 * l] = Real_aux;
+ proto_frame_f[2 * l + 1] = Imag_aux;
+
+ proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
+ proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
+ }
}
- else
+ else if ( stereo_type_detect != NULL )
{
- coherence_flag = 0;
- }
+ p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 2;
-#ifdef DEBUG_MODE_DIRAC
- {
- int16_t n, tmp[IVAS_SPAR_MAX_CH * L_FRAME48k];
- char file_name[50] = { 0 };
- const int16_t output_frame = st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC;
+ left_bb_power = 0.0f;
+ right_bb_power = 0.0f;
+ total_bb_power = 0.0f;
- for ( n = 0; n < nchan_transport; n++ )
+ left_hi_power = 0.0f;
+ right_hi_power = 0.0f;
+ total_hi_power = 0.0f;
+
+ dipole_freq_range[0] = stereo_type_detect->dipole_freq_range[0];
+ dipole_freq_range[1] = stereo_type_detect->dipole_freq_range[1];
+
+ a = 0.01f; /* Temporal smoothing coefficient */
+ b = 1.0f - a; /* Temporal smoothing coefficient */
+ a2 = 0.1f; /* Temporal smoothing coefficient */
+ b2 = 1.0f - a2; /* Temporal smoothing coefficient */
+
+ if ( stereo_type_detect->interpolator > 0 )
{
- for ( i = 0; i < output_frame; i++ )
+ if ( stereo_type_detect->type_change_direction == MASA_STEREO_SPACED_MICS )
{
- tmp[nchan_transport * i + n] = (int16_t) ( output_f[n][i] + 0.5f );
+ interpolatorSpaced = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS );
+ interpolatorDmx = 1.0f - interpolatorSpaced;
+ }
+ else
+ {
+ interpolatorDmx = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS );
+ interpolatorSpaced = 1.0f - interpolatorDmx;
}
}
- sprintf( file_name, "./res/ivas_dirac_dec_DMX%d.%d.pcm", nchan_transport, (int16_t) ( output_frame * 0.05 ) );
- dbgwrite( tmp, sizeof( int16_t ), nchan_transport * output_frame, 1, file_name );
- }
-#endif
- /* Subframe loop */
- slot_idx_start = hSpatParamRendCom->slots_rendered;
- slot_idx_start_cldfb_synth = 0;
+ for ( l = 0; l < num_freq_bands; l++ )
+ {
+ float Left_power;
+ float Right_power;
- subframe_idx = hSpatParamRendCom->subframes_rendered;
- if ( hDirAC->hConfig->dec_param_estim == FALSE )
- {
- md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
- }
- else
- {
- md_idx = hSpatParamRendCom->render_to_md_map[slot_idx_start];
- }
- /* ToDo: Another workaround for self test BE */
+ /* Compute sum signal */
+ Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
+ Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
- /* copy parameters into local buffers*/
- if ( hDirAC->hConfig->dec_param_estim == FALSE )
- {
- mvs2s( hSpatParamRendCom->azimuth[hSpatParamRendCom->render_to_md_map[subframe_idx]], azimuth, hSpatParamRendCom->num_freq_bands );
- mvs2s( hSpatParamRendCom->elevation[hSpatParamRendCom->render_to_md_map[subframe_idx]], elevation, hSpatParamRendCom->num_freq_bands );
- mvr2r( hSpatParamRendCom->diffuseness_vector[hSpatParamRendCom->render_to_md_map[subframe_idx]], diffuseness_vector, hSpatParamRendCom->num_freq_bands );
- }
- else
- {
- set_zero( diffuseness_vector, hSpatParamRendCom->num_freq_bands );
- }
+ /* Compute reference power */
+ Left_power = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ Right_power = RealBuffer[1][0][l] * RealBuffer[1][0][l] + ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
- {
- set_zero( reference_power_smooth, hSpatParamRendCom->num_freq_bands );
- }
- else
- {
- set_zero( onset_filter_subframe, hSpatParamRendCom->num_freq_bands );
- }
+ reference_power[l] = Left_power + Right_power;
- if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] )
- {
- p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0];
+ left_bb_power += Left_power;
+ right_bb_power += Right_power;
+ total_bb_power += reference_power[l];
- if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
- {
- num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
- if ( hDirAC->hConfig->dec_param_estim == FALSE )
+ if ( l > MASA_HI_FREQ_START_BIN )
{
- rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hSpatParamRendCom->num_freq_bands, p_Rmat );
+ left_hi_power += Left_power;
+ right_hi_power += Right_power;
+ total_hi_power += reference_power[l];
}
- }
- }
- else
- {
- p_Rmat = 0;
- }
- if ( hDirAC->hConfig->dec_param_estim == FALSE )
- {
- /* compute response */
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
- {
- ivas_dirac_dec_compute_power_factors( hSpatParamRendCom->num_freq_bands,
- diffuseness_vector,
- hDirACRend->h_output_synthesis_psd_params.max_band_decorr,
- hDirACRend->h_output_synthesis_psd_state.direct_power_factor,
- hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor );
+ if ( l < min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) )
+ {
+ sum_power = Real_aux * Real_aux + Imag_aux * Imag_aux;
- if ( coherence_flag )
+ stereo_type_detect->sum_power[l] = a * sum_power + b * stereo_type_detect->sum_power[l];
+ stereo_type_detect->total_power[l] = a * reference_power[l] + b * stereo_type_detect->total_power[l];
+
+ sum_total_ratio[l] = stereo_type_detect->sum_power[l] / ( stereo_type_detect->total_power[l] + EPSILON );
+ }
+
+ if ( l == 0 )
+ {
+ RealSubtract = RealBuffer[0][0][l] - RealBuffer[1][0][l];
+ ImagSubtract = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
+ stereo_type_detect->subtract_power_y += RealSubtract * RealSubtract + ImagSubtract * ImagSubtract;
+ }
+
+ /* Compute protos (and their power) for direct sound rendering */
+
+ /* W prototype */
+ if ( stereo_type_detect->interpolator > 0 )
{
- for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
+ if ( l < ( dipole_freq_range[1] - 1 ) || l >= MASA_SUM_PROTO_START_BIN )
{
- dirEne = hDirACRend->h_output_synthesis_psd_state.direct_power_factor[i];
- surCohEner = hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor[i] * hSpatParamRendCom->surroundingCoherence[md_idx][i];
- hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor[i] -= surCohEner;
- hDirACRend->h_output_synthesis_psd_state.direct_power_factor[i] += surCohEner;
-
- surCohRatio[i] = surCohEner / ( 1e-12f + dirEne + surCohEner );
+ Real_aux = interpolatorSpaced * 0.5f * Real_aux + interpolatorDmx * Real_aux;
+ Imag_aux = interpolatorSpaced * 0.5f * Imag_aux + interpolatorDmx * Imag_aux;
+ proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
+ p_proto_buffer[2 * l] = Real_aux;
+ p_proto_buffer[2 * l + 1] = Imag_aux;
+ }
+ else
+ {
+ tempSpaced = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ tempDmx = Real_aux * Real_aux + Imag_aux * Imag_aux;
+ proto_power_smooth[l] += interpolatorSpaced * tempSpaced + interpolatorDmx * tempDmx;
+ p_proto_buffer[2 * l] = interpolatorSpaced * RealBuffer[0][0][l] + interpolatorDmx * Real_aux;
+ p_proto_buffer[2 * l + 1] = interpolatorSpaced * ImagBuffer[0][0][l] + interpolatorDmx * Imag_aux;
+ }
+ }
+ else if ( stereo_type_detect->masa_stereo_type == MASA_STEREO_SPACED_MICS )
+ {
+ if ( l < ( dipole_freq_range[1] - 1 ) || l >= MASA_SUM_PROTO_START_BIN )
+ {
+ Real_aux *= 0.5f;
+ Imag_aux *= 0.5f;
+ proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
+ p_proto_buffer[2 * l] = Real_aux;
+ p_proto_buffer[2 * l + 1] = Imag_aux;
+ }
+ else
+ {
+ proto_power_smooth[l] += RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
+ p_proto_buffer[2 * l] = RealBuffer[0][0][l];
+ p_proto_buffer[2 * l + 1] = ImagBuffer[0][0][l];
}
}
else
{
- set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands );
+ proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
+ p_proto_buffer[2 * l] = Real_aux;
+ p_proto_buffer[2 * l + 1] = Imag_aux;
}
- }
- else
- {
- ivas_dirac_dec_compute_gain_factors( hSpatParamRendCom->num_freq_bands,
- hSpatParamRendCom->diffuseness_vector[md_idx],
- hDirACRend->h_output_synthesis_psd_params.max_band_decorr,
- hDirACRend->h_output_synthesis_psd_state.direct_power_factor,
- hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor );
- if ( coherence_flag )
+ /* Y prototype */
+ if ( stereo_type_detect->interpolator > 0 )
{
- for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
+ if ( l < ( dipole_freq_range[0] ) )
{
- surCohRatio[i] = hSpatParamRendCom->surroundingCoherence[md_idx][i];
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * p_proto_buffer[2 * l] + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * p_proto_buffer[2 * l + 1] + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
+ }
+ else if ( l < ( dipole_freq_range[1] ) )
+ {
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] ) + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * ( -( RealBuffer[0][0][l] - RealBuffer[1][0][l] ) ) + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
+ }
+ else
+ {
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * p_proto_buffer[2 * l] + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * p_proto_buffer[2 * l + 1] + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
+ }
+ proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
+ }
+ else if ( stereo_type_detect->masa_stereo_type == MASA_STEREO_SPACED_MICS )
+ {
+ if ( l < ( dipole_freq_range[0] ) ) /* proto = W */
+ {
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = p_proto_buffer[2 * l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = p_proto_buffer[2 * l + 1];
+ proto_power_smooth[l + num_freq_bands] = proto_power_smooth[l];
+ }
+ else if ( l < ( dipole_freq_range[1] ) ) /* proto = -i * (x1-x2) * eq */
+ {
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = -( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
+ proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
+ }
+ else /* proto = W */
+ {
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = p_proto_buffer[2 * l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = p_proto_buffer[2 * l + 1];
+ proto_power_smooth[l + num_freq_bands] = proto_power_smooth[l];
}
}
else
{
- set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands );
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
+ proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
}
+
+ /* Compute protos for decorrelation */
+ proto_frame_f[2 * l] = Real_aux;
+ proto_frame_f[2 * l + 1] = Imag_aux;
+ proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
+ proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
}
- if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 )
+
+ if ( stereo_type_detect->interpolator > 0 )
{
- ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
- hDirACRend,
- st_ivas->hVBAPdata,
- st_ivas->hMasa,
- azimuth,
- elevation,
- md_idx,
- surCohRatio,
- st_ivas->hCombinedOrientationData->shd_rot_max_order,
- p_Rmat,
- hodirac_flag );
+ stereo_type_detect->interpolator++;
+ if ( stereo_type_detect->interpolator == MASA_STEREO_INTERPOLATION_SLOTS )
+ {
+ stereo_type_detect->interpolator = 0;
+ stereo_type_detect->current_stereo_type = stereo_type_detect->type_change_direction;
+ }
}
- else
+
+ stereo_type_detect->left_bb_power = a * left_bb_power + b * stereo_type_detect->left_bb_power;
+ stereo_type_detect->right_bb_power = a * right_bb_power + b * stereo_type_detect->right_bb_power;
+ stereo_type_detect->total_bb_power = a * total_bb_power + b * stereo_type_detect->total_bb_power;
+
+ lr_bb_power = ( stereo_type_detect->left_bb_power < stereo_type_detect->right_bb_power ) ? stereo_type_detect->left_bb_power : stereo_type_detect->right_bb_power;
+ lr_bb_power *= 2.0f;
+ lr_total_bb_ratio = 10.0f * log10f( lr_bb_power / ( stereo_type_detect->total_bb_power + EPSILON ) );
+
+ stereo_type_detect->left_hi_power = a2 * left_hi_power + b2 * stereo_type_detect->left_hi_power;
+ stereo_type_detect->right_hi_power = a2 * right_hi_power + b2 * stereo_type_detect->right_hi_power;
+ stereo_type_detect->total_hi_power = a2 * total_hi_power + b2 * stereo_type_detect->total_hi_power;
+
+ lr_hi_power = ( stereo_type_detect->left_hi_power < stereo_type_detect->right_hi_power ) ? stereo_type_detect->left_hi_power : stereo_type_detect->right_hi_power;
+ lr_hi_power *= 2.0f;
+ lr_total_hi_ratio = 10.0f * log10f( lr_hi_power / ( stereo_type_detect->total_hi_power + EPSILON ) );
+
+ minimum( sum_total_ratio, min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ), &min_sum_total_ratio );
+ min_sum_total_ratio_db = 10.0f * log10f( min_sum_total_ratio );
+
+ stereo_type_detect->lr_total_bb_ratio_db = lr_total_bb_ratio;
+ stereo_type_detect->lr_total_hi_ratio_db = lr_total_hi_ratio;
+ stereo_type_detect->min_sum_total_ratio_db = min_sum_total_ratio_db;
+
+ ivas_masa_stereotype_detection( stereo_type_detect );
+ }
+ else
+ {
+ p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 2;
+
+ for ( l = 0; l < num_freq_bands; l++ )
{
- ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
- hDirACRend,
- st_ivas->hVBAPdata,
- st_ivas->hMasa,
- azimuth,
- elevation,
- md_idx,
- surCohRatio,
- 0,
- NULL,
- hodirac_flag );
+ Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
+ Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
+
+ reference_power[l] = Real_aux * Real_aux + Imag_aux * Imag_aux;
+ proto_power_smooth[l] += reference_power[l];
+ p_proto_buffer[2 * l] = Real_aux;
+ p_proto_buffer[2 * l + 1] = Imag_aux;
+
+ p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
+ p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
+ proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
+
+ proto_frame_f[2 * l] = Real_aux;
+ proto_frame_f[2 * l + 1] = Imag_aux;
+
+ proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
+ proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
+ proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
}
}
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ return;
+}
+
+
+static void protoSignalComputation4(
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float *proto_frame_f,
+ float *proto_direct_buffer_f,
+ float *reference_power,
+ float *proto_power_smooth,
+ const int16_t slot_index,
+ const int16_t num_outputs_diff,
+ const int16_t num_freq_bands,
+ const float *mtx_hoa_decoder,
+ const int16_t nchan_transport,
+ const int16_t *sba_map_tc_ind )
+{
+ int16_t k, l;
+ int16_t n;
+ float sq_tmp;
+ float *p_proto_buffer;
+
+ set_zero( reference_power, num_freq_bands );
+ for ( k = 0; k < 4; k++ )
{
- index_slot = slot_idx_start + slot_idx;
- if ( hDirAC->hConfig->dec_param_estim == TRUE )
+ for ( l = 0; l < num_freq_bands; l++ )
{
- md_idx = hSpatParamRendCom->render_to_md_map[index_slot];
- }
- else
- {
- md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
+ sq_tmp = RealBuffer[k][0][l] * RealBuffer[k][0][l] + ImagBuffer[k][0][l] * ImagBuffer[k][0][l];
+ reference_power[l] += 0.5f * sq_tmp;
}
+ }
- if ( st_ivas->ivas_format == SBA_FORMAT )
- {
- for ( ch = 0; ch < nchan_transport; ch++ )
- {
- mvr2r( pppQMfFrame_ts_re[ch][slot_idx], Cldfb_RealBuffer[ch][0], hSpatParamRendCom->num_freq_bands );
- mvr2r( pppQMfFrame_ts_im[ch][slot_idx], Cldfb_ImagBuffer[ch][0], hSpatParamRendCom->num_freq_bands );
- }
- }
- else
+ /*For decorrelated diffuseness*/
+ for ( l = 0; l < num_outputs_diff; l++ )
+ {
+ for ( k = 0; k < num_freq_bands; k++ )
{
- /* CLDFB Analysis*/
- for ( ch = 0; ch < nchan_transport; ch++ )
+ proto_frame_f[2 * l * num_freq_bands + 2 * k] = 0.f;
+ proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] = 0.f;
+ for ( n = 0; n < nchan_transport; n++ )
{
- cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[hDirACRend->sba_map_tc[ch]][hSpatParamRendCom->num_freq_bands * index_slot] ),
- Cldfb_RealBuffer[ch][0],
- Cldfb_ImagBuffer[ch][0],
- hSpatParamRendCom->num_freq_bands,
- st_ivas->cldfbAnaDec[ch] );
+ proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]];
+ proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]];
}
}
+ }
- /* CNG in DirAC, extra CLDFB ana for CNA*/
- if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT )
+ p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * num_outputs_diff;
+ for ( k = 0; k < num_outputs_diff; k++ )
+ {
+ for ( l = 0; l < num_freq_bands; l++ )
{
- Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0];
-
- generate_masking_noise_dirac( st->hFdCngDec->hFdCngCom,
- st_ivas->cldfbAnaDec[1],
- st_ivas->hTcBuffer->tc[1],
- Cldfb_RealBuffer[1][0],
- Cldfb_ImagBuffer[1][0],
- index_slot,
- st->cna_dirac_flag && st->flag_cna,
- ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->cng_type == FD_CNG && st->cng_sba_flag );
+ sq_tmp = proto_frame_f[k * 2 * num_freq_bands + 2 * l] * proto_frame_f[k * 2 * num_freq_bands + 2 * l] + proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1] * proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1];
+ proto_power_smooth[l + k * num_freq_bands] += sq_tmp;
+ p_proto_buffer[k * 2 * num_freq_bands + 2 * l] = proto_frame_f[k * 2 * num_freq_bands + 2 * l];
+ p_proto_buffer[k * 2 * num_freq_bands + 2 * l + 1] = proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1];
}
+ }
- /* LFE synthesis */
- if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled && !( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && hDirACRend->hOutSetup.num_lfe == 0 ) )
- {
- ivas_lfe_synth_with_cldfb( st_ivas->hMasa->hMasaLfeSynth,
- Cldfb_RealBuffer, Cldfb_ImagBuffer,
- Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1],
- slot_idx,
- md_idx,
- nchan_transport );
- }
+ return;
+}
- /*-----------------------------------------------------------------*
- * protoype signal computation
- *-----------------------------------------------------------------*/
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+/*-------------------------------------------------------------------------
+ * ivas_dirac_dec_compute_diffuse_proto()
+ *
+ * Compute diffuse prototype buffer and smooth power, only for decorrelated bands
+ *------------------------------------------------------------------------*/
+
+static void ivas_dirac_dec_compute_diffuse_proto(
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t slot_idx /* i : slot index */
+)
+{
+ int16_t k, l;
+ int16_t num_freq_bands, num_freq_bands_diff;
+ float *p_diff_buffer, *p_diff_buffer_1;
+ float *p_proto_diff, *p_power_smooth, *proto_frame_dec_f;
+ DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
+ DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
+ int16_t m;
+ float *p_hoa_enc;
+
+ proto_frame_dec_f = hDirAC->proto_frame_dec_f;
+ h_dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ h_dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
+
+ num_freq_bands = hDirAC->num_freq_bands;
+ num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
+
+ p_diff_buffer = h_dirac_output_synthesis_state->proto_diffuse_buffer_f + slot_idx * 2 * num_freq_bands_diff * hDirAC->hOutSetup.nchan_out_woLFE;
+ p_diff_buffer_1 = p_diff_buffer + 1;
+ p_power_smooth = h_dirac_output_synthesis_state->proto_power_diff_smooth;
+
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
+ {
+ for ( k = 0; k < hDirAC->hOutSetup.nchan_out_woLFE; k++ )
{
- if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
- {
- protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f,
- reference_power, slot_idx, nchan_transport,
- hDirACRend->num_outputs_diff,
- hSpatParamRendCom->num_freq_bands,
- p_Rmat );
- }
- else
+ p_proto_diff = proto_frame_dec_f + k * 2 * num_freq_bands;
+ for ( l = 0; l < num_freq_bands_diff; l++ )
{
- protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f,
- reference_power, slot_idx, nchan_transport,
- hDirACRend->num_outputs_diff,
- hSpatParamRendCom->num_freq_bands,
- 0 );
+ *p_diff_buffer = *( p_proto_diff++ );
+ *p_diff_buffer_1 = *( p_proto_diff++ );
+ *( p_power_smooth++ ) += ( *p_diff_buffer ) * ( *p_diff_buffer ) + ( *p_diff_buffer_1 ) * ( *p_diff_buffer_1 );
+ p_diff_buffer += 2;
+ p_diff_buffer_1 += 2;
}
}
- else if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
- {
- protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirACRend->proto_frame_f,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- reference_power, hDirACRend->h_output_synthesis_psd_state.proto_power_smooth,
- 0, slot_idx, hSpatParamRendCom->num_freq_bands, hDirACRend->masa_stereo_type_detect );
- }
- else
+ }
+ else
+ {
+ /*DIRAC_SYNTHESIS_PSD_SHD: Virtual LS->HOA encoding*/
+ for ( k = 0; k < hDirAC->hOutSetup.nchan_out_woLFE; k++ )
{
- switch ( nchan_transport )
+ for ( l = 0; l < num_freq_bands_diff; l++ )
{
- case 11:
- case 8:
- case 6:
- case 4:
- protoSignalComputation4( Cldfb_RealBuffer, Cldfb_ImagBuffer,
- hDirACRend->proto_frame_f,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- reference_power,
- hDirACRend->h_output_synthesis_psd_state.proto_power_smooth,
- slot_idx, hDirACRend->num_outputs_diff,
- hSpatParamRendCom->num_freq_bands,
- hDirACRend->hoa_decoder,
- nchan_transport,
- hDirACRend->sba_map_tc );
- break;
- case 2:
- protoSignalComputation2( Cldfb_RealBuffer, Cldfb_ImagBuffer,
- hDirACRend->proto_frame_f,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- reference_power,
- hDirACRend->h_output_synthesis_psd_state.proto_power_smooth,
- hDirACRend->hOutSetup.is_loudspeaker_setup,
- slot_idx,
- hSpatParamRendCom->num_freq_bands,
- hDirACRend->masa_stereo_type_detect );
- break;
- case 1:
- protoSignalComputation1( Cldfb_RealBuffer, Cldfb_ImagBuffer,
- hDirACRend->proto_frame_f,
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f,
- reference_power,
- hDirACRend->h_output_synthesis_psd_state.proto_power_smooth,
- slot_idx,
- hDirACRend->num_protos_diff,
- hSpatParamRendCom->num_freq_bands );
- break;
- default:
- return;
- }
- }
+ p_hoa_enc = hDirAC->hoa_encoder + k;
+ p_proto_diff = proto_frame_dec_f + 2 * l;
+ *p_diff_buffer = 0.f;
+ *p_diff_buffer_1 = 0.f;
- /*-----------------------------------------------------------------*
- * Compute DirAC parameters at decoder side
- *-----------------------------------------------------------------*/
+ /*LS to HOA*/
+ for ( m = 0; m < hDirAC->num_outputs_diff; m++ )
+ {
+ *p_diff_buffer += ( *p_hoa_enc ) * ( *p_proto_diff );
+ *p_diff_buffer_1 += ( *p_hoa_enc ) * ( *( p_proto_diff + 1 ) );
+ p_hoa_enc += hDirAC->hOutSetup.nchan_out_woLFE;
+ p_proto_diff += 2 * num_freq_bands;
+ }
- if ( hDirAC->hConfig->dec_param_estim == TRUE )
- {
- mvs2s( &hSpatParamRendCom->azimuth[md_idx][hDirAC->hConfig->enc_param_start_band], &azimuth[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band );
- mvs2s( &hSpatParamRendCom->elevation[md_idx][hDirAC->hConfig->enc_param_start_band], &elevation[hDirAC->hConfig->enc_param_start_band], hSpatParamRendCom->num_freq_bands - hDirAC->hConfig->enc_param_start_band );
- if ( ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 )
- {
- num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
- rotateAziEle_DirAC( azimuth, elevation, num_freq_bands, hSpatParamRendCom->num_freq_bands, p_Rmat );
+ *( p_power_smooth++ ) += ( *p_diff_buffer ) * ( *p_diff_buffer ) + ( *p_diff_buffer_1 ) * ( *p_diff_buffer_1 );
+ p_diff_buffer += 2;
+ p_diff_buffer_1 += 2;
}
+ }
+ }
- hDirACRend->index_buffer_intensity = ( hDirACRend->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
+ return;
+}
- index = hDirACRend->index_buffer_intensity;
- num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band];
+/*-------------------------------------------------------------------------
+ * computeDirectionAngles()
+ *
+ *------------------------------------------------------------------------*/
- computeIntensityVector_dec( Cldfb_RealBuffer,
- Cldfb_ImagBuffer,
- num_freq_bands,
- hDirACRend->buffer_intensity_real[0][index - 1],
- hDirACRend->buffer_intensity_real[1][index - 1],
- hDirACRend->buffer_intensity_real[2][index - 1] );
+static void computeDirectionAngles(
+ float *intensity_real_x,
+ float *intensity_real_y,
+ float *intensity_real_z,
+ const int16_t num_frequency_bands,
+ int16_t *azimuth,
+ int16_t *elevation )
+{
+ int16_t k;
+ float intensityNorm;
+ float x, y, z, radius;
- computeDirectionAngles( hDirACRend->buffer_intensity_real[0][index - 1],
- hDirACRend->buffer_intensity_real[1][index - 1],
- hDirACRend->buffer_intensity_real[2][index - 1],
- num_freq_bands,
- azimuth,
- elevation );
+ for ( k = 0; k < num_frequency_bands; ++k )
- mvr2r( reference_power, &( hDirACRend->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
+ {
+ intensityNorm = *( intensity_real_x ) * *( intensity_real_x ) +
+ *( intensity_real_y ) * *( intensity_real_y ) +
+ *( intensity_real_z ) * *( intensity_real_z );
- computeDiffuseness( hDirACRend->buffer_intensity_real, hDirACRend->buffer_energy, num_freq_bands, hSpatParamRendCom->diffuseness_vector[md_idx] );
+ if ( intensityNorm <= EPSILON )
+ {
+ intensityNorm = 1.0f;
+ x = 1.0f;
+ y = 0.0f;
+ z = 0.0f;
+ intensity_real_x++;
+ intensity_real_y++;
+ intensity_real_z++;
}
-
-#ifdef DEBUG_MODE_DIRAC
+ else
{
- static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL;
+ intensityNorm = sqrtf( 1.f / intensityNorm );
+ x = *( intensity_real_x++ ) * intensityNorm;
+ y = *( intensity_real_y++ ) * intensityNorm;
+ z = *( intensity_real_z++ ) * intensityNorm;
+ }
+ radius = sqrtf( x * x + y * y );
+ azimuth[k] = (int16_t) ( max( -180.0f, min( 180.0f, atan2f( y, x ) / EVS_PI * 180.0f ) ) + 0.5f );
+ elevation[k] = (int16_t) ( max( -90.0f, min( 180.0f, atan2f( z, radius ) / EVS_PI * 180.0f ) ) + 0.5f );
+ }
+ return;
+}
- if ( fp_direction_vector == NULL )
- fp_direction_vector = fopen( "./res/dbg_direction_vector_C_dec.bin", "wb" );
- if ( fp_diffuseness == NULL )
- fp_diffuseness = fopen( "./res/dbg_diffuseness_C_dec.bin", "wb" );
- if ( fp_referencePower == NULL )
- fp_referencePower = fopen( "./res/dbg_reference_power_C_dec.bin", "wb" );
+/*-------------------------------------------------------------------------
+ * ivas_masa_init_stereotype_detection()
+ *
+ * Initialize stereo transport signal type detection
+ *------------------------------------------------------------------------*/
- for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ )
- {
- float radius_length;
- float dv[3];
+static void ivas_masa_init_stereotype_detection(
+ MASA_STEREO_TYPE_DETECT *stereo_type_detect )
+{
+ stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
+ stereo_type_detect->current_stereo_type = MASA_STEREO_DOWNMIX;
+ stereo_type_detect->type_change_direction = MASA_STEREO_DOWNMIX;
- if ( hDirAC->hConfig->dec_param_estim == FALSE )
- {
- radius_length = cos( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 );
- dv[0] = radius_length * cos( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 );
- dv[1] = radius_length * sin( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 );
- dv[2] = sin( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 );
+ stereo_type_detect->counter = 0;
+ stereo_type_detect->interpolator = 0;
- fwrite( dv, sizeof( float ), 3, fp_direction_vector );
- fwrite( &( hDirAC->diffuseness_vector[0][i] ), sizeof( float ), 1, fp_diffuseness );
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
- {
- reference_power[i] = Cldfb_RealBuffer[0][0][i] * Cldfb_RealBuffer[0][0][i] + Cldfb_ImagBuffer[0][0][i] * Cldfb_ImagBuffer[0][0][i];
- }
- fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower );
- }
- else
- {
- radius_length = cos( hDirAC->elevation[index_slot][i] * PI_OVER_180 );
- dv[0] = radius_length * cos( hDirAC->azimuth[index_slot][i] * PI_OVER_180 );
- dv[1] = radius_length * sin( hDirAC->azimuth[index_slot][i] * PI_OVER_180 );
- dv[2] = sin( hDirAC->elevation[index_slot][i] * PI_OVER_180 );
+ stereo_type_detect->dipole_freq_range[0] = 1;
+ stereo_type_detect->dipole_freq_range[1] = 3;
- fwrite( dv, sizeof( float ), 3, fp_direction_vector );
- fwrite( &( hDirAC->diffuseness_vector[index_slot][i] ), sizeof( float ), 1, fp_diffuseness );
- fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower );
- }
- }
- }
-#endif
+ stereo_type_detect->left_bb_power = 0.0f; /* Broadband estimates */
+ stereo_type_detect->right_bb_power = 0.0f;
+ stereo_type_detect->total_bb_power = 0.0f;
- /*-----------------------------------------------------------------*
- * frequency domain decorrelation
- *-----------------------------------------------------------------*/
+ stereo_type_detect->left_hi_power = 0.0f; /* High-frequency estimates */
+ stereo_type_detect->right_hi_power = 0.0f;
+ stereo_type_detect->total_hi_power = 0.0f;
+
+ set_zero( stereo_type_detect->sum_power, MASA_SUM_FREQ_RANGE_BINS );
+ set_zero( stereo_type_detect->total_power, MASA_SUM_FREQ_RANGE_BINS );
+
+ stereo_type_detect->subtract_power_y = 0.0f;
+ stereo_type_detect->subtract_power_y_smooth = 0.0f;
+ stereo_type_detect->target_power_y_smooth = 0.0f;
+
+ stereo_type_detect->lr_total_bb_ratio_db = 0.0f;
+ stereo_type_detect->lr_total_hi_ratio_db = 0.0f;
+ stereo_type_detect->min_sum_total_ratio_db = 0.0f;
+ stereo_type_detect->subtract_target_ratio_db = 0.0f;
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * ivas_masa_stereotype_detection()
+ *
+ * Detect the type of the transport audio signals
+ *------------------------------------------------------------------------*/
- if ( hDirACRend->proto_signal_decorr_on == 1 )
- {
- /* decorrelate prototype frame */
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
- {
- ivas_dirac_dec_decorr_process( hSpatParamRendCom->num_freq_bands,
- hDirACRend->num_outputs_diff,
- hDirACRend->num_protos_diff,
- hDirACRend->synthesisConf,
- nchan_transport,
- hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff,
- hDirACRend->num_protos_diff,
- hDirACRend->proto_index_diff,
- hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f + slot_idx * 2 * hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff + 2 * hSpatParamRendCom->num_freq_bands * min( 4, nchan_transport ),
- onset_filter,
- hDirACRend->h_freq_domain_decorr_ap_params,
- hDirACRend->h_freq_domain_decorr_ap_state );
+static void ivas_masa_stereotype_detection(
+ MASA_STEREO_TYPE_DETECT *stereo_type_detect )
+{
+ float lr_total_bb_ratio_db = stereo_type_detect->lr_total_bb_ratio_db;
+ float lr_total_hi_ratio_db = stereo_type_detect->lr_total_hi_ratio_db;
+ float min_sum_total_ratio_db = stereo_type_detect->min_sum_total_ratio_db;
+ float subtract_target_ratio_db = stereo_type_detect->subtract_target_ratio_db;
+ float change_to_spaced;
+ int16_t change_to_spaced_selection;
+ float change_to_downmix;
+ float change_to_downmix2;
+ int16_t change_to_downmix_selection;
+ float subtract_temp;
+ float min_sum_temp;
+ float lr_total_bb_temp;
+ float lr_total_hi_temp;
+
+ /* Determine if the determined features match the spaced mic type */
+ change_to_spaced_selection = 0;
+ if ( subtract_target_ratio_db < -3.0f )
+ {
+ subtract_temp = ( -subtract_target_ratio_db - 3.0f ) / 3.0f;
+ min_sum_temp = max( -min_sum_total_ratio_db / 6.0f, 0.0f );
+ lr_total_bb_temp = lr_total_bb_ratio_db / 6.0f;
- v_multc( onset_filter, 0.25f, onset_filter, hSpatParamRendCom->num_freq_bands );
- v_add( onset_filter, onset_filter_subframe, onset_filter_subframe, hSpatParamRendCom->num_freq_bands );
- p_onset_filter = onset_filter_subframe;
- }
- else
- {
- ivas_dirac_dec_decorr_process( hSpatParamRendCom->num_freq_bands,
- hDirACRend->num_outputs_diff,
- hDirACRend->num_protos_diff,
- hDirACRend->synthesisConf,
- nchan_transport,
- hDirACRend->proto_frame_f,
- hDirACRend->num_protos_diff,
- hDirACRend->proto_index_diff,
- DirAC_mem.frame_dec_f,
- onset_filter,
- hDirACRend->h_freq_domain_decorr_ap_params,
- hDirACRend->h_freq_domain_decorr_ap_state );
+ change_to_spaced = subtract_temp + min_sum_temp + lr_total_bb_temp;
- hDirACRend->proto_frame_dec_f = DirAC_mem.frame_dec_f;
- p_onset_filter = onset_filter;
- }
- }
- else
+ if ( change_to_spaced >= 1.0f )
{
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
- {
- set_f( onset_filter_subframe, 1.f, hSpatParamRendCom->num_freq_bands );
- p_onset_filter = onset_filter_subframe;
- }
- else
- {
- /* no frequency domain decorrelation: use prototype frame */
- hDirACRend->proto_frame_dec_f = hDirACRend->proto_frame_f;
- p_onset_filter = NULL;
- }
+ change_to_spaced_selection = 1;
}
+ }
- /*-----------------------------------------------------------------*
- * output synthesis
- *-----------------------------------------------------------------*/
+ /* Determine if the determined features match the downmix type, according to a metric */
+ change_to_downmix_selection = 0;
+ if ( subtract_target_ratio_db > 0.0f )
+ {
+ subtract_temp = subtract_target_ratio_db / 3.0f;
+ min_sum_temp = ( min_sum_total_ratio_db + 1.0f ) / 6.0f;
+ lr_total_bb_temp = -lr_total_bb_ratio_db / 6.0f;
+
+ change_to_downmix = subtract_temp + min_sum_temp + lr_total_bb_temp;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
+ if ( change_to_downmix >= 1.0f )
{
- /*Compute diffuse prototypes*/
- ivas_dirac_dec_compute_diffuse_proto( hDirACRend, hSpatParamRendCom->num_freq_bands, slot_idx );
+ change_to_downmix_selection = 1;
}
+ }
- /*Compute PSDs*/
- if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 )
+ /* Determine if the determined features match the downmix type, according to another metric */
+ if ( lr_total_hi_ratio_db < -12.0f )
+ {
+ subtract_temp = ( subtract_target_ratio_db + 4.0f ) / 3.0f;
+ min_sum_temp = min_sum_total_ratio_db / 6.0f;
+ lr_total_hi_temp = ( -lr_total_hi_ratio_db - 12.0f ) / 3.0f;
+
+ change_to_downmix2 = subtract_temp + min_sum_temp + lr_total_hi_temp;
+
+ if ( change_to_downmix2 >= 1.0f )
{
- ivas_dirac_dec_output_synthesis_process_slot( reference_power,
- p_onset_filter,
- azimuth,
- elevation,
- hSpatParamRendCom->diffuseness_vector[md_idx],
- hSpatParamRendCom,
- hDirACRend,
- st_ivas->hCombinedOrientationData->shd_rot_max_order,
- p_Rmat,
- st_ivas->hVBAPdata,
- hDirACRend->hOutSetup,
- nchan_transport,
- md_idx,
- hodirac_flag,
- hDirAC->hConfig->dec_param_estim );
+ change_to_downmix_selection = 1;
}
- else
+ }
+
+ if ( stereo_type_detect->counter < 400 )
+ {
+ stereo_type_detect->counter++;
+ }
+ else
+ {
+ if ( change_to_spaced_selection == 1 )
{
- ivas_dirac_dec_output_synthesis_process_slot( reference_power,
- p_onset_filter,
- azimuth,
- elevation,
- hSpatParamRendCom->diffuseness_vector[md_idx],
- hSpatParamRendCom,
- hDirACRend,
- 0,
- 0,
- st_ivas->hVBAPdata,
- hDirACRend->hOutSetup,
- nchan_transport,
- md_idx,
- hodirac_flag,
- hDirAC->hConfig->dec_param_estim );
+ stereo_type_detect->masa_stereo_type = MASA_STEREO_SPACED_MICS;
}
-
- if ( hDirAC->hConfig->dec_param_estim )
+ else if ( change_to_downmix_selection == 1 )
{
- float fac = 1.0f / (float) hSpatParamRendCom->subframe_nbslots[subframe_idx];
- v_multc_acc( hSpatParamRendCom->diffuseness_vector[md_idx], fac, diffuseness_vector, hSpatParamRendCom->num_freq_bands );
+ stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
}
+ }
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( stereo_type_detect->interpolator == 0 )
+ {
+ if ( stereo_type_detect->current_stereo_type != stereo_type_detect->masa_stereo_type )
{
- v_add( reference_power, reference_power_smooth, reference_power_smooth, hSpatParamRendCom->num_freq_bands );
+ stereo_type_detect->interpolator = 1;
+ stereo_type_detect->type_change_direction = stereo_type_detect->masa_stereo_type;
}
}
- ivas_dirac_dec_output_synthesis_get_interpolator( &hDirACRend->h_output_synthesis_psd_params, hSpatParamRendCom->subframe_nbslots[subframe_idx] );
+ return;
+}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+/*-------------------------------------------------------------------------
+ * computeIntensityVector_dec()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static void computeIntensityVector_dec(
+ float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ const int16_t num_frequency_bands,
+ float *intensity_real_x,
+ float *intensity_real_y,
+ float *intensity_real_z )
+{
+ /*
+ * W = a + ib; Y = c + id
+ * real(W*Y') = ac + bd
+ */
+ int16_t i;
+ float real, img;
+
+ for ( i = 0; i < num_frequency_bands; ++i )
{
- ivas_dirac_dec_output_synthesis_process_subframe_gain_shd( Cldfb_RealBuffer,
- Cldfb_ImagBuffer,
- hSpatParamRendCom,
- hDirACRend,
- nchan_transport,
- hSpatParamRendCom->subframe_nbslots[subframe_idx],
- p_onset_filter,
- diffuseness_vector,
- hodirac_flag,
- hDirAC->hConfig->dec_param_estim );
+ real = Cldfb_RealBuffer[0][0][i];
+ img = Cldfb_ImagBuffer[0][0][i];
+ intensity_real_x[i] = Cldfb_RealBuffer[3][0][i] * real + Cldfb_ImagBuffer[3][0][i] * img;
+ intensity_real_y[i] = Cldfb_RealBuffer[1][0][i] * real + Cldfb_ImagBuffer[1][0][i] * img;
+ intensity_real_z[i] = Cldfb_RealBuffer[2][0][i] * real + Cldfb_ImagBuffer[2][0][i] * img;
}
- else
- {
- /* Determine encoding quality based additional smoothing factor */
- float qualityBasedSmFactor = 1.0f;
- if ( st_ivas->hMasa != NULL )
- {
- qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality;
- qualityBasedSmFactor *= qualityBasedSmFactor;
- }
+ return;
+}
- ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( Cldfb_RealBuffer,
- Cldfb_ImagBuffer,
- hSpatParamRendCom,
- hDirACRend,
- hSpatParamRendCom->subframe_nbslots[subframe_idx],
- diffuseness_vector,
- reference_power_smooth,
- qualityBasedSmFactor,
- hDirAC->hConfig->enc_param_start_band );
+/*-------------------------------------------------------------------------
+ * ivas_lfe_synth_with_cldfb()
+ *
+ *
+ *------------------------------------------------------------------------*/
+
+static void ivas_lfe_synth_with_cldfb(
+ MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth,
+ float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float RealBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ float ImagBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
+ const int16_t slot_index,
+ const int16_t subframe_index,
+ const int16_t nchan_transport )
+{
+ float lfeGain;
+ float transportGain;
+ float protoLfeReal, protoLfeImag;
+ int16_t i;
+ float transportEne, protoLfeEne, targetEneLfe, targetEneTrans;
+
+ set_zero( RealBufferLfe[slot_index], CLDFB_NO_CHANNELS_MAX );
+ set_zero( ImagBufferLfe[slot_index], CLDFB_NO_CHANNELS_MAX );
+
+ protoLfeReal = RealBuffer[0][0][0];
+ protoLfeImag = ImagBuffer[0][0][0];
+ transportEne = RealBuffer[0][0][0] * RealBuffer[0][0][0] + ImagBuffer[0][0][0] * ImagBuffer[0][0][0];
+ for ( i = 1; i < nchan_transport; i++ )
+ {
+ protoLfeReal += RealBuffer[i][0][0];
+ protoLfeImag += ImagBuffer[i][0][0];
+ transportEne += RealBuffer[i][0][0] * RealBuffer[i][0][0] + ImagBuffer[i][0][0] * ImagBuffer[i][0][0];
}
+ protoLfeEne = protoLfeReal * protoLfeReal + protoLfeImag * protoLfeImag;
- /*-----------------------------------------------------------------*
- * CLDFB synthesis (and binaural rendering)
- *-----------------------------------------------------------------*/
+ targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
+ targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
- index_slot = slot_idx_start_cldfb_synth;
+ hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
+ hMasaLfeSynth->protoLfeEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
+ hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
+ hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
- if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
- {
- /* Perform binaural rendering */
- ivas_binRenderer( st_ivas->hBinRenderer,
-#ifdef SPLIT_REND_WITH_HEAD_ROT
- &st_ivas->splitBinRend.splitrend.multiBinPoseData,
-#endif
- st_ivas->hCombinedOrientationData,
- subframe_idx,
- hSpatParamRendCom->subframe_nbslots[subframe_idx],
- Cldfb_RealBuffer_Binaural,
- Cldfb_ImagBuffer_Binaural,
- Cldfb_RealBuffer,
- Cldfb_ImagBuffer );
+ hMasaLfeSynth->transportEneSmooth += transportEne;
+ hMasaLfeSynth->protoLfeEneSmooth += protoLfeEne;
+ hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
+ hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
-#ifdef SPLIT_REND_WITH_HEAD_ROT
- if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ||
- ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
- {
- int16_t pos_idx;
-#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
- for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
-#else
- for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
-#endif
- {
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
- {
- for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
- {
- mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands );
- mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands );
- }
- }
- }
- }
-#endif
- /* Inverse CLDFB*/
- for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
- {
- /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
- float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
- float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
+ lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->protoLfeEneSmooth ) ) );
+ transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
- {
-#ifdef SPLIT_REND_WITH_HEAD_ROT
- RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i];
- ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i];
-#else
- RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i];
- ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i];
-#endif
- }
+ RealBufferLfe[slot_index][0] = protoLfeReal * lfeGain;
+ ImagBufferLfe[slot_index][0] = protoLfeImag * lfeGain;
- cldfbSynthesis( RealBuffer,
- ImagBuffer,
- &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ),
- hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx],
- st_ivas->cldfbSynDec[ch] );
- }
- }
- else if ( st_ivas->ivas_format == SBA_FORMAT )
+ RealBuffer[0][0][0] *= transportGain;
+ ImagBuffer[0][0][0] *= transportGain;
+ for ( i = 1; i < nchan_transport; i++ )
{
- for ( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ )
- {
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
- {
- mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hSpatParamRendCom->num_freq_bands );
- mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hSpatParamRendCom->num_freq_bands );
- }
- }
+ RealBuffer[i][0][0] *= transportGain;
+ ImagBuffer[i][0][0] *= transportGain;
}
- else
- {
- float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
- float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
- int16_t outchannels;
- idx_in = 0;
- idx_lfe = 0;
+ return;
+}
- outchannels = hDirACRend->hOutSetup.nchan_out_woLFE + hDirACRend->hOutSetup.num_lfe;
- if ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1 ||
- hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_7_1 ||
- hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1_2 ||
- hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_5_1_4 ||
- hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_7_1_4 ||
- ( hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) )
- {
- outchannels++;
- }
- if ( hDirACRend->hOutSetup.separateChannelEnabled && hDirACRend->hOutSetup.output_config == AUDIO_CONFIG_LS_CUSTOM )
- {
- float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
- float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES];
- const int16_t subframe_start_sample = index_slot * hSpatParamRendCom->num_freq_bands;
- const int16_t num_samples_subframe = hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx];
+/*-------------------------------------------------------------------------
+ * rotateAziEle_DirAC()
+ *
+ * Apply rotation to DirAC DOAs
+ *------------------------------------------------------------------------*/
- /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */
- mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe );
- mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe );
+static void rotateAziEle_DirAC(
+ int16_t *azi, /* i/o: array of azimuth values */
+ int16_t *ele, /* i/o: array of elevation values */
+ const int16_t band1, /* i : bands to work on (lower limit) */
+ const int16_t band2, /* i : bands to work on (upper bound) */
+ const float *p_Rmat /* i : pointer to real-space rotation matrix */
+)
+{
+ int16_t b;
+ float dv_0, dv_1, dv_2;
+ float dv_r_0, dv_r_1, dv_r_2;
+ float w;
- for ( ch = 0; ch < outchannels; ch++ )
- {
- if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) )
- {
- /* Move the LFE channel to the correct place */
- mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
+ push_wmops( "rotateAziEle_DirAC" );
- if ( idx_lfe < ( hDirACRend->hOutSetup.num_lfe - 1 ) )
- {
- idx_lfe++;
- }
- }
- else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirACRend->hOutSetup.separateChannelIndex == ch ) )
- {
- /* Move the separated channel to the correct place. Thus, the separated channel is
- * combined with the synthesized channels here when there is a matching channel. */
- mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
- }
- else
- {
- /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
- {
- RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
- ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
- }
- cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] );
+ for ( b = band1; b < band2; b++ )
+ {
- if ( !st_ivas->hLsSetupCustom->separate_ch_found )
- {
- /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel
- * is combined with the synthesized channels here when there is no matching channel. */
- v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe );
- }
+ /*Conversion spherical to cartesian coordinates*/
+ w = cosf( ele[b] * PI_OVER_180 );
+ dv_0 = w * cosf( azi[b] * PI_OVER_180 );
+ dv_1 = w * sinf( azi[b] * PI_OVER_180 );
+ dv_2 = sinf( ele[b] * PI_OVER_180 );
- idx_in++;
- }
- }
- }
- else
- {
- for ( ch = 0; ch < outchannels; ch++ )
- {
- if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) )
- {
- if ( st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled )
- {
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
- {
- RealBuffer[i] = Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i];
- ImagBuffer[i] = Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i];
- }
- cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe] );
- }
- else if ( st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled )
- {
- /* LFE has been synthesized in the time domain, do nothing. */
- }
- else
- {
- set_zero( &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands );
- }
+ dv_r_0 = p_Rmat[0] * dv_0 + p_Rmat[1] * dv_1 + p_Rmat[2] * dv_2;
+ dv_r_1 = p_Rmat[3] * dv_0 + p_Rmat[4] * dv_1 + p_Rmat[5] * dv_2;
+ dv_r_2 = p_Rmat[6] * dv_0 + p_Rmat[7] * dv_1 + p_Rmat[8] * dv_2;
- if ( idx_lfe < ( hDirACRend->hOutSetup.num_lfe - 1 ) )
- {
- idx_lfe++;
- }
- }
- else if ( ( hDirACRend->hOutSetup.separateChannelEnabled ) && ( hDirACRend->hOutSetup.separateChannelIndex == ch ) )
- {
- /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated
- * channel is combined with the synthesized channels here. */
- }
- else
- {
- /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
- {
- RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
- ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
- }
- cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[idx_in] );
- idx_in++;
- }
- }
- }
+ /*Conversion spherical to cartesian coordinates*/
+ azi[b] = (int16_t) ( atan2f( dv_r_1, dv_r_0 ) * _180_OVER_PI );
+ ele[b] = (int16_t) ( atan2f( dv_r_2, sqrtf( dv_r_0 * dv_r_0 + dv_r_1 * dv_r_1 ) ) * _180_OVER_PI );
}
- hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe_idx];
- hSpatParamRendCom->subframes_rendered++;
pop_wmops();
diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_dec/ivas_dirac_decorr_dec.c
similarity index 99%
rename from lib_rend/ivas_dirac_decorr_dec.c
rename to lib_dec/ivas_dirac_decorr_dec.c
index e8311888819097d56c1a30837fe588d2cd501046..3687ed53b186321928374b7f55b33e8f6d99a998 100644
--- a/lib_rend/ivas_dirac_decorr_dec.c
+++ b/lib_dec/ivas_dirac_decorr_dec.c
@@ -37,9 +37,9 @@
#include "cnst.h"
#include "prot.h"
#include "ivas_prot.h"
-#include "ivas_prot_rend.h"
#include "ivas_stat_dec.h"
#include "ivas_cnst.h"
+#include "ivas_rom_com.h"
#include "ivas_rom_dec.h"
#ifdef DEBUGGING
#include "debug.h"
diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_dec/ivas_dirac_onsets_dec.c
similarity index 99%
rename from lib_rend/ivas_dirac_onsets_dec.c
rename to lib_dec/ivas_dirac_onsets_dec.c
index 8a03dc2c50da814c0788b1c81325e87633e0ec46..c094b45ff68aa32a7770f677b3c61e70b763f127 100644
--- a/lib_rend/ivas_dirac_onsets_dec.c
+++ b/lib_dec/ivas_dirac_onsets_dec.c
@@ -36,7 +36,6 @@
#include "cnst.h"
#include "prot.h"
#include "ivas_prot.h"
-#include "ivas_prot_rend.h"
#include "ivas_cnst.h"
#include "ivas_rom_com.h"
#include "ivas_rom_dec.h"
diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_dec/ivas_dirac_output_synthesis_dec.c
similarity index 77%
rename from lib_rend/ivas_dirac_output_synthesis_dec.c
rename to lib_dec/ivas_dirac_output_synthesis_dec.c
index 2788c7f0e17eed921e6e0bcc575dcc2bd36bd42f..68bd32528f3420e69a7361e3b56a75ddc77a792d 100644
--- a/lib_rend/ivas_dirac_output_synthesis_dec.c
+++ b/lib_dec/ivas_dirac_output_synthesis_dec.c
@@ -37,7 +37,6 @@
#include "cnst.h"
#include "prot.h"
#include "ivas_prot.h"
-#include "ivas_prot_rend.h"
#include "ivas_stat_dec.h"
#include "ivas_cnst.h"
#include "ivas_rom_com.h"
@@ -88,12 +87,11 @@ static void normalizePanningGains( float *direct_response, const int16_t num_cha
*------------------------------------------------------------------------*/
ivas_error ivas_dirac_dec_output_synthesis_open(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- RENDERER_TYPE renderer_type, /* i : renderer type */
- const int16_t nchan_transport, /* i : number of transport channels */
- const int32_t output_Fs, /* i : output sampling rate */
- const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ RENDERER_TYPE renderer_type, /* i : renderer type */
+ const int16_t nchan_transport, /* i : number of transport channels */
+ const int32_t output_Fs, /* i : output sampling rate */
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
)
{
int16_t idx, ch_idx;
@@ -103,20 +101,20 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
float temp_alpha_synthesis[CLDFB_NO_CHANNELS_MAX];
/* pointers to structs for allocation */
- DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
+ DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
/* check / set input parameters */
- assert( hSpatParamRendCom->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
- assert( hDirACRend->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
- assert( hDirACRend->num_outputs_diff > 0 );
- assert( hSpatParamRendCom->slot_size > 0 );
- assert( hDirACRend->hOutSetup.is_loudspeaker_setup == 0 || hDirACRend->hOutSetup.is_loudspeaker_setup == 1 );
- assert( hDirACRend->diffuse_response_function != NULL );
+ assert( hDirAC->num_freq_bands > 0 && "Error: Number of frequency bands <= 0!" );
+ assert( hDirAC->hOutSetup.nchan_out_woLFE > 0 && "Error: Number of output channels > 0!" );
+ assert( hDirAC->num_outputs_diff > 0 );
+ assert( hDirAC->slot_size > 0 );
+ assert( hDirAC->hOutSetup.is_loudspeaker_setup == 0 || hDirAC->hOutSetup.is_loudspeaker_setup == 1 );
+ assert( hDirAC->diffuse_response_function != NULL );
- if ( hDirACRend->proto_signal_decorr_on )
+ if ( hDirAC->proto_signal_decorr_on )
{
- dirac_output_synthesis_params->max_band_decorr = hDirACRend->h_freq_domain_decorr_ap_params->max_band_decorr;
+ dirac_output_synthesis_params->max_band_decorr = hDirAC->h_freq_domain_decorr_ap_params->max_band_decorr;
}
else
{
@@ -128,16 +126,16 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
*-----------------------------------------------------------------*/
dirac_output_synthesis_state->diffuse_responses_square = NULL;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( 2 * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
- else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ else if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
{
- if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->diffuse_responses_square = (float *) malloc( hDirAC->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
@@ -145,16 +143,16 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
/* prototype power buffers */
dirac_output_synthesis_state->proto_power_smooth_prev = NULL;
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
{
- if ( ( dirac_output_synthesis_state->proto_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->proto_power_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_protos_dir * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
- if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
+ if ( dirac_output_synthesis_params->max_band_decorr > 0 && ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS || hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD ) )
{
- if ( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->proto_power_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirAC->hOutSetup.nchan_out_woLFE * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
@@ -173,42 +171,42 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
/* target PSD buffers */
if ( hodirac_flag )
{
- size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
+ size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir * DIRAC_HO_NUMSECTORS;
}
else
{
- size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
+ size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir;
}
if ( ( dirac_output_synthesis_state->cy_cross_dir_smooth_prev = (float *) malloc( size * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
dirac_output_synthesis_state->cy_auto_dir_smooth_prev = NULL;
- if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
else
{
- if ( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->cy_auto_dir_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_dir * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
{
- if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_dir * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
else
{
- if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->cy_auto_diff_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
@@ -221,23 +219,23 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
- else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirACRend->synthesisConf != DIRAC_SYNTHESIS_MONO )
+ else if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD && hDirAC->synthesisConf != DIRAC_SYNTHESIS_MONO )
{
- if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_diff * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
}
else
{
- if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->gains_diff_prev = (float *) malloc( hDirAC->num_freq_bands * hDirAC->num_outputs_dir * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
@@ -248,32 +246,32 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
*-----------------------------------------------------------------*/
/* compute alpha */
- if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
+ if ( !( renderer_type == RENDERER_BINAURAL_PARAMETRIC || renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) )
{
- computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX, &dirac_output_synthesis_params->numAlphas, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
+ computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS, DIRAC_ALPHA_MAX, &dirac_output_synthesis_params->numAlphas, hDirAC->slot_size, hDirAC->num_freq_bands, hDirAC->frequency_axis, output_Fs );
if ( ( dirac_output_synthesis_params->alpha_synthesis = (float *) malloc( dirac_output_synthesis_params->numAlphas * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis, dirac_output_synthesis_params->numAlphas );
- computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST, &dirac_output_synthesis_params->numAlphasFast, hSpatParamRendCom->slot_size, hSpatParamRendCom->num_freq_bands, hDirACRend->frequency_axis, output_Fs );
+ computeAlphaSynthesis( temp_alpha_synthesis, DIRAC_AVG_LENGTH_SYNTH_MS_FAST, DIRAC_ALPHA_MAX_FAST, &dirac_output_synthesis_params->numAlphasFast, hDirAC->slot_size, hDirAC->num_freq_bands, hDirAC->frequency_axis, output_Fs );
if ( ( dirac_output_synthesis_params->alpha_synthesis_fast = (float *) malloc( dirac_output_synthesis_params->numAlphasFast * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
mvr2r( temp_alpha_synthesis, dirac_output_synthesis_params->alpha_synthesis_fast, dirac_output_synthesis_params->numAlphasFast );
- if ( ( dirac_output_synthesis_state->reference_power_smooth_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->reference_power_smooth_prev = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
- if ( ( dirac_output_synthesis_state->direction_smoothness_prev = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
+ if ( ( dirac_output_synthesis_state->direction_smoothness_prev = (float *) malloc( hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC synthesis\n" ) );
}
- set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hSpatParamRendCom->num_freq_bands );
- set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hSpatParamRendCom->num_freq_bands );
+ set_zero( dirac_output_synthesis_state->reference_power_smooth_prev, hDirAC->num_freq_bands );
+ set_zero( dirac_output_synthesis_state->direction_smoothness_prev, hDirAC->num_freq_bands );
}
else
{
@@ -290,13 +288,13 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
}
/* prepare diffuse response function */
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
num_diffuse_responses = 2;
}
else
{
- num_diffuse_responses = hDirACRend->hOutSetup.nchan_out_woLFE;
+ num_diffuse_responses = hDirAC->hOutSetup.nchan_out_woLFE;
}
if ( dirac_output_synthesis_state->diffuse_responses_square != NULL )
@@ -304,34 +302,34 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
for ( ch_idx = 0; ch_idx < num_diffuse_responses; ++ch_idx )
{
/*dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = pow(dirac_output_synthesis_params->diffuse_response_function[ch_idx]/max_response, 2.0f);*/
- tmp = hDirACRend->diffuse_response_function[ch_idx];
+ tmp = hDirAC->diffuse_response_function[ch_idx];
dirac_output_synthesis_state->diffuse_responses_square[ch_idx] = tmp * tmp;
}
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
int16_t diff_compensation_order;
float diff_nrg_total, diff_nrg, diff_nrg_trans, diff_nrg_decorr;
diff_compensation_order = nchan_transport >= 3 ? 3 : 2; /* compensate missing diffuseness modelling up order 2, except for HR*/
- diff_compensation_order = min( diff_compensation_order, hDirACRend->hOutSetup.ambisonics_order );
+ diff_compensation_order = min( diff_compensation_order, hDirAC->hOutSetup.ambisonics_order );
diff_nrg_total = 0;
diff_nrg_trans = 0;
diff_nrg_decorr = 0;
for ( ch_idx = 0; ch_idx < ( diff_compensation_order + 1 ) * ( diff_compensation_order + 1 ); ch_idx++ )
{
- diff_nrg = hDirACRend->diffuse_response_function[ch_idx] * hDirACRend->diffuse_response_function[ch_idx];
+ diff_nrg = hDirAC->diffuse_response_function[ch_idx] * hDirAC->diffuse_response_function[ch_idx];
diff_nrg_total += diff_nrg;
/* is it a transport channel?*/
- if ( ch_idx == 0 || hDirACRend->proto_index_dir[ch_idx] != 0 )
+ if ( ch_idx == 0 || hDirAC->proto_index_dir[ch_idx] != 0 )
{
diff_nrg_trans += diff_nrg;
}
/* is it a decorrelated or transport channel?*/
- if ( ch_idx < hDirACRend->num_outputs_diff )
+ if ( ch_idx < hDirAC->num_outputs_diff )
{
diff_nrg_decorr += diff_nrg;
}
@@ -356,10 +354,9 @@ ivas_error ivas_dirac_dec_output_synthesis_open(
*------------------------------------------------------------------------*/
void ivas_dirac_dec_output_synthesis_init(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */
- const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
)
{
int16_t size;
@@ -367,8 +364,8 @@ void ivas_dirac_dec_output_synthesis_init(
DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
- h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
+ h_dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ h_dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
/*-----------------------------------------------------------------*
* init outputSynthesisPSD_Init
@@ -377,45 +374,45 @@ void ivas_dirac_dec_output_synthesis_init(
/* initialize buffers */
if ( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev != NULL )
{
- set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
+ set_zero( h_dirac_output_synthesis_state->cy_auto_dir_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir );
}
if ( hodirac_flag )
{
- size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir * DIRAC_HO_NUMSECTORS;
+ size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir * DIRAC_HO_NUMSECTORS;
}
else
{
- size = hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir;
+ size = hDirAC->num_freq_bands * hDirAC->num_outputs_dir;
}
set_zero( h_dirac_output_synthesis_state->cy_cross_dir_smooth_prev, size );
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
+ set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_diff );
}
- else if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
+ else if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
{
- set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_diff );
+ set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_diff );
}
else
{
- set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
+ set_zero( h_dirac_output_synthesis_state->cy_auto_diff_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir );
}
if ( h_dirac_output_synthesis_state->proto_power_smooth_prev != NULL )
{
- set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_protos_dir );
+ set_zero( h_dirac_output_synthesis_state->proto_power_smooth_prev, hDirAC->num_freq_bands * hDirAC->num_protos_dir );
}
set_zero( h_dirac_output_synthesis_state->gains_dir_prev, size );
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- set_zero( h_dirac_output_synthesis_state->gains_diff_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirACRend->num_outputs_diff );
+ set_zero( h_dirac_output_synthesis_state->gains_diff_prev, h_dirac_output_synthesis_params->max_band_decorr * hDirAC->num_outputs_diff );
}
else
{
- set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hSpatParamRendCom->num_freq_bands * hDirACRend->num_outputs_dir );
+ set_zero( h_dirac_output_synthesis_state->gains_diff_prev, hDirAC->num_freq_bands * hDirAC->num_outputs_dir );
}
if ( h_dirac_output_synthesis_state->proto_power_diff_smooth_prev != NULL )
@@ -434,12 +431,12 @@ void ivas_dirac_dec_output_synthesis_init(
*------------------------------------------------------------------------*/
void ivas_dirac_dec_output_synthesis_close(
- DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */
+ DIRAC_DEC_HANDLE hDirAC /* i/o: DirAC handle */
)
{
/* pointers to structs for allocation */
- DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
+ DIRAC_OUTPUT_SYNTHESIS_PARAMS *dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ DIRAC_OUTPUT_SYNTHESIS_STATE *dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
/*-----------------------------------------------------------------*
* memory deallocation
@@ -540,16 +537,15 @@ void ivas_dirac_dec_output_synthesis_process_slot(
const int16_t *azimuth,
const int16_t *elevation,
const float *diffuseness,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
const int16_t sh_rot_max_order,
const float *p_Rmat, /* i : rotation matrix */
const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
const int16_t nchan_transport, /* i : number of transport channels*/
const int16_t md_idx,
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- const int16_t dec_param_estim )
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+)
{
int16_t num_freq_bands, num_channels_dir;
int16_t num_freq_bands_diff, num_channels_diff;
@@ -559,8 +555,8 @@ void ivas_dirac_dec_output_synthesis_process_slot(
DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
- h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
+ h_dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ h_dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
h_dirac_output_synthesis_state->onset_filter = onset;
@@ -569,22 +565,24 @@ void ivas_dirac_dec_output_synthesis_process_slot(
*-----------------------------------------------------------------*/
/* collect some often used parameters */
- num_freq_bands = hSpatParamRendCom->num_freq_bands;
- num_channels_dir = hDirACRend->num_outputs_dir;
- num_channels_diff = hDirACRend->num_outputs_diff;
+ num_freq_bands = hDirAC->num_freq_bands;
+ num_channels_dir = hDirAC->num_outputs_dir;
+ num_channels_diff = hDirAC->num_outputs_diff;
num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_LS )
{
num_channels_dir = hOutSetup.nchan_out_woLFE;
}
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD && hodirac_flag )
{
- ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
- hDirACRend,
+ ivas_dirac_dec_compute_directional_responses( hDirAC,
hVBAPdata,
NULL,
+#ifdef MASA_AND_OBJECTS
+ NULL,
+#endif
azimuth,
elevation,
md_idx,
@@ -594,157 +592,157 @@ void ivas_dirac_dec_output_synthesis_process_slot(
hodirac_flag );
}
- if ( dec_param_estim == FALSE && hodirac_flag )
+ if ( hDirAC->hConfig->dec_param_estim == FALSE && hodirac_flag )
{
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- v_multc( hSpatParamRendCom->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
+ v_multc( hDirAC->energy_ratio1[md_idx], -1.f, aux_buf, num_freq_bands );
v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
- mvr2r( hSpatParamRendCom->energy_ratio1[md_idx],
+ mvr2r( hDirAC->energy_ratio1[md_idx],
h_dirac_output_synthesis_state->direct_power_factor,
num_freq_bands );
mvr2r( aux_buf,
h_dirac_output_synthesis_state->diffuse_power_factor,
num_freq_bands );
- v_multc( hSpatParamRendCom->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
+ v_multc( hDirAC->energy_ratio2[md_idx], -1.f, aux_buf, num_freq_bands );
v_addc( aux_buf, 1.f, aux_buf, num_freq_bands );
- mvr2r( hSpatParamRendCom->energy_ratio2[md_idx],
- &h_dirac_output_synthesis_state->direct_power_factor[hSpatParamRendCom->num_freq_bands],
+ mvr2r( hDirAC->energy_ratio2[md_idx],
+ &h_dirac_output_synthesis_state->direct_power_factor[hDirAC->num_freq_bands],
num_freq_bands );
mvr2r( aux_buf,
- &h_dirac_output_synthesis_state->diffuse_power_factor[hSpatParamRendCom->num_freq_bands],
+ &h_dirac_output_synthesis_state->diffuse_power_factor[hDirAC->num_freq_bands],
num_freq_bands );
}
else
{
ivas_dirac_dec_compute_gain_factors( num_freq_bands,
- hSpatParamRendCom->diffuseness_vector[md_idx],
+ hDirAC->diffuseness_vector[md_idx],
h_dirac_output_synthesis_params->max_band_decorr,
h_dirac_output_synthesis_state->direct_power_factor,
h_dirac_output_synthesis_state->diffuse_power_factor );
}
}
- else // ( dec_param_estim == TRUE )
- if ( dec_param_estim == TRUE )
- {
-
- /* compute direct responses */
- ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom,
- hDirACRend,
- hVBAPdata,
- NULL,
- azimuth,
- elevation,
- md_idx,
- NULL,
- sh_rot_max_order,
- p_Rmat,
- hodirac_flag );
+ else if ( hDirAC->hConfig->dec_param_estim == TRUE )
+ {
+ /* compute direct responses */
+ ivas_dirac_dec_compute_directional_responses( hDirAC,
+ hVBAPdata,
+ NULL,
+#ifdef MASA_AND_OBJECTS
+ NULL,
+#endif
+ azimuth,
+ elevation,
+ md_idx,
+ NULL,
+ sh_rot_max_order,
+ p_Rmat,
+ hodirac_flag );
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
- {
- ivas_dirac_dec_compute_gain_factors( num_freq_bands,
- diffuseness,
- h_dirac_output_synthesis_params->max_band_decorr,
- h_dirac_output_synthesis_state->direct_power_factor,
- h_dirac_output_synthesis_state->diffuse_power_factor );
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ {
+ ivas_dirac_dec_compute_gain_factors( num_freq_bands,
+ diffuseness,
+ h_dirac_output_synthesis_params->max_band_decorr,
+ h_dirac_output_synthesis_state->direct_power_factor,
+ h_dirac_output_synthesis_state->diffuse_power_factor );
- v_multc( h_dirac_output_synthesis_state->direct_power_factor,
- 0.25f,
- h_dirac_output_synthesis_state->direct_power_factor,
- num_freq_bands );
- v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
- 0.25f,
- h_dirac_output_synthesis_state->diffuse_power_factor,
- num_freq_bands );
+ v_multc( h_dirac_output_synthesis_state->direct_power_factor,
+ 0.25f,
+ h_dirac_output_synthesis_state->direct_power_factor,
+ num_freq_bands );
+ v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
+ 0.25f,
+ h_dirac_output_synthesis_state->diffuse_power_factor,
+ num_freq_bands );
- /*Direct gain*/
- for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
+ /*Direct gain*/
+ for ( ch_idx = 0; ch_idx < min( 4, nchan_transport ); ch_idx++ )
+ {
+ int16_t k;
+ if ( ch_idx != 0 )
{
- int16_t k;
- if ( ch_idx != 0 )
- {
- float a, b, c;
+ float a, b, c;
- /*Directonal sound gain nrg compensation*/
- for ( k = 0; k < num_freq_bands_diff; k++ )
- {
- a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
- b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
- c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
- h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
- }
- for ( ; k < num_freq_bands; k++ )
- {
- a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
- b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
- c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
- h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
- }
+ /*Directonal sound gain nrg compensation*/
+ for ( k = 0; k < num_freq_bands_diff; k++ )
+ {
+ a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
+ b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
+ c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ); /*Diffuseness modellling nrg compensation*/
+ h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
}
- else
+ for ( ; k < num_freq_bands; k++ )
{
- /*Diffuseness modellling nrg compensation*/
- for ( k = 0; k < num_freq_bands_diff; k++ )
- {
- h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) );
- }
- for ( ; k < num_freq_bands; k++ )
- {
- h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) );
- }
+ a = h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands + k];
+ b = reference_power[k + num_freq_bands] / ( reference_power[k + ( ch_idx + 1 ) * num_freq_bands] + EPSILON );
+ c = 1.f + ( 1.f / 6.f ) * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ); /*Diffuseness modellling nrg compensation*/
+ h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( diffuseness[k] * c + ( ( 1.f - diffuseness[k] ) * a * a * b ) );
}
}
-
- /*Directional gain (panning)*/
- for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
- {
- v_mult( h_dirac_output_synthesis_state->direct_power_factor,
- &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
- aux_buf,
- num_freq_bands );
-
- v_add( aux_buf,
- &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
- &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
- num_freq_bands );
- }
-
- /*Diffuse gain*/
- for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
+ else
{
- v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
- hDirACRend->diffuse_response_function[ch_idx],
- aux_buf,
- num_freq_bands_diff );
-
- v_add( aux_buf,
- &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
- &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
- num_freq_bands_diff );
+ /*Diffuseness modellling nrg compensation*/
+ for ( k = 0; k < num_freq_bands_diff; k++ )
+ {
+ h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor_decorr - 1.f ) );
+ }
+ for ( ; k < num_freq_bands; k++ )
+ {
+ h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands + k] += 0.25f * sqrtf( 1.0f + diffuseness[k] * 0.5f * ( h_dirac_output_synthesis_params->diffuse_compensation_factor - 1.f ) );
+ }
}
+ }
- return;
+ /*Directional gain (panning)*/
+ for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_dir; ch_idx++ )
+ {
+ v_mult( h_dirac_output_synthesis_state->direct_power_factor,
+ &h_dirac_output_synthesis_state->direct_responses[ch_idx * num_freq_bands],
+ aux_buf,
+ num_freq_bands );
+
+ v_add( aux_buf,
+ &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
+ &h_dirac_output_synthesis_state->cy_cross_dir_smooth[ch_idx * num_freq_bands],
+ num_freq_bands );
}
- else
+
+ /*Diffuse gain*/
+ for ( ch_idx = min( 4, nchan_transport ); ch_idx < num_channels_diff; ch_idx++ )
{
- /* compute reference and diffuse power factor for this frame */
- ivas_dirac_dec_compute_power_factors( num_freq_bands,
- diffuseness,
- h_dirac_output_synthesis_params->max_band_decorr,
- h_dirac_output_synthesis_state->direct_power_factor,
- h_dirac_output_synthesis_state->diffuse_power_factor );
+ v_multc( h_dirac_output_synthesis_state->diffuse_power_factor,
+ hDirAC->diffuse_response_function[ch_idx],
+ aux_buf,
+ num_freq_bands_diff );
+
+ v_add( aux_buf,
+ &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
+ &h_dirac_output_synthesis_state->cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
+ num_freq_bands_diff );
}
+
+ return;
}
+ else
+ {
+ /* compute reference and diffuse power factor for this frame */
+ ivas_dirac_dec_compute_power_factors( num_freq_bands,
+ diffuseness,
+ h_dirac_output_synthesis_params->max_band_decorr,
+ h_dirac_output_synthesis_state->direct_power_factor,
+ h_dirac_output_synthesis_state->diffuse_power_factor );
+ }
+ }
diff_start_band = 0;
if ( h_dirac_output_synthesis_params->use_onset_filters )
{
computeTargetPSDs_diffuse_with_onsets( num_channels_dir,
num_freq_bands, h_dirac_output_synthesis_params->max_band_decorr,
- hDirACRend->proto_index_diff,
+ hDirAC->proto_index_diff,
h_dirac_output_synthesis_state->diffuse_power_factor,
reference_power,
h_dirac_output_synthesis_state->diffuse_responses_square,
@@ -755,7 +753,7 @@ void ivas_dirac_dec_output_synthesis_process_slot(
}
/* process other PSDs only slot wise for 4 transport channels */
- if ( dec_param_estim == TRUE )
+ if ( hDirAC->hConfig->dec_param_estim == TRUE )
{
computeTargetPSDs_direct( num_channels_dir, num_freq_bands, h_dirac_output_synthesis_state->direct_power_factor, reference_power, h_dirac_output_synthesis_state->direct_responses, h_dirac_output_synthesis_state->direct_responses_square, h_dirac_output_synthesis_state->cy_auto_dir_smooth, h_dirac_output_synthesis_state->cy_cross_dir_smooth );
@@ -775,14 +773,13 @@ void ivas_dirac_dec_output_synthesis_process_slot(
void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
const int16_t nchan_transport, /* i : number of transport channels */
const int16_t nbslots, /* i : number of slots to process */
const float *onset_filter,
float *diffuseness,
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- const int16_t dec_param_estim )
+ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
+)
{
int16_t buf_idx, ch_idx, i, l;
int16_t num_freq_bands, num_freq_bands_diff;
@@ -805,15 +802,15 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
float ratio[DIRAC_HO_NUMSECTORS * CLDFB_NO_CHANNELS_MAX];
/* collect some often used parameters */
- h_dirac_output_synthesis_params = hDirACRend->h_output_synthesis_psd_params;
- h_dirac_output_synthesis_state = hDirACRend->h_output_synthesis_psd_state;
- proto_direct_index = hDirACRend->proto_index_dir;
+ h_dirac_output_synthesis_params = hDirAC->h_output_synthesis_psd_params;
+ h_dirac_output_synthesis_state = hDirAC->h_output_synthesis_psd_state;
+ proto_direct_index = hDirAC->proto_index_dir;
- num_protos_dir = hDirACRend->num_protos_dir;
- num_freq_bands = hSpatParamRendCom->num_freq_bands;
+ num_protos_dir = hDirAC->num_protos_dir;
+ num_freq_bands = hDirAC->num_freq_bands;
num_freq_bands_diff = h_dirac_output_synthesis_params.max_band_decorr;
- num_channels_dir = hDirACRend->num_outputs_dir;
- num_channels_diff = hDirACRend->num_outputs_diff;
+ num_channels_dir = hDirAC->num_outputs_dir;
+ num_channels_diff = hDirAC->num_outputs_diff;
nchan_transport_foa = min( 4, nchan_transport );
@@ -823,6 +820,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
if ( hodirac_flag )
{
+ assert( hDirAC->hConfig->dec_param_estim == FALSE );
/*Direct gain*/
for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
{
@@ -847,7 +845,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
for ( l = 0; l < num_freq_bands; l++ )
{
aux_buf[l] = 1.f - diffuseness[l];
- ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hSpatParamRendCom->num_freq_bands + l];
+ ratio[l] = 1.f - h_dirac_output_synthesis_state.direct_power_factor[hDirAC->num_freq_bands + l];
ratio[l + num_freq_bands] = 1.f - ratio[l];
}
@@ -868,12 +866,12 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
{
v_multc( h_dirac_output_synthesis_state.diffuse_power_factor,
- hDirACRend->diffuse_response_function[ch_idx],
+ hDirAC->diffuse_response_function[ch_idx],
&h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff],
num_freq_bands_diff );
}
}
- else if ( dec_param_estim == FALSE )
+ else if ( hDirAC->hConfig->dec_param_estim == FALSE )
{
/*Direct gain*/
for ( ch_idx = 0; ch_idx < nchan_transport_foa; ch_idx++ )
@@ -908,7 +906,7 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
/*Diffuse gain*/
for ( ch_idx = nchan_transport_foa; ch_idx < num_channels_diff; ch_idx++ )
{
- v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirACRend->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff );
+ v_multc( h_dirac_output_synthesis_state.diffuse_power_factor, hDirAC->diffuse_response_function[ch_idx], &h_dirac_output_synthesis_state.cy_auto_diff_smooth[ch_idx * num_freq_bands_diff], num_freq_bands_diff );
}
}
@@ -1122,8 +1120,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
for ( l = 0; l < num_freq_bands_diff; l++ )
{
g = g1 * ( *( p_gains_diff++ ) ) + g2 * ( *( p_gains_diff_prev++ ) );
- output_real[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
- output_imag[l * num_channels_dir + hDirACRend->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) );
+ output_real[l * num_channels_dir + hDirAC->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) ); /* maps ch_idx 5 to 8 */
+ output_imag[l * num_channels_dir + hDirAC->sba_map_tc[ch_idx]] += g * ( *( p_proto++ ) );
}
}
else
@@ -1140,14 +1138,14 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
* Copy output or HOA decoder
*-----------------------------------------------------------------*/
- if ( hDirACRend->hOutSetup.is_loudspeaker_setup && hDirACRend->hoa_decoder != NULL )
+ if ( hDirAC->hOutSetup.is_loudspeaker_setup && hDirAC->hoa_decoder != NULL )
{
float *p_real, *p_imag;
const float *hoa_decoder;
- hoa_decoder = hDirACRend->hoa_decoder;
+ hoa_decoder = hDirAC->hoa_decoder;
- for ( ch_idx = 0; ch_idx < hDirACRend->hOutSetup.nchan_out_woLFE; ch_idx++ )
+ for ( ch_idx = 0; ch_idx < hDirAC->hOutSetup.nchan_out_woLFE; ch_idx++ )
{
p_real = RealBuffer[ch_idx][buf_idx];
p_imag = ImagBuffer[ch_idx][buf_idx];
@@ -1221,13 +1219,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
const int16_t nbslots, /* i : number of slots to process */
float *diffuseness_vector,
float *reference_power_smooth,
- float qualityBasedSmFactor,
- const int16_t enc_param_start_band )
+ float qualityBasedSmFactor )
{
int16_t buf_idx, num_freq_bands;
int16_t diff_start_band;
@@ -1260,24 +1256,24 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
push_wmops( "dirac_out_synth_sfr" );
- h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
- proto_direct_index = hDirACRend->proto_index_dir;
- num_protos_dir = hDirACRend->num_protos_dir;
- nchan_out_woLFE = hDirACRend->hOutSetup.nchan_out_woLFE;
+ h_dirac_output_synthesis_params = &( hDirAC->h_output_synthesis_psd_params );
+ h_dirac_output_synthesis_state = &( hDirAC->h_output_synthesis_psd_state );
+ proto_direct_index = hDirAC->proto_index_dir;
+ num_protos_dir = hDirAC->num_protos_dir;
+ nchan_out_woLFE = hDirAC->hOutSetup.nchan_out_woLFE;
/* collect some often used parameters */
- num_freq_bands = hSpatParamRendCom->num_freq_bands;
+ num_freq_bands = hDirAC->num_freq_bands;
/*-----------------------------------------------------------------*
* compute target PSDs
*-----------------------------------------------------------------*/
- if ( enc_param_start_band == 0 )
+ if ( hDirAC->hConfig->enc_param_start_band == 0 )
{
diff_start_band = h_dirac_output_synthesis_params->use_onset_filters == 1 ? h_dirac_output_synthesis_params->max_band_decorr : 0;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
nchan_target_psds = 2;
}
@@ -1305,13 +1301,11 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
* compute variables for stereo transport signal type detection
*-----------------------------------------------------------------*/
- if ( hDirACRend->masa_stereo_type_detect != NULL )
+ if ( hDirAC->masa_stereo_type_detect != NULL )
{
- MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect = hDirACRend->masa_stereo_type_detect;
-
p_cy_auto_dir_smooth = h_dirac_output_synthesis_state->cy_auto_dir_smooth;
p_cy_auto_diff_smooth = h_dirac_output_synthesis_state->cy_auto_diff_smooth;
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ if ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
target_power_y = p_cy_auto_dir_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->direct_power_factor[0] ) + EPSILON );
target_power_y += p_cy_auto_diff_smooth[num_freq_bands] / ( sqrtf( h_dirac_output_synthesis_state->diffuse_power_factor[0] ) + EPSILON );
@@ -1320,19 +1314,19 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
{
target_power_y = p_cy_auto_dir_smooth[num_freq_bands] + p_cy_auto_diff_smooth[num_freq_bands];
}
- subtract_power_y = masa_stereo_type_detect->subtract_power_y;
+ subtract_power_y = hDirAC->masa_stereo_type_detect->subtract_power_y;
a = 0.0004f; /* Temporal smoothing coefficient */
b = 1.0f - a; /* Temporal smoothing coefficient */
- masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * masa_stereo_type_detect->target_power_y_smooth;
- masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * masa_stereo_type_detect->subtract_power_y_smooth;
+ hDirAC->masa_stereo_type_detect->target_power_y_smooth = a * target_power_y + b * hDirAC->masa_stereo_type_detect->target_power_y_smooth;
+ hDirAC->masa_stereo_type_detect->subtract_power_y_smooth = a * subtract_power_y + b * hDirAC->masa_stereo_type_detect->subtract_power_y_smooth;
- subtract_target_ratio = masa_stereo_type_detect->subtract_power_y_smooth / ( masa_stereo_type_detect->target_power_y_smooth + EPSILON );
+ subtract_target_ratio = hDirAC->masa_stereo_type_detect->subtract_power_y_smooth / ( hDirAC->masa_stereo_type_detect->target_power_y_smooth + EPSILON );
subtract_target_ratio_db = 10.0f * log10f( subtract_target_ratio );
- masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
+ hDirAC->masa_stereo_type_detect->subtract_target_ratio_db = subtract_target_ratio_db;
- masa_stereo_type_detect->subtract_power_y = 0.0f;
+ hDirAC->masa_stereo_type_detect->subtract_power_y = 0.0f;
}
/*-----------------------------------------------------------------*
@@ -1741,10 +1735,12 @@ static void ivas_dirac_dec_get_response_split_order(
*------------------------------------------------------------------------*/
void ivas_dirac_dec_compute_directional_responses(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
- const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
+ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */
+ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
+ const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
+#ifdef MASA_AND_OBJECTS
+ MASA_ISM_DATA_HANDLE hMasaIsm, /* i : MASA_ISM data structure */
+#endif
const int16_t *azimuth,
const int16_t *elevation,
const int16_t md_idx,
@@ -1772,24 +1768,29 @@ void ivas_dirac_dec_compute_directional_responses(
elevation2 = NULL;
transport_signal_type = MASA_STEREO_NOT_DEFINED;
- if ( hDirACRend->masa_stereo_type_detect != NULL )
+ if ( hDirAC->masa_stereo_type_detect != NULL )
{
- dipole_freq_range[0] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[0];
- dipole_freq_range[1] = hDirACRend->masa_stereo_type_detect->dipole_freq_range[1];
- transport_signal_type = hDirACRend->masa_stereo_type_detect->masa_stereo_type;
+ dipole_freq_range[0] = hDirAC->masa_stereo_type_detect->dipole_freq_range[0];
+ dipole_freq_range[1] = hDirAC->masa_stereo_type_detect->dipole_freq_range[1];
+ transport_signal_type = hDirAC->masa_stereo_type_detect->masa_stereo_type;
}
- num_channels_dir = hDirACRend->num_outputs_dir;
- if ( hSpatParamRendCom->numSimultaneousDirections == 2 )
+ num_channels_dir = hDirAC->num_outputs_dir;
+#ifdef MASA_AND_OBJECTS
+ if ( hDirAC->numParametricDirections == 2 )
+#else
+ if ( hDirAC->numSimultaneousDirections == 2 )
+#endif
{
- azimuth2 = hSpatParamRendCom->azimuth2[md_idx];
- elevation2 = hSpatParamRendCom->elevation2[md_idx];
+ azimuth2 = hDirAC->azimuth2[md_idx];
+ elevation2 = hDirAC->elevation2[md_idx];
}
+
codingBand = -1;
assert( num_channels_dir <= MAX_OUTPUT_CHANNELS && "Number of channels is too high" );
- for ( k = 0; k < hSpatParamRendCom->num_freq_bands; ++k )
+ for ( k = 0; k < hDirAC->num_freq_bands; ++k )
{
if ( hMasa != NULL && k == MASA_band_grouping_24[hMasa->data.band_mapping[codingBand + 1]] )
{
@@ -1798,24 +1799,24 @@ void ivas_dirac_dec_compute_directional_responses(
if ( hMasa != NULL && k > MASA_band_grouping_24[hMasa->data.band_mapping[codingBand]] &&
k < MASA_band_grouping_24[hMasa->data.band_mapping[codingBand + 1]] &&
- k != hDirACRend->h_output_synthesis_psd_params.max_band_decorr )
+ k != hDirAC->h_output_synthesis_psd_params.max_band_decorr )
{
/* Panning gains have to be computed only for the first bin of the coding band in MASA, for other bins the previous values can be used */
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
{
- mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k - 1],
- hSpatParamRendCom->num_freq_bands, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k],
- hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( &hDirAC->h_output_synthesis_psd_state.direct_responses_square[k - 1],
+ hDirAC->num_freq_bands, &hDirAC->h_output_synthesis_psd_state.direct_responses_square[k],
+ hDirAC->num_freq_bands, num_channels_dir );
}
- mvr2r_inc( &hDirACRend->h_output_synthesis_psd_state.direct_responses[k - 1],
- hSpatParamRendCom->num_freq_bands,
- &hDirACRend->h_output_synthesis_psd_state.direct_responses[k],
- hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( &hDirAC->h_output_synthesis_psd_state.direct_responses[k - 1],
+ hDirAC->num_freq_bands,
+ &hDirAC->h_output_synthesis_psd_state.direct_responses[k],
+ hDirAC->num_freq_bands, num_channels_dir );
}
else
{
/* HOA3 PANNING */
- if ( hDirACRend->panningConf == DIRAC_PANNING_HOA3 )
+ if ( hDirAC->panningConf == DIRAC_PANNING_HOA3 )
{
set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS );
set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS );
@@ -1831,36 +1832,41 @@ void ivas_dirac_dec_compute_directional_responses(
}
else
{
- ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order );
+ ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirAC->hOutSetup.ambisonics_order );
if ( hodirac_flag )
{
- ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order );
+ ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirAC->hOutSetup.ambisonics_order );
}
}
- if ( hMasa == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hMasa == NULL && hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
- mvr2r_inc( direct_response_hoa, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response_hoa, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k], hDirAC->num_freq_bands, num_channels_dir );
if ( hodirac_flag )
{
- mvr2r_inc( direct_response_dir2, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k + hSpatParamRendCom->num_freq_bands * num_channels_dir], hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response_dir2, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k + hDirAC->num_freq_bands * num_channels_dir], hDirAC->num_freq_bands, num_channels_dir );
}
}
- else if ( ( ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( hMasa != NULL ) ) ||
- hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirACRend->synthesisConf == DIRAC_SYNTHESIS_MONO )
+ else if ( ( ( hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) && ( hMasa != NULL ) ) ||
+ hDirAC->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD || hDirAC->synthesisConf == DIRAC_SYNTHESIS_MONO )
{
/* Synthesize the first direction */
- spreadCoherencePanningHoa( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_hoa, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
+ spreadCoherencePanningHoa( azimuth[k], elevation[k], hDirAC->spreadCoherence[md_idx][k], direct_response_hoa, num_channels_dir, hDirAC->hOutSetup.ambisonics_order );
+
/* Synthesize the second direction and combine the gains */
- if ( hSpatParamRendCom->numSimultaneousDirections == 2 )
+#ifdef MASA_AND_OBJECTS
+ if ( hDirAC->numParametricDirections == 2 )
+#else
+ if ( hDirAC->numSimultaneousDirections == 2 )
+#endif
{
- spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hDirACRend->hOutSetup.ambisonics_order );
+ spreadCoherencePanningHoa( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hDirAC->hOutSetup.ambisonics_order );
/* Combine gains from the two directions */
- totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
- directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
- directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
+ totalDirect = hDirAC->energy_ratio1[md_idx][k] + hDirAC->energy_ratio2[md_idx][k] + EPSILON;
+ directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect;
+ directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect;
for ( l = 0; l < num_channels_dir; l++ )
{
direct_response_hoa[l] *= directRatio[0];
@@ -1868,6 +1874,58 @@ void ivas_dirac_dec_compute_directional_responses(
}
}
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: Here we probably need to use md_idx for meta access
+ if ( hDirAC->numIsmDirections > 0 )
+ {
+ int16_t dir;
+ float direct_response_temp[MAX_OUTPUT_CHANNELS];
+ float direct_response_ism[MAX_OUTPUT_CHANNELS];
+ float masaDirect;
+ float ismDirect;
+
+ set_zero( direct_response_ism, num_channels_dir );
+
+ for ( dir = 0; dir < hDirAC->numIsmDirections; dir++ )
+ {
+ if ( hMasaIsm->ism_is_edited[dir] )
+ {
+ ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], direct_response_temp, hDirAC->hOutSetup.ambisonics_order );
+ }
+ else
+ {
+ ivas_dirac_dec_get_response( hMasaIsm->azimuth_ism[dir][hDirAC->dirac_read_idx], hMasaIsm->elevation_ism[dir][hDirAC->dirac_read_idx], direct_response_temp, hDirAC->hOutSetup.ambisonics_order );
+ }
+
+ for ( l = 0; l < num_channels_dir; l++ )
+ {
+ direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][hDirAC->dirac_read_idx][k];
+ }
+ }
+
+ masaDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + EPSILON;
+ if ( hDirAC->numParametricDirections == 2 )
+ {
+ masaDirect += hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k];
+ }
+
+ ismDirect = hMasaIsm->energy_ratio_ism[0][hDirAC->dirac_read_idx][k];
+ for ( dir = 1; dir < hDirAC->numIsmDirections; dir++ )
+ {
+ ismDirect += hMasaIsm->energy_ratio_ism[dir][hDirAC->dirac_read_idx][k];
+ }
+
+ totalDirect = masaDirect + ismDirect;
+ directRatio[0] = masaDirect / totalDirect;
+ directRatio[1] = ismDirect / totalDirect;
+ for ( l = 0; l < num_channels_dir; l++ )
+ {
+ direct_response_hoa[l] *= directRatio[0];
+ direct_response_hoa[l] += directRatio[1] * direct_response_ism[l];
+ }
+ }
+#endif
+
/* Synthesize surrounding coherence */
if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
{
@@ -1879,10 +1937,10 @@ void ivas_dirac_dec_compute_directional_responses(
/* Set computed gains */
direct_response = direct_response_hoa;
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
+ if ( hDirAC->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
{
v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
- mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response_square, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses_square[k], hDirAC->num_freq_bands, num_channels_dir );
if ( transport_signal_type == MASA_STEREO_SPACED_MICS )
{
@@ -1894,33 +1952,38 @@ void ivas_dirac_dec_compute_directional_responses(
}
else
{
- set_f( direct_response, 1.0f, hDirACRend->num_protos_ambi );
+ set_f( direct_response, 1.0f, hDirAC->num_protos_ambi );
}
}
- mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k], hDirAC->num_freq_bands, num_channels_dir );
}
else
{
assert( 0 && "Not supported synthesis method!" );
}
}
- else if ( hDirACRend->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
+ else if ( hDirAC->panningConf == DIRAC_PANNING_VBAP ) /*VBAP*/
{
/* Synthesize the first direction */
- spreadCoherencePanningVbap( azimuth[k], elevation[k], hSpatParamRendCom->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
+ spreadCoherencePanningVbap( azimuth[k], elevation[k], hDirAC->spreadCoherence[md_idx][k], direct_response_ls, num_channels_dir, hVBAPdata );
normalizePanningGains( direct_response_ls, num_channels_dir );
/* Synthesize the second direction and combine the gains */
- if ( hSpatParamRendCom->numSimultaneousDirections == 2 )
+#ifdef MASA_AND_OBJECTS
+ if ( hDirAC->numParametricDirections == 2 )
+#else
+ if ( hDirAC->numSimultaneousDirections == 2 )
+#endif
+
{
- spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hSpatParamRendCom->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
+ spreadCoherencePanningVbap( azimuth2[k], elevation2[k], hDirAC->spreadCoherence2[md_idx][k], direct_response_dir2, num_channels_dir, hVBAPdata );
normalizePanningGains( direct_response_dir2, num_channels_dir );
/* Combine gains from the two directions */
- totalDirect = hSpatParamRendCom->energy_ratio1[md_idx][k] + hSpatParamRendCom->energy_ratio2[md_idx][k] + EPSILON;
- directRatio[0] = hSpatParamRendCom->energy_ratio1[md_idx][k] / totalDirect;
- directRatio[1] = hSpatParamRendCom->energy_ratio2[md_idx][k] / totalDirect;
+ totalDirect = hDirAC->energy_ratio1[md_idx][k] + hDirAC->energy_ratio2[md_idx][k] + EPSILON;
+ directRatio[0] = hDirAC->energy_ratio1[md_idx][k] / totalDirect;
+ directRatio[1] = hDirAC->energy_ratio2[md_idx][k] / totalDirect;
for ( l = 0; l < num_channels_dir; l++ )
{
direct_response_ls[l] *= directRatio[0];
@@ -1929,18 +1992,71 @@ void ivas_dirac_dec_compute_directional_responses(
normalizePanningGains( direct_response_ls, num_channels_dir );
}
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: Here we also probably need md_idx
+ if ( hDirAC->numIsmDirections > 0 )
+ {
+ int16_t dir;
+ float direct_response_temp[MAX_OUTPUT_CHANNELS];
+ float direct_response_ism[MAX_OUTPUT_CHANNELS];
+ float masaDirect;
+ float ismDirect;
+
+ set_zero( direct_response_ism, num_channels_dir );
+
+ for ( dir = 0; dir < hDirAC->numIsmDirections; dir++ )
+ {
+ if ( hMasaIsm->ism_is_edited[dir] )
+ {
+ vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism_edited[dir], hMasaIsm->elevation_ism_edited[dir], 1 );
+ }
+ else
+ {
+ vbap_determine_gains( hVBAPdata, direct_response_temp, hMasaIsm->azimuth_ism[dir][hDirAC->dirac_read_idx], hMasaIsm->elevation_ism[dir][hDirAC->dirac_read_idx], 1 );
+ }
+
+ for ( l = 0; l < num_channels_dir; l++ )
+ {
+ direct_response_ism[l] += direct_response_temp[l] * hMasaIsm->energy_ratio_ism[dir][hDirAC->dirac_read_idx][k];
+ }
+ }
+ normalizePanningGains( direct_response_ism, num_channels_dir );
+
+ masaDirect = hDirAC->energy_ratio1[hDirAC->dirac_read_idx][k] + EPSILON;
+ if ( hDirAC->numParametricDirections == 2 )
+ {
+ masaDirect += hDirAC->energy_ratio2[hDirAC->dirac_read_idx][k];
+ }
+
+ ismDirect = hMasaIsm->energy_ratio_ism[0][hDirAC->dirac_read_idx][k];
+ for ( dir = 1; dir < hDirAC->numIsmDirections; dir++ )
+ {
+ ismDirect += hMasaIsm->energy_ratio_ism[dir][hDirAC->dirac_read_idx][k];
+ }
+
+ totalDirect = masaDirect + ismDirect;
+ directRatio[0] = masaDirect / totalDirect;
+ directRatio[1] = ismDirect / totalDirect;
+ for ( l = 0; l < num_channels_dir; l++ )
+ {
+ direct_response_ls[l] *= directRatio[0];
+ direct_response_ls[l] += directRatio[1] * direct_response_ism[l];
+ }
+ normalizePanningGains( direct_response_ls, num_channels_dir );
+ }
+#endif
/* Synthesize surrounding coherence */
if ( surCohRatio != NULL && surCohRatio[k] > 0.f )
{
int16_t num_channels_surrCoh;
num_channels_surrCoh = num_channels_dir;
- num_channels_surrCoh -= hDirACRend->num_ele_spk_no_diffuse_rendering;
+ num_channels_surrCoh -= hDirAC->num_ele_spk_no_diffuse_rendering;
for ( l = 0; l < num_channels_dir; l++ )
{
direct_response_ls[l] *= sqrtf( 1.0f - surCohRatio[k] );
- if ( hDirACRend->diffuse_response_function[l] > 0.f )
+ if ( hDirAC->diffuse_response_function[l] > 0.f )
{
direct_response_ls[l] += sqrtf( surCohRatio[k] / (float) num_channels_surrCoh );
}
@@ -1951,8 +2067,8 @@ void ivas_dirac_dec_compute_directional_responses(
/* Set computed gains */
direct_response = direct_response_ls;
v_mult( direct_response, direct_response, direct_response_square, num_channels_dir );
- mvr2r_inc( direct_response_square, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses_square[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
- mvr2r_inc( direct_response, 1, &hDirACRend->h_output_synthesis_psd_state.direct_responses[k], hSpatParamRendCom->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response_square, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses_square[k], hDirAC->num_freq_bands, num_channels_dir );
+ mvr2r_inc( direct_response, 1, &hDirAC->h_output_synthesis_psd_state.direct_responses[k], hDirAC->num_freq_bands, num_channels_dir );
}
else
{
@@ -2414,12 +2530,21 @@ static void spreadCoherencePanningVbap(
return;
}
+#ifdef MASA_AND_OBJECTS
+ vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation, 0 );
+#else
vbap_determine_gains( hVBAPdata, direct_response, azimuth, elevation );
+#endif
if ( spreadCoh > 0.f )
{
+#ifdef MASA_AND_OBJECTS
+ vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation, 0 );
+ vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation, 0 );
+#else
vbap_determine_gains( hVBAPdata, direct_response_left, azimuth + 30, elevation );
vbap_determine_gains( hVBAPdata, direct_response_right, azimuth - 30, elevation );
+#endif
if ( spreadCoh < 0.5f )
{
diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c
index 616069f25fbe1000500cd49ff6179189ab351bcd..111a9ab18b155eab1e4485ea304dbdd0eb81f31b 100644
--- a/lib_dec/ivas_init_dec.c
+++ b/lib_dec/ivas_init_dec.c
@@ -72,6 +72,7 @@ ivas_error ivas_dec_setup(
Decoder_State *st;
int32_t ivas_total_brate;
ivas_error error;
+
error = IVAS_ERR_OK;
num_bits_read = 0;
@@ -163,20 +164,56 @@ ivas_error ivas_dec_setup(
/* reconfigure in case a change of operation mode is detected */
if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) )
{
- if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->nCPE == 1 )
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->last_ivas_format == MASA_FORMAT )
{
- st_ivas->hCPE[0]->nchan_out = 1;
+#endif
+ if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->nCPE == 1 )
+ {
+ st_ivas->hCPE[0]->nchan_out = 1;
+ }
+ else
+ {
+ if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#ifdef MASA_AND_OBJECTS
}
else
{
- if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
}
+#endif
+ }
+ }
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */
+
+ /* for the DISC mode the number of objects are written at the end of the bitstream, in the MASA metadata */
+ st_ivas->nchan_ism = 2 * st_ivas->bit_stream[ivas_total_brate / FRAMES_PER_SEC - 1] + st_ivas->bit_stream[ivas_total_brate / FRAMES_PER_SEC - 2] + 1;
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism );
+
+ if ( st_ivas->ini_frame > 0 )
+ {
+ /* reconfigure in case a change of operation mode is detected */
+ if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) )
+ {
+ if ( ( error = ivas_omasa_dec_config( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
}
}
+#endif
else if ( st_ivas->ivas_format == MC_FORMAT )
{
/* read MC configuration */
@@ -404,9 +441,21 @@ static ivas_error ivas_read_format(
{
if ( st_ivas->bit_stream[*num_bits_read] )
{
+#ifdef MASA_AND_OBJECTS
+ ( *num_bits_read )++;
+ if ( st_ivas->bit_stream[*num_bits_read] )
+ {
+ /* Placeholder for SBA + objects */
+ }
+ else
+ {
+ st_ivas->ivas_format = MASA_ISM_FORMAT;
+ }
+#else
/* placeholder for combined format signaling */
( *num_bits_read )++;
+#endif
}
( *num_bits_read )++;
@@ -423,6 +472,7 @@ static ivas_error ivas_read_format(
st_ivas->ivas_format = SBA_FORMAT;
}
( *num_bits_read )++;
+
break;
}
}
@@ -705,7 +755,11 @@ ivas_error ivas_init_decoder(
Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
+#ifdef MASA_AND_OBJECTS
+ int16_t i, n, k;
+#else
int16_t i, n;
+#endif
int16_t sce_id, cpe_id;
int16_t numCldfbAnalyses, numCldfbSyntheses;
int16_t granularity, n_channels_transport_jbm;
@@ -714,6 +768,9 @@ ivas_error ivas_init_decoder(
AUDIO_CONFIG output_config;
DECODER_CONFIG_HANDLE hDecoderConfig;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
@@ -727,10 +784,18 @@ ivas_error ivas_init_decoder(
if ( output_config == AUDIO_CONFIG_EXTERNAL )
{
- if ( !( st_ivas->ism_mode == ISM_MODE_PARAM ) )
+#ifdef OMASA_EXT_OUTPUT
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ hDecoderConfig->nchan_out = st_ivas->nchan_transport + st_ivas->nchan_ism;
+ }
+ else
+#endif
+ if ( !( st_ivas->ism_mode == ISM_MODE_PARAM ) )
{
hDecoderConfig->nchan_out = st_ivas->nchan_transport;
}
+
st_ivas->hOutSetup.nchan_out_woLFE = hDecoderConfig->nchan_out;
}
@@ -894,57 +959,82 @@ ivas_error ivas_init_decoder(
st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2;
}
}
- else if ( st_ivas->ivas_format == SBA_FORMAT )
+ else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT )
{
+
if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
{
return error;
}
- if ( ( error = ivas_spar_dec_open( st_ivas, 0 ) ) != IVAS_ERR_OK )
+ if ( st_ivas->ivas_format == MASA_FORMAT )
{
- return error;
+#ifdef MASA_AND_OBJECTS
+ /* if we start in ISM_MODE_NONE in MASA_ISM, that appears as normal MASA, but we may change to a mode with ISMs */
+ st_ivas->ism_extmeta_active = -1;
+ st_ivas->ism_extmeta_cnt = 0;
+#endif
+ if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
-
- if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup )
+ else if ( st_ivas->ivas_format == SBA_FORMAT )
{
- if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_spar_dec_open( st_ivas, 0 ) ) != IVAS_ERR_OK )
{
return error;
}
- }
- if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK )
- {
- return error;
- }
+ if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup )
+ {
+ if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
- if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO )
- {
- if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK )
{
return error;
}
- st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
- }
- else
- {
- int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1];
+ if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO )
+ {
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
- st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
- if ( ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) )
+ st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band;
+ }
+ else
{
- st_ivas->hSpar->enc_param_start_band = 0;
+ int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1];
- set_c( (int8_t *) st_ivas->hQMetaData->twoDirBands, (int8_t) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
- st_ivas->hQMetaData->numTwoDirBands = (uint8_t) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
+ st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
+ if ( ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) )
+ {
+ st_ivas->hSpar->enc_param_start_band = 0;
+
+ set_c( (int8_t *) st_ivas->hQMetaData->twoDirBands, (int8_t) 1, st_ivas->hQMetaData->q_direction[0].cfg.nbands );
+ st_ivas->hQMetaData->numTwoDirBands = (uint8_t) st_ivas->hQMetaData->q_direction[0].cfg.nbands;
+ }
+
+ ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ),
+ st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
}
+ st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
+ }
- ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ),
- st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 );
+ if ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM &&
+ st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && st_ivas->ivas_format != SBA_FORMAT )
+ {
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
}
- st_ivas->sba_dirac_stereo_flag = ivas_get_sba_dirac_stereo_flag( st_ivas );
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
{
@@ -992,52 +1082,95 @@ ivas_error ivas_init_decoder(
/* set CNA/CNG flags */
ivas_sba_set_cna_cng_flag( st_ivas );
}
- else if ( st_ivas->ivas_format == MASA_FORMAT )
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
{
+ st_ivas->ism_extmeta_active = -1;
+ st_ivas->ism_extmeta_cnt = 0;
+
if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
{
return error;
}
- if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ k = 0;
+ ism_total_brate = 0;
+ while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
{
- return error;
+ k++;
}
- if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
{
- if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ /* one separated object */
+ st_ivas->nSCE = 1;
+
+ ism_total_brate = sep_object_brate[k - 2][0];
+ if ( ( error = create_sce_dec( st_ivas, 0, ism_total_brate ) ) != IVAS_ERR_OK )
{
return error;
}
- }
- for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ reset_indices_dec( st_ivas->hSCE[0]->hCoreCoder[0] );
+
+ if ( ( error = ivas_ism_metadata_dec_create( st_ivas, 1, NULL ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
{
- if ( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK )
+ int32_t temp_brate[MAX_SCE];
+ st_ivas->nSCE = st_ivas->nchan_ism; /* number of objects */
+
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ temp_brate[sce_id] = sep_object_brate[k - 2][st_ivas->nSCE - 1];
+ ism_total_brate += temp_brate[sce_id];
+
+ if ( ( error = create_sce_dec( st_ivas, sce_id, temp_brate[sce_id] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ }
+
+ if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, temp_brate ) ) != IVAS_ERR_OK )
{
return error;
}
+ }
- reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] );
+ if ( ( error = ivas_masa_dec_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
}
- for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ if ( ( error = ivas_masa_ism_data_open( st_ivas ) ) != IVAS_ERR_OK )
{
- if ( ( error = create_cpe_dec( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK )
+ return error;
+ }
+
+ if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MONO_DOWNMIX )
+ {
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
+ }
- for ( n = 0; n < CPE_CHANNELS; n++ )
- {
- reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] );
- }
+ if ( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate - ism_total_brate ) ) != IVAS_ERR_OK )
+ {
+ return error;
}
- /* set CNA/CNG flags */
- ivas_sba_set_cna_cng_flag( st_ivas );
+ for ( n = 0; n < CPE_CHANNELS; n++ )
+ {
+ reset_indices_dec( st_ivas->hCPE[0]->hCoreCoder[n] );
+ }
}
+#endif
else if ( st_ivas->ivas_format == MC_FORMAT )
{
if ( st_ivas->mc_mode == MC_MODE_MCT )
@@ -1144,7 +1277,7 @@ ivas_error ivas_init_decoder(
}
}
- if ( st_ivas->nCPE > 1 )
+ if ( st_ivas->nCPE > 1 ) // VE: TBV - is this needed?
{
if ( ( error = create_mct_dec( st_ivas ) ) != IVAS_ERR_OK )
{
@@ -1172,7 +1305,7 @@ ivas_error ivas_init_decoder(
if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO )
{
- if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -1188,7 +1321,11 @@ ivas_error ivas_init_decoder(
}
else
{
+#ifdef MASA_AND_OBJECTS
+ vbap_determine_gains( st_ivas->hVBAPdata, st_ivas->hLsSetupCustom->separate_ch_gains, 0, 0, 0 );
+#else
vbap_determine_gains( st_ivas->hVBAPdata, st_ivas->hLsSetupCustom->separate_ch_gains, 0, 0 );
+#endif
}
}
@@ -1316,8 +1453,7 @@ ivas_error ivas_init_decoder(
}
#endif
}
- /* ParamISM is handled separately from other common config */
- else if ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) )
+ else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
if ( st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
{
@@ -1487,6 +1623,35 @@ ivas_error ivas_init_decoder(
}
}
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ /* Allocate TD renderer for the objects in DISC mode */
+ if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ if ( ( error = ivas_masa_ism_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_DIRAC && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ if ( ( error = ivas_masa_ism_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+#endif
+
if ( st_ivas->ivas_format == ISM_FORMAT &&
st_ivas->ism_mode == ISM_MODE_DISC &&
( st_ivas->renderer_type == RENDERER_TD_PANNING ||
@@ -1821,8 +1986,6 @@ void ivas_initialize_handles_dec(
ivas_init_split_rend_handles( &st_ivas->splitBinRend.splitrend );
#endif
st_ivas->hDiracDecBin = NULL;
- st_ivas->hDirACRend = NULL;
- st_ivas->hSpatParamRendCom = NULL;
st_ivas->hLsSetUpConversion = NULL;
st_ivas->hEFAPdata = NULL;
st_ivas->hVBAPdata = NULL;
@@ -1835,6 +1998,9 @@ void ivas_initialize_handles_dec(
st_ivas->hHrtfFastConv = NULL;
st_ivas->hHrtfParambin = NULL;
st_ivas->hoa_dec_mtx = NULL;
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hMasaIsmData = NULL;
+#endif
st_ivas->hHeadTrackData = NULL;
st_ivas->hHrtfTD = NULL;
@@ -1920,7 +2086,11 @@ void ivas_destroy_dec(
}
/* ISM metadata handles */
+#ifdef MASA_AND_OBJECTS
+ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
+#else
ivas_ism_metadata_close( st_ivas->hIsmMetaData );
+#endif
/* ISM renderer handle */
if ( st_ivas->hIsmRendererData != NULL )
@@ -1933,12 +2103,10 @@ void ivas_destroy_dec(
/* DirAC handle */
if ( st_ivas->ivas_format == ISM_FORMAT )
{
- ivas_param_ism_dec_close( &( st_ivas->hDirAC ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config );
+ ivas_param_ism_dec_close( &( st_ivas->hDirAC ), st_ivas->hDecoderConfig->output_config );
}
else
{
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
}
@@ -2014,6 +2182,11 @@ void ivas_destroy_dec(
st_ivas->hMonoDmxRenderer = NULL;
}
+#ifdef MASA_AND_OBJECTS
+ /* MASA ISM structure */
+ ivas_masa_ism_data_close( &st_ivas->hMasaIsmData );
+#endif
+
/* Head track data handle */
ivas_headTrack_close( &st_ivas->hHeadTrackData );
@@ -2094,6 +2267,44 @@ void ivas_init_dec_get_num_cldfb_instances(
case RENDERER_BINAURAL_PARAMETRIC:
case RENDERER_BINAURAL_PARAMETRIC_ROOM:
case RENDERER_STEREO_PARAMETRIC:
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->nchan_transport == 1 )
+ {
+ *numCldfbAnalyses = st_ivas->nchan_transport + 1;
+ }
+
+ if ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ *numCldfbAnalyses = st_ivas->nchan_transport + 1;
+ }
+
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ *numCldfbAnalyses += st_ivas->nchan_ism;
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ *numCldfbAnalyses = st_ivas->nchan_transport + 1;
+ }
+ }
+
+ if ( st_ivas->hDiracDecBin->useTdDecorr )
+ {
+ *numCldfbAnalyses += 2;
+ }
+ break;
+ case RENDERER_NON_DIEGETIC_DOWNMIX:
+ case RENDERER_MONO_DOWNMIX:
+ if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ /* CLDFB not used in rendering */
+ *numCldfbAnalyses = 0;
+ *numCldfbSyntheses = 0;
+ }
+ break;
+#else
if ( st_ivas->nchan_transport == 1 )
{
*numCldfbAnalyses = st_ivas->nchan_transport + 1;
@@ -2118,6 +2329,7 @@ void ivas_init_dec_get_num_cldfb_instances(
*numCldfbSyntheses = 0;
}
break;
+#endif
case RENDERER_DIRAC:
if ( st_ivas->ivas_format == SBA_FORMAT )
{
@@ -2142,7 +2354,7 @@ void ivas_init_dec_get_num_cldfb_instances(
{
*numCldfbAnalyses = st_ivas->nchan_transport + 1;
}
- else if ( st_ivas->nchan_transport == 1 && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
+ else if ( st_ivas->nchan_transport == 1 && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD )
{
*numCldfbAnalyses = st_ivas->nchan_transport + 1;
}
@@ -2355,5 +2567,15 @@ static ivas_error doSanityChecks_IVAS(
}
#endif
+#ifdef OMASA_EXT_OUTPUT
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && output_config == AUDIO_CONFIG_EXTERNAL )
+ {
+ return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" );
+ }
+ }
+#endif
+
return IVAS_ERR_OK;
}
diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c
index 63464def7f1251008048659757c2a6f21b6228e3..d3d3baa85e59ae52698b779581b8de4b9470d77e 100644
--- a/lib_dec/ivas_ism_dec.c
+++ b/lib_dec/ivas_ism_dec.c
@@ -76,7 +76,12 @@ static ivas_error ivas_ism_bitrate_switching(
ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
st_ivas->ism_mode = ism_mode;
- if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nchan_ism, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL
+#ifdef MASA_AND_OBJECTS
+ ,
+ 0
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -122,13 +127,13 @@ static ivas_error ivas_ism_bitrate_switching(
if ( st_ivas->hDecoderConfig->voip_active )
{
/* transfer subframe info from DirAC or ParamMC to central tc buffer */
- if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hSpatParamRendCom != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) )
+ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hDirAC != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) )
{
- st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
- st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
- st_ivas->hTcBuffer->num_slots = st_ivas->hSpatParamRendCom->num_slots;
- st_ivas->hTcBuffer->slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
- mvs2s( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
+ st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes;
+ st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered;
+ st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots;
+ st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered;
+ mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
/* JBM: when granularity goes down (e.g. Discrete ISM with TD Obj Renderer -> ParamISM with binaural fastconv
@@ -169,9 +174,13 @@ static ivas_error ivas_ism_bitrate_switching(
if ( st_ivas->ism_mode == ISM_MODE_DISC && last_ism_mode == ISM_MODE_PARAM )
{
/* Deallocate the ParamISM struct */
- ivas_param_ism_dec_close( &( st_ivas->hDirAC ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config );
+ ivas_param_ism_dec_close( &( st_ivas->hDirAC ), st_ivas->hDecoderConfig->output_config );
+#ifdef FIX_568_ISM_BITRATE_SWITCHING
if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#else
+ if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL )
+#endif
{
/* close the parametric binaural renderer */
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
@@ -210,7 +219,11 @@ static ivas_error ivas_ism_bitrate_switching(
}
}
+#ifdef FIX_568_ISM_BITRATE_SWITCHING
if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR )
+#else
+ if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#endif
{
/* close the parametric binaural renderer */
ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
@@ -238,7 +251,11 @@ static ivas_error ivas_ism_bitrate_switching(
{
return error;
}
+#ifdef FIX_568_ISM_BITRATE_SWITCHING
if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#else
+ if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL )
+#endif
{
/* open the parametric binaural renderer */
if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
@@ -284,7 +301,11 @@ static ivas_error ivas_ism_bitrate_switching(
}
}
+#ifdef FIX_568_ISM_BITRATE_SWITCHING
if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR )
+#else
+ if ( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+#endif
{
/* open the parametric binaural renderer */
if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
@@ -353,14 +374,14 @@ static ivas_error ivas_ism_bitrate_switching(
}
/* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */
- if ( st_ivas->hSpatParamRendCom != NULL )
+ if ( st_ivas->hDirAC != NULL )
{
- st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
- st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
- st_ivas->hSpatParamRendCom->num_slots = st_ivas->hTcBuffer->num_slots;
- st_ivas->hSpatParamRendCom->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
+ st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
+ st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
+ st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots;
+ st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
- mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
+ mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
}
diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c
index f5ed58974f3d6aa50c18a1da679b3dfc86859a5c..fb7acc33442155efc8d632d75bda94e8f6854699 100644
--- a/lib_dec/ivas_ism_metadata_dec.c
+++ b/lib_dec/ivas_ism_metadata_dec.c
@@ -206,9 +206,15 @@ ivas_error ivas_ism_metadata_dec(
*----------------------------------------------------------------*/
/* number of objects was read in ivas_dec_setup() */
- st0->next_bit_pos += nchan_ism;
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+#endif
+ {
+ /* number of objects was read in ivas_dec_setup() */
+ st0->next_bit_pos += nchan_ism;
- ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate );
+ ism_mode = ivas_ism_mode_select( nchan_ism, ism_total_brate );
+ }
if ( ism_mode == ISM_MODE_PARAM )
{
@@ -225,7 +231,11 @@ ivas_error ivas_ism_metadata_dec(
}
/* read extended metadata presence flag */
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC && ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
+#else
if ( ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
+#endif
{
ism_extmeta_bitstream = get_next_indice( st0, ISM_EXTENDED_METADATA_BITS );
@@ -255,7 +265,17 @@ ivas_error ivas_ism_metadata_dec(
/* Read ISM metadata flags (one per object) */
for ( ch = 0; ch < *nchan_transport; ch++ )
{
- ism_imp[ch] = get_next_indice( st0, ISM_METADATA_FLAG_BITS );
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* ISM importance flag is already read in ivas_masa_decode() */
+ ism_imp[ch] = hIsmMeta[ch]->ism_imp;
+ }
+ else
+#endif
+ {
+ ism_imp[ch] = get_next_indice( st0, ISM_METADATA_FLAG_BITS );
+ }
if ( ism_imp[ch] > ISM_NO_META )
{
@@ -282,8 +302,17 @@ ivas_error ivas_ism_metadata_dec(
{
if ( ism_imp[ch] == ISM_NO_META )
{
+#ifdef MASA_AND_OBJECTS
/* low-rate ISM_NO_META frame */
- null_metadata_flag[ch] = get_next_indice( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ null_metadata_flag[ch] = hIsmMeta[ch]->ism_md_null_flag;
+ }
+ else
+#endif
+ {
+ null_metadata_flag[ch] = get_next_indice( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
+ }
}
}
@@ -291,17 +320,31 @@ ivas_error ivas_ism_metadata_dec(
{
if ( ism_imp[ch] == ISM_NO_META )
{
- if ( null_metadata_flag[ch] )
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
{
- /* read the true ISM class */
- ism_imp[ch] = get_next_indice( st0, ISM_METADATA_FLAG_BITS );
+ lowrate_metadata_flag[ch] = hIsmMeta[ch]->ism_md_lowrate_flag;
+
+ if ( null_metadata_flag[ch] == 0 )
+ {
+ ism_metadata_flag_global |= lowrate_metadata_flag[ch];
+ }
}
else
+#endif
{
- /* read presence of MD in low-rate ISM_NO_META frame flag */
- lowrate_metadata_flag[ch] = get_next_indice( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
+ if ( null_metadata_flag[ch] )
+ {
+ /* read the true ISM class */
+ ism_imp[ch] = get_next_indice( st0, ISM_METADATA_FLAG_BITS );
+ }
+ else
+ {
+ /* read presence of MD in low-rate ISM_NO_META frame flag */
+ lowrate_metadata_flag[ch] = get_next_indice( st0, ISM_METADATA_INACTIVE_FLAG_BITS );
- ism_metadata_flag_global |= lowrate_metadata_flag[ch];
+ ism_metadata_flag_global |= lowrate_metadata_flag[ch];
+ }
}
}
}
@@ -324,7 +367,11 @@ ivas_error ivas_ism_metadata_dec(
for ( ch = 0; ch < nchan_ism; ch++ )
{
hIsmMetaData = hIsmMeta[ch];
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
nb_bits_start = st0->next_bit_pos;
}
@@ -410,7 +457,11 @@ ivas_error ivas_ism_metadata_dec(
}
}
/* save number of metadata bits read */
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
nb_bits_metadata[ch] = st0->next_bit_pos - nb_bits_start;
}
@@ -494,13 +545,38 @@ ivas_error ivas_ism_metadata_dec(
hISMDTX.ism_dtx_hangover_cnt += 1;
}
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ ism_metadata_flag_global = 1;
+ }
+#endif
+
/*----------------------------------------------------------------*
* Configuration and decision about bitrates per channel
*----------------------------------------------------------------*/
if ( !bfi )
{
- if ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK )
+#ifdef MASA_AND_OBJECTS
+ int16_t masa_ism_flag = 0;
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ masa_ism_flag = 1;
+
+ for ( ch = 0; ch < *nchan_transport; ch++ )
+ {
+ element_brate[ch] = hSCE[ch]->element_brate;
+ }
+ }
+#endif
+
+ if ( ( error = ivas_ism_config( ism_total_brate, *nchan_transport, nchan_ism, hIsmMeta, ism_extmeta_bitstream, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata
+#ifdef MASA_AND_OBJECTS
+ ,
+ masa_ism_flag
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -510,16 +586,29 @@ ivas_error ivas_ism_metadata_dec(
hIsmMeta[ch]->last_ism_metadata_flag = hIsmMeta[ch]->ism_metadata_flag;
hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
+#ifdef FIX_562_ISM2_64KBPS
if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
+#else
+ if ( ism_imp[ch] == ISM_NO_META && total_brate[ch] < ACELP_8k00 )
+#endif
{
hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
}
}
- hSCE[ch]->element_brate = element_brate[ch];
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+#endif
+ {
+ hSCE[ch]->element_brate = element_brate[ch];
+ }
hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
}
@@ -605,13 +694,31 @@ ivas_error ivas_ism_metadata_dec_create(
st_ivas->hIsmMetaData[ch]->last_azimuth = 0;
st_ivas->hIsmMetaData[ch]->last_elevation = 0;
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hIsmMetaData[ch]->ism_imp = -1;
+ st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
+ st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
+#endif
+
ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
}
- if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK )
+#ifdef MASA_AND_OBJECTS
+ if ( element_brate_tmp != NULL )
{
- return error;
+#endif
+ if ( ( error = ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, n_ISms, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL
+#ifdef MASA_AND_OBJECTS
+ ,
+ 0
+#endif
+ ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+#ifdef MASA_AND_OBJECTS
}
+#endif
st_ivas->hISMDTX.ism_dtx_hangover_cnt = IVAS_ISM_DTX_HO_MAX;
diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c
index 8cea5347b448516a5968080d4d7cccd9d79274e0..2497f5ab988c4a042367ec78e5f33961254d897d 100644
--- a/lib_dec/ivas_ism_param_dec.c
+++ b/lib_dec/ivas_ism_param_dec.c
@@ -287,7 +287,6 @@ static void ivas_param_ism_compute_mixing_matrix(
static void ivas_param_ism_render_slot(
DIRAC_DEC_HANDLE hDirAC,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
float *Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX],
float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX],
float Cldfb_RealBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
@@ -303,7 +302,7 @@ static void ivas_param_ism_render_slot(
tmp_1 = hDirAC->hParamIsmRendering->interpolator[interpolator_idx];
- for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
+ for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ )
{
/* smooth the mixing matrix */
for ( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ )
@@ -325,7 +324,6 @@ static void ivas_param_ism_render_slot(
static void ivas_param_ism_rendering(
DIRAC_DEC_HANDLE hDirAC,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
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 Cldfb_RealBuffer[PARAM_ISM_MAX_CHAN][4][CLDFB_NO_CHANNELS_MAX],
@@ -341,7 +339,7 @@ static void ivas_param_ism_rendering(
tmp_1 = hDirAC->hParamIsmRendering->interpolator[slot_idx];
- for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
+ for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ )
{
/* smooth the mixing matrix */
for ( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ )
@@ -442,7 +440,6 @@ ivas_error ivas_param_ism_dec_open(
int16_t i;
DIRAC_DEC_HANDLE hDirAC;
IVAS_OUTPUT_SETUP hOutSetup;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
AUDIO_CONFIG output_config;
int32_t output_Fs;
ivas_error error;
@@ -460,11 +457,6 @@ ivas_error ivas_param_ism_dec_open(
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
}
- if ( ( hSpatParamRendCom = (SPAT_PARAM_REND_COMMON_DATA_HANDLE) malloc( sizeof( SPAT_PARAM_REND_COMMON_DATA ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
/* Assign memory to Param Object handle */
if ( ( hDirAC->hParamIsm = (PARAM_ISM_CONFIG_HANDLE) malloc( sizeof( PARAM_ISM_CONFIG_DATA ) ) ) == NULL )
{
@@ -485,15 +477,15 @@ ivas_error ivas_param_ism_dec_open(
* set input parameters
*-----------------------------------------------------------------*/
- hSpatParamRendCom->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );
+ hDirAC->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );
hDirAC->hConfig = NULL;
- set_s( hSpatParamRendCom->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set_s( hSpatParamRendCom->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
- hSpatParamRendCom->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
- hSpatParamRendCom->subframes_rendered = 0;
- hSpatParamRendCom->slots_rendered = 0;
- hSpatParamRendCom->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
- hSpatParamRendCom->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
+ set_s( hDirAC->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
+ set_s( hDirAC->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
+ hDirAC->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
+ hDirAC->subframes_rendered = 0;
+ hDirAC->slots_rendered = 0;
+ hDirAC->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
+ hDirAC->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
hDirAC->hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
@@ -501,9 +493,9 @@ ivas_error ivas_param_ism_dec_open(
{
hDirAC->hParamIsm->band_grouping[i] = Param_ISM_band_grouping[i];
- if ( hDirAC->hParamIsm->band_grouping[i] > hSpatParamRendCom->num_freq_bands )
+ if ( hDirAC->hParamIsm->band_grouping[i] > hDirAC->num_freq_bands )
{
- hDirAC->hParamIsm->band_grouping[i] = hSpatParamRendCom->num_freq_bands;
+ hDirAC->hParamIsm->band_grouping[i] = hDirAC->num_freq_bands;
}
}
@@ -554,19 +546,19 @@ ivas_error ivas_param_ism_dec_open(
set_zero( hDirAC->azimuth_values, MAX_NUM_OBJECTS );
set_zero( hDirAC->elevation_values, MAX_NUM_OBJECTS );
- hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
- hSpatParamRendCom->dirac_bs_md_write_idx = 0;
- hSpatParamRendCom->dirac_read_idx = 0;
+ hDirAC->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
+ hDirAC->dirac_bs_md_write_idx = 0;
+ hDirAC->dirac_read_idx = 0;
hDirAC->spar_to_dirac_write_idx = 0;
if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
{
- if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 1 ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_allocate_parameters( hDirAC, 1 ) ) != IVAS_ERR_OK )
{
return error;
}
- if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 2 ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_allocate_parameters( hDirAC, 2 ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -575,7 +567,6 @@ ivas_error ivas_param_ism_dec_open(
st_ivas->hISMDTX.dtx_flag = 0;
st_ivas->hDirAC = hDirAC;
- st_ivas->hSpatParamRendCom = hSpatParamRendCom;
if ( st_ivas->hDecoderConfig->voip_active )
{
@@ -591,17 +582,17 @@ ivas_error ivas_param_ism_dec_open(
}
else
{
- if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
+ if ( ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) );
}
- set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hSpatParamRendCom->num_freq_bands );
+ set_zero( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands );
- if ( ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
+ if ( ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands * sizeof( float ) ) ) == NULL )
{
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Param ISM JBM Rendering handle\n" ) );
}
- set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hSpatParamRendCom->num_freq_bands );
+ set_zero( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc, MAX_JBM_CLDFB_TIMESLOTS * nchan_transport * hDirAC->num_freq_bands );
}
if ( st_ivas->hTcBuffer == NULL )
{
@@ -643,71 +634,67 @@ ivas_error ivas_param_ism_dec_open(
*-------------------------------------------------------------------------*/
void ivas_param_ism_dec_close(
- DIRAC_DEC_HANDLE *hDirAC_out, /* i/o: decoder DirAC handle */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: common spatial renderer data */
- AUDIO_CONFIG output_config /* i : output audio configuration */
+ DIRAC_DEC_HANDLE *hDirAC_out, /* i/o: decoder DirAC handle */
+ AUDIO_CONFIG output_config /* i : output audio configuration */
)
{
- if ( hDirAC_out != NULL && *hDirAC_out != NULL )
+ DIRAC_DEC_HANDLE hDirAC;
+
+ if ( hDirAC_out == NULL || *hDirAC_out == NULL )
{
- DIRAC_DEC_HANDLE hDirAC;
- hDirAC = *hDirAC_out;
+ return;
+ }
- /* Config & CLDFB */
- if ( hDirAC->hParamIsm != NULL )
- {
- free( hDirAC->hParamIsm );
- hDirAC->hParamIsm = NULL;
- }
+ hDirAC = *hDirAC_out;
- if ( !( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) )
- {
- /* Param ISM Rendering */
- if ( hDirAC->hParamIsmRendering->interpolator != NULL )
- {
- free( hDirAC->hParamIsmRendering->interpolator );
- hDirAC->hParamIsmRendering->interpolator = NULL;
- }
- if ( hDirAC->hParamIsmRendering->proto_matrix != NULL )
- {
- free( hDirAC->hParamIsmRendering->proto_matrix );
- hDirAC->hParamIsmRendering->proto_matrix = NULL;
- }
- }
+ /* Config & CLDFB */
+ if ( hDirAC->hParamIsm != NULL )
+ {
+ free( hDirAC->hParamIsm );
+ hDirAC->hParamIsm = NULL;
+ }
- if ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc != NULL )
- {
- free( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc );
- hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL;
- }
- if ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc != NULL )
+ if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
+ {
+ ivas_dirac_deallocate_parameters( hDirAC, 1 );
+ ivas_dirac_deallocate_parameters( hDirAC, 2 );
+ }
+
+ if ( !( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) )
+ {
+ /* Param ISM Rendering */
+ if ( hDirAC->hParamIsmRendering->interpolator != NULL )
{
- free( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc );
- hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL;
+ free( hDirAC->hParamIsmRendering->interpolator );
+ hDirAC->hParamIsmRendering->interpolator = NULL;
}
-
- if ( hDirAC->hParamIsmRendering != NULL )
+ if ( hDirAC->hParamIsmRendering->proto_matrix != NULL )
{
- free( hDirAC->hParamIsmRendering );
- hDirAC->hParamIsmRendering = NULL;
+ free( hDirAC->hParamIsmRendering->proto_matrix );
+ hDirAC->hParamIsmRendering->proto_matrix = NULL;
}
-
- free( *hDirAC_out );
- *hDirAC_out = NULL;
}
- if ( hSpatParamRendCom_out != NULL && *hSpatParamRendCom_out != NULL )
+ if ( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc != NULL )
{
- if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
- {
- ivas_dirac_deallocate_parameters( *hSpatParamRendCom_out, 1 );
- ivas_dirac_deallocate_parameters( *hSpatParamRendCom_out, 2 );
- }
+ free( hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc );
+ hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL;
+ }
+ if ( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc != NULL )
+ {
+ free( hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc );
+ hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL;
+ }
- free( *hSpatParamRendCom_out );
- *hSpatParamRendCom_out = NULL;
+ if ( hDirAC->hParamIsmRendering != NULL )
+ {
+ free( hDirAC->hParamIsmRendering );
+ hDirAC->hParamIsmRendering = NULL;
}
+ free( *hDirAC_out );
+ *hDirAC_out = NULL;
+
return;
}
@@ -726,9 +713,11 @@ 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;
int32_t ivas_total_brate;
+#ifdef FIX_549_DMX_GAIN
int16_t output_frame;
float gain, ene_tc, ene_sum, grad;
float last_gain;
+#endif
float ref_power[CLDFB_NO_CHANNELS_MAX];
float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX];
/* CLDFB Input Buffers */
@@ -746,19 +735,18 @@ void ivas_param_ism_dec(
float mixing_matrix[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX];
DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
IVAS_OUTPUT_SETUP hSetup;
/* Initialization */
hDirAC = st_ivas->hDirAC;
assert( hDirAC );
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- assert( hSpatParamRendCom );
+#ifdef FIX_549_DMX_GAIN
ene_tc = 0.0f;
ene_sum = 0.0f;
last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain;
output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
+#endif
nchan_transport = st_ivas->nchan_transport;
if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL )
@@ -842,6 +830,7 @@ void ivas_param_ism_dec(
}
}
+#ifdef FIX_549_DMX_GAIN
/* Energy Compensation */
for ( i = 0; i < output_frame; i++ )
{
@@ -875,6 +864,7 @@ void ivas_param_ism_dec(
}
}
st_ivas->hDirAC->hParamIsm->last_dmx_gain = gain;
+#endif
for ( ch = 0; ch < nchan_transport; ch++ )
{
@@ -883,14 +873,14 @@ void ivas_param_ism_dec(
*-----------------------------------------------------------------*/
for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ )
{
- cldfbAnalysis_ts( &( output_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] );
+ cldfbAnalysis_ts( &( output_f[ch][hDirAC->num_freq_bands * slot_idx] ), Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] );
ivas_param_ism_collect_slot( hDirAC, Cldfb_RealBuffer_in[ch][slot_idx], Cldfb_ImagBuffer_in[ch][slot_idx], ch, ref_power, cx_diag );
}
}
/* Obtain Mixing Matrix on a frame-level */
- for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
+ for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ )
{
set_f( mixing_matrix[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE );
}
@@ -898,28 +888,28 @@ void ivas_param_ism_dec(
/* Compute mixing matrix */
ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hDirAC, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, mixing_matrix );
/* subframe loop for synthesis*/
- for ( subframe_idx = 0; subframe_idx < hSpatParamRendCom->nb_subframes; subframe_idx++ )
+ for ( subframe_idx = 0; subframe_idx < hDirAC->nb_subframes; subframe_idx++ )
{
- uint16_t slot_idx_start = subframe_idx * hSpatParamRendCom->subframe_nbslots[subframe_idx];
+ uint16_t slot_idx_start = subframe_idx * hDirAC->subframe_nbslots[subframe_idx];
uint16_t idx_in;
uint16_t idx_lfe;
/* Set some memories to zero */
for ( ch = 0; ch < nchan_out_woLFE; ch++ )
{
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
{
- set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands );
- set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands );
+ set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands );
+ set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands );
}
}
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
{
index_slot = slot_idx_start + slot_idx;
/* Compute bandwise rendering to target LS using covariance rendering */
- ivas_param_ism_rendering( hDirAC, hSpatParamRendCom, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in,
+ ivas_param_ism_rendering( hDirAC, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in,
Cldfb_RealBuffer, Cldfb_ImagBuffer, mixing_matrix, slot_idx, index_slot,
nchan_out_woLFE, nchan_transport );
}
@@ -932,7 +922,7 @@ void ivas_param_ism_dec(
{
if ( ( hSetup.num_lfe > 0 ) && ( hSetup.index_lfe[idx_lfe] == ch ) )
{
- set_zero( &( output_f[ch][slot_idx_start * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands );
+ set_zero( &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ), hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands );
if ( idx_lfe < ( hSetup.num_lfe - 1 ) )
{
idx_lfe++;
@@ -944,14 +934,14 @@ void ivas_param_ism_dec(
float *ImagBuffer[16];
/* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
{
RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
}
- cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hSpatParamRendCom->num_freq_bands] ),
- hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] );
+ cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_idx_start * hDirAC->num_freq_bands] ),
+ hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] );
idx_in++;
}
@@ -1091,25 +1081,26 @@ void ivas_param_ism_dec_digest_tc(
int16_t ch, nchan_transport, nchan_out, nchan_out_woLFE, i;
int16_t slot_idx, bin_idx;
int32_t ivas_total_brate;
+#ifdef FIX_549_DMX_GAIN
int16_t output_frame;
float gain, ene_tc, ene_sum, grad;
float last_gain;
+#endif
float ref_power[CLDFB_NO_CHANNELS_MAX];
float cx_diag[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_DMX];
/* Direct Response/EFAP Gains */
float direct_response[MAX_NUM_OBJECTS][PARAM_ISM_MAX_CHAN];
DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
/* Initialization */
hDirAC = st_ivas->hDirAC;
assert( hDirAC );
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- assert( hSpatParamRendCom );
+#ifdef FIX_549_DMX_GAIN
ene_tc = 0.0f;
ene_sum = 0.0f;
last_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain;
output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
+#endif
nchan_transport = st_ivas->nchan_transport;
ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
@@ -1196,6 +1187,7 @@ void ivas_param_ism_dec_digest_tc(
}
}
+#ifdef FIX_549_DMX_GAIN
/* Energy Compensation */
for ( i = 0; i < output_frame; i++ )
{
@@ -1229,6 +1221,7 @@ void ivas_param_ism_dec_digest_tc(
}
}
st_ivas->hDirAC->hParamIsm->last_dmx_gain = gain;
+#endif
for ( ch = 0; ch < nchan_transport; ch++ )
{
@@ -1240,16 +1233,16 @@ void ivas_param_ism_dec_digest_tc(
float RealBuffer[CLDFB_NO_CHANNELS_MAX];
float ImagBuffer[CLDFB_NO_CHANNELS_MAX];
- cldfbAnalysis_ts( &( transport_channels_f[ch][hSpatParamRendCom->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hSpatParamRendCom->num_freq_bands, st_ivas->cldfbAnaDec[ch] );
- mvr2r( RealBuffer, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands );
- mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands], hSpatParamRendCom->num_freq_bands );
+ cldfbAnalysis_ts( &( transport_channels_f[ch][hDirAC->num_freq_bands * slot_idx] ), RealBuffer, ImagBuffer, hDirAC->num_freq_bands, st_ivas->cldfbAnaDec[ch] );
+ mvr2r( RealBuffer, &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands );
+ mvr2r( ImagBuffer, &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[slot_idx * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands], hDirAC->num_freq_bands );
ivas_param_ism_collect_slot( hDirAC, RealBuffer, ImagBuffer, ch, ref_power, cx_diag );
}
}
/* Obtain Mixing Matrix on a frame-level */
- for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ )
+ for ( bin_idx = 0; bin_idx < hDirAC->num_freq_bands; bin_idx++ )
{
set_f( hDirAC->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE );
}
@@ -1285,7 +1278,6 @@ static void ivas_ism_param_dec_render_sf(
float *Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX];
float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX];
DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
int16_t slot_idx_start;
int16_t idx_in;
@@ -1293,32 +1285,31 @@ static void ivas_ism_param_dec_render_sf(
int16_t subframe_idx;
hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- slot_idx_start = hSpatParamRendCom->slots_rendered;
- subframe_idx = hSpatParamRendCom->subframes_rendered;
+ slot_idx_start = hDirAC->slots_rendered;
+ subframe_idx = hDirAC->subframes_rendered;
/* Set some memories to zero */
for ( ch = 0; ch < nchan_out_woLFE; ch++ )
{
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
{
- set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands );
- set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands );
+ set_f( Cldfb_RealBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands );
+ set_f( Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hDirAC->num_freq_bands );
}
}
- for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ )
+ for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ )
{
index_slot = slot_idx_start + slot_idx;
for ( ch = 0; ch < nchan_transport; ch++ )
{
- Cldfb_RealBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands];
- Cldfb_ImagBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands];
+ Cldfb_RealBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_RealBuffer_tc[index_slot * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands];
+ Cldfb_ImagBuffer_in[ch] = &hDirAC->hParamIsmRendering->Cldfb_ImagBuffer_tc[index_slot * hDirAC->num_freq_bands * nchan_transport + ch * hDirAC->num_freq_bands];
}
/* Compute bandwise rendering to target LS using covariance rendering */
- ivas_param_ism_render_slot( hDirAC, hSpatParamRendCom, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in,
+ ivas_param_ism_render_slot( hDirAC, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in,
Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirAC->hParamIsmRendering->mixing_matrix_lin, index_slot, slot_idx,
nchan_out_woLFE, nchan_transport );
}
@@ -1331,7 +1322,7 @@ static void ivas_ism_param_dec_render_sf(
{
if ( ( hSetup.num_lfe > 0 ) && ( hSetup.index_lfe[idx_lfe] == ch ) )
{
- set_zero( output_f[ch], hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands );
+ set_zero( output_f[ch], hDirAC->subframe_nbslots[subframe_idx] * hDirAC->num_freq_bands );
if ( idx_lfe < ( hSetup.num_lfe - 1 ) )
{
idx_lfe++;
@@ -1343,19 +1334,19 @@ static void ivas_ism_param_dec_render_sf(
float *ImagBuffer[16];
/* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */
- for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ )
+ for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ )
{
RealBuffer[i] = Cldfb_RealBuffer[idx_in][i];
ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i];
}
cldfbSynthesis( RealBuffer, ImagBuffer, output_f[ch],
- hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] );
+ hDirAC->num_freq_bands * hDirAC->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] );
idx_in++;
}
}
- hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe_idx];
- hSpatParamRendCom->subframes_rendered++;
+ hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe_idx];
+ hDirAC->subframes_rendered++;
return;
}
@@ -1378,17 +1369,14 @@ void ivas_param_ism_dec_render(
int16_t ch, slots_to_render, first_sf, last_sf, subframe_idx;
uint16_t slot_size, n_samples_sf;
DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
IVAS_OUTPUT_SETUP hSetup;
int16_t nchan_transport, nchan_out, nchan_out_woLFE;
float *output_f_local[MAX_OUTPUT_CHANNELS];
hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
hSetup = st_ivas->hIntSetup;
#ifdef DEBUGGING
assert( hDirAC );
- assert( hSpatParamRendCom );
#endif
nchan_transport = st_ivas->nchan_transport;
if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL )
@@ -1405,14 +1393,14 @@ void ivas_param_ism_dec_render(
slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
/* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
- slots_to_render = min( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered, nSamplesAsked / slot_size );
+ slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size );
*nSamplesRendered = slots_to_render * slot_size;
- first_sf = hSpatParamRendCom->subframes_rendered;
+ first_sf = hDirAC->subframes_rendered;
last_sf = first_sf;
while ( slots_to_render > 0 )
{
- slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
+ slots_to_render -= hDirAC->subframe_nbslots[last_sf];
last_sf++;
}
#ifdef DEBUGGING
@@ -1427,14 +1415,14 @@ void ivas_param_ism_dec_render(
for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
{
ivas_ism_param_dec_render_sf( st_ivas, hSetup, nchan_transport, nchan_out, nchan_out_woLFE, output_f_local );
- n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size;
+ n_samples_sf = hDirAC->subframe_nbslots[subframe_idx] * st_ivas->hDirAC->slot_size;
for ( ch = 0; ch < nchan_out; ch++ )
{
output_f_local[ch] += n_samples_sf;
}
}
- if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots )
+ if ( hDirAC->slots_rendered == hDirAC->num_slots )
{
/* copy the memories */
/* store mixing matrix for next subframe */
@@ -1456,7 +1444,7 @@ void ivas_param_ism_dec_render(
}
}
- *nSamplesAvailable = ( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered ) * slot_size;
+ *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size;
return;
}
@@ -1473,7 +1461,6 @@ void ivas_param_ism_params_to_masa_param_mapping(
)
{
DIRAC_DEC_HANDLE hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
int16_t nBins;
int16_t band_idx, bin_idx, sf_idx;
int16_t brange[2];
@@ -1483,8 +1470,7 @@ void ivas_param_ism_params_to_masa_param_mapping(
int32_t ivas_total_brate;
hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- nBins = hSpatParamRendCom->num_freq_bands;
+ nBins = hDirAC->num_freq_bands;
ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
@@ -1506,7 +1492,7 @@ void ivas_param_ism_params_to_masa_param_mapping(
float energy_ratio;
energy_ratio = powf( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->coherence, 2.0f );
- hSpatParamRendCom->numSimultaneousDirections = 1;
+ hDirAC->numSimultaneousDirections = 1;
azimuth[0] = (int16_t) roundf( hDirAC->azimuth_values[0] );
elevation[0] = (int16_t) roundf( hDirAC->elevation_values[0] );
@@ -1514,19 +1500,19 @@ void ivas_param_ism_params_to_masa_param_mapping(
{
for ( bin_idx = 0; bin_idx < nBins; bin_idx++ )
{
- hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
- hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
+ hDirAC->azimuth[sf_idx][bin_idx] = azimuth[0];
+ hDirAC->elevation[sf_idx][bin_idx] = elevation[0];
- hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = energy_ratio;
+ hDirAC->energy_ratio1[sf_idx][bin_idx] = energy_ratio;
- hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0;
+ hDirAC->spreadCoherence[sf_idx][bin_idx] = 0.0f;
+ hDirAC->surroundingCoherence[sf_idx][bin_idx] = 0.0;
}
}
}
else
{
- hSpatParamRendCom->numSimultaneousDirections = 2;
+ hDirAC->numSimultaneousDirections = 2;
for ( band_idx = 0; band_idx < hDirAC->hParamIsm->nbands; band_idx++ )
{
brange[0] = hDirAC->hParamIsm->band_grouping[band_idx];
@@ -1544,12 +1530,12 @@ void ivas_param_ism_params_to_masa_param_mapping(
{
for ( bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++ )
{
- hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
- hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
- hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = power_ratio[0];
- hSpatParamRendCom->azimuth2[sf_idx][bin_idx] = azimuth[1];
- hSpatParamRendCom->elevation2[sf_idx][bin_idx] = elevation[1];
- hSpatParamRendCom->energy_ratio2[sf_idx][bin_idx] = power_ratio[1];
+ 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];
}
}
}
@@ -1558,16 +1544,16 @@ void ivas_param_ism_params_to_masa_param_mapping(
{
for ( bin_idx = 0; bin_idx < nBins; bin_idx++ )
{
- hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f;
- hSpatParamRendCom->spreadCoherence2[sf_idx][bin_idx] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0;
+ 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
{
- hSpatParamRendCom->numSimultaneousDirections = 1;
+ hDirAC->numSimultaneousDirections = 1;
azimuth[0] = (int16_t) roundf( hDirAC->azimuth_values[0] );
elevation[0] = (int16_t) roundf( hDirAC->elevation_values[0] );
@@ -1575,11 +1561,11 @@ void ivas_param_ism_params_to_masa_param_mapping(
{
for ( bin_idx = 0; bin_idx < nBins; bin_idx++ )
{
- hSpatParamRendCom->azimuth[sf_idx][bin_idx] = azimuth[0];
- hSpatParamRendCom->elevation[sf_idx][bin_idx] = elevation[0];
- hSpatParamRendCom->energy_ratio1[sf_idx][bin_idx] = 1.0f;
- hSpatParamRendCom->spreadCoherence[sf_idx][bin_idx] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[sf_idx][bin_idx] = 0.0;
+ hDirAC->azimuth[sf_idx][bin_idx] = azimuth[0];
+ hDirAC->elevation[sf_idx][bin_idx] = elevation[0];
+ hDirAC->energy_ratio1[sf_idx][bin_idx] = 1.0f;
+ hDirAC->spreadCoherence[sf_idx][bin_idx] = 0.0f;
+ hDirAC->surroundingCoherence[sf_idx][bin_idx] = 0.0;
}
}
}
diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c
index 77563629aea067143dfffa3946f8dd46547b3afe..9c4479374daa9e2a36fb3476201b59331d5c685d 100644
--- a/lib_dec/ivas_ism_renderer.c
+++ b/lib_dec/ivas_ism_renderer.c
@@ -338,3 +338,189 @@ void ivas_ism_get_stereo_gains(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------------*
+ * ivas_masa_ism_separate_object_renderer_open()
+ *
+ * Open structures, reserve memory, and init values.
+ *-------------------------------------------------------------------------*/
+
+ivas_error ivas_masa_ism_separate_object_renderer_open(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ int16_t interpolator_length;
+ int16_t i;
+ int16_t init_interpolator_length;
+
+ if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
+ }
+
+ for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
+ {
+ set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
+ }
+
+ // Todo OMASA JBM: This needs touches for VOIP path at least. Current version is mostly an adapted copy from ivas_ism_renderer_open()
+ if ( st_ivas->hDecoderConfig->voip_active )
+ {
+ init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS );
+ interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
+ }
+ else
+ {
+ init_interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
+ interpolator_length = init_interpolator_length;
+ }
+ st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length );
+
+ for ( i = 0; i < interpolator_length; i++ )
+ {
+ st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
+ }
+
+ st_ivas->hMasaIsmData->delayBuffer_size = (int16_t) ( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
+ }
+ else
+ {
+ st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
+ }
+
+ if ( ( st_ivas->hMasaIsmData->delayBuffer = (float **) malloc( st_ivas->hMasaIsmData->delayBuffer_nchan * sizeof( float * ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
+ }
+
+ for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
+ {
+ if ( ( st_ivas->hMasaIsmData->delayBuffer[i] = (float *) malloc( st_ivas->hMasaIsmData->delayBuffer_size * sizeof( float ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
+ }
+ set_zero( st_ivas->hMasaIsmData->delayBuffer[i], st_ivas->hMasaIsmData->delayBuffer_size );
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------------*
+ * ivas_masa_ism_separate_object_render()
+ *
+ * Rendering separated objects and mixing them to the parametrically rendered signals
+ *-------------------------------------------------------------------------*/
+
+// Todo OMASA JBM: This might need adjustments
+void ivas_masa_ism_separate_object_render(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float input_f[][L_FRAME48k], /* i : separated object signal */
+ float output_f[][L_FRAME48k], /* i/o: output signals */
+ const int16_t output_frame /* i : output frame length per channel */
+)
+{
+ VBAP_HANDLE hVBAPdata;
+ int16_t nchan_out_woLFE;
+ ISM_RENDERER_HANDLE hRendererData;
+ int16_t j, k, j2;
+ int16_t obj;
+ float gains[MAX_OUTPUT_CHANNELS];
+ float g1, g2;
+ int16_t lfe_index;
+ int16_t azimuth, elevation;
+ int16_t num_objects;
+ uint8_t single_separated;
+ int16_t block;
+ int16_t subframe_len;
+ int16_t idx_offset;
+ int16_t dirac_read_idx;
+
+ hVBAPdata = st_ivas->hVBAPdata;
+ nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
+ hRendererData = st_ivas->hIsmRendererData;
+ lfe_index = st_ivas->hDirAC->hOutSetup.index_lfe[0];
+ subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ single_separated = 1;
+ num_objects = 1;
+ }
+ else
+ {
+ single_separated = 0;
+ num_objects = st_ivas->nchan_ism;
+ }
+
+ for ( obj = 0; obj < num_objects; obj++ )
+ {
+ delay_signal( input_f[obj], output_frame, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size ); /* Delay the signal to match CLDFB delay */
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ idx_offset = block * subframe_len;
+ dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + block ) % st_ivas->hDirAC->dirac_md_buffer_length;
+
+ if ( single_separated )
+ {
+ azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[dirac_read_idx];
+ elevation = st_ivas->hMasaIsmData->elevation_separated_ism[dirac_read_idx];
+ }
+ else
+ {
+ azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx];
+ elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx];
+ }
+
+ if ( st_ivas->hOutSetup.is_planar_setup )
+ {
+ /* If no elevation support in output format, then rendering should be done with zero elevation */
+ elevation = 0;
+ }
+
+ if ( hVBAPdata != NULL )
+ {
+ vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 );
+ }
+ else
+ {
+ ivas_dirac_dec_get_response( azimuth, elevation, gains, st_ivas->hDirAC->hOutSetup.ambisonics_order );
+ }
+
+ for ( j = 0; j < nchan_out_woLFE; j++ )
+ {
+ if ( st_ivas->hDirAC->hOutSetup.num_lfe > 0 )
+ {
+ j2 = j + ( j >= lfe_index );
+ }
+ else
+ {
+ j2 = j;
+ }
+
+ if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f )
+ {
+ for ( k = 0; k < subframe_len; k++ )
+ {
+ g1 = hRendererData->interpolator[k];
+ g2 = 1.0f - g1;
+ output_f[j2][k + idx_offset] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + idx_offset];
+ }
+ }
+ hRendererData->prev_gains[obj][j] = gains[j];
+ }
+ }
+ }
+
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % st_ivas->hDirAC->dirac_md_buffer_length;
+
+ return;
+}
+#endif
diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c
index e1a7a9cbd28640a5357caa7cc844d572d8042af5..98b0672af362fe780fa5aab249eff7b45a88ed11 100644
--- a/lib_dec/ivas_jbm_dec.c
+++ b/lib_dec/ivas_jbm_dec.c
@@ -320,7 +320,7 @@ ivas_error ivas_jbm_dec_tc(
{
#ifdef FIX_564
/* loudness correction */
- ivas_dirac_dec_binaural_sba_gain( output, nchan_remapped, output_frame );
+ ivas_dirac_dec_binaural_gain( output, nchan_remapped, output_frame );
#else
float gain = 0.8414f; /* Todo: Temporary gain for roughly matching the loudness. To be tuned later together with other outputs. Also, this is not inline with ivas_dec() */
@@ -691,7 +691,6 @@ ivas_error ivas_jbm_dec_render(
ivas_error error;
float *p_output[MAX_OUTPUT_CHANNELS];
float *p_tc[MAX_TRANSPORT_CHANNELS];
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
error = IVAS_ERR_OK;
@@ -701,7 +700,6 @@ ivas_error ivas_jbm_dec_render(
* Initialization of local vars after struct has been set
*----------------------------------------------------------------*/
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
output_Fs = st_ivas->hDecoderConfig->output_Fs;
nchan_out = st_ivas->hDecoderConfig->nchan_out;
nchan_transport = st_ivas->hTcBuffer->nchan_transport_jbm;
@@ -969,7 +967,7 @@ ivas_error ivas_jbm_dec_render(
}
else if ( st_ivas->mc_mode == MC_MODE_MCMASA )
{
- int16_t offset = hSpatParamRendCom->slots_rendered * hSpatParamRendCom->slot_size;
+ int16_t offset = st_ivas->hDirAC->slots_rendered * st_ivas->hDirAC->slot_size;
nchan_remapped = st_ivas->nchan_transport;
if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c
index 4a6053ccd5b44aa3ccf191ecb847ed553d4eea41..1c9cc56417f48ae45fbafc1ac2ce6bfca5f8fea2 100644
--- a/lib_dec/ivas_masa_dec.c
+++ b/lib_dec/ivas_masa_dec.c
@@ -35,7 +35,6 @@
#include
#include "ivas_cnst.h"
#include "ivas_prot.h"
-#include "ivas_prot_rend.h"
#include "ivas_rom_com.h"
#include "ivas_stat_dec.h"
#include "prot.h"
@@ -73,6 +72,16 @@ static int16_t decode_lfe_to_total_energy_ratio( MCMASA_LFE_SYNTH_DATA_HANDLE hM
static ivas_error ivas_masa_dec_config( Decoder_Struct *st_ivas );
+#ifdef MASA_AND_OBJECTS
+static int16_t ivas_decode_masaism_metadata( IVAS_QMETADATA_HANDLE hQMetaData, MASA_DECODER_HANDLE hMasa, MASA_ISM_DATA_HANDLE hMasaIsmData, const int16_t nchan_ism, uint16_t *bit_stream, int16_t *next_bit_pos, const int16_t idx_separated_object, const int16_t ism_imp, const int16_t dirac_bs_md_write_idx, const int16_t dirac_md_buffer_length );
+
+static void decode_index_slice( int16_t index, int16_t *ratio_idx_ism, const int16_t nchan_ism, const int16_t K );
+
+static void decode_ism_ratios( uint16_t *bit_stream, int16_t *next_bit_pos, IVAS_QMETADATA_HANDLE hQMetaData, float ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const int16_t nchan_ism, const int16_t nbands, const int16_t nblocks, const int16_t idx_separated_object );
+
+static void read_ism_ratio_index( int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], const int16_t nchan_ism, const int16_t numCodingBands, const int16_t sf, int16_t ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], uint16_t *bit_stream, int16_t *next_bit_pos, float *masa_to_total_energy_ratio, const int16_t idx_sep_obj, int16_t *num_zeros );
+#endif
+
/*-----------------------------------------------------------------------*
* ivas_masa_decode()
@@ -94,13 +103,26 @@ ivas_error ivas_masa_decode(
IVAS_FORMAT ivas_format;
int16_t low_bitrate_mode, tmp_elem_mode;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int16_t obj;
+ int16_t i, ch, ism_imp;
+ int16_t dirac_bs_md_write_idx;
+ int32_t masa_total_brate;
+
+ dirac_bs_md_write_idx = 0;
+ ism_imp = 0;
+#endif
error = IVAS_ERR_OK;
ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
low_bitrate_mode = -1; /* This means that LBR mode is not used. */
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->hOutSetup.separateChannelEnabled || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+#else
if ( st_ivas->hOutSetup.separateChannelEnabled )
+#endif
{
masa_brate = st_ivas->hCPE[0]->element_brate;
}
@@ -131,10 +153,109 @@ ivas_error ivas_masa_decode(
{
if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) )
{
- /* the number of MASA transport channels was read in ivas_dec_setup() */
- st->next_bit_pos -= MASA_TRANSP_BITS;
- *nb_bits_read += MASA_TRANSP_BITS;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format != MASA_ISM_FORMAT )
+ {
+ /* number of transport channels is always 2 for MASA_ISM format */
+#endif
+ /* the number of MASA transport channels was read in ivas_dec_setup() */
+ st->next_bit_pos -= MASA_TRANSP_BITS;
+ *nb_bits_read += MASA_TRANSP_BITS;
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MODE_NONE )
+ {
+ /* the number of objects was read */
+ st->next_bit_pos -= NO_BITS_MASA_ISM_NO_OBJ;
+ *nb_bits_read += NO_BITS_MASA_ISM_NO_OBJ;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ /* read index of separated object */
+ /* nchan_ism should be > 1*/
+ byteBuffer = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read )++;
+ st_ivas->hMasaIsmData->idx_separated_ism = 2 * byteBuffer + st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read )++;
+ }
+ else
+ {
+ st_ivas->hMasaIsmData->idx_separated_ism = -1;
+ }
+
+ /* read ISM importance flag (one per object) */
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ ism_imp = 0;
+ for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
+ {
+ byteBuffer = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read )++;
+ ism_imp = ( ism_imp << 1 ) + byteBuffer;
+ }
+ st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
+ }
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ ism_imp = 0;
+ for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
+ {
+ byteBuffer = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read )++;
+ ism_imp = ( ism_imp << 1 ) + byteBuffer;
+ }
+ st_ivas->hIsmMetaData[0]->ism_imp = ism_imp;
+ /* reset */
+ st_ivas->hIsmMetaData[0]->ism_md_null_flag = 0;
+ st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = 0;
+ if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META )
+ {
+ /* read flags */
+ st_ivas->hIsmMetaData[0]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read ) += ISM_METADATA_MD_FLAG_BITS;
+ st_ivas->hIsmMetaData[0]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read ) += ISM_METADATA_INACTIVE_FLAG_BITS;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ for ( ch = 0; ch < st_ivas->nchan_ism; ch++ )
+ {
+ ism_imp = 0;
+ for ( i = 0; i < ISM_METADATA_FLAG_BITS; i++ )
+ {
+ byteBuffer = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read )++;
+ ism_imp = ( ism_imp << 1 ) + byteBuffer;
+ }
+ st_ivas->hIsmMetaData[ch]->ism_imp = ism_imp;
+
+ /* reset */
+ st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
+ st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
+ if ( st_ivas->hIsmMetaData[ch]->ism_imp == ISM_NO_META )
+ {
+ /* read flags */
+ st_ivas->hIsmMetaData[ch]->ism_md_null_flag = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read ) += ISM_METADATA_MD_FLAG_BITS;
+ st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read ) += ISM_METADATA_INACTIVE_FLAG_BITS;
+ }
+ }
+ st_ivas->flag_omasa_brate = 0;
+ if ( st_ivas->nchan_ism >= 3 && ivas_total_brate == IVAS_128k )
+ {
+ st_ivas->flag_omasa_brate = st->bit_stream[( st->next_bit_pos )--];
+ ( *nb_bits_read ) += 1;
+ }
+ }
+ }
+#endif
/* Placeholder for descriptive metadata content */
byteBuffer = st->bit_stream[( st->next_bit_pos )--];
byteBuffer += st->bit_stream[( st->next_bit_pos )--];
@@ -193,9 +314,57 @@ ivas_error ivas_masa_decode(
/* Remove already read bits from the bit budget */
hQMetaData->metadata_max_bits -= *nb_bits_read;
+
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ if ( st_ivas->hDirAC != NULL )
+ {
+ *nb_bits_read += ivas_decode_masaism_metadata( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
+ st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, st_ivas->hDirAC->dirac_bs_md_write_idx, st_ivas->hDirAC->dirac_md_buffer_length );
+
+ for ( obj = 0; obj <= st_ivas->nchan_ism; obj++ )
+ {
+ if ( st_ivas->hMasaIsmData->idx_separated_ism == obj )
+ {
+ int16_t sf;
+ int16_t meta_write_index;
+
+ for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
+ {
+ meta_write_index = ( st_ivas->hDirAC->dirac_bs_md_write_idx + sf ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->azimuth_ism[obj][meta_write_index];
+ st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = st_ivas->hMasaIsmData->elevation_ism[obj][meta_write_index];
+ }
+ }
+ }
+ }
+ else
+ {
+ *nb_bits_read += ivas_decode_masaism_metadata( hQMetaData, st_ivas->hMasa, st_ivas->hMasaIsmData, st_ivas->nchan_ism, st->bit_stream, &st->next_bit_pos,
+ st_ivas->hMasaIsmData->idx_separated_ism, ism_imp, 0, MAX_PARAM_SPATIAL_SUBFRAMES );
+ }
+ }
+ }
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ masa_total_brate = ivas_total_brate;
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ masa_total_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
+ }
+
+ if ( masa_total_brate >= IVAS_384k )
+ {
+ if ( masa_total_brate >= IVAS_512k )
+#else
if ( ivas_total_brate >= IVAS_384k )
{
if ( ivas_total_brate >= IVAS_512k )
+#endif
{
*nb_bits_read += ivas_qmetadata_dec_decode_hr_384_512( hQMetaData, st->bit_stream, &st->next_bit_pos, hMasa->data.sph_grid16, 16, 4, hMasa->config.numCodingBands );
}
@@ -209,6 +378,14 @@ ivas_error ivas_masa_decode(
*nb_bits_read += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &st->next_bit_pos, 0 );
}
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* Modify spatial metadata based on the MASA-to-total energy ratios */
+ modify_masa_energy_ratios( hQMetaData );
+ }
+#endif
+
/* Get direction decoding quality. EC 1 and 2 are handled by the default value. */
if ( hQMetaData->ec_flag == 2 )
{
@@ -242,7 +419,12 @@ ivas_error ivas_masa_decode(
return error;
}
- ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+ ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE
+#ifdef MASA_AND_OBJECTS
+ ,
+ st_ivas->ivas_format, st_ivas->ism_mode, 0
+#endif
+ );
hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC;
@@ -286,21 +468,93 @@ ivas_error ivas_masa_decode(
}
}
}
+
if ( st_ivas->hDirAC != NULL )
{
- ivas_qmetadata_to_dirac( hQMetaData, st_ivas->hDirAC, hMasa, st_ivas->hSpatParamRendCom, ivas_total_brate, ivas_format, 0, 0 );
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: This might need adjustments
+ dirac_bs_md_write_idx = st_ivas->hDirAC->dirac_bs_md_write_idx; /* Store the write-index for this frame */
+#endif
+
+ ivas_qmetadata_to_dirac( hQMetaData, st_ivas->hDirAC, hMasa, ivas_total_brate, ivas_format, 0, 0 );
+ }
+
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( hQMetaData->q_direction == NULL )
+ {
+ if ( ( error = ivas_masa_dec_config( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( st_ivas->hDirAC != NULL )
+ {
+ int16_t b;
+ int16_t block;
+ int16_t meta_write_index;
+
+ for ( i = 0; i < st_ivas->hDirAC->numIsmDirections; i++ ) /* Todo Nokia: Probably there is a better place for this eventually */
+ {
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ // Todo OMASA JBM: This might need adjustments
+ meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hDirAC->dirac_md_buffer_length;
+
+ for ( b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ )
+ {
+ st_ivas->hDirAC->diffuseness_vector[meta_write_index][b] -= st_ivas->hMasaIsmData->energy_ratio_ism[i][meta_write_index][b];
+ }
+ }
+ }
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hDirAC->dirac_md_buffer_length;
+
+ for ( b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ )
+ {
+ st_ivas->hDirAC->diffuseness_vector[meta_write_index][b] = max( 0.0f, st_ivas->hDirAC->diffuseness_vector[meta_write_index][b] );
+ }
+ }
+ }
}
+#endif
+
st->next_bit_pos = next_bit_pos_orig;
- if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
{
- st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0;
+ int32_t cpe_brate;
+ cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
+
+ if ( st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
+ {
+ st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = cpe_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0;
- if ( ivas_total_brate <= IVAS_SID_5k2 )
+ if ( ivas_total_brate <= IVAS_SID_5k2 )
+ {
+ st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
+ }
+ }
+ }
+ else
+ {
+#endif
+ if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
{
- st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
+ st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0;
+
+ if ( ivas_total_brate <= IVAS_SID_5k2 )
+ {
+ st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0;
+ }
}
+#ifdef MASA_AND_OBJECTS
}
+#endif
if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 )
{
@@ -317,7 +571,11 @@ ivas_error ivas_masa_decode(
}
}
+#ifdef OMASA_EXT_OUTPUT
+ if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL )
+#else
if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL )
+#endif
{
create_masa_ext_out_meta( hMasa, hQMetaData, st_ivas->nchan_transport );
}
@@ -338,6 +596,10 @@ ivas_error ivas_masa_dec_open(
{
MASA_DECODER_HANDLE hMasa;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int16_t i;
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
@@ -346,7 +608,23 @@ ivas_error ivas_masa_dec_open(
return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA decoder\n" ) );
}
- ivas_masa_set_elements( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+#ifdef MASA_AND_OBJECTS
+ ism_total_brate = 0;
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ for ( i = 0; i < st_ivas->nSCE; i++ )
+ {
+ ism_total_brate += st_ivas->hSCE[i]->element_brate;
+ }
+ }
+#endif
+
+ ivas_masa_set_elements( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE
+#ifdef MASA_AND_OBJECTS
+ ,
+ st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate
+#endif
+ );
mvs2s( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
mvs2s( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 );
@@ -487,15 +765,43 @@ static ivas_error ivas_masa_dec_config(
uint8_t maxBand;
int16_t maxBin;
ivas_error error;
-
+#ifdef MASA_AND_OBJECTS
+ int32_t ivas_total_brate;
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
hMasa = st_ivas->hMasa;
- ivas_masa_set_elements( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+#ifdef MASA_AND_OBJECTS
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+ ism_total_brate = 0;
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ for ( i = 0; i < st_ivas->nSCE; i++ )
+ {
+ ism_total_brate += st_ivas->hSCE[i]->element_brate;
+ }
+ }
- ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) );
+ ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE, st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate );
- if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_512k )
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hCPE[0]->element_brate, st_ivas->nchan_transport, MC_MODE_NONE );
+ }
+ else
+ {
+ ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) );
+ }
+#else
+ ivas_masa_set_elements( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+ ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) );
+#endif
+#ifdef MASA_AND_OBJECTS
+ if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_512k )
+#else
+ if ( ( st_ivas->ivas_format == MASA_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate == IVAS_512k )
+#endif
{
hMasa->config.mergeRatiosOverSubframes = 0;
/* initialize spherical grid */
@@ -971,6 +1277,9 @@ ivas_error ivas_masa_dec_reconfigure(
int32_t ivas_total_brate, last_ivas_total_brate;
int16_t numCldfbAnalyses_old, numCldfbSyntheses_old;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
@@ -982,7 +1291,11 @@ ivas_error ivas_masa_dec_reconfigure(
/* renderer might have changed, reselect */
ivas_renderer_select( st_ivas );
- if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend == NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin == NULL ) )
+#ifdef OMASA_BRSW_MONO_FIX
+ if ( ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MONO_DOWNMIX ) && st_ivas->hDirAC == NULL )
+#else
+ if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->hDirAC == NULL )
+#endif
{
/* init a new DirAC dec */
if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
@@ -990,16 +1303,14 @@ ivas_error ivas_masa_dec_reconfigure(
return error;
}
}
- else if ( st_ivas->renderer_type == RENDERER_DISABLE )
+#ifdef OMASA_BRSW_MONO_FIX
+ else if ( ( st_ivas->renderer_type == RENDERER_DISABLE || st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) && st_ivas->hDirAC != NULL )
+#else
+ else if ( st_ivas->renderer_type == RENDERER_DISABLE && st_ivas->hDirAC != NULL )
+#endif
{
- if ( st_ivas->hDirAC != NULL )
- {
- /* close all unnecessary parametric decoding and rendering */
- ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
- ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
- }
+ /* close unnecessary DirAC dec */
+ ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
}
/* possible reconfigure is done later */
@@ -1018,14 +1329,6 @@ ivas_error ivas_masa_dec_reconfigure(
sts = st_ivas->hSCE[sce_id]->hCoreCoder;
sts[0]->bit_stream = bit_stream + num_bits;
num_bits += (int16_t) ( st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC );
-
- if ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL )
- {
- if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
}
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
@@ -1040,13 +1343,13 @@ ivas_error ivas_masa_dec_reconfigure(
sts = st_ivas->hCPE[cpe_id]->hCoreCoder;
sts[0]->bit_stream = bit_stream + num_bits;
num_bits += (int16_t) ( st_ivas->hCPE[cpe_id]->element_brate / FRAMES_PER_SEC );
-
+ /* Todo: Nokia make for MASA_ISM*/
if ( ( ivas_total_brate < MASA_STEREO_MIN_BITRATE && last_ivas_total_brate >= MASA_STEREO_MIN_BITRATE ) ||
( ivas_total_brate < MASA_STEREO_MIN_BITRATE && last_ivas_total_brate == FRAME_NO_DATA ) )
{
st_ivas->hCPE[cpe_id]->nchan_out = 1;
- if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) )
+ if ( st_ivas->hDirAC != NULL )
{
if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
{
@@ -1058,7 +1361,7 @@ ivas_error ivas_masa_dec_reconfigure(
{
st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS;
- if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) )
+ if ( st_ivas->hDirAC != NULL )
{
if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
{
@@ -1067,27 +1370,69 @@ ivas_error ivas_masa_dec_reconfigure(
}
}
}
-
if ( st_ivas->hDiracDecBin != NULL )
{
/* regularization factor is bitrate-dependent */
st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
}
- /*-----------------------------------------------------------------*
- * CLDFB instances
- *-----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */
+ {
+#endif
+ /*-----------------------------------------------------------------*
+ * TD Decorrelator
+ *-----------------------------------------------------------------*/
+
+ if ( st_ivas->hDiracDecBin != NULL )
+ {
+ if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
- if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, st_ivas->nchan_transport, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK )
+ /*-----------------------------------------------------------------*
+ * CLDFB instances
+ *-----------------------------------------------------------------*/
+
+ if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, st_ivas->nchan_transport, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /*-----------------------------------------------------------------*
+ * Set-up MASA coding elements and bitrates
+ *-----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ ism_total_brate = 0;
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
{
- return error;
+ for ( n = 0; n < st_ivas->nSCE; n++ )
+ {
+ ism_total_brate += st_ivas->hSCE[n]->element_brate;
+ }
}
+#endif
- /*-----------------------------------------------------------------*
- * Set-up MASA coding elements and bitrates
- *-----------------------------------------------------------------*/
+ ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp
+#ifdef MASA_AND_OBJECTS
+ ,
+ st_ivas->ivas_format, st_ivas->ism_mode, ism_total_brate
+#endif
+ );
- ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp );
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_FORMAT )
+ {
+ st_ivas->nchan_ism = 0;
+ st_ivas->ism_mode = ISM_MODE_NONE;
+ }
+#endif
if ( st_ivas->hDecoderConfig->voip_active == 1 )
{
@@ -1117,6 +1462,12 @@ ivas_error ivas_masa_dec_reconfigure(
}
+/*-------------------------------------------------------------------*
+ * ivas_spar_param_to_masa_param_mapping()
+ *
+ * Determine MASA metadata from the SPAR metadata
+ *-------------------------------------------------------------------*/
+
void ivas_spar_param_to_masa_param_mapping(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */
float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */
@@ -1143,17 +1494,18 @@ void ivas_spar_param_to_masa_param_mapping(
int16_t slot_idx, slot_idx_start, sf;
SPAR_DEC_HANDLE hSpar;
float slot_fac;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
/* Set values */
hDirAC = st_ivas->hDirAC;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- hSpatParamRendCom->numSimultaneousDirections = 1;
- hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist;
+#ifdef MASA_AND_OBJECTS
+ hDirAC->numParametricDirections = 1;
+#endif
+ hDirAC->numSimultaneousDirections = 1;
+ hDiffuseDist = st_ivas->hDirAC->hDiffuseDist;
nchan_transport = st_ivas->nchan_transport;
band_grouping = hDirAC->band_grouping;
hSpar = st_ivas->hSpar;
- dirac_write_idx = hSpatParamRendCom->render_to_md_map[subframe];
+ dirac_write_idx = hDirAC->render_to_md_map[subframe];
/* Init arrays */
for ( i = 0; i < FOA_CHANNELS; i++ )
@@ -1238,7 +1590,7 @@ void ivas_spar_param_to_masa_param_mapping(
set_zero( transportSignalEnergies[1], nBins );
set_zero( transportSignalCrossCorrelation, nBins );
- for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
+ for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe]; slot++ )
{
for ( bin = 0; bin < nBins; bin++ )
{
@@ -1298,13 +1650,13 @@ void ivas_spar_param_to_masa_param_mapping(
ratio = I / fmaxf( 1e-12f, E ); /* Energy ratio */
ratio = fmaxf( 0.0f, fminf( 1.0f, ratio ) );
- hSpatParamRendCom->azimuth[dirac_write_idx][bin] = (int16_t) roundf( azi / PI_OVER_180 );
- hSpatParamRendCom->elevation[dirac_write_idx][bin] = (int16_t) roundf( ele / PI_OVER_180 );
- hSpatParamRendCom->energy_ratio1[dirac_write_idx][bin] = ratio;
- hSpatParamRendCom->diffuseness_vector[dirac_write_idx][bin] = 1.0f - ratio;
+ hDirAC->azimuth[dirac_write_idx][bin] = (int16_t) roundf( azi / PI_OVER_180 );
+ hDirAC->elevation[dirac_write_idx][bin] = (int16_t) roundf( ele / PI_OVER_180 );
+ hDirAC->energy_ratio1[dirac_write_idx][bin] = ratio;
+ hDirAC->diffuseness_vector[dirac_write_idx][bin] = 1.0f - ratio;
- hSpatParamRendCom->spreadCoherence[dirac_write_idx][bin] = 0.0f;
- hSpatParamRendCom->surroundingCoherence[dirac_write_idx][bin] = 0.0f;
+ hDirAC->spreadCoherence[dirac_write_idx][bin] = 0.0f;
+ hDirAC->surroundingCoherence[dirac_write_idx][bin] = 0.0f;
/* Determine directional distribution of the indirect audio based on the SPAR mixing matrices (and the transport audio signals when 2 TC) */
if ( hDiffuseDist != NULL )
@@ -1519,3 +1871,622 @@ static void create_masa_ext_out_meta(
return;
}
+
+#ifdef MASA_AND_OBJECTS
+// Todo OMASA JBM: There is a lot of metadata access here via dirac indices, they could be wrong post JBM.
+static void decode_index_slice(
+ int16_t index, /* i : index to decode */
+ int16_t *ratio_idx_ism, /* o : decodec array of integers */
+ const int16_t nchan_ism, /* i : number of elements in array (objects) */
+ const int16_t K ) /* i : sum of array elements */
+{
+ int16_t i, j, sum, elem;
+ int16_t base[MAX_NUM_OBJECTS];
+
+ switch ( nchan_ism )
+ {
+ case 2:
+ ratio_idx_ism[0] = index;
+ ratio_idx_ism[1] = K - ratio_idx_ism[0];
+ break;
+ case 3:
+ case 4:
+ {
+ j = 0;
+ while ( index >= 0 )
+ {
+ if ( valid_ratio_index( j, K, nchan_ism - 1 ) )
+ {
+ index--;
+ }
+ j++;
+ }
+ j--;
+ base[0] = 1;
+ for ( i = 1; i < nchan_ism - 1; i++ )
+ {
+ base[i] = base[i - 1] * 10;
+ }
+ sum = 0;
+ for ( i = nchan_ism - 2; i >= 0; i-- )
+ {
+ elem = j / base[i];
+ ratio_idx_ism[nchan_ism - i - 2] = elem;
+ sum += elem;
+ j -= elem * base[i];
+ }
+ ratio_idx_ism[nchan_ism - 1] = K - sum;
+ }
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+
+static void read_ism_ratio_index(
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM read ratio indexes */
+ const int16_t nchan_ism, /* i : number of objects */
+ const int16_t numCodingBands, /* i : number of subbands */
+ const int16_t sf, /* i : index of subframe */
+ int16_t ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i : previous subframe ISM ratio indexes */
+ uint16_t *bit_stream, /* i : bitstream */
+ int16_t *next_bit_pos, /* i/o: position in bitstream */
+ float *masa_to_total_energy_ratio, /* i : masa to total ratios */
+ const int16_t idx_sep_obj, /* i : index of separated index, -1 if none */
+ int16_t *num_zeros /* i/o: number of zero values in first subframe for separated object */
+)
+{
+ int16_t b, i, b_signif;
+ int16_t index;
+ int16_t GR_order, differential_subframe;
+ int16_t buf;
+ int16_t no_levels_ratio_ism;
+ int16_t bits_index;
+ int16_t ratio_ism_idx_ref[MAX_NUM_OBJECTS];
+ int16_t idx_sep_obj_local, shift_one;
+
+ idx_sep_obj_local = idx_sep_obj;
+ if ( idx_sep_obj > -1 )
+ {
+ if ( idx_sep_obj == nchan_ism - 1 && nchan_ism > 2 )
+ {
+ idx_sep_obj_local = 0;
+ }
+ }
+
+ b_signif = 0;
+ no_levels_ratio_ism = ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 );
+ while ( ( b_signif < numCodingBands ) && ( masa_to_total_energy_ratio[b_signif] >= MASA2TOTAL_THR ) )
+ {
+ /* distribute evenly the objects */
+ distribute_evenly_ism( ratio_ism_idx[b_signif], no_levels_ratio_ism, nchan_ism );
+ b_signif++;
+ }
+
+ if ( b_signif == numCodingBands )
+ {
+ return;
+ }
+ else
+ {
+
+ if ( sf == 0 )
+ {
+ bits_index = bits_index_ism_ratio( nchan_ism );
+
+ /* read coding type */
+ if ( bit_stream[( *next_bit_pos )--] == 1 )
+ {
+ /* independent coding*/
+ for ( b = 0; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ index = 0;
+ for ( i = 0; i < bits_index; i++ )
+ {
+ index = ( index << 1 ) + bit_stream[( *next_bit_pos )--];
+ }
+ decode_index_slice( index, ratio_ism_idx[b], nchan_ism, no_levels_ratio_ism );
+ if ( idx_sep_obj > -1 && ratio_ism_idx[b][idx_sep_obj_local] == 0 )
+ {
+ ( *num_zeros )++;
+ }
+ }
+ else
+ {
+ /* distribute evenly the objects */
+ distribute_evenly_ism( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
+ }
+ }
+ }
+ else
+ {
+ /* differential coding */
+ index = 0;
+ for ( i = 0; i < bits_index; i++ )
+ {
+ index = ( index << 1 ) + bit_stream[( *next_bit_pos )--];
+ }
+ decode_index_slice( index, ratio_ism_idx[b_signif], nchan_ism, no_levels_ratio_ism );
+ if ( idx_sep_obj > -1 && ratio_ism_idx[b_signif][idx_sep_obj_local] == 0 )
+ {
+ ( *num_zeros )++;
+ }
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, 0 );
+ if ( ( buf % 2 ) == 0 )
+ {
+ ratio_ism_idx[b][i] = -( buf >> 1 );
+ }
+ else
+ {
+ ratio_ism_idx[b][i] = ( ( buf + 1 ) >> 1 );
+ }
+ ratio_ism_idx[b][i] = ratio_ism_idx[b][i] + ratio_ism_idx_ref[i];
+ ratio_ism_idx[b][nchan_ism - 1] -= ratio_ism_idx[b][i];
+ }
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
+ if ( idx_sep_obj > -1 && ratio_ism_idx[b][idx_sep_obj_local] == 0 )
+ {
+ ( *num_zeros )++;
+ }
+ }
+ else
+ {
+ /* distribute evenly the objects */
+ distribute_evenly_ism( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( numCodingBands > 1 )
+ {
+ /* read prediction type */
+ differential_subframe = bit_stream[( *next_bit_pos )--];
+ }
+ else
+ {
+ differential_subframe = 1;
+ }
+
+ if ( *num_zeros == numCodingBands )
+ {
+ shift_one = 1;
+ }
+ else
+ {
+ shift_one = 0;
+ }
+
+ if ( shift_one == 1 && nchan_ism == 2 )
+ {
+ /* nothing has been sent ; values can be inferred */
+ for ( b = b_signif; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ if ( idx_sep_obj_local == 0 )
+ {
+ ratio_ism_idx[b][0] = 0;
+ ratio_ism_idx[b][1] = 7;
+ }
+ else
+ {
+ ratio_ism_idx[b][0] = 7;
+ ratio_ism_idx[b][1] = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* read GR order */
+ GR_order = bit_stream[( *next_bit_pos )--];
+ for ( b = b_signif; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ for ( i = 0; i < nchan_ism - 1 - shift_one; i++ )
+ {
+ buf = ivas_qmetadata_DecodeExtendedGR( bit_stream, next_bit_pos, 100, GR_order );
+ if ( ( buf % 2 ) == 0 )
+ {
+ ratio_ism_idx[b][i] = -( buf >> 1 );
+ }
+ else
+ {
+ ratio_ism_idx[b][i] = ( ( buf + 1 ) >> 1 );
+ }
+ }
+
+ /* insert separated obj */
+ if ( shift_one )
+ {
+ for ( i = nchan_ism - 1; i > idx_sep_obj_local; i-- )
+ {
+ ratio_ism_idx[b][i] = ratio_ism_idx[b][i - 1];
+ }
+ ratio_ism_idx[b][idx_sep_obj_local] = 0; /* this is only difference; need to pdate later as well */
+ }
+ }
+ }
+ if ( differential_subframe )
+ {
+ /* differential to previous subframe */
+ for ( b = b_signif; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ ratio_ism_idx[b][i] = ratio_ism_idx[b][i] + ratio_ism_idx_prev_sf[b][i];
+ if ( shift_one && i == idx_sep_obj_local )
+ {
+ ratio_ism_idx[b][i] = 0;
+ }
+ ratio_ism_idx[b][nchan_ism - 1] -= ratio_ism_idx[b][i];
+ }
+ }
+ else
+ {
+ /* distribute evenly the objects */
+ distribute_evenly_ism( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
+ }
+ }
+ }
+ else
+ {
+ /* difference to previous subband */
+ ratio_ism_idx[b_signif][nchan_ism - 1] = no_levels_ratio_ism;
+
+ /* first significant subband - differential to previous subframe */
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ ratio_ism_idx[b_signif][i] = ratio_ism_idx[b_signif][i] + ratio_ism_idx_prev_sf[b_signif][i];
+ if ( shift_one && i == idx_sep_obj_local )
+ {
+ ratio_ism_idx[b_signif][i] = 0;
+ }
+ ratio_ism_idx[b_signif][nchan_ism - 1] -= ratio_ism_idx[b_signif][i];
+ }
+
+ /* rest of subbands differential to previous subband */
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ ratio_ism_idx[b][nchan_ism - 1] = no_levels_ratio_ism;
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ ratio_ism_idx[b][i] = ratio_ism_idx[b][i] + ratio_ism_idx_ref[i];
+ if ( shift_one && i == idx_sep_obj_local )
+ {
+ ratio_ism_idx[b][i] = 0;
+ }
+ ratio_ism_idx[b][nchan_ism - 1] -= ratio_ism_idx[b][i];
+ }
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
+ }
+ else
+ {
+ /* distribute evenly the objects */
+ distribute_evenly_ism( ratio_ism_idx[b], no_levels_ratio_ism, nchan_ism );
+ }
+ }
+ }
+ }
+ }
+
+ return;
+ }
+}
+
+
+static void decode_ism_ratios(
+ uint16_t *bit_stream, /* i : bitstream */
+ int16_t *next_bit_pos, /* i/o: position in bitstream */
+ IVAS_QMETADATA_HANDLE hQMetaData, /* i : Metadata handle */
+ float ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* o : ISM ratios */
+ const int16_t n_ism, /* i : number of objects */
+ const int16_t nbands, /* i : number of subbands */
+ const int16_t numSf, /* i : number of subframes */
+ const int16_t idx_separated_object /* i: index of separated object */
+)
+{
+ int16_t sf, band;
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ int16_t ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ float tmp;
+ int16_t num_zeros;
+ num_zeros = 0;
+
+ /* hQMetaData->q_direction->cfg.nblocks; */
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ /* read ism ratio indexes */
+ read_ism_ratio_index( ratio_ism_idx, n_ism, nbands, sf, ratio_ism_idx_prev_sf, bit_stream, next_bit_pos, hQMetaData->masa_to_total_energy_ratio[sf], idx_separated_object, &num_zeros );
+
+ /* save previous subframe index values */
+ if ( sf < numSf - 1 )
+ {
+ /* Todo Nokia: can be moved to the read_ism_ratio ... function */
+ for ( band = 0; band < nbands; band++ )
+ {
+ mvs2s( ratio_ism_idx[band], ratio_ism_idx_prev_sf[band], n_ism );
+ }
+ }
+
+ /* reconstructed values */
+ for ( band = 0; band < nbands; band++ )
+ {
+ reconstruct_ism_ratios( ratio_ism_idx[band], n_ism, 1.0f / (float) ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ), ratio_ism[sf][band] );
+ }
+
+ if ( ( n_ism > 2 ) && ( idx_separated_object == n_ism - 1 ) )
+ {
+ /* rotate */
+ for ( band = 0; band < nbands; band++ )
+ {
+ if ( hQMetaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR )
+ {
+ tmp = ratio_ism[sf][band][n_ism - 1];
+ ratio_ism[sf][band][n_ism - 1] = ratio_ism[sf][band][0];
+ ratio_ism[sf][band][0] = tmp;
+ }
+ }
+ }
+
+ if ( nbands == 1 )
+ {
+ for ( band = 1; band < 5; band++ )
+ {
+ mvr2r( ratio_ism[sf][0], ratio_ism[sf][band], n_ism );
+ }
+ }
+ }
+
+ if ( numSf == 1 )
+ {
+ for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
+ {
+ for ( band = 0; band < nbands; band++ )
+ {
+ mvr2r( ratio_ism[0][band], ratio_ism[sf][band], n_ism );
+ }
+ }
+ }
+
+ return;
+}
+
+
+static int16_t ivas_decode_masaism_metadata(
+ IVAS_QMETADATA_HANDLE hQMetaData,
+ MASA_DECODER_HANDLE hMasa,
+ MASA_ISM_DATA_HANDLE hMasaIsmData,
+ const int16_t nchan_ism,
+ uint16_t *bit_stream,
+ int16_t *next_bit_pos,
+ const int16_t idx_separated_object,
+ const int16_t ism_imp,
+ const int16_t dirac_bs_md_write_idx,
+ const int16_t dirac_md_buffer_length )
+{
+ int16_t sf, band, dir, nbands, nblocks, obj, i;
+ float energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ int16_t *band_mapping;
+ int16_t b;
+ int16_t bits_ism[MAX_NUM_OBJECTS], index;
+ uint16_t idx_el, idx_az;
+ float azimuth, elevation;
+ int16_t nb_bits_read;
+ float delta_phi;
+ int16_t meta_write_index;
+
+ nb_bits_read = *next_bit_pos;
+ nbands = hQMetaData->q_direction->cfg.nbands;
+ nblocks = hQMetaData->q_direction->cfg.nblocks; /* To do: what if other value than 4? */
+
+ /* Read MASA-to-total energy ratios */
+ decode_masa_to_total( bit_stream, next_bit_pos, hQMetaData->masa_to_total_energy_ratio, nbands, nblocks );
+ if ( nchan_ism > 1 )
+ {
+ /* read ISM ratios */
+ decode_ism_ratios( bit_stream, next_bit_pos, hQMetaData, energy_ratio_ism, nchan_ism, nbands, nblocks, idx_separated_object );
+ }
+ else
+ {
+ for ( sf = 0; sf < nblocks; sf++ )
+ {
+ for ( band = 0; band < nbands; band++ )
+ {
+ energy_ratio_ism[sf][band][0] = 1.0f;
+ }
+ }
+ }
+
+ /* read ISM metadata */
+ calculate_nbits_meta( nchan_ism, energy_ratio_ism, hQMetaData->masa_to_total_energy_ratio, nblocks, nbands, bits_ism, idx_separated_object, ism_imp );
+
+ for ( obj = 0; obj < nchan_ism; obj++ )
+ {
+ index = 0;
+ if ( bits_ism[obj] < 8 ) /* if low resolution, can look to the past */
+ {
+ /* read if same as previous */
+ if ( bit_stream[( *next_bit_pos )--] )
+ {
+ azimuth = hMasaIsmData->q_azimuth_old[obj];
+ elevation = hMasaIsmData->q_elevation_old[obj];
+ }
+ else
+ {
+ for ( i = 0; i < bits_ism[obj]; i++ )
+ {
+ index = ( index << 1 ) + bit_stream[( *next_bit_pos )--];
+ }
+ deindex_spherical_component( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
+
+ if ( azimuth * hMasaIsmData->q_azimuth_old[obj] > 0 )
+ {
+ delta_phi = 180.0f / (float) ( no_phi_masa[bits_ism[obj] - 1][idx_el] ); /* 360/2*/
+ if ( azimuth - hMasaIsmData->q_azimuth_old[obj] > delta_phi )
+ {
+ azimuth -= delta_phi;
+ }
+ else
+ {
+ if ( hMasaIsmData->q_azimuth_old[obj] - azimuth > delta_phi )
+ {
+ azimuth += delta_phi;
+ }
+ }
+ }
+
+ hMasaIsmData->q_azimuth_old[obj] = azimuth;
+ hMasaIsmData->q_elevation_old[obj] = elevation;
+ }
+ }
+ else
+ {
+ for ( i = 0; i < bits_ism[obj]; i++ )
+ {
+ index = ( index << 1 ) + bit_stream[( *next_bit_pos )--];
+ }
+ deindex_spherical_component( index, &azimuth, &elevation, &idx_az, &idx_el, bits_ism[obj], MC_LS_SETUP_INVALID );
+ hMasaIsmData->q_azimuth_old[obj] = azimuth;
+ hMasaIsmData->q_elevation_old[obj] = elevation;
+ }
+
+ for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
+ {
+ meta_write_index = ( dirac_bs_md_write_idx + sf ) % dirac_md_buffer_length;
+ hMasaIsmData->azimuth_ism[obj][meta_write_index] = (int16_t) rint( azimuth );
+ hMasaIsmData->elevation_ism[obj][meta_write_index] = (int16_t) rint( elevation );
+ }
+ }
+
+ /* Modify ISM metadata based on the MASA-to-total energy ratios */
+ for ( sf = 0; sf < nblocks; sf++ )
+ {
+ for ( band = 0; band < nbands; band++ )
+ {
+ for ( dir = 0; dir < nchan_ism; dir++ )
+ {
+ energy_ratio_ism[sf][band][dir] *= ( 1.0f - hQMetaData->masa_to_total_energy_ratio[sf][band] );
+ }
+ }
+ }
+
+ /* Set data to struct in bins */
+ band_mapping = hMasa->data.band_mapping;
+ for ( band = 0; band < hMasa->config.numCodingBands; ++band )
+ {
+ for ( b = MASA_band_grouping_24[band_mapping[band]]; b < MASA_band_grouping_24[band_mapping[band + 1]]; ++b )
+ {
+ for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; ++sf )
+ {
+ if ( nblocks == 1 )
+ {
+ i = 0;
+ }
+ else
+ {
+ i = sf;
+ }
+
+ meta_write_index = ( dirac_bs_md_write_idx + sf ) % dirac_md_buffer_length;
+
+ for ( dir = 0; dir < nchan_ism; dir++ )
+ {
+ hMasaIsmData->energy_ratio_ism[dir][meta_write_index][b] = energy_ratio_ism[i][band][dir];
+ }
+ }
+ }
+ }
+
+ return ( nb_bits_read - *next_bit_pos );
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_masa_ism_set_edited_objects()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ivas_masa_ism_set_edited_objects(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ int16_t dir, sf;
+ MASA_ISM_DATA_HANDLE hMasaIsmData;
+
+ hMasaIsmData = st_ivas->hMasaIsmData;
+
+ /* Set positions of the edited objects */
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ if ( st_ivas->editing_ism_enabled )
+ {
+ for ( sf = 0; sf < ( MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR ); sf++ )
+ {
+ hMasaIsmData->azimuth_ism[st_ivas->index_of_edited_ism][sf] = st_ivas->azimuth_edited;
+ hMasaIsmData->elevation_ism[st_ivas->index_of_edited_ism][sf] = st_ivas->elevation_edited;
+ }
+
+ st_ivas->hIsmMetaData[st_ivas->index_of_edited_ism]->azimuth = st_ivas->azimuth_edited;
+ st_ivas->hIsmMetaData[st_ivas->index_of_edited_ism]->elevation = st_ivas->elevation_edited;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* Directions cannot be edited in this mode */
+ }
+ else
+ {
+ for ( dir = 0; dir < MAX_NUM_OBJECTS; dir++ )
+ {
+ if ( dir == st_ivas->index_of_edited_ism && st_ivas->editing_ism_enabled )
+ {
+ hMasaIsmData->ism_is_edited[dir] = 1;
+ hMasaIsmData->azimuth_ism_edited[dir] = st_ivas->azimuth_edited;
+ hMasaIsmData->elevation_ism_edited[dir] = st_ivas->elevation_edited;
+ }
+ else
+ {
+ hMasaIsmData->ism_is_edited[dir] = 0;
+ }
+ }
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->editing_ism_enabled )
+ {
+ if ( st_ivas->hMasaIsmData->idx_separated_ism == st_ivas->index_of_edited_ism )
+ {
+ for ( sf = 0; sf < ( MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR ); sf++ )
+ {
+ st_ivas->hMasaIsmData->azimuth_separated_ism[sf] = st_ivas->azimuth_edited;
+ st_ivas->hMasaIsmData->elevation_separated_ism[sf] = st_ivas->elevation_edited;
+ }
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c
index 0ba001d415aee165d188879bcfa20bf787f76ae0..8f750fa819bf5cff7cd551e6fa01f2eaba3c438c 100644
--- a/lib_dec/ivas_mc_param_dec.c
+++ b/lib_dec/ivas_mc_param_dec.c
@@ -3090,13 +3090,19 @@ static void ivas_param_mc_bs_decode_parameter_values(
int16_t i, j, k;
float dequant_seq[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
float dequant_ordered[PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE];
+#ifdef FIX_578_PARAMMC_ILD_BS
int16_t n_lfe_idx;
+#endif
range_coding = bit_buffer[( *bit_pos )++];
/* Decoding the sequence */
+#ifdef FIX_578_PARAMMC_ILD_BS
n_lfe_idx = map_size - map_size_wo_lfe;
sz_seq = num_param_bands * ( map_size_wo_lfe ) + num_lfe_bands * n_lfe_idx;
+#else
+ sz_seq = num_param_bands * ( map_size_wo_lfe ) + num_lfe_bands;
+#endif
set_s( idx, 0, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE );
set_zero( dequant_ordered, PARAM_MC_MAX_PARAMETER_BANDS * PARAM_MC_MAX_VAL_MAP_SIZE );
@@ -3157,10 +3163,14 @@ static void ivas_param_mc_bs_decode_parameter_values(
for ( i = 0; i < num_lfe_bands; i++ )
{
+#ifdef FIX_578_PARAMMC_ILD_BS
for ( j = 0; j < n_lfe_idx; j++ )
{
dequant_ordered[map_size - n_lfe_idx + j + i * map_size] = dequant_seq[k++];
}
+#else
+ dequant_ordered[map_size - 1 + i * map_size] = dequant_seq[k++];
+#endif
}
if ( !( *BER_detect ) )
diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c
index efdb0a8122809153902ba3c5a4acbee1488f9c62..99b3ff68744b0daf4e3460cd3c9ab3b764ad6bc3 100755
--- a/lib_dec/ivas_mcmasa_dec.c
+++ b/lib_dec/ivas_mcmasa_dec.c
@@ -82,7 +82,7 @@ ivas_error ivas_mcmasa_dec_reconfig(
{
if ( st_ivas->hDirAC == NULL )
{
- if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -96,5 +96,51 @@ ivas_error ivas_mcmasa_dec_reconfig(
}
}
+ /*-------------------------------------------------------------------*
+ * 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 ( st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ) ) != 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
+ {
+ /* if necessary, close/open td-decorrs */
+ if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* regularization factor is bitrate-dependent */
+ st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
+ }
+ }
+
return error;
}
diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c
index e99cf63fa64376f9ab08878e7d95380cc2f284d8..1350b9656c354f01ba4eaf22c5705c1f0a945589 100755
--- a/lib_dec/ivas_mct_dec.c
+++ b/lib_dec/ivas_mct_dec.c
@@ -737,13 +737,13 @@ static ivas_error ivas_mc_dec_reconfig(
st_ivas->hTcBuffer->slots_rendered = st_ivas->hParamMC->slots_rendered;
mvs2s( st_ivas->hParamMC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
- else if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->hSpatParamRendCom != NULL )
+ else if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->hDirAC != NULL )
{
- st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
- st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
- st_ivas->hTcBuffer->num_slots = st_ivas->hSpatParamRendCom->num_slots;
- st_ivas->hTcBuffer->slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
- mvs2s( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
+ st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes;
+ st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered;
+ st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots;
+ st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered;
+ mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
/* JBM: when granularity goes down (e.g. MCT with CREND -> ParamMC with binaural fastconv
@@ -800,9 +800,7 @@ static ivas_error ivas_mc_dec_reconfig(
if ( st_ivas->hDirAC != NULL )
{
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
- ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
+ ivas_dirac_dec_close( &st_ivas->hDirAC );
vbap_free_data( &( st_ivas->hVBAPdata ) );
}
@@ -886,9 +884,7 @@ static ivas_error ivas_mc_dec_reconfig(
if ( st_ivas->hDirAC != NULL )
{
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
- ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
+ ivas_dirac_dec_close( &st_ivas->hDirAC );
vbap_free_data( &( st_ivas->hVBAPdata ) );
}
@@ -1119,8 +1115,6 @@ static ivas_error ivas_mc_dec_reconfig(
}
else if ( st_ivas->renderer_type == RENDERER_DISABLE && st_ivas->hDirAC != NULL )
{
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
vbap_free_data( &( st_ivas->hVBAPdata ) );
@@ -1167,6 +1161,16 @@ static ivas_error ivas_mc_dec_reconfig(
{
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, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
}
/* init necessary new renderers */
@@ -1177,6 +1181,21 @@ static ivas_error ivas_mc_dec_reconfig(
return error;
}
}
+ else if ( st_ivas->hDiracDecBin == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) )
+ {
+ if ( st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
else if ( st_ivas->hBinRendererTd == NULL && st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
{
if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
@@ -1248,6 +1267,18 @@ static ivas_error ivas_mc_dec_reconfig(
#endif
}
+ /*-----------------------------------------------------------------*
+ * TD Decorrelator
+ *-----------------------------------------------------------------*/
+
+ if ( st_ivas->hDiracDecBin != NULL )
+ {
+ if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
/*-----------------------------------------------------------------*
* CLDFB instances
*-----------------------------------------------------------------*/
@@ -1293,13 +1324,13 @@ static ivas_error ivas_mc_dec_reconfig(
}
/* transfer subframe info from central tc buffer to ParamMC or McMASA (DirAC) */
- if ( st_ivas->hSpatParamRendCom != NULL )
+ if ( st_ivas->hDirAC != NULL )
{
- st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
- st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
- st_ivas->hSpatParamRendCom->num_slots = st_ivas->hTcBuffer->num_slots;
- st_ivas->hSpatParamRendCom->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
- mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
+ st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
+ st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
+ st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots;
+ st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
+ mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
else if ( st_ivas->hParamMC != NULL )
{
diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer.c
index d4dcb7ac7339e69e50347c4061c68b9547d8a3b9..61d8c6809492ff8ed5ed8e662a3d7ed86838e46b 100644
--- a/lib_dec/ivas_mono_dmx_renderer.c
+++ b/lib_dec/ivas_mono_dmx_renderer.c
@@ -94,6 +94,21 @@ void ivas_mono_downmix_render_passive(
MONO_DOWNMIX_RENDERER_HANDLE hDownmix;
numInputChannels = st_ivas->nSCE;
+
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ numInputChannels = st_ivas->nchan_transport + 1;
+ }
+ else
+ {
+ numInputChannels = st_ivas->nchan_transport + st_ivas->nchan_ism;
+ }
+ }
+#endif
+
hDownmix = st_ivas->hMonoDmxRenderer;
set_zero( proto_signal, output_frame );
diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c
index 3be8a2c62ebfdf1c46806b276c8a7a0c8a54b23d..95ffee7423f56d6779b785e004edc1fe1a927965 100644
--- a/lib_dec/ivas_objectRenderer_internal.c
+++ b/lib_dec/ivas_objectRenderer_internal.c
@@ -53,8 +53,22 @@ ivas_error ivas_td_binaural_open(
Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
)
{
+#ifdef MASA_AND_OBJECTS
+ int16_t num_src;
+
+ num_src = st_ivas->nchan_transport;
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ num_src = st_ivas->nchan_ism;
+ }
+
+ return ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, num_src, st_ivas->ivas_format,
+ st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns );
+#else
+
return ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, st_ivas->hDecoderConfig->output_Fs, st_ivas->nchan_transport, st_ivas->ivas_format,
st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hTransSetup, &st_ivas->hBinRendererTd, &st_ivas->binaural_latency_ns );
+#endif
}
@@ -72,6 +86,17 @@ ivas_error ivas_td_binaural_renderer(
)
{
int16_t ism_md_subframe_update;
+#ifdef MASA_AND_OBJECTS
+ int16_t num_src;
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ num_src = st_ivas->nchan_transport;
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ num_src = st_ivas->nchan_ism;
+ }
+#endif
if ( st_ivas->hDecoderConfig->Opt_delay_comp )
{
@@ -81,10 +106,24 @@ ivas_error ivas_td_binaural_renderer(
{
ism_md_subframe_update = 2;
}
+
+#ifdef FIX_356_ISM_METADATA_SYNC_OMASA
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ ism_md_subframe_update = 0;
+ }
+#endif
+
return ivas_td_binaural_renderer_unwrap(
st_ivas->hReverb,
st_ivas->transport_config,
- st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format,
+ st_ivas->hBinRendererTd,
+#ifdef MASA_AND_OBJECTS
+ num_src,
+#else
+ st_ivas->nchan_transport,
+#endif
+ LFE_CHANNEL, st_ivas->ivas_format,
st_ivas->hIsmMetaData,
( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL,
( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL,
diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c
new file mode 100644
index 0000000000000000000000000000000000000000..b419da1b59a2524cb48104235f6138154d0a0f80
--- /dev/null
+++ b/lib_dec/ivas_omasa_dec.c
@@ -0,0 +1,642 @@
+/******************************************************************************************************
+
+ (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 "options.h"
+#include
+#include "ivas_cnst.h"
+#include "ivas_prot.h"
+#include "prot.h"
+#include "ivas_prot_rend.h"
+#include "ivas_rom_com.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------*
+ * ivas_masa_ism_data_open()
+ *
+ * Allocate and initialize MASA_ISM rendering handle
+ *-------------------------------------------------------------------*/
+
+ivas_error ivas_masa_ism_data_open(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
+)
+{
+ MASA_ISM_DATA_HANDLE hMasaIsmData;
+ int16_t ch, bin;
+ int16_t sf, obj_idx;
+
+ if ( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
+ }
+
+ for ( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
+ {
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ hMasaIsmData->ismPreprocMatrix[ch][ch][bin] = 1.0f;
+ hMasaIsmData->ismPreprocMatrix[1 - ch][ch][bin] = 0.0f;
+ hMasaIsmData->eneMoveIIR[ch][bin] = 0.0f;
+ hMasaIsmData->enePreserveIIR[ch][bin] = 0.0f;
+ }
+ hMasaIsmData->preprocEneTarget[bin] = 0.0f;
+ hMasaIsmData->preprocEneRealized[bin] = 0.0f;
+ }
+
+ hMasaIsmData->objectsMoved = 0;
+ hMasaIsmData->delayBuffer = NULL;
+
+ for ( ch = 0; ch < st_ivas->nchan_ism; ch++ )
+ {
+ hMasaIsmData->q_elevation_old[ch] = 0.0f;
+ hMasaIsmData->q_azimuth_old[ch] = 0.0f;
+ }
+
+ for ( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
+ {
+ set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
+ set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
+ for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
+ {
+ set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
+ }
+ }
+ set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
+ set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
+
+ st_ivas->hMasaIsmData = hMasaIsmData;
+
+ return IVAS_ERR_OK;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_masa_ism_data_close()
+ *
+ * Deallocate MASA_ISM rendering handle
+ *-------------------------------------------------------------------*/
+
+void ivas_masa_ism_data_close(
+ MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle */
+)
+{
+ int16_t i;
+
+ if ( hMasaIsmData == NULL || *hMasaIsmData == NULL )
+ {
+ return;
+ }
+
+ if ( ( *hMasaIsmData )->delayBuffer != NULL )
+ {
+ for ( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
+ {
+ free( ( *hMasaIsmData )->delayBuffer[i] );
+ }
+ free( ( *hMasaIsmData )->delayBuffer );
+ ( *hMasaIsmData )->delayBuffer = NULL;
+ }
+
+ free( *hMasaIsmData );
+ *hMasaIsmData = NULL;
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_dec_config()
+ *
+ * oMASA decoder configuration
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_dec_config(
+ Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
+)
+{
+ int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD;
+ int32_t ivas_total_brate, ism_total_brate, cpe_brate;
+ ISM_MODE ism_mode_old;
+ IVAS_FORMAT ivas_format_orig;
+ ivas_error error;
+ RENDERER_TYPE old_renderer_type;
+
+ /* initializations */
+ ism_total_brate = 0;
+ ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
+
+ /* save previous frame parameters */
+ ism_mode_old = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
+ st_ivas->ism_mode = ism_mode_old;
+
+ ivas_format_orig = st_ivas->ivas_format;
+ st_ivas->ivas_format = st_ivas->last_ivas_format;
+ ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
+ st_ivas->ivas_format = ivas_format_orig;
+
+ nSCE_old = st_ivas->nSCE;
+ nchan_hp20_old = getNumChanSynthesis( st_ivas );
+
+ /* set ism_mode of current frame */
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism );
+
+ /*-----------------------------------------------------------------*
+ * Renderer selection
+ *-----------------------------------------------------------------*/
+
+ old_renderer_type = st_ivas->renderer_type;
+
+ /* MASA reconfig. */
+ cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
+ if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ( cpe_brate < MASA_STEREO_MIN_BITRATE ) && st_ivas->nCPE == 1 )
+ {
+ st_ivas->hCPE[0]->nchan_out = 1;
+ }
+ else if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( cpe_brate < MASA_STEREO_MIN_BITRATE )
+ {
+ st_ivas->hCPE[0]->nchan_out = 1;
+ }
+ else
+ {
+ st_ivas->hCPE[0]->nchan_out = 2;
+ }
+
+ /* OMASA reconfig. */
+ if ( st_ivas->hMasaIsmData == NULL && st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( ( error = ivas_masa_ism_data_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ ivas_set_omasa_TC( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
+
+ /* re-configure hp20 memories */
+ if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* reconfigure core-coders for ISMs */
+ k = 0;
+ while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
+ {
+ k++;
+ }
+
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
+ }
+
+ if ( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, 1, 2, 0, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( ism_mode_old != st_ivas->ism_mode )
+ {
+ /* ISM MD reconfig. */
+ n_MD = 0;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ n_MD = 1;
+
+ if ( st_ivas->hIsmMetaData[0] == NULL )
+ {
+ if ( ( error = ivas_ism_metadata_dec_create( st_ivas, 1, NULL ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ n_MD = st_ivas->nchan_ism;
+
+ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
+
+ if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD );
+
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
+
+ /*-----------------------------------------------------------------*
+ * Renderer selection
+ *-----------------------------------------------------------------*/
+
+ ivas_renderer_select( st_ivas );
+
+ /*-------------------------------------------------------------------*
+ * Reallocate rendering handles
+ *--------------------------------------------------------------------*/
+
+ if ( old_renderer_type != st_ivas->renderer_type )
+ {
+ if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
+ {
+ if ( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if ( st_ivas->hMonoDmxRenderer != NULL )
+ {
+ free( st_ivas->hMonoDmxRenderer );
+ st_ivas->hMonoDmxRenderer = NULL;
+ }
+ }
+ }
+
+ /* objects renderer reconfig. */
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ && st_ivas->ism_mode != ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hIsmRendererData != NULL )
+ {
+ ivas_masa_ism_data_close( &( st_ivas->hMasaIsmData ) );
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ /* Allocate TD renderer for the objects in DISC mode */
+ if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ if ( ( error = ivas_masa_ism_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ /* TD renderer handle */
+ if ( st_ivas->hBinRendererTd != NULL )
+ {
+ ivas_td_binaural_close( &st_ivas->hBinRendererTd );
+ }
+
+ if ( st_ivas->hHrtfTD != NULL ) // VE: this is copied from ivas_ism_bitrate_switching() but a review is needed
+ {
+ st_ivas->hHrtfTD = NULL;
+ }
+
+ /* ISM renderer handle */
+ if ( st_ivas->hIsmRendererData != NULL )
+ {
+ free( st_ivas->hIsmRendererData );
+ st_ivas->hIsmRendererData = NULL;
+ }
+ }
+ }
+
+ if ( st_ivas->renderer_type == RENDERER_DIRAC )
+ {
+ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
+ if ( ( error = ivas_masa_ism_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ /* ISM renderer handle */
+ if ( st_ivas->hIsmRendererData != NULL )
+ {
+ free( st_ivas->hIsmRendererData );
+ st_ivas->hIsmRendererData = NULL;
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * TD Decorrelator
+ *-----------------------------------------------------------------*/
+
+ if ( st_ivas->hDiracDecBin != NULL )
+ {
+ if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /*-----------------------------------------------------------------*
+ * CLDFB instances
+ *-----------------------------------------------------------------*/
+
+ if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_set_surplus_brate_dec()
+ *
+ * set bit-rate surplus in combined format coding
+ *--------------------------------------------------------------------------*/
+
+void ivas_set_surplus_brate_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ int32_t *ism_total_brate /* i/o: ISM total bitrate */
+)
+{
+ int16_t n, bits_ism, bits_element[MAX_NUM_OBJECTS];
+ int32_t ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
+
+ *ism_total_brate = 0;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ *ism_total_brate = ivas_interformat_brate( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
+
+ st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - *ism_total_brate;
+
+ /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
+ st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
+
+ st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
+ if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META )
+ {
+ st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ int16_t brate_limit_flag, ism_imp[MAX_NUM_OBJECTS];
+
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
+ }
+
+ brate_limit_flag = calculate_brate_limit_flag( ism_imp, st_ivas->nchan_ism );
+
+ ism_total_brate_ref = 0;
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ ism_total_brate_ref += st_ivas->hSCE[n]->element_brate;
+ }
+
+ bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC );
+ set_s( bits_element, bits_ism / st_ivas->nchan_ism, st_ivas->nchan_ism );
+ bits_element[st_ivas->nchan_ism - 1] += bits_ism % st_ivas->nchan_ism;
+ bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
+
+ *ism_total_brate = 0;
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ st_ivas->hSCE[n]->element_brate = element_brate[n];
+
+ *ism_total_brate += ivas_interformat_brate( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag );
+
+ if ( ism_imp[n] > 1 && st_ivas->flag_omasa_brate == 1 && brate_limit_flag >= 0 )
+ {
+ *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
+ }
+
+ if ( brate_limit_flag == -1 && ism_imp[n] >= 1 && st_ivas->nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
+ {
+ *ism_total_brate += ADJUST_ISM_BRATE_POS;
+ }
+ }
+ st_ivas->hCPE[0]->brate_surplus = ism_total_brate_ref - *ism_total_brate;
+
+ /* 'st->total_brate' is set in ivas_ism_config */
+ }
+ else
+ {
+ st_ivas->hCPE[0]->brate_surplus = 0;
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_ism_metadata_dec()
+ *
+ * decode ISM metadata in OMASA format
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_ism_metadata_dec(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ const int32_t ism_total_brate, /* i : ISM total bitrate */
+ int16_t *nchan_ism, /* o : number of ISM separated channels */
+ int16_t *nchan_transport_ism, /* o : number of ISM TCs */
+ const int16_t dirac_bs_md_write_idx, /* i : DirAC bitstream write index */
+ int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */
+)
+{
+ int16_t n, block;
+ int16_t azimuth_ism, elevation_ism, meta_write_index;
+ ivas_error error;
+
+ /* set ISM parameters */
+ *nchan_ism = st_ivas->nchan_ism;
+ *nchan_transport_ism = st_ivas->nchan_ism;
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ *nchan_ism = 1;
+ *nchan_transport_ism = 1;
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ *nchan_ism = 0;
+ *nchan_transport_ism = 1;
+ }
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* decode ISM metadata */
+ if ( ( error = ivas_ism_metadata_dec( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
+ nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->hDirAC != NULL )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
+ elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
+ st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
+ }
+ }
+ }
+ else /* ISM_MASA_MODE_MASA_ONE_OBJ */
+ {
+ azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
+ elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
+
+ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
+ {
+ meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hDirAC->dirac_md_buffer_length;
+ st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
+ st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
+ }
+ }
+ }
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_dirac_rend()
+ *
+ * Rendering in OMASA format
+ *--------------------------------------------------------------------------*/
+
+// Todo OMASA JBM: This might need adjustments
+void ivas_omasa_dirac_rend(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float output[][L_FRAME48k], /* o : output synthesis signal */
+ const int16_t output_frame /* i : output frame length per channel */
+)
+{
+ int16_t n, dirac_read_idx;
+ float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ mvr2r( output[2], data_separated_objects[0], output_frame );
+ }
+ else
+ {
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ mvr2r( output[n + 2], data_separated_objects[n], output_frame );
+ }
+ }
+
+ dirac_read_idx = st_ivas->hDirAC->dirac_read_idx;
+
+ ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport );
+
+ st_ivas->hDirAC->dirac_read_idx = dirac_read_idx; /* Original read index is needed for the next function which will update it again */
+
+ ivas_masa_ism_separate_object_render( st_ivas, data_separated_objects, output, output_frame );
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_dirac_td_binaural()
+ *
+ * Binaural rendering in OMASA format
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_dirac_td_binaural(
+ Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
+ float output[][L_FRAME48k], /* o : output synthesis signal */
+ const int16_t output_frame /* i : output frame length per channel */
+)
+{
+ int16_t n;
+ float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
+ float gain = 0.7943f; /* Todo Nokia: Temporary gain for roughly matching the loudness of other processing paths. */
+ ivas_error error;
+ float *p_sepobj[MAX_NUM_OBJECTS];
+
+ for ( n = 0; n < MAX_NUM_OBJECTS; n++ )
+ {
+ p_sepobj[n] = &data_separated_objects[n][0];
+ }
+
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ mvr2r( output[2 + n], data_separated_objects[n], output_frame );
+ v_multc( data_separated_objects[n], gain, data_separated_objects[n], output_frame );
+ }
+
+ for ( n = 0; n < st_ivas->nchan_ism; n++ )
+ {
+ delay_signal( data_separated_objects[n], output_frame, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size );
+ }
+
+ ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, output, st_ivas->nchan_transport );
+
+ if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ for ( n = 0; n < BINAURAL_CHANNELS; n++ )
+ {
+ v_add( output[n], p_sepobj[n], output[n], output_frame );
+ }
+
+ return IVAS_ERR_OK;
+}
+#endif
diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c
index abc9a9012dfe0b90e81193ce49f12716626a2834..fb5469fe43adbd5dcf361c4432f05af9e2b44f22 100644
--- a/lib_dec/ivas_output_config.c
+++ b/lib_dec/ivas_output_config.c
@@ -147,7 +147,11 @@ void ivas_renderer_select(
}
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport <= 2 ) )
+#else
else if ( st_ivas->ivas_format == MASA_FORMAT || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport <= 2 ) )
+#endif
{
*internal_config = output_config;
if ( output_config == AUDIO_CONFIG_BINAURAL
@@ -424,6 +428,27 @@ void ivas_renderer_select(
*renderer_type = RENDERER_SBA_LINEAR_DEC;
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ *renderer_type = RENDERER_DIRAC;
+
+ if ( output_config == AUDIO_CONFIG_MONO )
+ {
+ *renderer_type = RENDERER_MONO_DOWNMIX;
+ }
+ else if ( output_config == AUDIO_CONFIG_STEREO )
+ {
+ *renderer_type = RENDERER_STEREO_PARAMETRIC;
+ }
+#ifdef OMASA_EXT_OUTPUT
+ else if ( output_config == AUDIO_CONFIG_EXTERNAL )
+ {
+ *renderer_type = RENDERER_DISABLE;
+ }
+#endif
+ }
+#endif
else if ( st_ivas->ivas_format == MC_FORMAT )
{
*internal_config = transport_config;
diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c
index 417cd7c5b4982e0b28dee6f3f04c60c7b4b70e66..7f1c84983b3834b6948e06c0af71cd88341cc0d0 100755
--- a/lib_dec/ivas_post_proc.c
+++ b/lib_dec/ivas_post_proc.c
@@ -208,7 +208,11 @@ void stereo_dft_dec_core_switching(
lerp( hCPE->input_mem_BPF[0], hCPE->input_mem_BPF[0], NS2SA( st->L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ), NS2SA( st->last_L_frame * FRAMES_PER_SEC, STEREO_DFT32MS_OVL_NS ) );
}
+#ifdef FIX_558_PLC_DISCONT
if ( st->prev_bfi && !( st->last_core_bfi == ACELP_CORE && st->last_con_tcx == 1 ) )
+#else
+ if ( st->prev_bfi )
+#endif
{
/* last_core needed for correctly decoding ACELP->TCX/HQ switching frames in ivas_core_dec().
In the following steps the decoder needs to consider if the core was changed due to a lost frame to apply the correct transition */
diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c
index e4c69cd288a01bdc124ae7e289fe2befc6eb75b0..97209faf7ca760d0ecbedaf5678f0660ada2557a 100644
--- a/lib_dec/ivas_qmetadata_dec.c
+++ b/lib_dec/ivas_qmetadata_dec.c
@@ -55,7 +55,9 @@ static int16_t ivas_qmetadata_raw_decode_dir( IVAS_QDIRECTION *q_direction, uint
static uint16_t ivas_qmetadata_DecodeQuasiUniform( const uint16_t *bitstream, int16_t *index, const uint16_t alphabet_size );
+#ifndef MASA_AND_OBJECTS
static int16_t ivas_qmetadata_DecodeExtendedGR( uint16_t *bitstream, int16_t *index, const int16_t alph_size, const int16_t gr_param );
+#endif
static int16_t ivas_qmetadata_ReorderElevationDecoded( const int16_t elev_dist, const int16_t elev_avg, const int16_t elev_alph );
@@ -101,6 +103,10 @@ static int16_t read_surround_coherence_hr( uint16_t *bitstream, int16_t *p_bit_p
static int16_t read_coherence_data_hr_512( uint16_t *bitstream, int16_t *p_bit_pos, IVAS_QMETADATA *hQMetaData, const int16_t idx_dir, const int16_t nbits_coh );
+#ifdef MASA_AND_OBJECTS
+static void read_stream_dct_coeffs_omasa( int16_t *q_idx, float *q_dct_data, const int16_t len_stream, uint16_t *bit_stream, int16_t *index, const int16_t first_line );
+#endif
+
/*-----------------------------------------------------------------------*
* Global function definitions
@@ -607,6 +613,7 @@ int16_t ivas_qmetadata_dec_decode(
bits_dir_target += bits_dir_raw;
bits_dir_used += bits_dir;
+
#ifdef DEBUG_MODE_QMETADATA
fprintf( pF, "frame %d: diff %d coh %d surcoh %d ", frame, bits_diff, bits_coherence, bits_sur_coherence );
fprintf( pF, "dir %d %d,%d,%d\n", ec_flag, start_index_0 - *index, total_bits_1dir, bits_dir_raw );
@@ -962,6 +969,7 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512(
}
}
#else
+#ifdef FIX_566_2DIR_MASA_384K
float ratioSum;
for ( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
{
@@ -979,6 +987,19 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512(
}
}
}
+#else
+ for ( b = hQMetaData->q_direction[1].cfg.start_band; b < hQMetaData->q_direction[1].cfg.nbands; b++ )
+ {
+ for ( m = 0; m < hQMetaData->q_direction[1].cfg.nblocks; m++ )
+ {
+ hQMetaData->q_direction[1].band_data[b].energy_ratio[m] = 1.0f - diffuseness_reconstructions_hr[hQMetaData->q_direction[1].band_data[b].energy_ratio_index[m]];
+ if ( hQMetaData->q_direction[1].band_data[b].energy_ratio[m] > 1.0f - hQMetaData->q_direction[0].band_data[b].energy_ratio[m] )
+ {
+ hQMetaData->q_direction[1].band_data[b].energy_ratio[m] = 1.0f - hQMetaData->q_direction[0].band_data[b].energy_ratio[m];
+ }
+ }
+ }
+#endif
#endif
}
@@ -2403,12 +2424,16 @@ static uint16_t ivas_qmetadata_DecodeQuasiUniform(
*------------------------------------------------------------------------*/
/*! r: Value decoded from the bitstream */
-static int16_t ivas_qmetadata_DecodeExtendedGR(
- uint16_t *bitstream, /* i : pointer to the bitstream to read */
- int16_t *index, /* i/o: position in the bitstream to start reading (gets updated with reading) */
- const int16_t alph_size, /* i : size of the alphabet, used to calculate the number of bits needed */
- const int16_t gr_param /* i : GR parameter that indicates the limit for the most significant bits (msb) */
-)
+#ifndef MASA_AND_OBJECTS
+static
+#endif
+ int16_t
+ ivas_qmetadata_DecodeExtendedGR(
+ uint16_t *bitstream, /* i : pointer to the bitstream to read */
+ int16_t *index, /* i/o: position in the bitstream to start reading (gets updated with reading) */
+ const int16_t alph_size, /* i : size of the alphabet, used to calculate the number of bits needed */
+ const int16_t gr_param /* i : GR parameter that indicates the limit for the most significant bits (msb) */
+ )
{
int16_t i, msb_size;
uint16_t value;
@@ -4394,3 +4419,205 @@ static void decode_combined_index(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+static void read_stream_dct_coeffs_omasa(
+ int16_t *q_idx,
+ float *q_dct_data,
+ const int16_t len_stream,
+ uint16_t *bit_stream,
+ int16_t *index,
+ const int16_t first_line )
+{
+ int16_t sign, nbits;
+ int16_t i, j, i_min;
+
+ float step;
+ int16_t GR1, GR2;
+
+ step = STEP_M2T;
+ nbits = 0;
+ sign = 1;
+ if ( first_line == 0 )
+ {
+ /* read sign */
+ sign = bit_stream[( *index )--];
+ if ( sign == 0 )
+ {
+ sign = -1;
+ }
+ nbits++;
+ }
+
+ set_s( q_idx, 0, len_stream );
+ /* read DCT 0 component */
+ for ( i = 0; i < BITS_MASA2TOTTAL_DCT0; i++ )
+ {
+ q_idx[0] = ( q_idx[0] << 1 ) + bit_stream[( *index )--];
+ }
+ q_idx[0] *= sign;
+
+ if ( q_idx[0] != 0 )
+ {
+ if ( len_stream >= 8 )
+ {
+ /* read index of last index encoded with GR2 */
+ i_min = 0;
+ j = 4;
+ for ( i = 0; i < j; i++ )
+ {
+ i_min = ( i_min << 1 ) + bit_stream[( *index )--];
+ }
+ nbits += j;
+ /* read GR orders */
+ GR1 = bit_stream[( *index )--] + 1;
+ if ( GR1 == 2 )
+ {
+ GR2 = bit_stream[( *index )--];
+ }
+ else
+ {
+ GR2 = 0;
+ }
+
+ /* read GR data */
+ for ( i = 1; i <= i_min; i++ )
+ {
+ q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 );
+ }
+ for ( i = i_min + 1; i < len_stream; i++ )
+ {
+ q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR2 );
+ }
+ }
+ else
+ {
+ /* read GR order (only one) */
+ GR1 = bit_stream[( *index )--];
+ for ( i = 1; i < len_stream; i++ )
+ {
+ q_idx[i] = ivas_qmetadata_DecodeExtendedGR( bit_stream, index, 100, GR1 );
+ }
+ }
+ }
+
+ /* deindex */
+ q_dct_data[0] = q_idx[0] * step;
+ for ( i = 1; i < len_stream; i++ )
+ {
+ if ( ( q_idx[i] % 2 ) == 0 )
+ {
+ q_dct_data[i] = -( q_idx[i] >> 1 ) * step;
+ }
+ else
+ {
+ q_dct_data[i] = ( ( q_idx[i] + 1 ) >> 1 ) * step;
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------
+ * decode_masa_to_total()
+ *
+ *------------------------------------------------------------------------*/
+
+void decode_masa_to_total(
+ uint16_t *bit_stream,
+ int16_t *index,
+ float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ const int16_t nbands,
+ const int16_t nblocks )
+{
+ int16_t i, j, k;
+ int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS],
+ dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ int16_t n_streams, len_stream;
+
+ /* Setup coding parameters */
+ n_streams = 1;
+ len_stream = nbands * nblocks;
+ if ( len_stream == 32 )
+ {
+ n_streams = 4;
+ len_stream = 8;
+ }
+
+ set_s( q_idx, 0, nbands * nblocks );
+ for ( i = 0; i < n_streams; i++ )
+ {
+ read_stream_dct_coeffs_omasa( &q_idx[i * len_stream], &q_dct_data[i * len_stream], len_stream, bit_stream, index, i == 0 );
+ }
+
+ /* inverse DCT2 transform */
+ switch ( len_stream )
+ {
+ case 4:
+ matrix_product( dct4, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nblocks );
+ break;
+ case 5:
+ matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 8:
+ matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 12:
+ matrix_product( dct12, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 20:
+ matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/
+ break;
+ case 32:
+ matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data );
+ break;
+ default:
+ printf( "Incorrect number of coefficients for OMASA.\n" );
+ break;
+ }
+
+ k = 0;
+ for ( i = 0; i < nblocks; i++ )
+ {
+ for ( j = 0; j < nbands; j++ )
+ {
+ masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] );
+ masa_to_total_energy_ratio[i][j] = min( 1.0f, masa_to_total_energy_ratio[i][j] );
+ k++;
+ }
+ }
+
+ if ( nblocks == 1 )
+ {
+ for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ for ( j = 0; j < nbands; j++ )
+ {
+ masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[0][j];
+ }
+ }
+ }
+
+ if ( nbands == 1 )
+ {
+ for ( j = 1; j < 5; j++ )
+ {
+ for ( i = 0; i < nblocks; i++ )
+ {
+ masa_to_total_energy_ratio[i][j] = masa_to_total_energy_ratio[i][0];
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c
index 763a1b222fde2f2c596e3f0239a9ea812788475c..fb97faf0de1c23cd02e987813e119e1f4868534b 100755
--- a/lib_dec/ivas_sba_dec.c
+++ b/lib_dec/ivas_sba_dec.c
@@ -65,7 +65,7 @@ void ivas_sba_set_cna_cng_flag(
/* st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 0; */
/* st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 0; */
}
- else if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) ) )
+ else if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) ) )
{
st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 1;
st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 1;
@@ -114,6 +114,8 @@ ivas_error ivas_sba_dec_reconfigure(
int16_t num_channels, num_md_sub_frames;
#endif
+ RENDERER_TYPE old_renderer_type;
+
DECODER_CONFIG_HANDLE hDecoderConfig;
ivas_error error;
error = IVAS_ERR_OK;
@@ -145,13 +147,13 @@ ivas_error ivas_sba_dec_reconfigure(
st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpar->subframes_rendered;
mvs2s( st_ivas->hSpar->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
- else if ( st_ivas->hSpatParamRendCom != NULL )
+ else if ( st_ivas->hDirAC != NULL )
{
- st_ivas->hTcBuffer->num_slots = st_ivas->hSpatParamRendCom->num_slots;
- st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes;
- st_ivas->hTcBuffer->slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
- st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
- mvs2s( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
+ st_ivas->hTcBuffer->num_slots = st_ivas->hDirAC->num_slots;
+ st_ivas->hTcBuffer->nb_subframes = st_ivas->hDirAC->nb_subframes;
+ st_ivas->hTcBuffer->slots_rendered = st_ivas->hDirAC->slots_rendered;
+ st_ivas->hTcBuffer->subframes_rendered = st_ivas->hDirAC->subframes_rendered;
+ mvs2s( st_ivas->hDirAC->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
/*-----------------------------------------------------------------*
@@ -238,6 +240,7 @@ ivas_error ivas_sba_dec_reconfigure(
/* renderer might have changed */
intern_config_old = st_ivas->intern_config;
+ old_renderer_type = st_ivas->renderer_type;
ivas_renderer_select( st_ivas );
/* side effect of the renderer selection can be a changed internal config */
@@ -290,6 +293,29 @@ ivas_error ivas_sba_dec_reconfigure(
#endif
}
+ if ( st_ivas->renderer_type != old_renderer_type )
+ {
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC )
+ {
+ if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ) ) != 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 && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) )
+ {
+ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin );
+ }
+
if ( ( ( st_ivas->renderer_type != RENDERER_DISABLE ) && ( st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC ) ) || ( ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO ) && ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO ) ) || ( last_ivas_total_brate > IVAS_256k && ivas_total_brate <= IVAS_256k ) || ( last_ivas_total_brate <= IVAS_256k && ivas_total_brate > IVAS_256k ) )
{
DIRAC_CONFIG_FLAG flag_config;
@@ -306,14 +332,11 @@ ivas_error ivas_sba_dec_reconfigure(
}
/* synchronize subframe info */
- if ( st_ivas->hSpatParamRendCom != NULL )
- {
- st_ivas->hSpatParamRendCom->num_slots = st_ivas->hTcBuffer->num_slots;
- st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
- st_ivas->hSpatParamRendCom->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
- st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
- mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
- }
+ st_ivas->hDirAC->num_slots = st_ivas->hTcBuffer->num_slots;
+ st_ivas->hDirAC->nb_subframes = st_ivas->hTcBuffer->nb_subframes;
+ st_ivas->hDirAC->slots_rendered = st_ivas->hTcBuffer->slots_rendered;
+ st_ivas->hDirAC->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered;
+ mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hDirAC->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS );
}
if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) ) != IVAS_ERR_OK )
@@ -323,8 +346,6 @@ ivas_error ivas_sba_dec_reconfigure(
if ( st_ivas->renderer_type == RENDERER_DISABLE )
{
- ivas_dirac_rend_close( &( st_ivas->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) );
ivas_dirac_dec_close( &( st_ivas->hDirAC ) );
vbap_free_data( &( st_ivas->hVBAPdata ) );
@@ -403,7 +424,7 @@ ivas_error ivas_sba_dec_reconfigure(
}
else
{
- if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
+ if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) )
{
tc_nchan_to_allocate++; /* we need a channel for the CNG in this case*/
}
@@ -510,11 +531,9 @@ void ivas_sba_dec_render(
uint16_t slot_size, ch;
uint16_t nchan_internal, nchan_out;
SPAR_DEC_HANDLE hSpar;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
float *output_f_local[MAX_OUTPUT_CHANNELS];
hSpar = st_ivas->hSpar;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate );
nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe;
@@ -563,11 +582,11 @@ void ivas_sba_dec_render(
{
if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
else
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
}
diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c
index 9bb7fc227d17823c66bd1958479d71b9f8ecd302..cae8f13ef1bdc97c7de4d7c26df56dd814e78ecb 100755
--- a/lib_dec/ivas_sce_dec.c
+++ b/lib_dec/ivas_sce_dec.c
@@ -123,8 +123,12 @@ ivas_error ivas_sce_dec(
/* only WB is supported */
st->bwidth = WB;
}
+#ifdef ISM_FB
else if ( ( hSCE->element_brate < MIN_BRATE_FB_STEREO && !st->is_ism_format ) ||
( hSCE->element_brate < MIN_BRATE_FB_ISM && st->is_ism_format ) )
+#else
+ else if ( hSCE->element_brate < MIN_BRATE_FB_STEREO )
+#endif
{
/* WB and SWB are supported */
st->bwidth = get_next_indice( st, 1 ) + WB;
@@ -153,7 +157,15 @@ ivas_error ivas_sce_dec(
if ( ( st_ivas->hQMetaData != NULL ) &&
( st_ivas->ivas_format != SBA_FORMAT ) )
{
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ st->bits_frame_nominal = (int16_t) ( ( hSCE->element_brate / FRAMES_PER_SEC ) - ISM_NB_BITS_METADATA_NOMINAL );
+ }
+ else if ( ( st_ivas->mc_mode == MC_MODE_MCMASA && ivas_total_brate >= MCMASA_SEPARATE_BRATE ) || ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) )
+#else
if ( st_ivas->mc_mode == MC_MODE_MCMASA && ivas_total_brate >= MCMASA_SEPARATE_BRATE )
+#endif
{
st->bits_frame_nominal = (int16_t) ( hSCE->element_brate / FRAMES_PER_SEC );
}
@@ -171,6 +183,7 @@ ivas_error ivas_sce_dec(
st->bits_frame_nominal = (int16_t) ( ( hSCE->element_brate / FRAMES_PER_SEC ) - ISM_NB_BITS_METADATA_NOMINAL );
}
+
/* set "total_brate" */
if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 )
{
@@ -185,16 +198,36 @@ ivas_error ivas_sce_dec(
{
st->total_brate = ivas_total_brate;
}
+#ifndef FIX_565_SBA_BURST_IN_FEC
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT ) /* note: total_brate[] is set in ivas_ism_config() or ivas_set_surplus_brate_dec() */
+#else
+ else if ( st_ivas->ivas_format != ISM_FORMAT ) /* note: in ISMs, total_brate[] is set in ivas_ism_config() */
+#endif
+ {
+ st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC;
+ }
+#else
+#ifdef MASA_AND_OBJECTS
+ else if ( !st_ivas->bfi && st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT ) /* note: in ISMs, total_brate[] is set in ivas_ism_config() */
+#else
else if ( !st_ivas->bfi && st_ivas->ivas_format != ISM_FORMAT ) /* note: in ISMs, total_brate[] is set in ivas_ism_config() */
+#endif
{
st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC;
}
+#endif
/*----------------------------------------------------------------*
* Core codec configuration
*----------------------------------------------------------------*/
- /* set ACELP12k8 / ACELP16k flag for flexible ACELP core */
+/* set ACELP12k8 / ACELP16k flag for flexible ACELP core */
+#ifdef MASA_AND_OBJECTS
+ if ( ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) &&
+ st->low_rate_mode && !( st->total_brate == SID_2k40 || st->total_brate == FRAME_NO_DATA ) )
+#else
if ( st_ivas->ivas_format == ISM_FORMAT && st->low_rate_mode && !( st->total_brate == SID_2k40 || st->total_brate == FRAME_NO_DATA ) )
+#endif
{
st->flag_ACELP16k = 0;
}
@@ -290,9 +323,15 @@ ivas_error ivas_sce_dec(
dbgwrite( &st->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode", 0, sce_id, DEC ) );
dbgwrite( output, sizeof( float ), output_frame, 1, fname( debug_dir, "output.sce", 0, sce_id, DEC ) );
- tmpF = 0;
- dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.cpe", 0, sce_id, DEC ) );
- dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, sce_id, DEC ) );
+
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format != MASA_ISM_FORMAT )
+ {
+ tmpF = 0;
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.cpe", 0, sce_id, DEC ) );
+ dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, sce_id, DEC ) );
+ }
+#endif
}
}
#endif
@@ -355,7 +394,11 @@ ivas_error create_sce_dec(
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;
st->is_ism_format = 0;
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == ISM_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT )
+#else
if ( st_ivas->ivas_format == ISM_FORMAT )
+#endif
{
st->is_ism_format = 1;
}
diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c
index 1c839316e52fefb4ad4f4e44bc7d7533cd95efe8..79ed6c7cf3d67400f11897d8c13f8fd491553a0c 100644
--- a/lib_dec/ivas_spar_decoder.c
+++ b/lib_dec/ivas_spar_decoder.c
@@ -325,7 +325,7 @@ ivas_error ivas_spar_dec(
/* read DirAC bitstream */
if ( st_ivas->hQMetaData != NULL )
{
- ivas_dirac_dec_read_BS( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hSpatParamRendCom, st_ivas->hQMetaData, nb_bits_read,
+ ivas_dirac_dec_read_BS( hDecoderConfig->ivas_total_brate, st0, st_ivas->hDirAC, st_ivas->hQMetaData, nb_bits_read,
ivas_get_hodirac_flag( hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ), st_ivas->hSpar->dirac_to_spar_md_bands );
}
@@ -345,7 +345,9 @@ ivas_error ivas_spar_dec(
st0->bit_stream = bstr_meta;
st0->next_bit_pos = 0;
st0->bits_frame = min( MAX_BITS_METADATA, last_bit_pos + 1 );
+#ifdef FIX_565_SBA_BURST_IN_FEC
if ( !st0->bfi )
+#endif
{
st0->total_brate = hDecoderConfig->ivas_total_brate; /* to avoid BER detect */
}
@@ -1311,7 +1313,6 @@ void ivas_spar_dec_upmixer(
)
{
SPAR_DEC_HANDLE hSpar;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
int16_t nchan_transport, nchan_out;
int16_t subframe_idx, n, i;
int16_t n_samples_sf;
@@ -1391,16 +1392,15 @@ void ivas_spar_dec_upmixer(
st_ivas->hTcBuffer->tc[n] = NULL;
}
- if ( st_ivas->hDirAC != NULL && st_ivas->hSpatParamRendCom != NULL )
+ if ( st_ivas->hDirAC != 0 )
{
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 )
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
else
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
}
@@ -1689,7 +1689,7 @@ void ivas_spar_dec_upmixer_sf(
if ( ( st_ivas->hOutSetup.num_lfe > 0 ) && ( st_ivas->hOutSetup.index_lfe[idx_lfe] == ch ) )
{
set_zero( output[ch], hSpar->subframe_nbslots[hSpar->subframes_rendered] * num_cldfb_bands );
- if ( idx_lfe < ( st_ivas->hDirACRend->hOutSetup.num_lfe - 1 ) )
+ if ( idx_lfe < ( st_ivas->hDirAC->hOutSetup.num_lfe - 1 ) )
{
idx_lfe++;
}
diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c
index c61effd67359f2e1873e7230e1ddda0e154b4b38..a1d3e9839276bac93dc0eab7d026314f0697d885 100644
--- a/lib_dec/ivas_spar_md_dec.c
+++ b/lib_dec/ivas_spar_md_dec.c
@@ -3051,9 +3051,6 @@ void ivas_spar_to_dirac(
end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ) / bw;
hDirAC = st_ivas->hDirAC;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
-
dirac_to_spar_md_bands = st_ivas->hSpar->dirac_to_spar_md_bands;
enc_param_start_band = st_ivas->hSpar->enc_param_start_band / bw;
active_w_vlbr = ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0;
@@ -3148,46 +3145,46 @@ void ivas_spar_to_dirac(
{
int16_t ts_start, ts_end, ts;
- ts_start = DirAC_block_grouping[block];
- ts_end = DirAC_block_grouping[block + 1];
+ ts_start = hDirAC->block_grouping[block];
+ ts_end = hDirAC->block_grouping[block + 1];
for ( b = qmf_band_start; b < qmf_band_end; b++ )
{
azi_dith = azi[band];
ele_dith = ele[band];
- hSpatParamRendCom->energy_ratio1[block][b] = en_ratio;
+ hDirAC->energy_ratio1[block][b] = en_ratio;
tmp_write_idx_band = tmp_write_idx_param_band;
if ( hDirAC->hConfig->dec_param_estim == FALSE )
{
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith;
- hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band];
+ hDirAC->elevation[tmp_write_idx_band][b] = ele_dith;
+ hDirAC->azimuth[tmp_write_idx_band][b] = azi_dith;
+ hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band];
}
else
{
for ( ts = ts_start; ts < ts_end; ts++ )
{
- hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith;
- hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith;
- hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band];
- tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
+ hDirAC->elevation[tmp_write_idx_band][b] = ele_dith;
+ hDirAC->azimuth[tmp_write_idx_band][b] = azi_dith;
+ hDirAC->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band];
+ tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hDirAC->dirac_md_buffer_length;
}
}
}
- tmp_write_idx_param_band = ( tmp_write_idx_param_band + num_slots_in_subfr ) % hSpatParamRendCom->dirac_md_buffer_length;
+ tmp_write_idx_param_band = ( tmp_write_idx_param_band + num_slots_in_subfr ) % hDirAC->dirac_md_buffer_length;
}
}
/* update buffer write index */
if ( hDirAC->hConfig->dec_param_estim == FALSE )
{
- hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length;
+ hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hDirAC->dirac_md_buffer_length;
}
else
{
- hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + CLDFB_NO_COL_MAX ) % hSpatParamRendCom->dirac_md_buffer_length;
+ hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + CLDFB_NO_COL_MAX ) % hDirAC->dirac_md_buffer_length;
}
}
else
diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h
index 5c70409ac2892ff9da3cd11cb968662475c17784..d5144018e5589464eef85fb06621a2aea303851b 100644
--- a/lib_dec/ivas_stat_dec.h
+++ b/lib_dec/ivas_stat_dec.h
@@ -396,9 +396,40 @@ typedef struct
} ISM_DTX_DATA_DEC;
/*----------------------------------------------------------------------------------*
- * DirAC decoder structures
+ * DirAC decoder structure
*----------------------------------------------------------------------------------*/
+typedef struct dirac_dec_stack_mem
+{
+ /*Decorrelator*/
+ float *frame_dec_f;
+
+ /*Prototypes*/
+ float *proto_direct_buffer_f;
+ float *proto_diffuse_buffer_f;
+
+ /*Prototype NRGs*/
+ float *proto_power_smooth;
+ float *proto_power_diff_smooth;
+
+ /*Gain or power factors for directional and diffuse streams*/
+ float *direct_power_factor;
+ float *diffuse_power_factor;
+
+ /*Directional responses (gains & Nrg)*/
+ float *direct_responses;
+ float *direct_responses_square;
+
+ /* Target co-variance mtx */
+ float *cy_auto_dir_smooth;
+ float *cy_cross_dir_smooth;
+ float *cy_auto_diff_smooth;
+
+ float *reference_power;
+ float *onset_filter;
+
+} DIRAC_DEC_STACK_MEM, *DIRAC_DEC_STACK_MEM_HANDLE;
+
typedef struct param_ism_rendering
{
float *proto_matrix;
@@ -411,32 +442,115 @@ typedef struct param_ism_rendering
} PARAM_ISM_RENDERING_DATA, *PARAM_ISM_RENDERING_HANDLE;
-/* ===== DirAC main structure ===== */
-typedef struct ivas_dirac_dec_data_structure
+/*Onset detector*/
+typedef struct dirac_onset_detection_params_structure
{
- DIRAC_CONFIG_DATA_HANDLE hConfig;
+ int16_t num_freq_bands;
+ int16_t max_band_decorr;
- /*Parameter decoding*/
- float azimuth_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS];
- float elevation_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS];
- int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1];
+} DIRAC_ONSET_DETECTION_PARAMS;
- int16_t dithering_seed;
- int16_t spar_to_dirac_write_idx;
+typedef struct dirac_onset_detection_state_structure
+{
+ float *onset_detector_1;
+ float *onset_detector_2;
- /*sub-modules*/
- PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM handle */
- float power_ratios[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE];
- PARAM_ISM_RENDERING_HANDLE hParamIsmRendering;
+} DIRAC_ONSET_DETECTION_STATE;
- IVAS_FB_MIXER_HANDLE hFbMdft;
+/*Decorrelator*/
+typedef struct dirac_decorr_params_structure
+{
+ int16_t max_band_decorr;
+ int16_t max_frequency;
-} DIRAC_DEC_DATA, *DIRAC_DEC_HANDLE;
+ int16_t *pre_delay;
+ int16_t *filter_length;
+ float *filter_coeff_num_real;
+ float *filter_coeff_den_real;
+ float *phase_coeff_real;
+ float *phase_coeff_imag;
+ int16_t *split_frequency_bands;
+ int16_t num_split_frequency_bands;
+ int16_t use_ducker;
+ int16_t add_back_onsets_on;
-/*----------------------------------------------------------------------------------*
- * ParamMC structures
- *----------------------------------------------------------------------------------*/
+ DIRAC_ONSET_DETECTION_PARAMS h_onset_detection_power_params;
+
+} DIRAC_DECORR_PARAMS, *HANDLE_DIRAC_DECORR_PARAMS;
+
+typedef struct dirac_decorr_state_structure
+{
+ float *decorr_buffer;
+ float *direct_energy_smooth;
+ float *reverb_energy_smooth;
+
+ DIRAC_ONSET_DETECTION_STATE h_onset_detection_power_state;
+
+} DIRAC_DECORR_STATE, *HANDLE_DIRAC_DECORR_STATE;
+
+/*Output synthesis*/
+typedef struct dirac_output_synthesis_params_structure
+{
+ int16_t max_band_decorr;
+
+ int16_t use_onset_filters;
+
+ float *interpolator;
+ float *alpha_synthesis;
+ float *alpha_synthesis_fast;
+ int16_t numAlphas;
+ int16_t numAlphasFast;
+
+ float *proto_matrix;
+
+ float diffuse_compensation_factor;
+ float diffuse_compensation_factor_decorr;
+
+} DIRAC_OUTPUT_SYNTHESIS_PARAMS;
+
+typedef struct dirac_output_synthesis_state_structure
+{
+ /* only pointer to local buffers */
+ float *direct_responses; /* direct responses for DOA of current frame. Size: num_freq_bands*num_channels. */
+ float *direct_responses_square;
+ float *diffuse_responses_square; /* squared diffuse responses. Size: num_channels. */
+
+ /* only pointer to local buffers */
+ float *direct_power_factor;
+ float *diffuse_power_factor;
+
+ float *proto_power_smooth; /* Smoothed power of the prototype signals. Size: num_freq_bands*num_channels. */
+ float *proto_power_smooth_prev; /* Smoothed power of the prototype signals of the previous synthesis block. Size: num_freq_bands*num_channels. */
+
+ float *proto_power_diff_smooth;
+ float *proto_power_diff_smooth_prev;
+
+ /* only pointer to local buffers */
+ float *proto_direct_buffer_f; /* Buffer for direct sound prototype signals. Size: 2*num_freq_bands*num_channels*buffer_length (complex interleaved). */
+ float *proto_diffuse_buffer_f; /* Buffer for diffuse sound prototype signals. Size: 2*num_freq_bands*num_channels*buffer_length (complex interleaved). */
+
+ /* Output gain memories */
+ float *gains_dir_prev; /* Direct sound gains of current synthesis block. Size: num_freq_bands*num_channel. */
+ float *gains_diff_prev; /* Diffuse sound gains of previous synthesis block. Size: num_freq_bands*num_channel. */
+
+ /* only pointer to local buffers */
+ float *cy_auto_dir_smooth; /* Target auto PSD of direct sound. Size: num_freq_bands*num_channels. */
+ float *cy_cross_dir_smooth; /* Target cross PSD of direct sound. Size: num_freq_bands*num_channels. */
+ float *cy_auto_diff_smooth; /* Target auto PSD of diffuse sound. Size: num_freq_bands*num_channels. */
+
+ /* PSD memories */
+ float *cy_auto_dir_smooth_prev; /* Target auto PSD of direct sound of previous synthesis block. Size: num_freq_bands*num_channels. */
+ float *cy_cross_dir_smooth_prev; /* Target cross PSD of direct sound of previous synthesis block. Size: num_freq_bands*num_channels. */
+ float *cy_auto_diff_smooth_prev; /* Target auto PSD of diffuse sound of previous synthesis block. Size: num_freq_bands*num_channels. */
+
+ const float *onset_filter;
+
+ /* Temporal smoothing memories */
+ float *reference_power_smooth_prev;
+ float *direction_smoothness_prev;
+
+} DIRAC_OUTPUT_SYNTHESIS_STATE;
typedef struct dirac_output_synthesis_cov_state_structure
{
@@ -465,6 +579,160 @@ typedef struct dirac_output_synthesis_cov_state_structure
} DIRAC_OUTPUT_SYNTHESIS_COV_STATE;
+/* MASA stereo transport signal type detection structure */
+typedef struct
+{
+ MASA_TRANSPORT_SIGNAL_TYPE masa_stereo_type;
+ MASA_TRANSPORT_SIGNAL_TYPE current_stereo_type;
+ MASA_TRANSPORT_SIGNAL_TYPE type_change_direction;
+
+ int16_t dipole_freq_range[2];
+
+ float left_bb_power;
+ float right_bb_power;
+ float total_bb_power;
+
+ float left_hi_power;
+ float right_hi_power;
+ float total_hi_power;
+
+ float sum_power[MASA_SUM_FREQ_RANGE_BINS];
+ float total_power[MASA_SUM_FREQ_RANGE_BINS];
+
+ float subtract_power_y;
+ float subtract_power_y_smooth;
+ float target_power_y_smooth;
+
+ float lr_total_bb_ratio_db;
+ float lr_total_hi_ratio_db;
+ float min_sum_total_ratio_db;
+ float subtract_target_ratio_db;
+
+ int16_t counter;
+ int16_t interpolator;
+
+} MASA_STEREO_TYPE_DETECT;
+
+/* Diffuse sound directional distribution data structure */
+typedef struct ivas_diffuse_distribution_data_structure
+{
+ float diffuseRatioX[CLDFB_NO_CHANNELS_MAX];
+ float diffuseRatioY[CLDFB_NO_CHANNELS_MAX];
+ float diffuseRatioZ[CLDFB_NO_CHANNELS_MAX];
+
+} DIFFUSE_DISTRIBUTION_DATA, *DIFFUSE_DISTRIBUTION_HANDLE;
+
+
+/* ===== DirAC main structure ===== */
+typedef struct ivas_dirac_dec_data_structure
+{
+ DIRAC_CONFIG_DATA_HANDLE hConfig;
+ IVAS_OUTPUT_SETUP hOutSetup;
+
+ int16_t slot_size;
+ int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS];
+ int16_t subframes_rendered;
+ int16_t slots_rendered;
+ int16_t num_slots;
+ int16_t render_to_md_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME];
+ int16_t nb_subframes;
+ int16_t num_freq_bands;
+
+ /*Parameter decoding*/
+ float azimuth_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS];
+ float elevation_values[MAX_PARAM_SPATIAL_SUBFRAMES * IVAS_MAX_NUM_BANDS];
+ int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1];
+
+ int16_t block_grouping[5];
+ /* decoded, ungrouped and rounded values, we have 1 degree resolution anyway */
+ int16_t **azimuth;
+ int16_t **elevation;
+ int16_t **azimuth2;
+ int16_t **elevation2;
+
+ float **diffuseness_vector;
+ float **energy_ratio1;
+ float **energy_ratio2;
+
+ float **spreadCoherence;
+ float **spreadCoherence2;
+ float **surroundingCoherence;
+
+ int16_t dithering_seed;
+ int16_t dirac_bs_md_write_idx;
+ int16_t dirac_read_idx;
+ int16_t dirac_estimator_idx;
+ int16_t spar_to_dirac_write_idx;
+ int16_t dirac_md_buffer_length;
+
+#ifdef MASA_AND_OBJECTS
+ int16_t numSimultaneousDirections; /* From 1 to 2 + MAX_NUM_OBJECTS */
+ int16_t numParametricDirections; /* 1 or 2 */
+ int16_t numIsmDirections; /* From 0 to MAX_NUM_OBJECTS */
+#else
+ int16_t numSimultaneousDirections; /* 1 or 2 */
+#endif
+ DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist;
+
+ /*Parameter estimation*/
+ int16_t index_buffer_intensity;
+ float *buffer_intensity_real[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF];
+ float *buffer_energy;
+
+ /*Decoder parameters */
+ /*Prototypes*/
+ int16_t num_outputs_dir;
+ int16_t num_outputs_diff;
+ int16_t num_protos_dir;
+ int16_t num_protos_diff;
+ int16_t num_protos_ambi;
+ DIRAC_SYNTHESIS_CONFIG synthesisConf;
+ DIRAC_PANNING_CONFIG panningConf;
+
+ float *frequency_axis;
+ float *diffuse_response_function;
+ float *hoa_encoder;
+ const float *hoa_decoder;
+
+ /*Options*/
+ /* Decorrelator options */
+ int16_t max_band_decorr;
+
+ /* prototype computing */
+ int16_t *proto_index_dir;
+ int16_t *proto_index_diff;
+
+ int16_t proto_signal_decorr_on;
+
+ /*Decoder states=memories*/
+ float *proto_frame_f;
+ float *proto_frame_dec_f;
+
+ DIRAC_DEC_STACK_MEM stack_mem;
+ MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect;
+
+ int16_t num_ele_spk_no_diffuse_rendering;
+
+ /*sub-modules*/
+ HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params;
+ HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state;
+
+ DIRAC_OUTPUT_SYNTHESIS_PARAMS h_output_synthesis_psd_params;
+ DIRAC_OUTPUT_SYNTHESIS_STATE h_output_synthesis_psd_state;
+
+ PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM handle */
+ float power_ratios[MAX_PARAM_ISM_NBANDS][MAX_PARAM_ISM_NBLOCKS][MAX_PARAM_ISM_WAVE];
+ PARAM_ISM_RENDERING_HANDLE hParamIsmRendering;
+ IVAS_FB_MIXER_HANDLE hFbMdft;
+ const int16_t *sba_map_tc;
+
+} DIRAC_DEC_DATA, *DIRAC_DEC_HANDLE;
+
+
+/*----------------------------------------------------------------------------------*
+ * ParamMC structures
+ *----------------------------------------------------------------------------------*/
+
typedef struct ivas_param_mc_diff_proto_info_structure
{
int16_t num_protos_diff;
@@ -715,6 +983,10 @@ typedef struct cpe_dec_data_structure
float old_out_mdct[STEREO_MDCT2DFT_FADE_LEN_48k];
float old_outLB_mdct[2 * STEREO_MDCT2DFT_FADE_LEN_48k];
+#ifdef MASA_AND_OBJECTS
+ int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */
+#endif
+
} CPE_DEC_DATA, *CPE_DEC_HANDLE;
@@ -765,6 +1037,53 @@ typedef struct ivas_lfe_dec_data_structure
} LFE_DEC_DATA, *LFE_DEC_HANDLE;
+// Note: the following structures are used only in lib_dec but this would likely change in the future
+/*----------------------------------------------------------------------------------*
+ * VBAP structures
+ *----------------------------------------------------------------------------------*/
+
+/* Defines a single virtual surface triplet of loudspeakers
+ * with a precalculated inverse matrix */
+typedef struct vbap_vs_triplet_structure
+{
+ uint8_t speaker_node[3];
+ float inverse_matrix[3][3];
+
+} VBAP_VS_TRIPLET;
+
+
+/* Storage structure for fast runtime triplet search */
+typedef struct triplet_search_structure
+{
+ VBAP_VS_TRIPLET *triplets;
+ int16_t num_triplets;
+ int16_t initial_search_indices[VBAP_NUM_SEARCH_SECTORS];
+
+} VBAP_SEARCH_STRUCT;
+
+
+/* VBAP data structure. Contains the formed virtual surface arrangement * and supporting data. */
+typedef struct vbap_data_structure
+{
+ VBAP_SEARCH_STRUCT search_struct[2]; /* Default to max two groups in this implementation */
+ int16_t num_search_structs;
+ int16_t num_speaker_nodes;
+ int16_t num_speaker_nodes_internal;
+ int16_t top_virtual_speaker_node_index; /* These indices can be negative */
+ int16_t bottom_virtual_speaker_node_index;
+ int16_t back_virtual_speaker_node_index;
+ float *bottom_virtual_speaker_node_division_gains;
+ float *top_virtual_speaker_node_division_gains;
+ float *back_virtual_speaker_node_division_gains;
+#ifdef MASA_AND_OBJECTS
+ float *object_mode_bottom_virtual_speaker_node_division_gains;
+ float *object_mode_top_virtual_speaker_node_division_gains;
+ float *object_mode_back_virtual_speaker_node_division_gains;
+#endif
+
+} VBAP_DATA, *VBAP_HANDLE;
+
+
/*----------------------------------------------------------------------------------*
* renderer structures
*----------------------------------------------------------------------------------*/
@@ -809,6 +1128,39 @@ typedef struct ivas_binaural_rendering_struct
* MASA decoder structures
*----------------------------------------------------------------------------------*/
+/* McMASA LFE synthesis structure */
+typedef struct ivas_mcmasa_lfe_synth_struct
+{
+ float lfeToTotalEnergyRatio[MAX_PARAM_SPATIAL_SUBFRAMES];
+ int16_t lfeGainPrevIndex;
+ float transportEneSmooth;
+ float protoLfeEneSmooth;
+ float targetEneLfeSmooth;
+ float targetEneTransSmooth;
+
+ float *lfeSynthRingBuffer;
+ int16_t ringBufferLoPointer;
+ int16_t ringBufferHiPointer;
+ float lowpassSum;
+ int16_t ringBufferSize;
+
+ float *lfeSynthRingBuffer2;
+ int16_t ringBufferLoPointer2;
+ float lowpassSum2;
+ int16_t ringBufferSize2;
+
+ float *delayBuffer_syncLp;
+ int16_t delayBuffer_syncLp_size;
+
+ float *delayBuffer_syncDirAC;
+ int16_t delayBuffer_syncDirAC_size;
+
+ float lfeGainPrev;
+ float transportGainPrev;
+ float interpolator[CLDFB_NO_CHANNELS_MAX];
+
+} MCMASA_LFE_SYNTH_DATA, *MCMASA_LFE_SYNTH_DATA_HANDLE;
+
typedef struct ivas_masa_decoder_ext_out_meta_struct
{
MASA_DECRIPTIVE_META descriptiveMeta;
@@ -840,6 +1192,40 @@ typedef struct ivas_masa_decoder_struct
} MASA_DECODER, *MASA_DECODER_HANDLE;
+#ifdef MASA_AND_OBJECTS
+/* Data structure for MASA_ISM rendering */
+typedef struct ivas_masa_ism_data_structure
+{
+ int16_t azimuth_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR];
+ int16_t elevation_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR];
+ float energy_ratio_ism[MAX_NUM_OBJECTS][MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR][CLDFB_NO_CHANNELS_MAX];
+
+ int16_t azimuth_ism_edited[MAX_NUM_OBJECTS];
+ int16_t elevation_ism_edited[MAX_NUM_OBJECTS];
+ uint8_t ism_is_edited[MAX_NUM_OBJECTS];
+
+ int16_t idx_separated_ism;
+ int16_t azimuth_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR];
+ int16_t elevation_separated_ism[MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR];
+
+ float q_azimuth_old[MAX_NUM_OBJECTS];
+ float q_elevation_old[MAX_NUM_OBJECTS];
+
+ float ismPreprocMatrix[2][2][CLDFB_NO_CHANNELS_MAX];
+ uint8_t objectsMoved;
+ float eneMoveIIR[2][CLDFB_NO_CHANNELS_MAX];
+ float enePreserveIIR[2][CLDFB_NO_CHANNELS_MAX];
+ float preprocEneTarget[CLDFB_NO_CHANNELS_MAX];
+ float preprocEneRealized[CLDFB_NO_CHANNELS_MAX];
+
+ float **delayBuffer;
+ int16_t delayBuffer_size;
+ int16_t delayBuffer_nchan;
+
+} MASA_ISM_DATA, *MASA_ISM_DATA_HANDLE;
+#endif
+
+
/*----------------------------------------------------------------------------------*
* Decoder configuration structure
*----------------------------------------------------------------------------------*/
@@ -940,6 +1326,9 @@ typedef struct Decoder_Struct
DECODER_CONFIG_HANDLE hDecoderConfig; /* Decoder configuration structure */
IVAS_FORMAT ivas_format; /* IVAS format */
+#ifdef MASA_AND_OBJECTS
+ IVAS_FORMAT last_ivas_format; /* last frame IVAS format */
+#endif
int16_t sid_format; /* IVAS format indicator from SID frame */
int16_t nchan_transport; /* number of transport channels */
IVAS_OUTPUT_SETUP hOutSetup; /* output setup structure */
@@ -1011,11 +1400,19 @@ typedef struct Decoder_Struct
float *hoa_dec_mtx; /* Pointer to decoder matrix for SBA */
HEAD_TRACK_DATA_HANDLE hHeadTrackData; /* Head tracking data structure */
RENDER_CONFIG_DATA *hRenderConfig; /* Renderer config pointer */
- int32_t binaural_latency_ns; /* Binauralization latency in ns */
+ int32_t binaural_latency_ns; /* binauralization latency in ns */
+#ifdef MASA_AND_OBJECTS
+ MASA_ISM_DATA_HANDLE hMasaIsmData; /* MASA_ISM rendering structure */
EXTERNAL_ORIENTATION_HANDLE hExtOrientationData; /* External orientation data structure */
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; /* Combined external and head orientation data structure */
- DIRAC_REND_HANDLE hDirACRend; /* DirAC renderer handle */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; /* Spatial parametric (DirAC rend, ParamBin, ParamISM) rendering common data handle. */
+
+ uint8_t editing_ism_enabled; /* Todo Nokia: Temporary, used until proper ISM control available */
+ int16_t index_of_edited_ism; /* Todo Nokia: Temporary, used until proper ISM control available */
+ int16_t azimuth_edited; /* Todo Nokia: Temporary, used until proper ISM control available */
+ int16_t elevation_edited; /* Todo Nokia: Temporary, used until proper ISM control available */
+
+ int16_t flag_omasa_brate;
+#endif
/* JBM module */
DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */
diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c
index 013cc24660264ccf974f7bd9529ca8de09dc9d46..4a4bb5ad14f8628091fe246ba98c932b0571c5ee 100644
--- a/lib_dec/ivas_stereo_switching_dec.c
+++ b/lib_dec/ivas_stereo_switching_dec.c
@@ -768,7 +768,11 @@ ivas_error stereo_memory_dec(
if ( hCPE->hCoreCoder[0]->bfi == 0 )
{
st = hCPE->hCoreCoder[1];
+#ifdef MASA_AND_OBJECTS
+ hCPE->hStereoTD->tdm_LRTD_flag = get_indice_st( hCPE->hCoreCoder[0], hCPE->element_brate + hCPE->brate_surplus, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata + ( hCPE->brate_surplus / FRAMES_PER_SEC ) - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS - TDM_LR_CONTENT_BITS ), TDM_LR_CONTENT_BITS );
+#else
hCPE->hStereoTD->tdm_LRTD_flag = get_indice_st( hCPE->hCoreCoder[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS - TDM_LR_CONTENT_BITS ), TDM_LR_CONTENT_BITS );
+#endif
if ( hCPE->hStereoTD->tdm_LRTD_flag )
{
@@ -876,7 +880,11 @@ ivas_error stereo_memory_dec(
* Bitrate switching in MASA format
*---------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && nchan_transport == 2 )
+#else
if ( ivas_format == MASA_FORMAT && nchan_transport == 2 )
+#endif
{
if ( hCPE->nchan_out == 1 )
{
diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c
index 605d5ad388ca0f2bf6853c8deb59ac9cd881762d..3b654960c18af14a7a869041da48af43b155a000 100644
--- a/lib_dec/ivas_stereo_td_dec.c
+++ b/lib_dec/ivas_stereo_td_dec.c
@@ -84,6 +84,10 @@ void stereo_td_init_dec(
*-------------------------------------------------------------------*/
void tdm_configure_dec(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i : ISM mode in combined format */
+#endif
CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
int16_t *tdm_ratio_idx, /* o : ratio index */
const int16_t nb_bits_metadata /* i : number of metadata bits */
@@ -94,10 +98,19 @@ void tdm_configure_dec(
int16_t tdm_tmp_SM_LRTD_flag;
int16_t mod_ct, core, bits_offset;
int16_t idx_LRTD_pri_side, tdm_inst_ratio_idx;
+#ifdef MASA_AND_OBJECTS
+ int32_t element_brate_adapt;
+ int16_t bstr_last_pos;
+#endif
hStereoTD = hCPE->hStereoTD;
sts = hCPE->hCoreCoder;
+#ifdef MASA_AND_OBJECTS
+ element_brate_adapt = hCPE->element_brate + hCPE->brate_surplus;
+ bstr_last_pos = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata + (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
+#endif
+
/*----------------------------------------------------------------*
* Decode CoreCoder signaling
*----------------------------------------------------------------*/
@@ -123,7 +136,11 @@ void tdm_configure_dec(
/* Get few parameters needed to decode the bitrate allocated to each channel */
/* Get the coder_type of the secondary channel (last parameter on 2 bits) */
+#ifdef MASA_AND_OBJECTS
+ sts[1]->coder_type = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING, TDM_SECONDARY_SIGNALLING );
+#else
sts[1]->coder_type = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SECONDARY_SIGNALLING ), TDM_SECONDARY_SIGNALLING );
+#endif
/* Get the LRTD config flag: 1 = LRTD configuration, favor closer bitrate per channel;
0 = Pri/Sec configuration, bitrates linked wrt. the mono */
@@ -151,19 +168,31 @@ void tdm_configure_dec(
*----------------------------------------------------------------*/
/* Get the correlation ratio */
+#ifdef MASA_AND_OBJECTS
+ *tdm_ratio_idx = get_indice_st( sts[0], element_brate_adapt, (int16_t) ( bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS ), TDM_RATIO_BITS );
+#else
*tdm_ratio_idx = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS ), TDM_RATIO_BITS );
+#endif
hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
if ( sts[1]->coder_type == INACTIVE )
{
/* Get the flag on the LPC reusage type (primary channel of ave LPC */
+#ifdef MASA_AND_OBJECTS
+ hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
+#else
hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS ), TDM_LP_REUSE_BITS );
+#endif
hStereoTD->tdm_lp_reuse_flag = 1;
}
else
{
/* Get the flag on the LPC reusage */
+#ifdef MASA_AND_OBJECTS
+ hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
+#else
hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS ), TDM_LP_REUSE_BITS );
+#endif
}
sts[0]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* the flag was already read in function stereo_memory_dec() */
@@ -219,7 +248,11 @@ void tdm_configure_dec(
int16_t tmpS = 20;
if ( hStereoTD->tdm_LRTD_flag == 0 )
{
+#ifdef MASA_AND_OBJECTS
+ tmpS = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
+#else
tmpS = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS ), STEREO_BITS_TCA_GD );
+#endif
}
hCPE->hStereoDftDmx->targetGain = usdequant( tmpS, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP );
hCPE->hStereoDftDmx->targetGain = powf( 10, hCPE->hStereoDftDmx->targetGain );
@@ -228,9 +261,15 @@ void tdm_configure_dec(
{
if ( hStereoTD->tdm_LRTD_flag == 0 )
{
+#ifdef MASA_AND_OBJECTS
+ hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS, STEREO_BITS_TCA_CHAN );
+ hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN, STEREO_BITS_TCA_CORRSTATS );
+ hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
+#else
hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ), STEREO_BITS_TCA_CHAN );
hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN ), STEREO_BITS_TCA_CORRSTATS );
hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], hCPE->element_brate, (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS ), STEREO_BITS_TCA_GD );
+#endif
}
else
{
@@ -250,7 +289,11 @@ void tdm_configure_dec(
#endif
/* set the BW of the secondary channel */
+#ifdef MASA_AND_OBJECTS
+ if ( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC )
+#else
if ( hStereoTD->tdm_LRTD_flag && hCPE->element_brate > IVAS_13k2 )
+#endif
{
/* set BW of the secondary channel in LRTD stereo mode as the BW of the primary channel at higher bitrates */
sts[1]->bwidth = sts[0]->bwidth;
@@ -265,7 +308,16 @@ void tdm_configure_dec(
* bitbudget distribution between channels (taking into account also metadata bitbudget)
*----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ tdm_bit_alloc( ivas_format,
+ ism_mode,
+ hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus,
+ hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
+ &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag,
+ sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx );
+#else
tdm_bit_alloc( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC, hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ), &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag, sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx );
+#endif
return;
}
diff --git a/lib_dec/ivas_vbap.c b/lib_dec/ivas_vbap.c
index 841f3df132015ea8ac0505bde28ffb4374ec315c..dcc73907e2942a0d7e348958203a59a924ce4130 100644
--- a/lib_dec/ivas_vbap.c
+++ b/lib_dec/ivas_vbap.c
@@ -141,7 +141,11 @@ static enum VirtualSpeakerNodeType check_need_of_virtual_speaker_node( VBAP_HAND
static int16_t determine_best_triplet_and_gains( VBAP_SEARCH_STRUCT *search_struct, const float panning_unit_vec[3], const int16_t azi_deg, float gains[3] );
+#ifdef MASA_AND_OBJECTS
+static void determine_virtual_speaker_node_division_gains( const int16_t virtual_speaker_node_index, float *virtual_node_division_gains, int16_t connections[][2], const enum VirtualSpeakerNodeType type, const int16_t max_num_connections, const int16_t num_speaker_nodes, const int16_t use_object_mode );
+#else
static void determine_virtual_speaker_node_division_gains( const int16_t virtual_speaker_node_index, float *virtual_node_division_gains, int16_t connections[][2], const enum VirtualSpeakerNodeType type, const int16_t max_num_connections, const int16_t num_speaker_nodes );
+#endif
static void reorder_triplets( VBAP_VS_TRIPLET *triplets, const int16_t *target_order, const int16_t num_triplets );
@@ -157,6 +161,10 @@ ivas_error vbap_init_data(
const float *speaker_node_azi_deg, /* i : vector of speaker node azimuths (positive left) */
const float *speaker_node_ele_deg, /* i : vector of speaker node elevations (positive up) */
const int16_t num_speaker_nodes /* i : number of speaker nodes in the set */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const IVAS_FORMAT ivas_format /* i : IVAS format */
+#endif
)
{
/* Variables */
@@ -207,6 +215,11 @@ ivas_error vbap_init_data(
vbap->bottom_virtual_speaker_node_division_gains = NULL;
vbap->top_virtual_speaker_node_division_gains = NULL;
vbap->back_virtual_speaker_node_division_gains = NULL;
+#ifdef MASA_AND_OBJECTS
+ vbap->object_mode_bottom_virtual_speaker_node_division_gains = NULL;
+ vbap->object_mode_top_virtual_speaker_node_division_gains = NULL;
+ vbap->object_mode_back_virtual_speaker_node_division_gains = NULL;
+#endif
vbap->num_speaker_nodes = num_speaker_nodes;
vbap->num_speaker_nodes_internal = num_speaker_nodes;
@@ -229,6 +242,16 @@ ivas_error vbap_init_data(
}
set_zero( vbap->bottom_virtual_speaker_node_division_gains, num_speaker_nodes );
is_success &= vbap->bottom_virtual_speaker_node_division_gains != NULL;
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ vbap->object_mode_bottom_virtual_speaker_node_division_gains = (float *) malloc( num_speaker_nodes * sizeof( float ) );
+ set_zero( vbap->object_mode_bottom_virtual_speaker_node_division_gains, num_speaker_nodes );
+ is_success &= vbap->object_mode_bottom_virtual_speaker_node_division_gains != NULL;
+ }
+#endif
+
speaker_node_azi_deg_internal[vbap->bottom_virtual_speaker_node_index] = 0.0f;
speaker_node_ele_deg_internal[vbap->bottom_virtual_speaker_node_index] = -90.0f;
}
@@ -241,6 +264,16 @@ ivas_error vbap_init_data(
}
set_zero( vbap->top_virtual_speaker_node_division_gains, num_speaker_nodes );
is_success &= vbap->top_virtual_speaker_node_division_gains != NULL;
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ vbap->object_mode_top_virtual_speaker_node_division_gains = (float *) malloc( num_speaker_nodes * sizeof( float ) );
+ set_zero( vbap->object_mode_top_virtual_speaker_node_division_gains, num_speaker_nodes );
+ is_success &= vbap->object_mode_top_virtual_speaker_node_division_gains != NULL;
+ }
+#endif
+
speaker_node_azi_deg_internal[vbap->top_virtual_speaker_node_index] = 0.0f;
speaker_node_ele_deg_internal[vbap->top_virtual_speaker_node_index] = 90.0f;
}
@@ -253,6 +286,14 @@ ivas_error vbap_init_data(
}
set_zero( vbap->back_virtual_speaker_node_division_gains, num_speaker_nodes );
is_success &= vbap->back_virtual_speaker_node_division_gains != NULL;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ vbap->object_mode_back_virtual_speaker_node_division_gains = (float *) malloc( num_speaker_nodes * sizeof( float ) );
+ set_zero( vbap->object_mode_back_virtual_speaker_node_division_gains, num_speaker_nodes );
+ is_success &= vbap->object_mode_back_virtual_speaker_node_division_gains != NULL;
+ }
+#endif
speaker_node_azi_deg_internal[vbap->back_virtual_speaker_node_index] = 180.0f;
speaker_node_ele_deg_internal[vbap->back_virtual_speaker_node_index] = 0.0f;
}
@@ -342,11 +383,23 @@ ivas_error vbap_init_data(
/* Determine how the virtual node gains should be distributed to real nodes, if necessary (checked within function). */
if ( is_success )
{
+#ifdef MASA_AND_OBJECTS
+ determine_virtual_speaker_node_division_gains( vbap->top_virtual_speaker_node_index, vbap->top_virtual_speaker_node_division_gains, connections, virtual_top_type, max_num_connections, num_speaker_nodes, 0 );
+ determine_virtual_speaker_node_division_gains( vbap->bottom_virtual_speaker_node_index, vbap->bottom_virtual_speaker_node_division_gains, connections, virtual_bottom_type, max_num_connections, num_speaker_nodes, 0 );
+ determine_virtual_speaker_node_division_gains( vbap->back_virtual_speaker_node_index, vbap->back_virtual_speaker_node_division_gains, connections, virtual_back_type, max_num_connections, num_speaker_nodes, 0 );
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ determine_virtual_speaker_node_division_gains( vbap->top_virtual_speaker_node_index, vbap->object_mode_top_virtual_speaker_node_division_gains, connections, virtual_top_type == NO_VIRTUAL_SPEAKER_NODE ? NO_VIRTUAL_SPEAKER_NODE : VIRTUAL_SPEAKER_NODE_DISTRIBUTE_ENERGY, max_num_connections, num_speaker_nodes, 1 );
+ determine_virtual_speaker_node_division_gains( vbap->bottom_virtual_speaker_node_index, vbap->object_mode_bottom_virtual_speaker_node_division_gains, connections, virtual_bottom_type == NO_VIRTUAL_SPEAKER_NODE ? NO_VIRTUAL_SPEAKER_NODE : VIRTUAL_SPEAKER_NODE_DISTRIBUTE_ENERGY, max_num_connections, num_speaker_nodes, 1 );
+ determine_virtual_speaker_node_division_gains( vbap->back_virtual_speaker_node_index, vbap->object_mode_back_virtual_speaker_node_division_gains, connections, virtual_back_type == NO_VIRTUAL_SPEAKER_NODE ? NO_VIRTUAL_SPEAKER_NODE : VIRTUAL_SPEAKER_NODE_DISTRIBUTE_ENERGY, max_num_connections, num_speaker_nodes, 1 );
+ }
+#else
determine_virtual_speaker_node_division_gains( vbap->top_virtual_speaker_node_index, vbap->top_virtual_speaker_node_division_gains, connections, virtual_top_type, max_num_connections, num_speaker_nodes );
determine_virtual_speaker_node_division_gains( vbap->bottom_virtual_speaker_node_index, vbap->bottom_virtual_speaker_node_division_gains, connections, virtual_bottom_type, max_num_connections, num_speaker_nodes );
determine_virtual_speaker_node_division_gains( vbap->back_virtual_speaker_node_index, vbap->back_virtual_speaker_node_division_gains, connections, virtual_back_type, max_num_connections, num_speaker_nodes );
+#endif
}
pop_wmops();
@@ -391,6 +444,20 @@ void vbap_free_data(
{
free( ( *hVBAPdata )->back_virtual_speaker_node_division_gains );
}
+#ifdef MASA_AND_OBJECTS
+ if ( ( *hVBAPdata )->object_mode_bottom_virtual_speaker_node_division_gains != NULL )
+ {
+ free( ( *hVBAPdata )->object_mode_bottom_virtual_speaker_node_division_gains );
+ }
+ if ( ( *hVBAPdata )->object_mode_top_virtual_speaker_node_division_gains != NULL )
+ {
+ free( ( *hVBAPdata )->object_mode_top_virtual_speaker_node_division_gains );
+ }
+ if ( ( *hVBAPdata )->object_mode_back_virtual_speaker_node_division_gains != NULL )
+ {
+ free( ( *hVBAPdata )->object_mode_back_virtual_speaker_node_division_gains );
+ }
+#endif
if ( ( *hVBAPdata )->search_struct[0].triplets != NULL )
{
free( ( *hVBAPdata )->search_struct[0].triplets );
@@ -418,6 +485,10 @@ void vbap_determine_gains(
float *gains, /* o : gain vector for loudspeakers for given direction */
const int16_t azi_deg, /* i : azimuth in degrees for panning direction (positive left)*/
const int16_t ele_deg /* i : elevation in degrees for panning direction (positive up)*/
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t use_object_mode /* i : select between object mode panning and spatial mode panning */
+#endif
)
{
/* This function formulates gains for the given angle. The triplet-selection has been pre-formulated. */
@@ -451,9 +522,24 @@ void vbap_determine_gains(
bottom_virtual_speaker_node_index = hVBAPdata->bottom_virtual_speaker_node_index;
top_virtual_speaker_node_index = hVBAPdata->top_virtual_speaker_node_index;
back_virtual_speaker_node_index = hVBAPdata->back_virtual_speaker_node_index;
+#ifdef MASA_AND_OBJECTS
+ if ( use_object_mode )
+ {
+ bottom_virtual_speaker_node_division_gains = hVBAPdata->object_mode_bottom_virtual_speaker_node_division_gains;
+ top_virtual_speaker_node_division_gains = hVBAPdata->object_mode_top_virtual_speaker_node_division_gains;
+ back_virtual_speaker_node_division_gains = hVBAPdata->object_mode_back_virtual_speaker_node_division_gains;
+ }
+ else
+ {
+ bottom_virtual_speaker_node_division_gains = hVBAPdata->bottom_virtual_speaker_node_division_gains;
+ top_virtual_speaker_node_division_gains = hVBAPdata->top_virtual_speaker_node_division_gains;
+ back_virtual_speaker_node_division_gains = hVBAPdata->back_virtual_speaker_node_division_gains;
+ }
+#else
bottom_virtual_speaker_node_division_gains = hVBAPdata->bottom_virtual_speaker_node_division_gains;
top_virtual_speaker_node_division_gains = hVBAPdata->top_virtual_speaker_node_division_gains;
back_virtual_speaker_node_division_gains = hVBAPdata->back_virtual_speaker_node_division_gains;
+#endif
panning_wrap_angles( (float) azi_deg, (float) ele_deg, &azi_temp, &ele_temp );
azi_rad = azi_temp * PI_OVER_180;
@@ -702,6 +788,10 @@ static void determine_virtual_speaker_node_division_gains(
const enum VirtualSpeakerNodeType type, /* i : virtual speaker node typel */
const int16_t max_num_connections, /* i : max number of connections */
const int16_t num_speaker_nodes /* i : max number of speaker nodes */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t use_object_mode /* i : use VBAP in object panning mode vs. spatial panning mode */
+#endif
)
{
/* When node type is VIRTUAL_SPEAKER_NODE_DISTRIBUTE_ENERGY, the gains of the virtual node
@@ -744,6 +834,12 @@ static void determine_virtual_speaker_node_division_gains(
for ( ch = 0; ch < num_speaker_nodes; ch++ )
{
virtual_node_division_gains[ch] /= sum_val;
+#ifdef MASA_AND_OBJECTS
+ if ( use_object_mode )
+ {
+ virtual_node_division_gains[ch] = powf( virtual_node_division_gains[ch], 0.8f );
+ }
+#endif
}
}
diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c
index 686a4b6da76eec1610cc50c681c95b682f7114f1..470ed95f1aa5653f6caf3dfbb59ceb45f28b2999 100644
--- a/lib_dec/lib_dec.c
+++ b/lib_dec/lib_dec.c
@@ -214,6 +214,13 @@ ivas_error IVAS_DEC_Open(
st_ivas->sba_planar = 0;
st_ivas->sba_analysis_order = 0;
+#ifdef MASA_AND_OBJECTS
+ hIvasDec->st_ivas->editing_ism_enabled = 0;
+ hIvasDec->st_ivas->index_of_edited_ism = 0;
+ hIvasDec->st_ivas->azimuth_edited = 0;
+ hIvasDec->st_ivas->elevation_edited = 0;
+#endif
+
return IVAS_ERR_OK;
}
@@ -401,6 +408,10 @@ static IVAS_DEC_BS_FORMAT mapIvasFormat(
return IVAS_DEC_BS_SBA;
case MASA_FORMAT:
return IVAS_DEC_BS_MASA;
+#ifdef OMASA_EXT_OUTPUT
+ case MASA_ISM_FORMAT:
+ return IVAS_DEC_BS_MASA_ISM;
+#endif
default:
break;
}
@@ -996,9 +1007,17 @@ ivas_error IVAS_DEC_GetNumObjects(
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
+#ifdef OMASA_EXT_OUTPUT
+ if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT || hIvasDec->st_ivas->ivas_format == MASA_ISM_FORMAT )
+#else
if ( hIvasDec->st_ivas->ivas_format == ISM_FORMAT )
+#endif
{
+#ifdef OMASA_EXT_OUTPUT
+ *numObjects = hIvasDec->st_ivas->nchan_ism;
+#else
*numObjects = hIvasDec->st_ivas->hDecoderConfig->nchan_out;
+#endif
}
else
{
@@ -1081,12 +1100,20 @@ ivas_error IVAS_DEC_GetObjectMetadata(
st_ivas = hIvasDec->st_ivas;
+#ifdef OMASA_EXT_OUTPUT
+ if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->ivas_format != MASA_ISM_FORMAT )
+#else
if ( st_ivas->ivas_format != ISM_FORMAT )
+#endif
{
return IVAS_ERR_WRONG_MODE;
}
+#ifdef OMASA_EXT_OUTPUT
+ if ( objectIdx >= st_ivas->nchan_ism )
+#else
if ( objectIdx >= st_ivas->hDecoderConfig->nchan_out )
+#endif
{
return IVAS_ERR_INVALID_INDEX;
}
@@ -1142,7 +1169,11 @@ ivas_error IVAS_DEC_GetMasaMetadata(
return IVAS_ERR_UNEXPECTED_NULL_POINTER;
}
+#ifdef OMASA_EXT_OUTPUT
+ if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT && hIvasDec->st_ivas->ivas_format != MASA_ISM_FORMAT )
+#else
if ( hIvasDec->st_ivas->ivas_format != MASA_FORMAT )
+#endif
{
return IVAS_ERR_WRONG_MODE;
}
@@ -1195,6 +1226,11 @@ ivas_error IVAS_DEC_FeedHeadTrackData(
{
/* check for Euler angle signaling */
#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifndef EULER2QUAT_FIX
+ /* TODO: temp change until Euler2Quat() is fixed*/
+ if ( ( hIvasDec->st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) &&
+ ( hIvasDec->st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
+#endif
#endif
{
if ( orientation[i].w == -3.0f )
@@ -1402,7 +1438,7 @@ ivas_error IVAS_DEC_GetHrtfHandle(
ivas_error IVAS_DEC_GetHrtfCRendHandle(
IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
- IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF /* o : Set of HRTF handle */
+ IVAS_DEC_HRTF_CREND_HANDLE *hSetOfHRTF /* o : Set of HRTF handle */
)
{
if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSetOfHRTF == NULL )
@@ -1415,6 +1451,36 @@ ivas_error IVAS_DEC_GetHrtfCRendHandle(
return IVAS_ERR_OK;
}
+
+#ifdef MASAISM_EDIT_OBJECTS
+/*---------------------------------------------------------------------*
+ * IVAS_DEC_SetEditedIsmPositions( )
+ *
+ *
+ *---------------------------------------------------------------------*/
+
+ivas_error IVAS_DEC_SetEditedIsmPositions(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ int16_t index_of_edited_ism, /* i : Index of edited ISM */
+ int16_t azimuth_edited_ism, /* i : Azimuth */
+ int16_t elevation_edited_ism /* i : Elevation */
+)
+{
+ if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL )
+ {
+ return IVAS_ERR_UNEXPECTED_NULL_POINTER;
+ }
+
+ hIvasDec->st_ivas->editing_ism_enabled = 1;
+ hIvasDec->st_ivas->index_of_edited_ism = index_of_edited_ism;
+ hIvasDec->st_ivas->azimuth_edited = azimuth_edited_ism;
+ hIvasDec->st_ivas->elevation_edited = elevation_edited_ism;
+
+ return IVAS_ERR_OK;
+}
+#endif
+
+
/*---------------------------------------------------------------------*
* IVAS_DEC_GetHrtfFastConvHandle( )
*
@@ -1422,8 +1488,8 @@ ivas_error IVAS_DEC_GetHrtfCRendHandle(
*---------------------------------------------------------------------*/
ivas_error IVAS_DEC_GetHrtfFastConvHandle(
- IVAS_DEC_HANDLE hIvasDec, /* i/oL IVAS decoder handle */
- IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv /* o : FASTCONV HRTF handle */
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv /* o : FASTCONV HRTF handle */
)
{
if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hHrtfFastConv == NULL )
@@ -1436,6 +1502,7 @@ ivas_error IVAS_DEC_GetHrtfFastConvHandle(
return IVAS_ERR_OK;
}
+
/*---------------------------------------------------------------------*
* IVAS_DEC_GetHrtfParamBinHandle( )
*
@@ -1457,6 +1524,7 @@ ivas_error IVAS_DEC_GetHrtfParamBinHandle(
return IVAS_ERR_OK;
}
+
/*---------------------------------------------------------------------*
* IVAS_DEC_GetRenderConfig( )
*
@@ -2615,7 +2683,11 @@ static ivas_error printConfigInfo_dec(
{
fprintf( stdout, "Input configuration: MASA - %d channel(s)\n", st_ivas->nchan_transport );
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MC_FORMAT )
+#else
else /* MC_FORMAT */
+#endif
{
if ( ( error = get_channel_config( st_ivas->transport_config, &config_str[0] ) ) != IVAS_ERR_OK )
{
@@ -2624,6 +2696,12 @@ static ivas_error printConfigInfo_dec(
fprintf( stdout, "Input configuration: %s\n", config_str );
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ fprintf( stdout, "Input configuration: combined ISM and MASA (%i ISM stream(s)) \n", st_ivas->nchan_ism );
+ }
+#endif
}
get_channel_config( st_ivas->hDecoderConfig->output_config, &config_str[0] );
diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h
index 9edc1a130c0bb520db9e529fd779361a263c5940..e214796629901515ee5d6496552f608329012639 100644
--- a/lib_dec/lib_dec.h
+++ b/lib_dec/lib_dec.h
@@ -116,6 +116,9 @@ typedef enum _IVAS_DEC_BS_FORMAT
IVAS_DEC_BS_SBA,
IVAS_DEC_BS_OBJ,
IVAS_DEC_BS_MASA,
+#ifdef OMASA_EXT_OUTPUT
+ IVAS_DEC_BS_MASA_ISM,
+#endif
IVAS_DEC_BS_UNKOWN = 0xffff
} IVAS_DEC_BS_FORMAT;
@@ -358,15 +361,24 @@ ivas_error IVAS_DEC_GetHrtfCRendHandle(
);
ivas_error IVAS_DEC_GetHrtfFastConvHandle(
- IVAS_DEC_HANDLE hIvasDec, /* i/oL IVAS decoder handle */
- IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv /* o : FASTCONV HRTF handle */
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ IVAS_DEC_HRTF_FASTCONV_HANDLE *hHrtfFastConv /* o : FASTCONV HRTF handle */
);
ivas_error IVAS_DEC_GetHrtfParamBinHandle(
- IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
- IVAS_DEC_HRTF_PARAMBIN_HANDLE *hHrtfParambin /* o : Parametric binauralizer HRTF handle */
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ IVAS_DEC_HRTF_PARAMBIN_HANDLE *hHrtfParambin /* o : Parametric binauralizer HRTF handle */
);
+#ifdef MASAISM_EDIT_OBJECTS
+ivas_error IVAS_DEC_SetEditedIsmPositions(
+ IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
+ int16_t index_of_edited_ism, /* i : Index of edited ISM */
+ int16_t azimuth_edited_ism, /* i : Azimuth */
+ int16_t elevation_edited_ism /* i : Elevation */
+);
+#endif
+
/*! r: error code*/
ivas_error IVAS_DEC_GetRenderConfig(
IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */
diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c
index 121754e1dcd339c75a99d7fd76fd416faebfa8ae..e1e068ab2ca2a284939a38bb711d882866ca11e6 100644
--- a/lib_enc/bw_detect.c
+++ b/lib_enc/bw_detect.c
@@ -579,8 +579,12 @@ void set_bw(
{
st->bwidth = WB;
}
+#ifdef ISM_FB
else if ( st->bwidth > SWB && ( ( element_brate < MIN_BRATE_FB_STEREO && !st->is_ism_format ) ||
( element_brate < MIN_BRATE_FB_ISM && st->is_ism_format ) ) )
+#else
+ else if ( element_brate < MIN_BRATE_FB_STEREO && st->bwidth > SWB )
+#endif
{
st->bwidth = SWB;
}
diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c
index 7ff583a6d244e59ab05987986fe86f4510adc73d..bb750ffe77ac4069f2cd83d09df6b9494d31d6ea 100644
--- a/lib_enc/ivas_core_enc.c
+++ b/lib_enc/ivas_core_enc.c
@@ -102,6 +102,9 @@ ivas_error ivas_core_enc(
float tdm_lspQ_PCh[M], tdm_lsfQ_PCh[M];
int16_t last_element_mode, tdm_Pitch_reuse_flag;
int32_t element_brate, last_element_brate, input_Fs;
+#ifdef MASA_AND_OBJECTS
+ int16_t diff_nBits;
+#endif
ivas_error error;
int16_t max_num_indices_BWE;
@@ -188,6 +191,18 @@ ivas_error ivas_core_enc(
}
}
+#ifdef MASA_AND_OBJECTS
+ /*------------------------------------------------------------------*
+ * Sanity check in combined format coding
+ *-----------------------------------------------------------------*/
+
+ diff_nBits = 0;
+ if ( hCPE != NULL && hCPE->element_mode == IVAS_CPE_DFT && hCPE->brate_surplus > 0 )
+ {
+ ivas_combined_format_brate_sanity( hCPE->element_brate, sts[0]->core, &( sts[0]->core_brate ), &diff_nBits );
+ }
+#endif
+
/*---------------------------------------------------------------------*
* Core Encoding
*---------------------------------------------------------------------*/
@@ -425,6 +440,22 @@ ivas_error ivas_core_enc(
}
}
+#ifdef MASA_AND_OBJECTS
+ /*------------------------------------------------------------------*
+ * Write potentially unused bits in combined format coding
+ *-----------------------------------------------------------------*/
+
+ if ( hCPE != NULL && hCPE->element_mode == IVAS_CPE_DFT && hCPE->brate_surplus > 0 )
+ {
+ while ( diff_nBits > 0 )
+ {
+ n = min( diff_nBits, 16 );
+ push_indice( sts[0]->hBstr, IND_UNUSED, 0, n );
+ diff_nBits -= n;
+ }
+ }
+#endif
+
#ifdef DEBUG_MODE_INFO
for ( n = 0; n < n_CoreChannels; n++ )
{
diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c
index 92c66f0de3a45a8fedce45a6eef569ef81f0e68b..20c2f164523ae396f77e29b1dab86b5eac69c8d2 100644
--- a/lib_enc/ivas_core_pre_proc_front.c
+++ b/lib_enc/ivas_core_pre_proc_front.c
@@ -161,6 +161,9 @@ ivas_error pre_proc_front_ivas(
float temp1F_icatdmResampBuf[L_FILT_MAX]; /* temp buffers for ICA TDM resamplers */
int16_t old_pitch1; /* previous frame OL pitch[1] @12.8 kHz */
int16_t LR_localVAD;
+#ifndef FIX_560_VAD_FLAG
+ int16_t LR_vad_flag;
+#endif
ivas_error error;
push_wmops( "pre_proc_front" );
@@ -177,6 +180,9 @@ ivas_error pre_proc_front_ivas(
res_cod_SNR_M = tmpF;
LR_localVAD = 0;
+#ifndef FIX_560_VAD_FLAG
+ LR_vad_flag = 0;
+#endif
if ( hSCE != NULL )
{
@@ -204,6 +210,9 @@ ivas_error pre_proc_front_ivas(
{
/* Combine localVAD and vad_flag from LR processing */
LR_localVAD = hCPE->hCoreCoder[0]->localVAD || hCPE->hCoreCoder[1]->localVAD;
+#ifndef FIX_560_VAD_FLAG
+ LR_vad_flag = hCPE->hFrontVad[0]->hVAD->vad_flag || hCPE->hFrontVad[1]->hVAD->vad_flag;
+#endif
}
if ( hCPE->hStereoTD != NULL )
@@ -457,6 +466,10 @@ ivas_error pre_proc_front_ivas(
/* Add down mix stereo activity to LR vad_flag_dtx */
*vad_flag_dtx = *vad_flag_dtx || st->vad_flag;
+#ifndef FIX_560_VAD_FLAG
+ /* Combine the LR VAD flag and stereo downmix VAD flag */
+ st->vad_flag = ( LR_vad_flag || st->vad_flag );
+#endif
/* Determine hangover flag status based on LR localVAD and downmix localVAD */
*vad_hover_flag = *vad_flag_dtx && !( LR_localVAD || st->localVAD );
diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c
index ff79dd11b08269953be932ce5a9c57063a6fc52c..6f43073801eb2dcf7f69d0daefd2a99c23110f63 100644
--- a/lib_enc/ivas_corecoder_enc_reconfig.c
+++ b/lib_enc/ivas_corecoder_enc_reconfig.c
@@ -251,7 +251,7 @@ ivas_error ivas_corecoder_enc_reconfig(
st_ivas->hCPE[0]->hStereoMdct = NULL;
}
- /* create missing core coder elements and set element bitrates for alrady existing ones */
+ /* create missing core coder elements and set element bitrates for already existing ones */
if ( st_ivas->nSCE > 0 )
{
nSCE_existing = min( nSCE_old, st_ivas->nSCE );
@@ -271,14 +271,22 @@ ivas_error ivas_corecoder_enc_reconfig(
}
/* propagate input audio buffers */
+#ifdef MASA_AND_OBJECTS
+ if ( n_CoreCoder_existing > sce_id && hEncoderConfig->ivas_format != MASA_ISM_FORMAT )
+#else
if ( n_CoreCoder_existing > sce_id )
+#endif
{
mvr2r( input_buff[sce_id], st_ivas->hSCE[sce_id]->hCoreCoder[0]->input_buff, len_inp_memory );
}
/* only reset indices if it is not the first index list, this already contains the IVAS format bits */
+#ifdef MASA_AND_OBJECTS
+ if ( sce_id > 0 || hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+#else
if ( sce_id > 0 )
+#endif
{
reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr,
st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_ind_tot );
@@ -303,7 +311,13 @@ ivas_error ivas_corecoder_enc_reconfig(
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 MASA_AND_OBJECTS
+ if ( ( cpe_id * CPE_CHANNELS + n > 0 ) ||
+ ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->nSCE > 0 ) ||
+ ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 ) )
+#else
if ( cpe_id * CPE_CHANNELS + n > 0 || ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->nSCE > 0 ) )
+#endif
{
reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr,
st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_ind_tot );
diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c
index 09cd09eacc2c91991ed9f7362b3d03657dd4dcbb..e45949bbb2711e05ee4de0dd4310e2302bb14178 100644
--- a/lib_enc/ivas_cpe_enc.c
+++ b/lib_enc/ivas_cpe_enc.c
@@ -45,6 +45,15 @@
#include "wmc_auto.h"
+#ifdef MASA_AND_OBJECTS
+/*--------------------------------------------------------------------------*
+ * Local function prototypes
+ *--------------------------------------------------------------------------*/
+
+static void stereo_mode_combined_format_enc( const Encoder_Struct *st_ivas, CPE_ENC_HANDLE hCPE );
+#endif
+
+
/*-------------------------------------------------------------------*
* ivas_cpe_enc()
*
@@ -101,6 +110,10 @@ ivas_error ivas_cpe_enc(
ENCODER_CONFIG_HANDLE hEncoderConfig;
int32_t ivas_total_brate;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t cpe_brate;
+ int32_t element_brate_ref;
+#endif
error = IVAS_ERR_OK;
@@ -113,6 +126,9 @@ ivas_error ivas_cpe_enc(
ivas_format = hEncoderConfig->ivas_format;
input_Fs = hEncoderConfig->input_Fs;
ivas_total_brate = hEncoderConfig->ivas_total_brate;
+#ifdef MASA_AND_OBJECTS
+ element_brate_ref = hCPE->element_brate;
+#endif
/*------------------------------------------------------------------*
* Initialization - general
@@ -168,6 +184,10 @@ ivas_error ivas_cpe_enc(
hCPE->element_mode = select_stereo_mode( hCPE, ivas_format, ivas_total_brate );
}
+#ifdef MASA_AND_OBJECTS
+ stereo_mode_combined_format_enc( st_ivas, hCPE );
+#endif
+
if ( ( error = front_vad( hCPE, NULL, hEncoderConfig, &hCPE->hFrontVad[0], st_ivas->hMCT != NULL, input_frame, vad_flag_dtx, fr_bands, Etot_LR, lf_E, localVAD_HE_SAD, vad_hover_flag, band_energies_LR, NULL, NULL ) ) != IVAS_ERR_OK )
{
return error;
@@ -193,6 +213,7 @@ ivas_error ivas_cpe_enc(
return error;
}
+
/*----------------------------------------------------------------*
* Set TD stereo parameters
*----------------------------------------------------------------*/
@@ -265,12 +286,28 @@ ivas_error ivas_cpe_enc(
sts[n]->element_mode = hCPE->element_mode;
}
+
if ( hCPE->element_mode != IVAS_CPE_MDCT && ( hCPE->element_brate != hCPE->last_element_brate || hCPE->last_element_mode != hCPE->element_mode ||
- sts[0]->ini_frame == 0 || sts[0]->last_core_brate <= SID_2k40 ) ) /* If the last frame was SID or NO_DATA, we need to run stereo_dft_config here since VAD decision is not known yet */
+ sts[0]->ini_frame == 0 ||
+#ifdef MASA_AND_OBJECTS
+ ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) ||
+#endif
+ sts[0]->last_core_brate <= SID_2k40 ) ) /* If the last frame was SID or NO_DATA, we need to run stereo_dft_config here since VAD decision is not known yet */
{
if ( st_ivas->hQMetaData != NULL )
{
- stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode != ISM_MODE_NONE )
+ {
+ stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, (int32_t) ( 0.70f * st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC ), &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+ }
+ else
+ {
+#endif
+ stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal );
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
}
else
{
@@ -294,6 +331,16 @@ ivas_error ivas_cpe_enc(
if ( hCPE->element_mode == IVAS_CPE_MDCT )
{
+#ifdef MASA_AND_OBJECTS
+ /* compute bit-rate surplus per channel in combined format coding */
+ int32_t brate_surplus[CPE_CHANNELS];
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ brate_surplus[0] = ( ( hCPE->brate_surplus / FRAMES_PER_SEC ) >> 1 ) * FRAMES_PER_SEC;
+ brate_surplus[1] = hCPE->brate_surplus - brate_surplus[0];
+ }
+#endif
+
/* this is just for initialization, the true values of "total_brate" and "bits_frame_channel" are set later */
for ( n = 0; n < n_CoreChannels; n++ )
{
@@ -310,6 +357,15 @@ ivas_error ivas_cpe_enc(
sts[n]->bits_frame_nominal = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC );
sts[n]->bits_frame_channel = (int16_t) ( ( hCPE->element_brate / FRAMES_PER_SEC ) / n_CoreChannels );
sts[n]->total_brate = hCPE->element_brate / n_CoreChannels;
+
+#ifdef MASA_AND_OBJECTS
+ /* subtract bit-rate for combined format coding */
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ sts[n]->bits_frame_channel += (int16_t) ( brate_surplus[n] / FRAMES_PER_SEC );
+ sts[n]->total_brate += brate_surplus[n];
+ }
+#endif
}
}
@@ -356,7 +412,11 @@ ivas_error ivas_cpe_enc(
else if ( hCPE->element_mode == IVAS_CPE_TD )
{
/* Determine the energy ratio between the 2 channels */
- tdm_ratio_idx = stereo_tdm_ener_analysis( hCPE, input_frame, &tdm_SM_or_LRTD_Pri, &tdm_ratio_idx_SM );
+ tdm_ratio_idx = stereo_tdm_ener_analysis(
+#ifdef MASA_AND_OBJECTS
+ ivas_format,
+#endif
+ hCPE, input_frame, &tdm_SM_or_LRTD_Pri, &tdm_ratio_idx_SM );
/* Compute the downmix signal based on the ratio index */
stereo_tdm_downmix( hCPE->hStereoTD, sts[0]->input, sts[1]->input, input_frame, tdm_ratio_idx, ( ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) ? tdm_SM_or_LRTD_Pri : 0 ), tdm_ratio_idx_SM );
@@ -364,6 +424,9 @@ ivas_error ivas_cpe_enc(
/* signal the bitrate for BW selection in the SCh */
sts[0]->bits_frame_channel = 0;
sts[1]->bits_frame_channel = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC );
+#ifdef MASA_AND_OBJECTS
+ sts[1]->bits_frame_channel += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
+#endif
if ( st_ivas->hQMetaData != NULL )
{
sts[1]->bits_frame_channel -= st_ivas->hQMetaData->metadata_max_bits;
@@ -518,7 +581,12 @@ ivas_error ivas_cpe_enc(
{
tdm_ol_pitch_comparison( hCPE, pitch_fr, voicing_fr );
- tdm_configure_enc( hCPE, Etot_last, tdm_SM_or_LRTD_Pri, tdm_ratio_idx, tdm_ratio_idx_SM, attack_flag[0], nb_bits_metadata );
+ tdm_configure_enc(
+#ifdef MASA_AND_OBJECTS
+ ivas_format,
+ st_ivas->ism_mode,
+#endif
+ hCPE, Etot_last, tdm_SM_or_LRTD_Pri, tdm_ratio_idx, tdm_ratio_idx_SM, attack_flag[0], nb_bits_metadata );
if ( hEncoderConfig->Opt_DTX_ON )
{
@@ -550,6 +618,9 @@ ivas_error ivas_cpe_enc(
* DFT Stereo parameters writing into the bitstream
*----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ cpe_brate = 0;
+#endif
if ( hCPE->element_mode == IVAS_CPE_DFT )
{
if ( hEncoderConfig->Opt_DTX_ON )
@@ -578,6 +649,36 @@ ivas_error ivas_cpe_enc(
}
/* Write stereo bitstream */
+#ifdef MASA_AND_OBJECTS
+ cpe_brate = st_ivas->hCPE[0]->element_brate;
+
+ /* DFT stereo side bits */
+ if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && cpe_brate < MASA_STEREO_MIN_BITRATE && sts[0]->core_brate != SID_2k40 && sts[0]->core_brate != FRAME_NO_DATA )
+ {
+ nb_bits = 0; /* Only mono downmix is transmitted in this case */
+ }
+ else if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) )
+ {
+ nb_bits = hCPE->hMetaData->nb_bits_tot;
+ }
+ else
+ {
+ stereo_dft_enc_write_BS( hCPE, &nb_bits );
+ }
+
+ /* Residual coding in MDCT domain */
+ if ( !( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && ( sts[0]->core_brate == SID_2k40 || sts[0]->core_brate == FRAME_NO_DATA ) ) )
+ {
+ int16_t max_bits = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal );
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+ {
+ max_bits -= nb_bits_metadata;
+ max_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
+ }
+
+ stereo_dft_enc_res( hCPE->hStereoDft, old_inp_12k8[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits );
+ }
+#else
if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && sts[0]->core_brate != SID_2k40 && sts[0]->core_brate != FRAME_NO_DATA )
{
nb_bits = 0; /* Only mono downmix is transmitted in this case */
@@ -596,7 +697,7 @@ ivas_error ivas_cpe_enc(
/* Residual coding in MDCT domain */
stereo_dft_enc_res( hCPE->hStereoDft, old_inp_12k8[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal - ( ( ivas_format == MASA_FORMAT ) ? nb_bits_metadata : 0 ) ) );
}
-
+#endif
if ( sts[0]->core_brate == FRAME_NO_DATA || sts[0]->core_brate == SID_2k40 )
{
assert( ( nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" );
@@ -611,8 +712,17 @@ ivas_error ivas_cpe_enc(
/* subtract metadata bitbudget */
sts[0]->total_brate -= ( nb_bits_metadata * FRAMES_PER_SEC );
+
+#ifdef MASA_AND_OBJECTS
+ /* subtract bit-rate for combined format coding */
+ if ( ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ sts[0]->total_brate += hCPE->brate_surplus;
+ }
+#endif
}
+
/*----------------------------------------------------------------*
* Core Encoder
*----------------------------------------------------------------*/
@@ -629,6 +739,13 @@ ivas_error ivas_cpe_enc(
hCPE->last_element_brate = hCPE->element_brate;
hCPE->last_element_mode = hCPE->element_mode;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ hCPE->element_brate = element_brate_ref;
+ }
+#endif
+
if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->hStereoMdct != NULL && hCPE->hStereoMdct->hItd != NULL )
{
/* update input samples buffer */
@@ -672,7 +789,7 @@ ivas_error ivas_cpe_enc(
dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_NCShift" );
dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_ica_gD" );
n = -1;
- dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" );
+ // dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" );
}
else if ( hCPE->element_mode == IVAS_CPE_TD )
{
@@ -689,7 +806,7 @@ ivas_error ivas_cpe_enc(
else if ( hCPE->element_mode == IVAS_CPE_MDCT )
{
n = -2;
- dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" );
+ // dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" );
}
{
@@ -762,13 +879,21 @@ ivas_error create_cpe_enc(
hCPE->hFrontVad[0] = NULL;
hCPE->hFrontVad[1] = NULL;
+#ifdef MASA_AND_OBJECTS
+ hCPE->brate_surplus = 0;
+#endif
+
/*-----------------------------------------------------------------*
* Input memory buffer: allocate and initialize
*-----------------------------------------------------------------*/
for ( n = 0; n < CPE_CHANNELS; n++ )
{
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == STEREO_FORMAT || ivas_format == MASA_FORMAT || ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == STEREO_FORMAT || ivas_format == MASA_FORMAT || ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) )
+#endif
{
if ( ( hCPE->input_mem[n] = (float *) malloc( sizeof( float ) * NS2SA( input_Fs, STEREO_DFT_OVL_NS ) ) ) == NULL )
{
@@ -830,10 +955,17 @@ ivas_error create_cpe_enc(
}
copy_encoder_config( st_ivas, st, 1 );
+
st->total_brate = hCPE->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */
st->mct_chan_mode = MCT_CHAN_MODE_REGULAR;
- if ( ( error = init_encoder( st, st_ivas, n, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 0, st_ivas->ism_mode ) ) != IVAS_ERR_OK )
+ if ( ( error = init_encoder( st, st_ivas, n, hEncoderConfig->var_SID_rate_flag, hEncoderConfig->interval_SID, 0,
+#ifdef MASA_AND_OBJECTS
+ ISM_MODE_NONE
+#else
+ st_ivas->ism_mode
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -1069,3 +1201,62 @@ void destroy_cpe_enc(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------------
+ * stereo_mode_combined_format_enc()
+ *
+ * Set stereo format in a combined format
+ *-------------------------------------------------------------------------*/
+
+static void stereo_mode_combined_format_enc(
+ const Encoder_Struct *st_ivas, /* i : encoder main structure */
+ CPE_ENC_HANDLE hCPE /* i/o: CPE handle */
+)
+{
+ ENCODER_CONFIG_HANDLE hEncoderConfig;
+ int32_t element_brate_ref;
+
+ hEncoderConfig = st_ivas->hEncoderConfig;
+
+ if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ element_brate_ref = hCPE->element_brate;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC &&
+ ( ( hEncoderConfig->nchan_ism == 3 && hEncoderConfig->ivas_total_brate == IVAS_96k ) ||
+ ( hEncoderConfig->nchan_ism == 4 && hEncoderConfig->ivas_total_brate == IVAS_128k ) ) )
+ {
+ if ( hCPE->element_brate + hCPE->brate_surplus > IVAS_64k )
+ {
+ st_ivas->hMasa->data.omasa_stereo_sw_cnt = 0;
+ }
+ else
+ {
+ st_ivas->hMasa->data.omasa_stereo_sw_cnt++;
+ st_ivas->hMasa->data.omasa_stereo_sw_cnt = min( st_ivas->hMasa->data.omasa_stereo_sw_cnt, OMASA_STEREO_SW_CNT_MAX );
+ }
+
+ if ( st_ivas->hMasa->data.omasa_stereo_sw_cnt < OMASA_STEREO_SW_CNT_MAX )
+ {
+ hCPE->element_mode = IVAS_CPE_MDCT;
+ hCPE->element_brate = IVAS_64k;
+ hCPE->brate_surplus -= ( hCPE->element_brate - element_brate_ref );
+ }
+
+ /* write OMASA stereo mode signalling */
+ if ( hCPE->element_mode == IVAS_CPE_MDCT )
+ {
+ push_indice( hCPE->hCoreCoder[0]->hBstr, IND_SMODE_OMASA, 1, NBITS_ELEMENT_MODE );
+ }
+ else
+ {
+ push_indice( hCPE->hCoreCoder[0]->hBstr, IND_SMODE_OMASA, 0, NBITS_ELEMENT_MODE );
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c
index c731eeff02d171087bdcd50403fad4bda9c49a10..09d307e6244a774c9135b1c74f39cd6dd6b4a20e 100644
--- a/lib_enc/ivas_decision_matrix_enc.c
+++ b/lib_enc/ivas_decision_matrix_enc.c
@@ -164,6 +164,20 @@ void ivas_decision_matrix_enc(
/* select TCX core or HQ core using bits_frame_nominal to match the TCX configuration bitrate */
st->core = mdct_classifier( st, fft_buff, enerBuffer, st->bits_frame_nominal * FRAMES_PER_SEC );
}
+
+#ifndef FIX_TCX_LOWRATE_LIMITATION
+ /* Warning: TCX not available at low bitrates -> replace it by GSC */
+ if ( st->core == TCX_20_CORE && st->total_brate < STEREO_TCX_MIN_RATE )
+ {
+ st->core = ACELP_CORE;
+ st->coder_type = AUDIO;
+ st->sp_aud_decision2 = 0;
+ if ( st->low_rate_mode )
+ {
+ st->coder_type = INACTIVE;
+ }
+ }
+#endif
}
/* do not allow TD stereo ACELP core -> DFT stereo TCX core switching as it is on the WC complexity path */
@@ -210,8 +224,23 @@ void ivas_decision_matrix_enc(
}
}
+#ifndef FIX_TCX_LOWRATE_LIMITATION
+ /* TCX not available at low bitrates -> replace it by GSC */
+ if ( st->core == TCX_20_CORE && st->total_brate < STEREO_TCX_MIN_RATE )
+ {
+ st->core = ACELP_CORE;
+ st->coder_type = AUDIO;
+ st->sp_aud_decision2 = 0;
+
+ if ( st->low_rate_mode )
+ {
+ st->coder_type = INACTIVE;
+ }
+ }
+#endif
#endif
+#ifdef FIX_TCX_LOWRATE_LIMITATION
/* TCX not available at low bitrates -> replace it by GSC */
if ( st->core == TCX_20_CORE && st->total_brate < STEREO_TCX_MIN_RATE )
{
@@ -224,6 +253,7 @@ void ivas_decision_matrix_enc(
st->coder_type = INACTIVE;
}
}
+#endif
/*---------------------------------------------------------------------*
* Select ACELP and GSC extension layer
@@ -408,7 +438,11 @@ void ivas_signaling_enc(
* Write element mode info
*--------------------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && !MCT_flag ) /* note: in MCT, the MDCT stereo is used exclusively */
+#else
if ( st->element_mode >= IVAS_CPE_DFT && element_brate < MIN_BRATE_MDCT_STEREO && !MCT_flag ) /* note: in MCT, the MDCT stereo is used exclusively */
+#endif
{
ind = st->element_mode - IVAS_CPE_DFT;
push_indice( hBstr, IND_SMODE, ind, NBITS_ELEMENT_MODE );
@@ -423,8 +457,12 @@ void ivas_signaling_enc(
{
/* only WB is supported */
}
+#ifdef ISM_FB
else if ( ( element_brate < MIN_BRATE_FB_STEREO && !st->is_ism_format ) ||
( element_brate < MIN_BRATE_FB_ISM && st->is_ism_format ) )
+#else
+ else if ( element_brate < MIN_BRATE_FB_STEREO )
+#endif
{
/* WB and SWB are supported */
ind = st->bwidth - WB;
diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c
index 86d9dc3ec627e8ba6dc7f2ddbd5f8c660902ef70..10066a104ea8908ae9af596f0b3c8a0078718083 100644
--- a/lib_enc/ivas_enc.c
+++ b/lib_enc/ivas_enc.c
@@ -61,7 +61,11 @@ ivas_error ivas_enc(
ENCODER_CONFIG_HANDLE hEncoderConfig;
BSTR_ENC_HANDLE hMetaData;
Encoder_State *st; /* used for bitstream handling */
+#ifdef MASA_AND_OBJECTS
+ int16_t nb_bits_metadata[MAX_SCE + 1];
+#else
int16_t nb_bits_metadata[MAX_SCE];
+#endif
float data_f[MAX_INPUT_CHANNELS][L_FRAME48k];
int32_t ivas_total_brate;
ivas_error error;
@@ -83,7 +87,11 @@ ivas_error ivas_enc(
input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
n_samples_chan = n_samples / nchan_inp;
+#ifdef MASA_AND_OBJECTS
+ set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+#else
set_s( nb_bits_metadata, 0, MAX_SCE );
+#endif
/*----------------------------------------------------------------*
* convert 'short' input data to 'float'
@@ -177,7 +185,12 @@ ivas_error ivas_enc(
ivas_param_ism_stereo_dmx( st_ivas, data_f, input_frame );
/* Core coding of Stereo DMX */
- if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, nb_bits_metadata ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, nb_bits_metadata
+#ifdef MASA_AND_OBJECTS
+ ,
+ 0
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -185,7 +198,12 @@ ivas_error ivas_enc(
else if ( st_ivas->ism_mode == ISM_MODE_DISC )
{
/* Analysis, decision about bitrates per channel & core coding */
- if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, nb_bits_metadata ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, nb_bits_metadata
+#ifdef MASA_AND_OBJECTS
+ ,
+ 0
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -225,7 +243,12 @@ ivas_error ivas_enc(
return error;
}
if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format,
- ivas_total_brate, hEncoderConfig->Opt_DTX_ON, st_ivas->nchan_transport == 2 ? st_ivas->hCPE[0]->element_mode : -1 ) ) != IVAS_ERR_OK )
+ ivas_total_brate, hEncoderConfig->Opt_DTX_ON, st_ivas->nchan_transport == 2 ? st_ivas->hCPE[0]->element_mode : -1
+#ifdef MASA_AND_OBJECTS
+ ,
+ ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
@@ -266,18 +289,119 @@ ivas_error ivas_enc(
}
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ float data_separated_object[L_FRAME48k];
+ int16_t idx_separated_object;
+ int16_t flag_omasa_ener_brate;
+
+ flag_omasa_ener_brate = 0;
+
+#ifdef OMASA_FIX_LOW_FS
+ /* Estimate TF-tile energy for the input MASA stream */
+ ivas_masa_estimate_energy( st_ivas->hMasa, &( data_f[hEncoderConfig->nchan_ism] ), input_frame, st_ivas->nchan_transport );
+#endif
+
+ if ( ( error = ivas_omasa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Stereo transport is used also with monoMASA, duplicate mono if monoMASA */
+ if ( ( st_ivas->hEncoderConfig->nchan_inp - hEncoderConfig->nchan_ism ) == 1 )
+ {
+ v_multc( data_f[hEncoderConfig->nchan_ism], 1.0f / SQRT2, data_f[hEncoderConfig->nchan_ism], input_frame );
+ mvr2r( data_f[hEncoderConfig->nchan_ism], data_f[hEncoderConfig->nchan_ism + 1], input_frame );
+ }
+
+ set_s( nb_bits_metadata, 0, MAX_SCE + 1 );
+ idx_separated_object = 0;
+
+#ifndef OMASA_FIX_LOW_FS
+ /* Estimate TF-tile energy for the input MASA stream */
+ ivas_masa_estimate_energy( st_ivas->hMasa, &( data_f[hEncoderConfig->nchan_ism] ), input_frame, st_ivas->nchan_transport );
+#endif
+
+ /* put audio object data in SCE's */
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
+ {
+ /* Estimate MASA parameters for the objects */
+ ivas_omasa_enc( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hIsmMetaData, data_f, input_frame, st_ivas->nchan_transport, hEncoderConfig->nchan_ism, st_ivas->ism_mode, data_separated_object, &idx_separated_object );
+ }
+
+ /* Encode ISMs transport channels */
+ n = 0;
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ if ( ( error = ivas_sce_enc( st_ivas, 0, data_separated_object, input_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) /* there are no metadata bits in SCE in this mode */
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ if ( ( error = ivas_ism_enc( st_ivas, &data_separated_object, input_frame, &nb_bits_metadata[1], 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ flag_omasa_ener_brate = ivas_omasa_ener_brate( st_ivas->hEncoderConfig->nchan_ism, ivas_total_brate, data_f, input_frame );
+
+ /* Analysis, decision about bitrates per channel & core coding */
+ if ( ( error = ivas_ism_enc( st_ivas, data_f, input_frame, &nb_bits_metadata[1], flag_omasa_ener_brate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ n = st_ivas->hEncoderConfig->nchan_ism;
+ }
+
+ hMetaData = st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData;
+
+ if ( st_ivas->nSCE > 0 )
+ {
+ /* update pointer to the buffer of indices (ISM indices were alredy written) */
+ hMetaData->ind_list = st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData->ind_list + st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData->nb_ind_tot;
+ st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->ind_list = st_ivas->hSCE[st_ivas->nSCE - 1]->hCoreCoder[0]->hBstr->ind_list + st_ivas->hSCE[st_ivas->nSCE - 1]->hCoreCoder[0]->hBstr->nb_ind_tot;
+ }
+
+ /* Encode MASA parameters and write MASA metadata bitstream */
+ if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, nb_bits_metadata, st_ivas->nchan_transport, ivas_format, ivas_total_brate, st_ivas->hEncoderConfig->Opt_DTX_ON, st_ivas->nchan_transport == 2 ? st_ivas->hCPE[0]->element_mode : -1,
+ st_ivas->ism_mode, hEncoderConfig->nchan_ism, st_ivas->hIsmMetaData, idx_separated_object, st_ivas->hOMasa, st_ivas->hIsmMetaData[0]->ism_imp, flag_omasa_ener_brate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* Configuration of combined-format bit-budget distribution */
+#ifdef DEBUG_MODE_INFO
+ ivas_set_surplus_brate_enc( st_ivas, nb_bits_metadata );
+#else
+ ivas_set_surplus_brate_enc( st_ivas );
+#endif
+
+ /* Encode MASA transport channels */
+ if ( ( ivas_cpe_enc( st_ivas, 0, data_f[n], data_f[n + 1], input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#endif
else if ( ivas_format == MC_FORMAT )
{
/* select MC format mode; write MC LS setup; reconfigure the MC format encoder */
- if ( ( ivas_mc_enc_config( st_ivas ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_mc_enc_config( st_ivas ) ) != IVAS_ERR_OK )
{
return error;
}
hMetaData = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData : st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData;
+#ifdef FIX_572_LFE_LPF_ENC
/* LFE low pass filter */
ivas_lfe_lpf_enc_apply( st_ivas->hLfeLpf, data_f[LFE_CHANNEL], input_frame );
+#endif
/* LFE channel encoder */
if ( st_ivas->mc_mode == MC_MODE_MCT )
@@ -336,7 +460,13 @@ ivas_error ivas_enc(
ivas_mcmasa_enc( st_ivas->hMcMasa, st_ivas->hQMetaData, st_ivas->hMasa, data_f, input_frame, st_ivas->nchan_transport, nchan_inp );
- if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, 0, -1 ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_masa_encode( st_ivas->hMasa, st_ivas->hQMetaData, hMetaData, &nb_bits_metadata[0], st_ivas->nchan_transport, ivas_format, ivas_total_brate, 0, -1
+#ifdef MASA_AND_OBJECTS
+ ,
+ ISM_MODE_NONE, -1, NULL, -1, NULL, 0, 0
+#endif
+
+ ) ) != IVAS_ERR_OK )
{
return error;
}
diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c
index 6d0b1086c17dd9a7fea071165c24f7218ead2043..4b8801f7c3dc2449b566db6052932d7209409c93 100644
--- a/lib_enc/ivas_init_enc.c
+++ b/lib_enc/ivas_init_enc.c
@@ -37,6 +37,9 @@
#include "prot.h"
#include "ivas_prot.h"
#include "ivas_stat_enc.h"
+#ifdef MASA_AND_OBJECTS
+#include "ivas_rom_com.h"
+#endif
#ifdef DEBUGGING
#include "debug.h"
#endif
@@ -83,6 +86,20 @@ void ivas_write_format(
ind = 7;
nBits += extra_bits;
break;
+#ifdef MASA_AND_OBJECTS
+ case MASA_ISM_FORMAT:
+ if ( st_ivas->ism_mode == ISM_MODE_NONE )
+ {
+ ind = 7; /* send MASA format */
+ nBits += extra_bits;
+ }
+ else
+ {
+ ind = 10;
+ nBits += extra_bits + IVAS_COMBINED_FORMAT_SIGNALLING_BITS;
+ }
+ break;
+#endif
default:
assert( !"Invalid format. Aborting." );
break;
@@ -161,7 +178,11 @@ void ivas_write_format_sid(
ind = SID_MASA_2TC;
}
break;
-
+#ifdef MASA_AND_OBJECTS
+ case MASA_ISM_FORMAT: /* TODO Nokia: Finalize for SID case */
+ ind = 8;
+ break;
+#endif
default:
assert( !"Reserved SID format symbol written." );
break;
@@ -203,7 +224,12 @@ int16_t getNumChanAnalysis(
{
n = st_ivas->hEncoderConfig->nchan_inp;
}
-
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ n = st_ivas->hEncoderConfig->nchan_inp;
+ }
+#endif
return n;
}
@@ -314,8 +340,15 @@ void ivas_initialize_handles_enc(
/* LFE handle */
st_ivas->hLFE = NULL;
+#ifdef FIX_572_LFE_LPF_ENC
/* LFE low pass filter handle */
st_ivas->hLfeLpf = NULL;
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ /* Object MASA handle */
+ st_ivas->hOMasa = NULL;
+#endif
return;
}
@@ -502,7 +535,7 @@ ivas_error ivas_init_encoder(
}
}
- for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) // VE: TBV - is this loop needed?
{
if ( ( error = create_sce_enc( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK )
{
@@ -540,21 +573,92 @@ ivas_error ivas_init_encoder(
}
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ int32_t element_brate_tmp[MAX_NUM_OBJECTS];
+ int32_t ism_total_brate;
+ int16_t k;
+
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, hEncoderConfig->nchan_ism );
+ st_ivas->nchan_transport = 2;
+
+ if ( ( error = ivas_ism_metadata_enc_create( st_ivas, hEncoderConfig->nchan_ism, element_brate_tmp ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ k = 0;
+ while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
+ {
+ k++;
+ }
+
+ ism_total_brate = 0;
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
+ if ( ( error = create_sce_enc( st_ivas, sce_id, sep_object_brate[k - 2][st_ivas->nSCE - 1] ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ set_f( st_ivas->hQMetaData->masa_to_total_energy_ratio[i], 0, MASA_FREQUENCY_BANDS );
+ }
+
+ if ( ( error = ivas_masa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
+ {
+ if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO )
+ {
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+ }
+ else
+ {
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
+ }
+
+ if ( ( error = create_cpe_enc( st_ivas, 0, ivas_total_brate - ism_total_brate ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#endif
else if ( ivas_format == MC_FORMAT )
{
st_ivas->mc_mode = ivas_mc_mode_select( hEncoderConfig->mc_input_setup, ivas_total_brate );
hEncoderConfig->nchan_inp = ivas_mc_ls_setup_get_num_channels( hEncoderConfig->mc_input_setup );
+#ifdef FIX_572_LFE_LPF_ENC
if ( ( error = ivas_create_lfe_lpf_enc( &st_ivas->hLfeLpf, hEncoderConfig->input_Fs ) ) != IVAS_ERR_OK )
{
return error;
}
+#endif
if ( st_ivas->mc_mode == MC_MODE_MCT )
{
st_ivas->nSCE = 0;
- st_ivas->nCPE = hEncoderConfig->nchan_inp / 2;
+ st_ivas->nCPE = hEncoderConfig->nchan_inp / CPE_CHANNELS;
for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
{
@@ -612,7 +716,7 @@ ivas_error ivas_init_encoder(
return error;
}
- for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) // VE: TBV - is this loop needed?
{
if ( ( error = create_cpe_enc( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nCPE + st_ivas->nSCE ) ) ) != IVAS_ERR_OK )
{
@@ -651,7 +755,7 @@ ivas_error ivas_init_encoder(
ivas_mcmasa_split_brate( st_ivas->hMcMasa->separateChannelEnabled, ivas_total_brate, st_ivas->nSCE, st_ivas->nCPE, &brate_sce, &brate_cpe );
- for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) // VE: TBV - is this loop needed?
{
if ( ( error = create_sce_enc( st_ivas, sce_id, brate_sce ) ) != IVAS_ERR_OK )
{
@@ -659,7 +763,7 @@ ivas_error ivas_init_encoder(
}
}
- for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ )
+ for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) // VE: TBV - is this loop needed?
{
hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
@@ -918,7 +1022,11 @@ void ivas_destroy_enc(
}
/* ISM metadata handles */
+#ifdef MASA_AND_OBJECTS
+ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
+#else
ivas_ism_metadata_close( st_ivas->hIsmMetaData );
+#endif
/* ISM DTX Handle */
if ( st_ivas->hISMDTX != NULL )
@@ -952,8 +1060,10 @@ void ivas_destroy_enc(
/* LFE handle */
ivas_lfe_enc_close( &( st_ivas->hLFE ) );
+#ifdef FIX_572_LFE_LPF_ENC
/* LFE low pass filter state */
ivas_lfe_lpf_enc_close( &( st_ivas->hLfeLpf ) );
+#endif
/* Param-Upmix MC handle */
ivas_mc_paramupmix_enc_close( &( st_ivas->hMCParamUpmix ), st_ivas->hEncoderConfig->input_Fs );
@@ -964,6 +1074,11 @@ void ivas_destroy_enc(
/* Multi-channel MASA handle */
ivas_mcmasa_enc_close( &( st_ivas->hMcMasa ), st_ivas->hEncoderConfig->input_Fs );
+#ifdef MASA_AND_OBJECTS
+ /* OMASA handle */
+ ivas_omasa_enc_close( &( st_ivas->hOMasa ) );
+#endif
+
/* Stereo downmix for EVS encoder handle */
stereo_dmx_evs_close_encoder( &( st_ivas->hStereoDmxEVS ) );
diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c
index 558455f017ce43db2b4cdf4cf1bdfadd0c87bf86..472ff1a6424e4cc47cd8d42752ff366031bc8381 100644
--- a/lib_enc/ivas_ism_enc.c
+++ b/lib_enc/ivas_ism_enc.c
@@ -53,6 +53,10 @@ ivas_error ivas_ism_enc(
float data[MAX_NUM_OBJECTS][L_FRAME48k], /* i : input signal */
const int16_t input_frame, /* i : input frame length per channel */
int16_t *nb_bits_metadata /* i : number of metadata bits */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */
+#endif
)
{
SCE_ENC_HANDLE hSCE;
@@ -88,6 +92,10 @@ ivas_error ivas_ism_enc(
int16_t nchan_ism, dtx_flag, sid_flag, flag_noisy_speech;
int16_t md_diff_flag[MAX_NUM_OBJECTS];
Encoder_State *prev_st = NULL;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate_ref, ism_total_brate;
+ int16_t i, nchan_transport_ism;
+#endif
ivas_error error;
push_wmops( "ivas_ism_enc" );
@@ -105,12 +113,29 @@ ivas_error ivas_ism_enc(
nchan_ism = st_ivas->hEncoderConfig->nchan_ism;
set_s( md_diff_flag, 1, nchan_ism );
+#ifdef MASA_AND_OBJECTS
+ nchan_transport_ism = st_ivas->nchan_transport;
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ nchan_transport_ism = 1;
+ nchan_ism = 1;
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ nchan_transport_ism = st_ivas->hEncoderConfig->nchan_ism;
+ }
+#endif
+
/*------------------------------------------------------------------*
* Preprocesing
*-----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ )
+#else
/* in ISM format: st_ivas->nchan_transport = st_ivas->nSCE */
for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ )
+#endif
{
hSCE = st_ivas->hSCE[sce_id];
st = hSCE->hCoreCoder[0];
@@ -222,11 +247,41 @@ ivas_error ivas_ism_enc(
}
else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
{
+#ifdef MASA_AND_OBJECTS
+ ivas_ism_metadata_enc( &st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData,
+ nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag, -1, 0, NULL );
+#else
ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, st_ivas->hDirAC->hParamIsm, st_ivas->hEncoderConfig->ism_extended_metadata_flag );
+#endif
}
else /* ISM_MODE_DISC */
{
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ ism_total_brate = 0;
+ for ( i = 0; i < st_ivas->nSCE; i++ )
+ {
+ ism_total_brate += st_ivas->hSCE[i]->element_brate;
+ }
+ }
+ else
+ {
+ ism_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
+ }
+
+ ism_total_brate_ref = ism_total_brate;
+
+ ivas_ism_metadata_enc( &ism_total_brate, nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData,
+ nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag, st_ivas->hMasa != NULL ? st_ivas->hMasa->data.lp_noise_CPE : 0, flag_omasa_ener_brate, st_ivas->hMasa != NULL ? &( st_ivas->hMasa->data.omasa_stereo_sw_cnt ) : NULL );
+
+ if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ st_ivas->hCPE[0]->brate_surplus = ism_total_brate_ref - ism_total_brate;
+ }
+#else
ivas_ism_metadata_enc( st_ivas->hEncoderConfig->ivas_total_brate, nchan_ism, st_ivas->nchan_transport, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hSCE[st_ivas->nSCE - 1]->hMetaData, nb_bits_metadata, vad_flag, st_ivas->ism_mode, NULL, st_ivas->hEncoderConfig->ism_extended_metadata_flag );
+#endif
}
update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag );
@@ -246,7 +301,11 @@ ivas_error ivas_ism_enc(
* CoreCoders encoding
*-----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ )
+#else
for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ )
+#endif
{
hSCE = st_ivas->hSCE[sce_id];
st = hSCE->hCoreCoder[0];
@@ -310,7 +369,11 @@ ivas_error ivas_ism_enc(
if ( dtx_flag )
{
+#ifdef MASA_AND_OBJECTS
+ for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ )
+#else
for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ )
+#endif
{
if ( sce_id != st_ivas->hISMDTX->sce_id_dtx )
{
@@ -328,7 +391,11 @@ ivas_error ivas_ism_enc(
int16_t id, n;
n = 0;
+#ifdef MASA_AND_OBJECTS
+ for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ )
+#else
for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ )
+#endif
{
if ( sce_id != st_ivas->hISMDTX->sce_id_dtx )
{
@@ -405,7 +472,12 @@ ivas_error ivas_ism_enc_config(
st_ivas->nSCE = st_ivas->nchan_transport;
st_ivas->nCPE = 0;
- if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL
+#ifdef MASA_AND_OBJECTS
+ ,
+ 0
+#endif
+ ) ) != IVAS_ERR_OK )
{
return error;
}
diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c
index ed43af153d0c8fc3294b60e8d156165ebb6c9c9c..0b8133ac34b42735b3919991afdfa77905a9d17e 100644
--- a/lib_enc/ivas_ism_metadata_enc.c
+++ b/lib_enc/ivas_ism_metadata_enc.c
@@ -168,7 +168,11 @@ static void rate_ism_importance(
*-------------------------------------------------------------------------*/
ivas_error ivas_ism_metadata_enc(
- const int32_t ism_total_brate, /* i : ISM total bitrate */
+#ifdef MASA_AND_OBJECTS
+ int32_t *ism_total_brate, /* i/o: ISM total bitrate */
+#else
+ const int32_t ism_total_brate, /* i : ISM total bitrate */
+#endif
const int16_t nchan_ism, /* i : number of ISM channels */
const int16_t nchan_transport, /* i : number of transport channels */
ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
@@ -179,6 +183,12 @@ ivas_error ivas_ism_metadata_enc(
const int16_t ism_mode, /* i : ISM mode */
const PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i : Param ISM Enc Handle */
const int16_t ism_extended_metadata_flag /* i : Extended metadata flag */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const float lp_noise_CPE,
+ const int16_t flag_omasa_ener_brate, /* i : less bitrate for objects in OMASA flag */
+ int16_t *omasa_stereo_sw_cnt
+#endif
)
{
int16_t i, ch, nb_bits_start = 0;
@@ -216,73 +226,104 @@ ivas_error ivas_ism_metadata_enc(
set_s( null_metadata_flag, 0, nchan_ism );
set_s( lowrate_metadata_flag, 0, nchan_ism );
- /*----------------------------------------------------------------*
- * Set Metadata presence / importance flag
- *----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /*----------------------------------------------------------------*
+ * Rate importance of particular ISM streams in combined format coding
+ *----------------------------------------------------------------*/
- for ( ch = 0; ch < nchan_ism; ch++ )
+ set_ism_importance_interformat( *ism_total_brate, nchan_transport, hIsmMeta, hSCE, lp_noise_CPE, ism_imp );
+ }
+ else
{
- if ( ism_mode == ISM_MODE_PARAM )
+#endif
+ /*----------------------------------------------------------------*
+ * Set Metadata presence / importance flag
+ *----------------------------------------------------------------*/
+
+ for ( ch = 0; ch < nchan_ism; ch++ )
{
- hIsmMeta[ch]->ism_metadata_flag = 1;
- }
+ if ( ism_mode == ISM_MODE_PARAM )
+ {
+ hIsmMeta[ch]->ism_metadata_flag = 1;
+ }
+#ifdef MASA_AND_OBJECTS
+ else if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC )
+#else
else if ( ism_mode == ISM_MODE_DISC )
- {
- null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
-
- if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
+#endif
{
- /* In case of low level noise for low bitrate inactive frames, do not sent metadata */
- hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10 || hSCE[ch]->hCoreCoder[0]->tcxonly;
+ null_metadata_flag[ch] = !hIsmMeta[ch]->ism_metadata_flag;
- /* in inactive frames, send MD 1) in ISM_MD_INC_DIFF_CNT_MAX consecutive frames when MD significantly change, 2) at least every ISM_MD_FEC_DIFF frames */
- if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
+ if ( hIsmMeta[ch]->ism_metadata_flag == 1 )
{
- if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
- ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_true_elevation ) > ISM_MD_FEC_DIFF ) || ( fabsf( hIsmMeta[ch]->radius - hIsmMeta[ch]->last_true_radius ) > ISM_MD_RAD_FEC_DIFF ) )
- {
- lowrate_metadata_flag[ch] = 1;
- hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
- }
- else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
+ /* In case of low level noise for low bitrate inactive frames, do not sent metadata */
+ hIsmMeta[ch]->ism_metadata_flag = vad_flag[ch] || hSCE[ch]->hCoreCoder[0]->lp_noise > 10 || hSCE[ch]->hCoreCoder[0]->tcxonly;
+
+ /* in inactive frames, send MD 1) in ISM_MD_INC_DIFF_CNT_MAX consecutive frames when MD significantly change, 2) at least every ISM_MD_FEC_DIFF frames */
+ if ( hIsmMeta[ch]->ism_metadata_flag == 0 )
{
- lowrate_metadata_flag[ch] = 1;
+ if ( ( fabsf( hIsmMeta[ch]->azimuth - hIsmMeta[ch]->last_true_azimuth ) > ISM_MD_FEC_DIFF ) ||
+ ( fabsf( hIsmMeta[ch]->elevation - hIsmMeta[ch]->last_true_elevation ) > ISM_MD_FEC_DIFF ) || ( fabsf( hIsmMeta[ch]->radius - hIsmMeta[ch]->last_true_radius ) > ISM_MD_RAD_FEC_DIFF ) )
+ {
+
+ lowrate_metadata_flag[ch] = 1;
- if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
+ hIsmMeta[ch]->ism_md_inc_diff_cnt = 0;
+ }
+ else if ( hIsmMeta[ch]->ism_md_inc_diff_cnt < ISM_MD_INC_DIFF_CNT_MAX )
{
- hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
+
+ lowrate_metadata_flag[ch] = 1;
+
+ if ( hIsmMeta[ch]->ism_md_inc_diff_cnt % 2 == 0 )
+ {
+ hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
+ }
+ else
+ {
+ hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
+ }
}
- else
+ else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
{
- hIsmMeta[ch]->position_angle.angle2_diff_cnt = ISM_FEC_MAX;
+
+ lowrate_metadata_flag[ch] = 1;
+
+ hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
}
}
- else if ( hIsmMeta[ch]->ism_md_fec_cnt_enc == ISM_MD_FEC_CNT_MAX )
- {
- lowrate_metadata_flag[ch] = 1;
- hIsmMeta[ch]->position_angle.angle1_diff_cnt = ISM_FEC_MAX;
- }
}
}
}
- }
- /*----------------------------------------------------------------*
- * Rate importance of particular ISM streams
- *----------------------------------------------------------------*/
+ /*----------------------------------------------------------------*
+ * Rate importance of particular ISM streams
+ *----------------------------------------------------------------*/
- rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
+ rate_ism_importance( nchan_transport, hIsmMeta, hSCE, lowrate_metadata_flag, ism_imp );
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
/*----------------------------------------------------------------*
* Write ISM common signaling
*----------------------------------------------------------------*/
- /* write number of objects - unary coding */
- for ( ch = 1; ch < nchan_ism; ch++ )
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode != ISM_MASA_MODE_DISC && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
{
- push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
+#endif
+ /* write number of objects - unary coding */
+ for ( ch = 1; ch < nchan_ism; ch++ )
+ {
+ push_indice( hBstr, IND_ISM_NUM_OBJECTS, 1, 1 );
+ }
+ push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
+#ifdef MASA_AND_OBJECTS
}
- push_indice( hBstr, IND_ISM_NUM_OBJECTS, 0, 1 );
+#endif
for ( ch = 0; ch < nchan_ism; ch++ )
{
@@ -292,7 +333,11 @@ ivas_error ivas_ism_metadata_enc(
}
/* write extended metadata presence flag */
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC && *ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
+#else
if ( ism_total_brate >= ISM_EXTENDED_METADATA_BRATE )
+#endif
{
push_indice( hBstr, IND_ISM_EXTENDED_FLAG, ism_extended_metadata_flag, ISM_EXTENDED_METADATA_BITS );
@@ -306,28 +351,42 @@ ivas_error ivas_ism_metadata_enc(
/* write ISM metadata flag (one per object) */
for ( ch = 0; ch < nchan_transport; ch++ )
{
- if ( null_metadata_flag[ch] )
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
{
- /* signal NULL metadata frame */
- push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS );
-
- /* write the ISM class to ISM_NO_META and again the true ISM class */
- push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
- push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
+ /* flags will be written in ivas_masa_encode() */
+ hIsmMeta[ch]->ism_imp = ism_imp[ch];
+ hIsmMeta[ch]->ism_md_null_flag = null_metadata_flag[ch];
+ hIsmMeta[ch]->ism_md_lowrate_flag = lowrate_metadata_flag[ch];
}
else
{
- push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
+#endif
+ if ( null_metadata_flag[ch] )
+ {
+ /* signal NULL metadata frame */
+ push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 1, ISM_METADATA_MD_FLAG_BITS );
- if ( ism_imp[ch] == ISM_NO_META )
+ /* write the ISM class to ISM_NO_META and again the true ISM class */
+ push_indice( hBstr, IND_ISM_METADATA_FLAG, ISM_NO_META, ISM_METADATA_FLAG_BITS );
+ push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
+ }
+ else
{
- /* signal low-rate ISM_NO_META frame */
- push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS );
+ push_indice( hBstr, IND_ISM_METADATA_FLAG, ism_imp[ch], ISM_METADATA_FLAG_BITS );
- /* signal presence of MD in low-rate ISM_NO_META frame */
- push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS );
+ if ( ism_imp[ch] == ISM_NO_META )
+ {
+ /* signal low-rate ISM_NO_META frame */
+ push_indice( hBstr, IND_ISM_MD_NULL_FLAG, 0, ISM_METADATA_MD_FLAG_BITS );
+
+ /* signal presence of MD in low-rate ISM_NO_META frame */
+ push_indice( hBstr, IND_ISM_MD_INACTIVE_FLAG, lowrate_metadata_flag[ch], ISM_METADATA_INACTIVE_FLAG_BITS );
+ }
}
+#ifdef MASA_AND_OBJECTS
}
+#endif
}
@@ -349,13 +408,18 @@ ivas_error ivas_ism_metadata_enc(
for ( ch = 0; ch < nchan_ism; ch++ )
{
hIsmMetaData = hIsmMeta[ch];
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
nb_bits_start = hBstr->nb_bits_tot;
}
if ( hIsmMeta[ch]->ism_metadata_flag || lowrate_metadata_flag[ch] )
{
+
/*----------------------------------------------------------------*
* Quantize and encode azimuth and elevation
*----------------------------------------------------------------*/
@@ -384,7 +448,11 @@ ivas_error ivas_ism_metadata_enc(
}
else
{
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
idx_angle1_abs = ism_quant_meta( hIsmMetaData->azimuth, &valQ, ism_azimuth_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_AZIMUTH_NBITS );
idx_angle2_abs = ism_quant_meta( hIsmMetaData->elevation, &valQ, ism_elevation_borders, ISM_Q_STEP, ISM_Q_STEP_BORDER, 1 << ISM_ELEVATION_NBITS );
@@ -413,7 +481,11 @@ ivas_error ivas_ism_metadata_enc(
}
/* save number of metadata bits written */
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MODE_DISC || ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+#else
if ( ism_mode == ISM_MODE_DISC )
+#endif
{
nb_bits_metadata[ch] = hBstr->nb_bits_tot - nb_bits_start;
}
@@ -546,14 +618,82 @@ ivas_error ivas_ism_metadata_enc(
}
}
+#ifdef MASA_AND_OBJECTS
+ /*----------------------------------------------------------------*
+ * Take into account the combined format bit-budget distribution
+ *----------------------------------------------------------------*/
+
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ int16_t bits_ism, bits_element[MAX_NUM_OBJECTS];
+ int16_t brate_limit_flag;
+ int32_t ism_total_brate_ref;
+ ism_total_brate_ref = *ism_total_brate;
+ brate_limit_flag = calculate_brate_limit_flag( ism_imp, nchan_ism );
+
+ bits_ism = (int16_t) ( *ism_total_brate / FRAMES_PER_SECOND );
+ set_s( bits_element, bits_ism / nchan_ism, nchan_ism );
+ bits_element[nchan_ism - 1] += bits_ism % nchan_ism;
+ bitbudget_to_brate( bits_element, element_brate, nchan_ism );
+
+ *ism_total_brate = 0;
+ for ( ch = 0; ch < nchan_ism; ch++ )
+ {
+ *ism_total_brate += ivas_interformat_brate( ism_mode, nchan_ism, hSCE[ch]->element_brate, ism_imp[ch], brate_limit_flag );
+
+ if ( ism_imp[ch] > 1 && flag_omasa_ener_brate == 1 && brate_limit_flag >= 0 )
+ {
+ *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
+ }
+
+ if ( brate_limit_flag == -1 && ism_imp[ch] >= 1 && nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
+ {
+ *ism_total_brate += ADJUST_ISM_BRATE_POS;
+ }
+ }
+ ism_metadata_flag_global = 1;
+
+ if ( ism_mode == ISM_MASA_MODE_DISC )
+ {
+ brate_limit_flag = 0;
+ for ( int16_t n = 0; n < nchan_ism; n++ )
+ {
+ brate_limit_flag += ism_imp[n];
+ }
+
+ if ( brate_limit_flag >= nchan_ism * ISM_HIGH_IMP - 2 )
+ {
+ *omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX;
+ }
+ }
+ }
+#endif
+
/*----------------------------------------------------------------*
* Configuration and decision about bitrates per channel
*----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else
+ {
+ if ( ( error = ivas_ism_config( *ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#else
if ( ( error = ivas_ism_config( ism_total_brate, nchan_transport, nchan_ism, hIsmMeta, ism_extended_metadata_flag, null_metadata_flag, ism_imp, element_brate, total_brate, nb_bits_metadata ) ) != IVAS_ERR_OK )
{
return error;
}
+#endif
for ( ch = 0; ch < nchan_ism; ch++ )
{
@@ -571,13 +711,47 @@ ivas_error ivas_ism_metadata_enc(
hIsmMeta[ch]->ism_md_inc_diff_cnt = min( hIsmMeta[ch]->ism_md_inc_diff_cnt, ISM_MD_INC_DIFF_CNT_MAX );
}
+#ifdef MASA_AND_OBJECTS
for ( ch = 0; ch < nchan_transport; ch++ )
{
hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
if ( ism_mode == ISM_MODE_DISC )
{
+#ifdef FIX_562_ISM2_64KBPS
if ( ism_imp[ch] == ISM_NO_META && ( ( total_brate[ch] < ACELP_8k00 && element_brate[ch] < SCE_CORE_16k_LOW_LIMIT ) ||
( total_brate[ch] <= ACELP_16k_LOW_LIMIT && element_brate[ch] >= SCE_CORE_16k_LOW_LIMIT ) ) )
+#else
+ if ( ism_imp[ch] == ISM_NO_META && total_brate[ch] < ACELP_8k00 )
+#endif
+ {
+ hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
+ }
+
+ hSCE[ch]->element_brate = element_brate[ch];
+ }
+ else if ( ism_mode == ISM_MASA_MODE_DISC || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ if ( ism_imp[ch] == ISM_INACTIVE_IMP )
+ {
+ hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
+ }
+ }
+
+ hSCE[ch]->hCoreCoder[0]->total_brate = total_brate[ch];
+
+ /* write metadata only in active frames */
+ if ( hSCE[0]->hCoreCoder[0]->core_brate > SID_2k40 )
+ {
+ reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot );
+ }
+ }
+#else
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ hSCE[ch]->hCoreCoder[0]->low_rate_mode = 0;
+ if ( ism_mode == ISM_MODE_DISC )
+ {
+ if ( hIsmMeta[ch]->ism_metadata_flag == 0 && localVAD[ch] == 0 && ism_metadata_flag_global )
{
hSCE[ch]->hCoreCoder[0]->low_rate_mode = 1;
}
@@ -592,6 +766,7 @@ ivas_error ivas_ism_metadata_enc(
reset_indices_enc( hSCE[ch]->hMetaData, hSCE[ch]->hMetaData->nb_ind_tot );
}
}
+#endif
pop_wmops();
@@ -614,18 +789,46 @@ ivas_error ivas_ism_metadata_enc_create(
int16_t ch, nchan_transport;
ivas_error error;
- if ( st_ivas->ism_mode == ISM_MODE_PARAM )
+#ifdef MASA_AND_OBJECTS
+ nchan_transport = st_ivas->nchan_transport;
+ if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
{
nchan_transport = MAX_PARAM_ISM_WAVE;
+ ivas_set_omasa_TC( st_ivas->ism_mode, n_ISms, &st_ivas->nSCE, &st_ivas->nCPE );
}
else
{
- nchan_transport = n_ISms;
- }
+#endif
+ if ( st_ivas->ism_mode == ISM_MODE_NONE )
+ {
+ nchan_transport = st_ivas->nchan_transport;
+
+ if ( nchan_transport == 1 )
+ {
+ st_ivas->nSCE = 1;
+ st_ivas->nCPE = 0;
+ }
+ else
+ {
+ st_ivas->nSCE = 0;
+ st_ivas->nCPE = 1;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MODE_PARAM )
+ {
+ nchan_transport = 2;
+ }
+ else
+ {
+ nchan_transport = n_ISms;
+ }
- st_ivas->nchan_transport = nchan_transport;
- st_ivas->nSCE = nchan_transport;
- st_ivas->nCPE = 0;
+ st_ivas->nchan_transport = nchan_transport;
+ st_ivas->nSCE = nchan_transport;
+ st_ivas->nCPE = 0;
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
/* allocate ISM metadata handles */
for ( ch = 0; ch < n_ISms; ch++ )
@@ -646,6 +849,14 @@ ivas_error ivas_ism_metadata_enc_create(
st_ivas->hIsmMetaData[ch]->radius_diff_cnt = ISM_FEC_MAX - 2;
st_ivas->hIsmMetaData[ch]->last_ism_metadata_flag = 0;
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hIsmMetaData[ch]->ism_imp = -1;
+ st_ivas->hIsmMetaData[ch]->ism_md_null_flag = 0;
+ st_ivas->hIsmMetaData[ch]->ism_md_lowrate_flag = 0;
+ st_ivas->hIsmMetaData[ch]->q_azimuth_old = 0.0f;
+ st_ivas->hIsmMetaData[ch]->q_elevation_old = 0.0f;
+#endif
+
ivas_ism_reset_metadata( st_ivas->hIsmMetaData[ch] );
st_ivas->hIsmMetaData[ch]->last_azimuth = 0.0f;
@@ -658,10 +869,37 @@ ivas_error ivas_ism_metadata_enc_create(
st_ivas->hIsmMetaData[ch]->last_true_radius = 1.0f;
}
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, 1, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ }
+ else
+ {
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL, 0 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+#else
if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, nchan_transport, n_ISms, NULL, 0, NULL, NULL, element_brate_tmp, NULL, NULL ) ) != IVAS_ERR_OK )
{
return error;
}
+#endif
return IVAS_ERR_OK;
}
diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c
index 7c99c491844d1622f27d41f07c057abe9167bfa8..c3d50d24db4d73de5ceceb14aef7fda314b246e1 100644
--- a/lib_enc/ivas_ism_param_enc.c
+++ b/lib_enc/ivas_ism_param_enc.c
@@ -222,9 +222,11 @@ void ivas_param_ism_stereo_dmx(
float alpha, azi_shift, tmp, tmp_1;
float cardioid_left[MAX_NUM_OBJECTS], cardioid_right[MAX_NUM_OBJECTS];
float stereo_dmx[2][L_FRAME48k];
+#ifdef FIX_549_DMX_GAIN
float dmx_gain, ene_dmx, ene_data, grad;
float last_dmx_gain;
float last_cardioid_left;
+#endif
ISM_METADATA_HANDLE hIsmMetaData;
push_wmops( "ivas_param_ism_st_dmx" );
@@ -232,10 +234,12 @@ void ivas_param_ism_stereo_dmx(
/*Initialization*/
alpha = 0.5;
azi_shift = 0;
+#ifdef FIX_549_DMX_GAIN
dmx_gain = 0;
ene_dmx = 0;
ene_data = 0;
last_dmx_gain = st_ivas->hDirAC->hParamIsm->last_dmx_gain;
+#endif
/* Set the stereo dmx to zero */
set_zero( stereo_dmx[0], L_FRAME48k );
@@ -245,11 +249,24 @@ void ivas_param_ism_stereo_dmx(
for ( i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
{
hIsmMetaData = st_ivas->hIsmMetaData[i];
+#ifdef FIX_549_DMX_GAIN
last_cardioid_left = st_ivas->hDirAC->hParamIsm->last_cardioid_left[i];
+#endif
/*Compute the Cardioids for the corresponding object direction */
tmp = hIsmMetaData->azimuth * ( EVS_PI / 180 );
tmp_1 = ( EVS_PI / 2 ) + azi_shift;
cardioid_left[i] = alpha + ( 1 - alpha ) * cosf( tmp - tmp_1 );
+#ifndef FIX_549_DMX_GAIN
+ cardioid_right[i] = alpha + ( 1 - alpha ) * cosf( tmp + tmp_1 );
+
+ /* Loop over all samples */
+ for ( j = 0; j < input_frame; j++ )
+ {
+ tmp = data[i][j];
+ stereo_dmx[0][j] += cardioid_left[i] * tmp; /* DMX Left */
+ stereo_dmx[1][j] += cardioid_right[i] * tmp; /* DMX Right */
+ }
+#else
if ( st_ivas->hSCE[0]->hCoreCoder[0]->ini_frame > 0 )
{
float last_cardioid_right;
@@ -289,8 +306,10 @@ void ivas_param_ism_stereo_dmx(
}
}
st_ivas->hDirAC->hParamIsm->last_cardioid_left[i] = cardioid_left[i];
+#endif
}
+#ifdef FIX_549_DMX_GAIN
/* Energy compensation */
for ( j = 0; j < input_frame; j++ )
{
@@ -323,6 +342,7 @@ void ivas_param_ism_stereo_dmx(
}
}
st_ivas->hDirAC->hParamIsm->last_dmx_gain = dmx_gain;
+#endif
/* Copy the stereo dmx to data variable */
mvr2r( stereo_dmx[0], data[0], input_frame );
mvr2r( stereo_dmx[1], data[1], input_frame );
diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc.c
index 75952fe62c5ea06d896707ac409689035d724909..61072cc1872212f424a15b3c834be118c48b8bb9 100644
--- a/lib_enc/ivas_lfe_enc.c
+++ b/lib_enc/ivas_lfe_enc.c
@@ -344,6 +344,10 @@ void ivas_lfe_enc(
zero_pad_len = hLFE->pWindow_state->zero_pad_len;
pWindow_coeffs = hLFE->pWindow_state->pWindow_coeffs;
+#ifndef FIX_572_LFE_LPF_ENC
+ /*Low Pass Filter */
+ ivas_filter_process( &hLFE->filter_state, data_lfe_ch, input_frame );
+#endif
/* Windowing */
ivas_dct_windowing( fade_len, full_len, dct_len, zero_pad_len, pWindow_coeffs, input_frame, wtda_audio, hLFE->old_wtda_audio, data_lfe_ch );
@@ -378,6 +382,9 @@ ivas_error ivas_create_lfe_enc(
{
int16_t input_frame;
LFE_ENC_HANDLE hLFE;
+#ifndef FIX_572_LFE_LPF_ENC
+ const float *filt_coeff;
+#endif
int16_t i, j;
input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC );
@@ -419,6 +426,10 @@ ivas_error ivas_create_lfe_enc(
lfe_window_init( hLFE->pWindow_state, input_Fs, input_frame );
+#ifndef FIX_572_LFE_LPF_ENC
+ ivas_lfe_lpf_select_filt_coeff( input_Fs, IVAS_FILTER_ORDER_4, &filt_coeff );
+ ivas_filters_init( &hLFE->filter_state, filt_coeff, IVAS_FILTER_ORDER_4 );
+#endif
/* Initialization for entropy coding */
hLFE->cum_freq_models[0][0] = ivas_str_lfe_freq_models.entropy_coder_model_fine_sg1;
@@ -478,6 +489,7 @@ void ivas_lfe_enc_close(
return;
}
+#ifdef FIX_572_LFE_LPF_ENC
/*-------------------------------------------------------------------------
* ivas_create_lfe_lpf_enc()
*
@@ -551,3 +563,4 @@ void ivas_lfe_lpf_enc_apply(
return;
}
+#endif
diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c
index ec8c22bcd9d52bc3ce6047bcd9014350e329e51c..abe899a7945d51bf42e985ce441a678aef6435f3 100644
--- a/lib_enc/ivas_masa_enc.c
+++ b/lib_enc/ivas_masa_enc.c
@@ -47,8 +47,9 @@
static void combine_freqbands_and_subframes( MASA_ENCODER_HANDLE hMasa );
+#ifndef MASA_AND_OBJECTS
static void combine_directions( MASA_ENCODER_HANDLE hMasa );
-
+#endif
static void find_n_largest( const float *input, int16_t *largestIndices, const int16_t numElements, const int16_t numLargest );
static void move_metadata_to_qmetadata( const MASA_ENCODER_HANDLE hMasa, IVAS_QMETADATA_HANDLE hQMeta );
@@ -59,7 +60,13 @@ static void compensate_energy_ratios( MASA_ENCODER_HANDLE hMasa );
static int16_t encode_lfe_to_total_energy_ratio( MASA_ENCODER_HANDLE hMasa, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate );
+#ifdef MASA_AND_OBJECTS
+static void ivas_encode_masaism_metadata( MASA_ENCODER_HANDLE hMasa, IVAS_QMETADATA_HANDLE hQMetaData, BSTR_ENC_HANDLE hMetaData, ISM_METADATA_HANDLE hIsmMeta[], const int16_t low_bitrate_mode, const int16_t omasa_nbands, const int16_t omasa_nblocks, const int16_t idx_separated_object, const int16_t ism_imp );
+
static void reduce_metadata_further( MASA_ENCODER_HANDLE hMasa, IVAS_QMETADATA_HANDLE hqmetadata, const IVAS_FORMAT ivas_format );
+#else
+static void reduce_metadata_further( MASA_ENCODER_HANDLE hMasa, IVAS_QMETADATA_HANDLE hqmetadata, const IVAS_FORMAT ivas_format );
+#endif
static void average_masa_metadata( MASA_METADATA_FRAME *masaMetadata, float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], const SPHERICAL_GRID_DATA *sphGrid, const uint8_t useSphGrid );
@@ -98,6 +105,9 @@ ivas_error ivas_masa_enc_open(
MASA_ENCODER_HANDLE hMasa;
ENCODER_CONFIG_HANDLE hEncoderConfig;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#endif
error = IVAS_ERR_OK;
@@ -107,9 +117,14 @@ ivas_error ivas_masa_enc_open(
}
hEncoderConfig = st_ivas->hEncoderConfig;
+
generate_gridEq( &( hMasa->data.Sph_Grid16 ) );
+#ifdef MASA_AND_OBJECTS
+ if ( hEncoderConfig->ivas_format == MASA_FORMAT || hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+#else
if ( hEncoderConfig->ivas_format == MASA_FORMAT )
+#endif
{
hMasa->data.num_Cldfb_instances = st_ivas->nchan_transport;
}
@@ -126,7 +141,23 @@ ivas_error ivas_masa_enc_open(
}
}
- ivas_masa_set_elements( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+#ifdef MASA_AND_OBJECTS
+ ism_total_brate = 0;
+ if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ for ( i = 0; i < st_ivas->nSCE; i++ )
+ {
+ ism_total_brate += st_ivas->hSCE[i]->element_brate;
+ }
+ }
+#endif
+
+ ivas_masa_set_elements( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE
+#ifdef MASA_AND_OBJECTS
+ ,
+ hEncoderConfig->ivas_format, st_ivas->ism_mode, ism_total_brate
+#endif
+ );
mvs2s( DirAC_block_grouping, hMasa->config.block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
mvs2s( MASA_band_grouping_24, hMasa->config.band_grouping, MASA_FREQUENCY_BANDS + 1 );
@@ -148,6 +179,12 @@ ivas_error ivas_masa_enc_open(
set_zero( hMasa->data.dir_align_state.previous_azi_dir2, MASA_FREQUENCY_BANDS );
set_zero( hMasa->data.dir_align_state.previous_ele_dir2, MASA_FREQUENCY_BANDS );
+#ifdef MASA_AND_OBJECTS
+ hMasa->data.lp_noise_CPE = -1;
+ hMasa->data.omasa_stereo_sw_cnt = OMASA_STEREO_SW_CNT_MAX;
+ hMasa->data.omasa_stereo_sw_cnt2 = OMASA_STEREO_SW_CNT_MAX2;
+#endif
+
st_ivas->hMasa = hMasa;
return error;
@@ -199,16 +236,36 @@ ivas_error ivas_masa_encode(
const int32_t ivas_total_brate, /* i : IVAS total bitrate */
const int16_t Opt_DTX_ON, /* i : DTX on flag */
const int16_t element_mode /* i : element mode */
+#ifdef MASA_AND_OBJECTS
+ ,
+ const ISM_MODE ism_mode, /* i : ISM format mode */
+ const int16_t nchan_ism, /* i : number of ISM channels */
+ ISM_METADATA_HANDLE hIsmMetaData[MAX_NUM_OBJECTS], /* i : ISM metadata handle */
+ const int16_t idx_separated_object, /* i : index of the separated object */
+ OMASA_ENC_HANDLE hOMasa, /* i : OMASA encoder handle */
+ const int16_t ism_imp /* i : importance of separated object */
+ ,
+ const int16_t flag_omasa_ener_brate /* i : less bitrate for objects in OMASA flag */
+#endif
)
{
MASA_DIRECTIONAL_SPATIAL_META *h_orig_metadata;
int16_t i, j;
int16_t masa_sid_descriptor;
+#ifdef MASA_AND_OBJECTS
+ int16_t low_bitrate_mode;
+ int32_t masa_total_brate;
+#endif
masa_sid_descriptor = -1;
h_orig_metadata = NULL;
+#ifdef MASA_AND_OBJECTS
+ low_bitrate_mode = 0;
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
/* Create the MASA SID descriptor for the metadata and CPE mode, in order to have the SID frame self-contained. */
if ( Opt_DTX_ON && hQMetaData != NULL )
@@ -245,7 +302,11 @@ ivas_error ivas_masa_encode(
}
}
- if ( ivas_format == MASA_FORMAT && ivas_total_brate >= IVAS_384k )
+#ifdef MASA_AND_OBJECTS
+ if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && ivas_total_brate >= IVAS_384k )
+#else
+ if ( ( ivas_format == MASA_FORMAT ) && ivas_total_brate >= IVAS_384k )
+#endif
{
hMasa->config.mergeRatiosOverSubframes = 0;
}
@@ -254,10 +315,22 @@ ivas_error ivas_masa_encode(
combine_freqbands_and_subframes( hMasa );
}
+#ifdef MASA_AND_OBJECTS
+ if ( hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands < hMasa->config.numCodingBands && ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) )
+#else
if ( hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands < hMasa->config.numCodingBands && ivas_format == MASA_FORMAT )
+#endif
{
+#ifdef MASA_AND_OBJECTS
+ if ( ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE && ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) || ( ivas_format != MASA_ISM_FORMAT ) )
+ {
+ /* Combine directions */
+ ivas_masa_combine_directions( hMasa );
+ }
+#else
/* Combine directions */
combine_directions( hMasa );
+#endif
/* If we joined all bands, then metadata is now one directional. */
if ( hMasa->config.numTwoDirBands == 0 )
@@ -270,12 +343,140 @@ ivas_error ivas_masa_encode(
/* Reset qmetadata bit budget */
hQMetaData->metadata_max_bits = hMasa->config.max_metadata_bits;
-
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
+#ifndef MASA_AND_OBJECTS
/* write the number of MASA transport channels */
push_next_indice( hMetaData, nchan_transport - 1, MASA_TRANSP_BITS );
hQMetaData->metadata_max_bits -= MASA_TRANSP_BITS;
+#endif
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && ism_mode != ISM_MODE_NONE )
+ {
+ /* write the number of objects in ISM_MASA format*/
+ push_next_indice( hMetaData, nchan_ism - 1, NO_BITS_MASA_ISM_NO_OBJ );
+ hQMetaData->metadata_max_bits -= NO_BITS_MASA_ISM_NO_OBJ;
+
+ /* write index of separated object if needed */
+ if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && hMasa->data.nchan_ism > 1 )
+ {
+ push_next_indice( hMetaData, idx_separated_object, NO_BITS_MASA_ISM_NO_OBJ );
+ hQMetaData->metadata_max_bits -= NO_BITS_MASA_ISM_NO_OBJ;
+ }
+
+ /* write ISM importance flag (one per object) */
+ if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+ }
+ else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+#ifdef MASA_AND_OBJECTS
+ if ( hIsmMetaData[0]->ism_md_null_flag )
+ {
+ /* signal NULL metadata frame */
+ push_next_indice( hMetaData, 1, ISM_METADATA_MD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_MD_FLAG_BITS;
+
+ /* write the ISM class to ISM_NO_META and again the true ISM class */
+ push_next_indice( hMetaData, ISM_NO_META, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+ }
+ else
+ {
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+
+ if ( hIsmMetaData[0]->ism_imp == ISM_NO_META )
+ {
+ /* signal low-rate ISM_NO_META frame */
+ push_next_indice( hMetaData, 0, ISM_METADATA_MD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_MD_FLAG_BITS;
+
+ /* signal presence of MD in low-rate ISM_NO_META frame */
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_md_lowrate_flag, ISM_METADATA_INACTIVE_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_INACTIVE_FLAG_BITS;
+ }
+ }
+#else
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+
+ if ( hIsmMetaData[0]->ism_metadata_flag == 0 )
+ {
+ /* write VAD flag */
+ push_next_indice( hMetaData, hIsmMetaData[0]->ism_vad_flag, ISM_METADATA_VAD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_VAD_FLAG_BITS;
+ }
+#endif
+ }
+ else if ( ism_mode == ISM_MASA_MODE_DISC )
+ {
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+#ifdef MASA_AND_OBJECTS
+ if ( hIsmMetaData[i]->ism_md_null_flag )
+ {
+ /* signal NULL metadata frame */
+ push_next_indice( hMetaData, 1, ISM_METADATA_MD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_MD_FLAG_BITS;
+
+ /* write the ISM class to ISM_NO_META and again the true ISM class */
+ push_next_indice( hMetaData, ISM_NO_META, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+ push_next_indice( hMetaData, hIsmMetaData[i]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+ }
+ else
+ {
+ push_next_indice( hMetaData, hIsmMetaData[i]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+
+ if ( hIsmMetaData[i]->ism_imp == ISM_NO_META )
+ {
+ /* signal low-rate ISM_NO_META frame */
+ push_next_indice( hMetaData, 0, ISM_METADATA_MD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_MD_FLAG_BITS;
+
+ /* signal presence of MD in low-rate ISM_NO_META frame */
+ push_next_indice( hMetaData, hIsmMetaData[i]->ism_md_lowrate_flag, ISM_METADATA_INACTIVE_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_INACTIVE_FLAG_BITS;
+ }
+ }
+#else
+ push_next_indice( hMetaData, hIsmMetaData[i]->ism_imp, ISM_METADATA_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_FLAG_BITS;
+
+ if ( hIsmMetaData[i]->ism_metadata_flag == 0 )
+ {
+ /* write VAD flag */
+ push_next_indice( hMetaData, hIsmMetaData[i]->ism_vad_flag, ISM_METADATA_VAD_FLAG_BITS );
+ hQMetaData->metadata_max_bits -= ISM_METADATA_VAD_FLAG_BITS;
+ }
+#endif
+ }
+
+ if ( ivas_total_brate == IVAS_128k && nchan_ism >= 3 )
+ {
+ push_next_indice( hMetaData, flag_omasa_ener_brate, 1 );
+ hQMetaData->metadata_max_bits -= 1;
+ }
+ }
+ }
+ else
+ {
+ /* write the number of MASA transport channels */
+ push_next_indice( hMetaData, nchan_transport - 1, MASA_TRANSP_BITS );
+ hQMetaData->metadata_max_bits -= MASA_TRANSP_BITS;
+ }
+#endif
/* write placeholder data for descriptive metadata */
push_next_indice( hMetaData, 0, MASA_HEADER_BITS );
@@ -298,21 +499,64 @@ ivas_error ivas_masa_encode(
}
/* Move data from encoder to qmetadata */
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
move_metadata_to_qmetadata( hMasa, hQMetaData );
}
if ( hMasa->config.max_metadata_bits < MINIMUM_BIT_BUDGET_NORMAL_META && !hMasa->config.joinedSubframes )
{
+#ifdef MASA_AND_OBJECTS
reduce_metadata_further( hMasa, hQMetaData, ivas_format );
+ low_bitrate_mode = ( ivas_total_brate <= 32000 );
+#else
+ reduce_metadata_further( hMasa, hQMetaData, ivas_format );
+#endif
+
/* Write low bitrate mode. 1 signals that we have merged through time, 0 signals merge through frequency. */
push_next_indice( hMetaData, hQMetaData->q_direction[0].cfg.nblocks == 1 ? 1 : 0, MASA_LOWBITRATE_MODE_BITS );
hQMetaData->metadata_max_bits -= MASA_LOWBITRATE_MODE_BITS;
}
+#ifdef MASA_AND_OBJECTS
+ /* Encode MASA+ISM metadata */
+ if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ /* encode MASA/ISM energy ratios */
+ ivas_encode_masaism_metadata( hMasa, hQMetaData, hMetaData, hIsmMetaData, low_bitrate_mode, hOMasa->nCodingBands, hOMasa->nSubframes,
+ idx_separated_object, ism_imp );
+ }
+ else
+ {
+ hQMetaData->masa_to_total_energy_ratio[0][0] = -1; /* signals NOT to adjust the energy ratios */
+ }
+#endif
+
/* Encode metadata */
+#ifdef MASA_AND_OBJECTS
+ masa_total_brate = ivas_total_brate;
+ if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MASA_MODE_DISC )
+ {
+ masa_total_brate = calculate_cpe_brate_MASA_ISM( ism_mode, ivas_total_brate, nchan_ism );
+ }
+
+ if ( masa_total_brate >= IVAS_384k )
+ {
+ if ( masa_total_brate >= IVAS_512k )
+ {
+ ivas_qmetadata_enc_encode_hr_384_512( hMetaData, hQMetaData, 16, 4 );
+ }
+ else
+ {
+ ivas_qmetadata_enc_encode_hr_384_512( hMetaData, hQMetaData, 11, 3 );
+ }
+ }
+#else
if ( ivas_total_brate >= IVAS_384k )
{
if ( ivas_total_brate >= IVAS_512k )
@@ -324,11 +568,20 @@ ivas_error ivas_masa_encode(
ivas_qmetadata_enc_encode_hr_384_512( hMetaData, hQMetaData, 11, 3 );
}
}
+#endif
else
{
ivas_qmetadata_enc_encode( hMetaData, hQMetaData, 0 );
}
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ /* Modify spatial metadata based on the MASA-to-total energy ratios */
+ modify_masa_energy_ratios( hQMetaData );
+ }
+
+#endif
*nb_bits_metadata = hMetaData->nb_bits_tot;
if ( ivas_format == MASA_FORMAT && Opt_DTX_ON )
@@ -362,7 +615,11 @@ ivas_error ivas_masa_encode(
if ( hMasa->config.numberOfDirections == 2 && hMasa->config.numTwoDirBands < hMasa->config.numCodingBands )
{
/* Combine directions */
+#ifdef MASA_AND_OBJECTS
+ ivas_masa_combine_directions( hMasa );
+#else
combine_directions( hMasa );
+#endif
/* If we joined all bands, then metadata is now one directional. */
if ( hMasa->config.numTwoDirBands == 0 )
@@ -486,6 +743,12 @@ ivas_error ivas_masa_enc_config(
uint8_t maxBand;
int16_t maxBin, sf;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#ifdef OMASA_FIX_LOW_FS
+ int32_t masa_total_brate;
+#endif
+#endif
error = IVAS_ERR_OK;
@@ -494,10 +757,30 @@ ivas_error ivas_masa_enc_config(
ivas_format = st_ivas->hEncoderConfig->ivas_format;
ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
- ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE );
+#ifdef MASA_AND_OBJECTS
+ ism_total_brate = 0;
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ for ( i = 0; i < st_ivas->nSCE; i++ )
+ {
+ ism_total_brate += st_ivas->hSCE[i]->element_brate;
+ }
+ }
+#endif
+
+ ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->hEncoderConfig->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE
+#ifdef MASA_AND_OBJECTS
+ ,
+ ivas_format, st_ivas->ism_mode, ism_total_brate
+#endif
+ );
hQMetaData->is_masa_ivas_format = 1;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == MASA_FORMAT )
+#endif
{
masa_metadata_direction_alignment( hMasa );
@@ -522,7 +805,18 @@ ivas_error ivas_masa_enc_config(
hMasa->config.numberOfDirections = 1;
}
- ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, ivas_total_brate, st_ivas->nchan_transport, ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) );
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+ ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, st_ivas->hCPE[0]->element_brate, st_ivas->nchan_transport, MC_MODE_NONE );
+ }
+ else
+ {
+#endif
+ ivas_masa_set_coding_config( &( hMasa->config ), hMasa->data.band_mapping, ivas_total_brate, st_ivas->nchan_transport, ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) );
+#ifdef MASA_AND_OBJECTS
+ }
+#endif
/* Setup importance weights for two-direction band selection. */
if ( hMasa->config.numberOfDirections == 2 )
@@ -607,7 +901,21 @@ ivas_error ivas_masa_enc_config(
}
maxBand--;
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hQMetaData->q_direction->cfg.inactiveBands = 0;
+#ifdef OMASA_FIX_LOW_FS
+ masa_total_brate = ivas_total_brate;
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ masa_total_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->hEncoderConfig->nchan_ism );
+ }
+ if ( masa_total_brate >= IVAS_384k && ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) )
+#else
+ if ( ivas_total_brate > IVAS_256k && ivas_format == MASA_FORMAT )
+#endif
+#else
if ( ivas_total_brate > IVAS_256k )
+#endif
{
int16_t continueLoop;
continueLoop = 1;
@@ -636,8 +944,12 @@ ivas_error ivas_masa_enc_config(
st_ivas->hQMetaData->q_direction->cfg.inactiveBands = 0;
}
}
+#ifdef OMASA_FIX_LOW_FS
+ masa_sample_rate_band_correction( &( hMasa->config ), hMasa->data.band_mapping, hQMetaData, maxBand, masa_total_brate >= IVAS_384k, NULL );
+#else
masa_sample_rate_band_correction( &( hMasa->config ), hMasa->data.band_mapping, hQMetaData, maxBand, ivas_total_brate > IVAS_256k, NULL );
+#endif
if ( hMasa->config.numTwoDirBands >= hMasa->config.numCodingBands )
{
@@ -647,10 +959,32 @@ ivas_error ivas_masa_enc_config(
/* Transmit stereo signals using a mono downmix at lowest bitrates */
+#ifdef MASA_AND_OBJECTS
+ if ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
+#else
if ( ivas_format == MASA_FORMAT && st_ivas->nCPE == 1 && st_ivas->hCPE[0]->hStereoDft != NULL && st_ivas->hCPE[0]->hStereoDft->hConfig != NULL )
+#endif
{
+#ifdef MASA_AND_OBJECTS
+ st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ( ivas_total_brate - ism_total_brate < MASA_STEREO_MIN_BITRATE ) ? 1 : 0;
+#else
st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0;
+#endif
+ }
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ if ( st_ivas->hCPE[0]->element_mode == IVAS_CPE_DFT || st_ivas->hMasa->data.omasa_stereo_sw_cnt < OMASA_STEREO_SW_CNT_MAX )
+ {
+ st_ivas->hMasa->data.lp_noise_CPE = st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise;
+ }
+ else
+ {
+ st_ivas->hMasa->data.lp_noise_CPE = ( st_ivas->hCPE[0]->hCoreCoder[0]->lp_noise + st_ivas->hCPE[0]->hCoreCoder[1]->lp_noise ) / CPE_CHANNELS;
+ }
}
+#endif
return error;
}
@@ -886,8 +1220,11 @@ static void combine_freqbands_and_subframes(
return;
}
-
+#ifdef MASA_AND_OBJECTS
+void ivas_masa_combine_directions(
+#else
static void combine_directions(
+#endif
MASA_ENCODER_HANDLE hMasa )
{
int16_t i, j, k;
@@ -1003,7 +1340,9 @@ static void combine_directions(
ambience2dir = 1.0f - ratioSum;
hMeta->directional_meta[0].energy_ratio[j][i] = sumVecLen[j][i] / ( hMeta->directional_meta[0].energy_ratio[j][i] + hMeta->directional_meta[1].energy_ratio[j][i] + ambience2dir / 2.0f );
-
+#ifdef MASA_AND_OBJECTS
+ hMeta->directional_meta[1].energy_ratio[j][i] = 0.0f;
+#endif
if ( computeCoherence )
{
ambience1dir = 1.0f - hMeta->directional_meta[0].energy_ratio[j][i];
@@ -1338,7 +1677,11 @@ static void reduce_metadata_further(
/* Get energy for the input data in 4-subframe, 5-band format */
totalEnergySum = 0.0f;
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) /* Energy data is in 4-subframe, 24-band format */
+#else
if ( ivas_format == MASA_FORMAT ) /* Energy data is in 4-subframe, 24-band format */
+#endif
{
for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
{
@@ -1717,9 +2060,23 @@ void ivas_masa_enc_reconfigure(
int16_t n, tmp;
int16_t sce_id, cpe_id;
int32_t ivas_total_brate;
+#ifdef MASA_AND_OBJECTS
+ int32_t ism_total_brate;
+#endif
ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate;
+#ifdef MASA_AND_OBJECTS
+ ism_total_brate = 0;
+ if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT && st_ivas->nSCE > 0 && ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) )
+ {
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ ism_total_brate += st_ivas->hSCE[sce_id]->element_brate;
+ }
+ }
+#endif
+
if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate )
{
for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
@@ -1740,6 +2097,16 @@ void ivas_masa_enc_reconfigure(
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 MASA_AND_OBJECTS
+ if ( ivas_total_brate - ism_total_brate < MASA_STEREO_MIN_BITRATE || ivas_total_brate - ism_total_brate < MIN_BRATE_MDCT_STEREO )
+ {
+ st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_DFT;
+ }
+ else
+ {
+ st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_MDCT;
+ }
+#else
if ( ivas_total_brate < MASA_STEREO_MIN_BITRATE )
{
st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_DFT;
@@ -1752,9 +2119,15 @@ void ivas_masa_enc_reconfigure(
{
st_ivas->hCPE[cpe_id]->element_mode = IVAS_CPE_MDCT;
}
+#endif
}
- ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp );
+ ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, st_ivas->hQMetaData, &tmp, &tmp, &tmp
+#ifdef MASA_AND_OBJECTS
+ ,
+ st_ivas->hEncoderConfig->ivas_format, st_ivas->ism_mode, ism_total_brate
+#endif
+ );
}
return;
@@ -1943,11 +2316,12 @@ static void copy_masa_metadata(
* Compare the similarity of MASA metadata in two sub-frames
*-------------------------------------------------------------------*/
+/* r: similarity decision */
static uint8_t are_masa_subframes_similar(
const MASA_METADATA_HANDLE frame1, /* i : MASA metadata frame 1 */
const uint8_t sf1_idx, /* i : index of the subframe of frame1 to inspect */
const MASA_METADATA_HANDLE frame2, /* i : MASA metadata frame 2 */
- const uint8_t sf2_idx /* o : index of the subframe of frame2 to inspect */
+ const uint8_t sf2_idx /* i : index of the subframe of frame2 to inspect */
)
{
uint8_t num_dir;
@@ -2130,7 +2504,7 @@ static void detect_framing_async(
else if ( n_sim_stop == 3 )
{
/* first sub-frame different that the rest 3
- => make a risky guess that the future sf would be the same too and we're in an offset case */
+ => make a risky guess that the future sf would be the same too and we're in an offset case */
frame_mode = MASA_FRAME_1SF;
found_offset = 3;
}
@@ -2328,3 +2702,1106 @@ static void masa_metadata_direction_alignment(
return;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------*
+ * ivas_merge_masa_metadata()
+ *
+ *
+ *-------------------------------------------------------------------*/
+
+void ivas_merge_masa_metadata(
+ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA enc handle. source for MASA metadata and combined metadata will be here */
+ OMASA_SPATIAL_META_HANDLE hOMasaMeta /* i : ISM-object metadata to be merged with the MASA metadata */
+)
+{
+ int16_t sf, band;
+ uint8_t numCodingBands;
+ uint8_t numDirections;
+ uint8_t numSf;
+ MASA_METADATA_HANDLE hMeta;
+ float energyTimesRatioISM;
+ float energyTimesRatioMASA[2];
+ float total_diff_nrg;
+ int16_t brange[2];
+ float eneBand;
+ float energyMerged[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
+ int16_t bin;
+
+ numCodingBands = hMasa->config.numCodingBands;
+ numDirections = hMasa->config.numberOfDirections;
+ numSf = hMasa->config.joinedSubframes == TRUE ? 1 : 4;
+ hMeta = &( hMasa->masaMetadata );
+
+
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ int16_t merge_dest;
+ float dir_sum;
+ uint8_t band_n_dirs;
+ brange[0] = band;
+ brange[1] = band + 1;
+ /* TODO: if this stays, remove the unnecessary range loop from the code */
+ if ( numDirections == 1 || ( numDirections == 2 && hMasa->data.twoDirBands[band] == 0 ) )
+ {
+ band_n_dirs = 1;
+ }
+ else
+ {
+ band_n_dirs = 2;
+ }
+
+ /* Compute energies */
+ /* MASA energy is in the full 24 band resolution, whereas the ISM energy is already in the coding band resolution */
+ eneBand = 0.0f;
+ for ( bin = brange[0]; bin < brange[1]; bin++ )
+ {
+ eneBand += hMasa->data.energy[sf][bin];
+ }
+ energyMerged[sf][band] = eneBand + hMasa->data.energy_ism[sf][band];
+
+ /* Compute weights */
+ energyTimesRatioMASA[0] = eneBand * hMeta->directional_meta[0].energy_ratio[sf][band];
+ if ( band_n_dirs == 2 )
+ {
+ energyTimesRatioMASA[1] = eneBand * hMeta->directional_meta[1].energy_ratio[sf][band];
+ }
+ else
+ {
+ energyTimesRatioMASA[1] = 0.0f;
+ }
+ /* target is original MASA diffuseness */
+ total_diff_nrg = eneBand * hMeta->common_meta.diffuse_to_total_ratio[sf][band];
+ /* criterion is mean of ISM ratio and new ratio */
+ energyTimesRatioISM = ( hOMasaMeta->directional_meta[0].energy_ratio[sf][band] + ( 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.energy_ism[sf][band] ) ) ) / 2.0f * hMasa->data.energy_ism[sf][band];
+
+ /* Determine combined metadata based on the weights */
+ merge_dest = -1;
+ if ( ( band_n_dirs == 1 && energyTimesRatioMASA[0] < energyTimesRatioISM ) ||
+ ( band_n_dirs == 2 && energyTimesRatioMASA[0] < energyTimesRatioMASA[1] && energyTimesRatioMASA[0] < energyTimesRatioISM ) )
+ {
+ /* 1dir and ISM the most energetic, or 2dir and ISM the more energetic than MASA1 */
+ merge_dest = 0;
+ }
+ else if ( band_n_dirs == 2 && energyTimesRatioMASA[1] <= energyTimesRatioMASA[0] && energyTimesRatioMASA[1] < energyTimesRatioISM )
+ {
+ /* 2dir and ISM the most energetic and MASA2 the least energetic */
+ merge_dest = 1;
+ }
+
+ if ( merge_dest >= 0 ) /* replace one MASA with ISM */
+ {
+ hMeta->directional_meta[merge_dest].azimuth[sf][band] = hOMasaMeta->directional_meta[0].azimuth[sf][band];
+ hMeta->directional_meta[merge_dest].elevation[sf][band] = hOMasaMeta->directional_meta[0].elevation[sf][band];
+ /* limit with the earlier direct-energy ratio */
+ dir_sum = 1.0f - total_diff_nrg / ( EPSILON + eneBand + hMasa->data.energy_ism[sf][band] ); /* new dir ratio */
+ hMeta->directional_meta[merge_dest].energy_ratio[sf][band] = min( dir_sum, hOMasaMeta->directional_meta[0].energy_ratio[sf][band] ); /* clip with original ISM dir */
+ hMeta->common_meta.diffuse_to_total_ratio[sf][band] = 1.0f - hMeta->directional_meta[merge_dest].energy_ratio[sf][band];
+
+ if ( hMasa->config.useCoherence ) /* TODO: is this correct condition? */
+ {
+ hMeta->directional_meta[merge_dest].spread_coherence[sf][band] = hOMasaMeta->directional_meta[0].spread_coherence[sf][band];
+ hMeta->common_meta.surround_coherence[sf][band] = hOMasaMeta->common_meta.surround_coherence[sf][band];
+ }
+
+ /* recompute direct energy ratios to match the diffuse ratio */
+ float direct_quota, direct_scaler;
+ direct_quota = 1.0f - hMeta->common_meta.diffuse_to_total_ratio[sf][band];
+ if ( band_n_dirs == 1 )
+ {
+ hMeta->directional_meta[0].energy_ratio[sf][band] = direct_quota;
+ }
+ else
+ {
+ dir_sum = hMeta->directional_meta[0].energy_ratio[sf][band] + hMeta->directional_meta[1].energy_ratio[sf][band];
+ direct_scaler = direct_quota / ( EPSILON + dir_sum );
+ hMeta->directional_meta[0].energy_ratio[sf][band] *= direct_scaler;
+ hMeta->directional_meta[1].energy_ratio[sf][band] *= direct_scaler;
+ }
+ }
+ }
+ }
+
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ hMasa->data.energy[sf][band] = energyMerged[sf][band];
+ }
+ }
+
+ return;
+}
+
+
+static void quantize_ratio_ism_vector(
+ const float *ratio_ism,
+ int16_t *idx,
+ const int16_t nchan_ism,
+ const float masa_to_total_energy_ratio,
+ const int16_t idx_sep_object )
+{
+ int16_t i, j, best_i, best_i2;
+ float dist, div, tmp, dist2, best_dist;
+ int16_t part_idx_sum, max_sum_idx;
+ float ratio_ism_loc[MAX_NUM_OBJECTS];
+ int16_t no_ism_loc;
+
+ max_sum_idx = ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1;
+
+ if ( idx_sep_object > -1 )
+ {
+ if ( ratio_ism[idx_sep_object] < 1.0f / (float) ( max_sum_idx ) )
+ {
+ /* take it out from quantize function */
+ mvr2r( ratio_ism, ratio_ism_loc, idx_sep_object );
+ mvr2r( &ratio_ism[idx_sep_object + 1], &ratio_ism_loc[idx_sep_object], nchan_ism - idx_sep_object - 1 );
+ no_ism_loc = nchan_ism - 1;
+ }
+ else
+ {
+ no_ism_loc = nchan_ism;
+ mvr2r( ratio_ism, ratio_ism_loc, nchan_ism );
+ }
+ }
+ else
+ {
+ no_ism_loc = nchan_ism;
+ mvr2r( ratio_ism, ratio_ism_loc, nchan_ism );
+ }
+
+ if ( nchan_ism > 1 )
+ {
+ if ( masa_to_total_energy_ratio >= MASA2TOTAL_THR )
+ {
+ distribute_evenly_ism( idx, max_sum_idx, nchan_ism );
+ }
+ else
+ {
+ if ( no_ism_loc > 1 )
+ {
+
+ dist = 0.0f;
+ div = 1.0f / (float) ( max_sum_idx );
+
+ part_idx_sum = 0;
+
+ for ( i = 0; i < no_ism_loc; i++ )
+ {
+ idx[i] = (int16_t) ( ( ratio_ism_loc[i] ) * ( max_sum_idx ) );
+ part_idx_sum += idx[i];
+
+ tmp = ( ratio_ism_loc[i] - ( idx[i] * div ) );
+ dist += ( tmp * tmp );
+ }
+
+ best_dist = dist;
+ best_i2 = -1;
+ while ( part_idx_sum < max_sum_idx )
+ {
+ best_i = -1;
+ /* check which index to increase by 1 for a possible improvement */
+
+ for ( i = 0; i < no_ism_loc; i++ )
+ {
+ idx[i]++;
+ dist2 = 0.0f;
+
+ for ( j = 0; j < no_ism_loc; j++ )
+ {
+ tmp = ( ratio_ism_loc[i] - ( idx[i] * div ) );
+ dist2 += ( tmp * tmp );
+ }
+
+ if ( dist2 < best_dist )
+ {
+ best_i2 = best_i;
+ best_i = i;
+ best_dist = dist2;
+ }
+ idx[i]--;
+ }
+ if ( best_i > -1 )
+ {
+ idx[best_i]++;
+ part_idx_sum++;
+ }
+ else
+ {
+ if ( best_i2 > -1 )
+ {
+ idx[best_i2]++;
+ part_idx_sum++;
+ }
+ else
+ {
+ idx[no_ism_loc - 1] += max_sum_idx - part_idx_sum;
+ part_idx_sum = max_sum_idx;
+ }
+ }
+ }
+ assert( sum_s( idx, no_ism_loc ) == max_sum_idx );
+ }
+ else
+ {
+ idx[0] = max_sum_idx;
+ }
+
+ if ( no_ism_loc < nchan_ism )
+ {
+ /* insert back the ratio of the separated object */
+ for ( i = nchan_ism - 1; i > idx_sep_object; i-- )
+ {
+ idx[i] = idx[i - 1];
+ }
+ idx[idx_sep_object] = 0;
+ }
+ }
+ }
+ else
+ {
+ idx[0] = (int16_t) ( ( ratio_ism[0] ) * ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) + 0.5f );
+ }
+
+ return;
+}
+
+
+static int16_t index_slice_enum(
+ const int16_t *ratio_ism_idx,
+ const int16_t nchan_ism )
+{
+ int16_t i;
+ int16_t x, index;
+ int16_t base;
+
+ if ( nchan_ism == 2 )
+ {
+ index = ratio_ism_idx[0];
+ }
+ else
+ {
+ x = ratio_ism_idx[nchan_ism - 2];
+ base = 10;
+ for ( i = nchan_ism - 3; i >= 0; i-- )
+ {
+ x += ratio_ism_idx[i] * base;
+ base *= 10;
+ }
+
+ index = 0;
+ i = 0;
+ while ( i <= x )
+ {
+ if ( valid_ratio_index( i, 7, nchan_ism - 1 ) )
+ {
+ index++;
+ }
+ i++;
+ }
+ index--;
+ }
+
+ return index;
+}
+
+
+static void transform_difference_index(
+ const int16_t *diff_idx,
+ int16_t *idx,
+ const int16_t len )
+{
+ int16_t i;
+ for ( i = 0; i < len; i++ )
+ {
+ if ( diff_idx[i] <= 0 )
+ {
+ idx[i] = -2 * diff_idx[i];
+ }
+ else
+ {
+ idx[i] = 2 * diff_idx[i] - 1;
+ }
+ }
+
+ return;
+}
+
+
+static void transform_index_and_GR_encode(
+ int16_t *diff_idx, /* i : differenc eindex to encode */
+ const int16_t len, /* i : input length */
+ const int16_t GR_order, /* i : GR order */
+ BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */
+)
+{
+ int16_t i;
+ int16_t idx[IVAS_MAX_NUM_OBJECTS];
+
+ /* transform difference index into positive */
+ transform_difference_index( diff_idx, idx, len );
+
+ /* GR encoding */
+ for ( i = 0; i < len; i++ )
+ {
+ ivas_qmetadata_encode_extended_gr( hMetaData, idx[i], 100, GR_order );
+ }
+
+ return;
+}
+
+
+static int16_t try_differential(
+ const int16_t numCodingBands,
+ const float *masa_to_total_energy_ratio,
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ const int16_t nchan_ism,
+ const int16_t bits_index,
+ int16_t *p_b_signif )
+{
+ int16_t b, i;
+ int16_t nbits0;
+ int16_t b_signif;
+ int16_t ratio_ism_idx_ref[MAX_NUM_OBJECTS];
+ int16_t diff_idx[MAX_NUM_OBJECTS];
+
+ b_signif = 0;
+ while ( ( b_signif < numCodingBands ) && ( masa_to_total_energy_ratio[b_signif] >= MASA2TOTAL_THR ) )
+ {
+ b_signif++;
+ }
+
+ nbits0 = 0;
+
+ if ( b_signif < numCodingBands )
+ {
+ nbits0 = bits_index;
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
+
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ v_sub_s( ratio_ism_idx[b], ratio_ism_idx_ref, diff_idx, nchan_ism );
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
+
+ /* transform difference index into positive */
+ transform_difference_index( diff_idx, diff_idx, nchan_ism - 1 );
+
+ /* GR encoding */
+ for ( i = 0; i < nchan_ism - 1; i++ )
+ {
+ nbits0 += ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 0 );
+ }
+ }
+ }
+ }
+ *p_b_signif = b_signif;
+
+ return nbits0;
+}
+
+
+static void differential_coding_first_subframe(
+ BSTR_ENC_HANDLE hMetaData,
+ const float *masa_to_total_energy_ratio,
+ const int16_t b_signif,
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ const int16_t nchan_ism,
+ const int16_t numCodingBands,
+ const int16_t bits_index )
+{
+ int16_t index, b;
+ int16_t ratio_ism_idx_ref[MAX_NUM_OBJECTS];
+ int16_t diff_idx[MAX_NUM_OBJECTS];
+
+ /* differential encoding*/
+ push_next_indice( hMetaData, 0, 1 );
+
+ if ( b_signif < numCodingBands )
+ {
+ index = index_slice_enum( ratio_ism_idx[b_signif], nchan_ism );
+ push_next_indice( hMetaData, index, bits_index );
+
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
+
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ v_sub_s( ratio_ism_idx[b], ratio_ism_idx_ref, diff_idx, nchan_ism );
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
+
+ /* transform difference index into positive */
+ transform_index_and_GR_encode( diff_idx, nchan_ism - 1, 0, hMetaData );
+ }
+ }
+ }
+
+ return;
+}
+
+
+static void independent_coding_ratio_ism_idx(
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], /* i : ISM ratios */
+ const float *masa_to_total_energy_ratio, /* i : MASA to total ratios */
+ const int16_t nchan_ism, /* i : number of objects */
+ const int16_t numCodingBands, /* i : number of subbands */
+ const int16_t bits_index, /* i : number of bits per index */
+ BSTR_ENC_HANDLE hMetaData /* i/o: metadata bitstream handle */
+)
+{
+ int16_t b, index;
+
+ for ( b = 0; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ index = index_slice_enum( ratio_ism_idx[b], nchan_ism );
+ push_next_indice( hMetaData, index, bits_index );
+ }
+ }
+
+ return;
+}
+
+
+static void remove_sep_obj(
+ int16_t *diff_idx, /* i/o: array of difference of indexes */
+ const int16_t nchan_ism, /* i : number of objects */
+ const int16_t idx_sep_obj /* i : index of separated object, to be taken out of array */
+)
+{
+ int16_t i;
+
+ for ( i = idx_sep_obj; i < nchan_ism - 1; i++ )
+ {
+ diff_idx[i] = diff_idx[i + 1];
+ }
+
+ return;
+}
+
+
+static void estimate_bits_subband_ism_ratio(
+ const int16_t *ratio_ism_idx,
+ const int16_t *ratio_ism_idx_ref, /* ( i/o ) */
+ const int16_t nchan_ism,
+ const int16_t shift_one,
+ const int16_t idx_sep_obj,
+ int16_t *p_nbits0,
+ int16_t *p_nbits1 )
+{
+ int16_t diff_idx[MAX_NUM_OBJECTS];
+ int16_t nbits0, nbits1;
+ int16_t i;
+
+ nbits0 = 0;
+ nbits1 = 0;
+
+ /* take difference with respect to previous subframe */
+ v_sub_s( ratio_ism_idx, ratio_ism_idx_ref, diff_idx, nchan_ism );
+
+ if ( shift_one )
+ {
+ remove_sep_obj( diff_idx, nchan_ism, idx_sep_obj );
+ }
+
+ /* transform difference index into positive */
+ transform_difference_index( diff_idx, diff_idx, nchan_ism - 1 - shift_one );
+
+ /* GR encoding */
+ for ( i = 0; i < nchan_ism - 1 - shift_one; i++ )
+ {
+ nbits0 += ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 0 );
+ nbits1 += ivas_qmetadata_encode_extended_gr_length( diff_idx[i], 100, 1 );
+ }
+
+ *p_nbits0 = nbits0;
+ *p_nbits1 = nbits1;
+
+ return;
+}
+
+
+static int16_t encode_ratio_ism_subframe(
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ const int16_t nchan_ism,
+ const uint8_t numCodingBands,
+ const int16_t sf,
+ int16_t ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
+ BSTR_ENC_HANDLE hMetaData,
+ const float *masa_to_total_energy_ratio,
+ const int16_t shift_one,
+ const int16_t idx_separated_obj )
+{
+ int16_t b, b_signif;
+ int16_t diff_idx[MAX_NUM_OBJECTS];
+ int16_t nbits, nbits0, nbits1, GR_order, GR_order_sb, bits_pos0;
+ int16_t differential_subframe;
+ int16_t ratio_ism_idx_ref[MAX_NUM_OBJECTS];
+ int16_t bits_index;
+ int16_t nbits00, nbits11;
+ int16_t idx_sep_obj_local;
+
+ idx_sep_obj_local = idx_separated_obj;
+ if ( idx_separated_obj > -1 )
+ {
+ if ( idx_separated_obj == nchan_ism - 1 )
+ {
+ idx_sep_obj_local = 0;
+ }
+ }
+ nbits = 0;
+ nbits0 = 0;
+ nbits1 = 0;
+
+ bits_pos0 = hMetaData->nb_bits_tot;
+ differential_subframe = 1; /* the differences are taken with respect to previous subframe */
+
+ /* first subframe */
+ bits_index = 0;
+ if ( sf == 0 )
+ {
+ bits_index = bits_index_ism_ratio( nchan_ism );
+
+ nbits = 0;
+ for ( b = 0; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ nbits += bits_index;
+ }
+ }
+
+ nbits0 = try_differential( numCodingBands, masa_to_total_energy_ratio, ratio_ism_idx, nchan_ism, bits_index, &b_signif );
+
+ if ( nbits <= nbits0 && nbits > 0 )
+ {
+ /* independent encoding */
+ push_next_indice( hMetaData, 1, 1 );
+ independent_coding_ratio_ism_idx( ratio_ism_idx, masa_to_total_energy_ratio, nchan_ism, numCodingBands, bits_index, hMetaData );
+ nbits = nbits + 1;
+ }
+ else
+ {
+ if ( nbits > 0 )
+ {
+ differential_coding_first_subframe( hMetaData, masa_to_total_energy_ratio, b_signif, ratio_ism_idx, nchan_ism, numCodingBands, bits_index );
+ nbits = nbits0 + 1;
+ }
+ }
+
+#ifdef DEBUGGING
+ assert( nbits == ( hMetaData->nb_bits_tot - bits_pos0 ) );
+#endif
+ }
+ else
+ {
+ /* not first subframe */
+ if ( shift_one == 1 && nchan_ism == 2 )
+ {
+ nbits = 0;
+ }
+ else
+ {
+ nbits0 = 0;
+ nbits1 = 0;
+
+ for ( b = 0; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ estimate_bits_subband_ism_ratio( ratio_ism_idx[b], ratio_ism_idx_prev_sf[b], nchan_ism, shift_one, idx_sep_obj_local, &nbits00, &nbits11 );
+ nbits0 += nbits00;
+ nbits1 += nbits11;
+ }
+ }
+ if ( nbits0 < nbits1 )
+ {
+ GR_order = 0;
+ nbits = nbits0;
+ }
+ else
+ {
+ GR_order = 1;
+ nbits = nbits1;
+ }
+
+ if ( numCodingBands > 1 )
+ {
+ /* try the difference from subband to subband; first subband is compared to previous subframe first subband*/
+ /* take difference with respect to previous subframe only for first subband */
+ nbits0 = 0;
+ nbits1 = 0;
+ b_signif = 0;
+ while ( ( b_signif < numCodingBands ) && ( masa_to_total_energy_ratio[b_signif] >= MASA2TOTAL_THR ) )
+ {
+ b_signif++;
+ }
+
+ if ( b_signif < numCodingBands )
+ {
+ estimate_bits_subband_ism_ratio( ratio_ism_idx[b_signif], ratio_ism_idx_prev_sf[b_signif], nchan_ism, shift_one, idx_sep_obj_local, &nbits0, &nbits1 );
+
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism );
+
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ estimate_bits_subband_ism_ratio( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism, shift_one, idx_sep_obj_local, &nbits00, &nbits11 );
+ nbits0 += nbits00;
+ nbits1 += nbits11;
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism );
+ }
+ }
+
+ if ( nbits0 < nbits1 )
+ {
+ GR_order_sb = 0;
+ }
+ else
+ {
+ GR_order_sb = 1;
+ nbits0 = nbits1;
+ }
+
+ if ( nbits0 < nbits )
+ {
+ differential_subframe = 0;
+ nbits = nbits0;
+ GR_order = GR_order_sb;
+ }
+
+ if ( nbits > 0 )
+ {
+ /* write prediction type */
+ push_next_indice( hMetaData, differential_subframe, 1 );
+ /* write GR order */
+ push_next_indice( hMetaData, GR_order, 1 );
+ nbits++; /* for the prediction type */
+ nbits++; /* for GR_order */
+
+ /* write data */
+ if ( differential_subframe )
+ {
+ for ( b = 0; b < numCodingBands; b++ )
+ {
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ /* take difference with respect to previous subframe */
+ v_sub_s( ratio_ism_idx[b], ratio_ism_idx_prev_sf[b], diff_idx, nchan_ism );
+
+ if ( shift_one )
+ {
+ remove_sep_obj( diff_idx, nchan_ism, idx_sep_obj_local );
+ }
+
+ transform_index_and_GR_encode( diff_idx, nchan_ism - 1 - shift_one, GR_order, hMetaData );
+ }
+ }
+ }
+ else
+ {
+ v_sub_s( ratio_ism_idx[b_signif], ratio_ism_idx_prev_sf[b_signif], diff_idx, nchan_ism );
+
+ if ( shift_one )
+ {
+ remove_sep_obj( diff_idx, nchan_ism, idx_sep_obj_local );
+ }
+
+ transform_index_and_GR_encode( diff_idx, nchan_ism - 1 - shift_one, GR_order, hMetaData );
+
+ mvs2s( ratio_ism_idx[b_signif], ratio_ism_idx_ref, nchan_ism - shift_one );
+
+ for ( b = b_signif + 1; b < numCodingBands; b++ )
+ {
+ /* take difference with respect to previous subband */
+ if ( masa_to_total_energy_ratio[b] < MASA2TOTAL_THR )
+ {
+ v_sub_s( ratio_ism_idx[b], ratio_ism_idx_ref, diff_idx, nchan_ism );
+
+ if ( shift_one )
+ {
+ remove_sep_obj( diff_idx, nchan_ism, idx_sep_obj_local );
+ }
+
+ transform_index_and_GR_encode( diff_idx, nchan_ism - 1 - shift_one, GR_order, hMetaData );
+
+ mvs2s( ratio_ism_idx[b], ratio_ism_idx_ref, nchan_ism - shift_one );
+ }
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /* only differential wrt previous subframe is possible */
+ /* write the differential to subframe case and no bit to signal the difference type */
+
+ if ( nbits > 0 )
+ {
+ /* write GR order */
+ push_next_indice( hMetaData, GR_order, 1 );
+ nbits++; /* for GR_order */
+ /* write data */
+ /* only one subband */
+ if ( masa_to_total_energy_ratio[0] < MASA2TOTAL_THR )
+ {
+ /* take difference with respect to previous subframe */
+ v_sub_s( ratio_ism_idx[0], ratio_ism_idx_prev_sf[0], diff_idx, nchan_ism );
+
+ if ( shift_one )
+ {
+ remove_sep_obj( diff_idx, nchan_ism, idx_sep_obj_local );
+ }
+
+ transform_index_and_GR_encode( diff_idx, nchan_ism - 1 - shift_one, GR_order, hMetaData );
+ }
+ }
+ }
+
+#ifdef DEBUGGING
+ assert( nbits == ( hMetaData->nb_bits_tot - bits_pos0 ) );
+#endif
+ }
+ }
+
+ return nbits;
+}
+
+
+static void ivas_encode_masaism_metadata(
+ MASA_ENCODER_HANDLE hMasa,
+ IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
+ BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream handle */
+ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
+ const int16_t low_bitrate_mode, /* i : is low bitrate more? 1/0 */
+ const int16_t omasa_nbands,
+ const int16_t omasa_nblocks,
+ const int16_t idx_separated_object,
+ const int16_t ism_imp )
+{
+ int16_t sf, band;
+ uint8_t numCodingBands;
+ uint8_t numSf;
+ int16_t brange[2];
+ float eneBand;
+ int16_t bin;
+ int16_t obj;
+ int16_t bits_ism[MAX_NUM_OBJECTS];
+ uint16_t idx_sph;
+ float theta_q, phi_q;
+ uint16_t index_theta, index_phi;
+ float ratio_ism[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ int16_t ratio_ism_idx[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], ratio_ism_idx_prev_sf[MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ float step;
+ int16_t inv_step;
+ float energy_ism, energy_ism_ind[MAX_NUM_OBJECTS];
+ int16_t tmp, rotate;
+ int16_t n_ism_tmp, i;
+
+
+ /* use the values from hQMetaData */
+ numCodingBands = (uint8_t) hQMetaData->q_direction->cfg.nbands;
+ numSf = (int8_t) hQMetaData->q_direction->cfg.nblocks;
+
+ if ( numCodingBands != omasa_nbands )
+ {
+ assert( numCodingBands == 1 );
+
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ if ( sum_f( hMasa->data.energy_ism[sf], omasa_nbands ) == 0.0f )
+ {
+ hQMetaData->masa_to_total_energy_ratio[sf][0] = 1.0f;
+ }
+ else
+ {
+ brange[0] = hMasa->data.band_mapping[0];
+ brange[1] = hMasa->data.band_mapping[omasa_nbands];
+ eneBand = 0.0f;
+ for ( bin = brange[0]; bin < brange[1]; bin++ )
+ {
+ eneBand += hMasa->data.energy[sf][bin];
+ }
+
+ energy_ism = 0.0f;
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ energy_ism_ind[obj] = 0.0f;
+ }
+
+ for ( band = 0; band < omasa_nbands; band++ )
+ {
+ energy_ism += hMasa->data.energy_ism[sf][band];
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ energy_ism_ind[obj] += hMasa->data.energy_ism[sf][band] * hMasa->data.energy_ratio_ism[sf][band][obj];
+ }
+ }
+
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ hMasa->data.energy_ratio_ism[sf][0][obj] = energy_ism_ind[obj] / energy_ism;
+ }
+ hQMetaData->masa_to_total_energy_ratio[sf][0] = eneBand / ( eneBand + energy_ism + EPSILON );
+ }
+ }
+ }
+ else if ( numSf != omasa_nblocks )
+ {
+ assert( numSf == 1 );
+
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ energy_ism = 0.0f; /* ISM energy for current subband */
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ energy_ism_ind[obj] = 0.0f;
+ }
+ for ( sf = 0; sf < omasa_nblocks; sf++ )
+ {
+ energy_ism += hMasa->data.energy_ism[sf][band];
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ energy_ism_ind[obj] += hMasa->data.energy_ism[sf][band] * hMasa->data.energy_ratio_ism[sf][band][obj];
+ }
+ }
+
+ if ( energy_ism == 0.0f )
+ {
+ hQMetaData->masa_to_total_energy_ratio[0][band] = 1.0f;
+ }
+ else
+ {
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ hMasa->data.energy_ratio_ism[0][band][obj] = energy_ism_ind[obj] / energy_ism;
+ }
+ brange[0] = hMasa->data.band_mapping[band];
+ brange[1] = hMasa->data.band_mapping[band + 1];
+
+ eneBand = 0.0f;
+ for ( sf = 0; sf < omasa_nblocks; sf++ )
+ {
+ for ( bin = brange[0]; bin < brange[1]; bin++ )
+ {
+ eneBand += hMasa->data.energy[sf][bin];
+ }
+ }
+ hQMetaData->masa_to_total_energy_ratio[0][band] = eneBand / ( eneBand + energy_ism + EPSILON );
+ }
+ }
+ }
+ else
+ {
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ if ( hMasa->data.energy_ism[sf][band] == 0.0f )
+ {
+ hQMetaData->masa_to_total_energy_ratio[sf][band] = 1.0f;
+ }
+ else
+ {
+ brange[0] = hMasa->data.band_mapping[band];
+ brange[1] = hMasa->data.band_mapping[band + 1];
+
+ eneBand = 0.0f;
+ for ( bin = brange[0]; bin < brange[1]; bin++ )
+ {
+ eneBand += hMasa->data.energy[sf][bin];
+ }
+ hQMetaData->masa_to_total_energy_ratio[sf][band] = eneBand / ( eneBand + hMasa->data.energy_ism[sf][band] + EPSILON );
+ }
+ }
+ }
+ }
+
+ encode_masa_to_total( hQMetaData, hMetaData, low_bitrate_mode, numCodingBands, numSf );
+
+ /* quantize ism_ratios */
+ if ( hMasa->data.nchan_ism > 1 )
+ {
+ inv_step = ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 );
+ step = 1.0f / inv_step;
+
+ rotate = 0;
+ n_ism_tmp = 0;
+
+ for ( sf = 0; sf < numSf; sf++ )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ assert( ( hMasa->data.energy_ratio_ism[sf][band][obj] >= 0 ) && ( hMasa->data.energy_ratio_ism[sf][band][obj] <= 1 ) );
+ ratio_ism[band][obj] = hMasa->data.energy_ratio_ism[sf][band][obj];
+ }
+
+ /* Quantize ISM ratios */
+ quantize_ratio_ism_vector( ratio_ism[band], ratio_ism_idx[band], hMasa->data.nchan_ism, hQMetaData->masa_to_total_energy_ratio[sf][band], idx_separated_object );
+
+ if ( n_ism_tmp == numCodingBands && ratio_ism_idx[band][idx_separated_object] != 0 && hQMetaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR )
+ {
+ i = 0;
+ while ( ratio_ism_idx[band][idx_separated_object] > 0 )
+ {
+ if ( i != idx_separated_object )
+ {
+ ratio_ism_idx[band][i]++;
+ ratio_ism_idx[band][idx_separated_object]--;
+ }
+ i++;
+ if ( i == hMasa->data.nchan_ism )
+ {
+ i = 0;
+ }
+ }
+ }
+
+ /* reconstructed values */
+ reconstruct_ism_ratios( ratio_ism_idx[band], hMasa->data.nchan_ism, step, hMasa->data.q_energy_ratio_ism[sf][band] );
+ /* encode vector */
+ }
+
+ if ( ( hMasa->data.nchan_ism > 2 ) && ( idx_separated_object == hMasa->data.nchan_ism - 1 ) )
+ {
+ /* rotate components */
+ rotate = 1;
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ if ( hQMetaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR )
+ {
+ tmp = ratio_ism_idx[band][hMasa->data.nchan_ism - 1];
+ ratio_ism_idx[band][hMasa->data.nchan_ism - 1] = ratio_ism_idx[band][0];
+ ratio_ism_idx[band][0] = tmp;
+ if ( sf == 0 && tmp == 0 )
+ {
+ n_ism_tmp += 1;
+ }
+
+ if ( n_ism_tmp == numCodingBands )
+ {
+ assert( tmp == 0 );
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( idx_separated_object > -1 )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ if ( hQMetaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR )
+ {
+ if ( ratio_ism_idx[band][idx_separated_object] == 0 && sf == 0 )
+ {
+ n_ism_tmp++;
+ }
+ }
+ }
+ }
+ }
+
+ /* encode data for current subframe */
+ if ( sf > 0 && n_ism_tmp == numCodingBands )
+ {
+ encode_ratio_ism_subframe( ratio_ism_idx, hMasa->data.nchan_ism, numCodingBands, sf, ratio_ism_idx_prev_sf, hMetaData, hQMetaData->masa_to_total_energy_ratio[sf], 1, idx_separated_object );
+ }
+ else
+ {
+ encode_ratio_ism_subframe( ratio_ism_idx, hMasa->data.nchan_ism, numCodingBands, sf, ratio_ism_idx_prev_sf, hMetaData, hQMetaData->masa_to_total_energy_ratio[sf], 0, idx_separated_object );
+ }
+
+ /* calculate quantized ISM ratios */
+ /* save previous subframe indexes */
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ mvs2s( ratio_ism_idx[band], ratio_ism_idx_prev_sf[band], hMasa->data.nchan_ism );
+ }
+
+ if ( rotate )
+ {
+ for ( band = 0; band < numCodingBands; band++ )
+ {
+ if ( hQMetaData->masa_to_total_energy_ratio[sf][band] < MASA2TOTAL_THR )
+ {
+ tmp = ratio_ism_idx[band][hMasa->data.nchan_ism - 1];
+ ratio_ism_idx[band][hMasa->data.nchan_ism - 1] = ratio_ism_idx[band][0];
+ ratio_ism_idx[band][0] = tmp;
+ }
+ }
+ }
+ }
+ }
+
+ calculate_nbits_meta( hMasa->data.nchan_ism, hMasa->data.q_energy_ratio_ism, hQMetaData->masa_to_total_energy_ratio, numSf, numCodingBands, bits_ism, idx_separated_object, ism_imp );
+
+ /* quantize directions */
+ for ( obj = 0; obj < hMasa->data.nchan_ism; obj++ )
+ {
+ if ( bits_ism[obj] < 8 )
+ {
+ /* check is same as previous */
+ if ( ( fabs( hIsmMeta[obj]->elevation - hIsmMeta[obj]->q_elevation_old ) < 0.01f ) && ( fabs( hIsmMeta[obj]->azimuth - hIsmMeta[obj]->q_azimuth_old ) < 0.01f ) )
+ {
+ push_next_indice( hMetaData, 1, 1 );
+ /* the old stays the same */
+ }
+ else
+ {
+ push_next_indice( hMetaData, 0, 1 );
+ idx_sph = quantize_direction( hIsmMeta[obj]->elevation, hIsmMeta[obj]->azimuth, bits_ism[obj], &theta_q, &phi_q, &index_theta, &index_phi, MC_LS_SETUP_INVALID );
+ push_next_indice( hMetaData, idx_sph, bits_ism[obj] );
+ hIsmMeta[obj]->q_elevation_old = hIsmMeta[obj]->elevation;
+ hIsmMeta[obj]->q_azimuth_old = hIsmMeta[obj]->azimuth;
+ }
+ }
+ else
+ {
+ idx_sph = quantize_direction( hIsmMeta[obj]->elevation, hIsmMeta[obj]->azimuth, bits_ism[obj], &theta_q, &phi_q, &index_theta, &index_phi, MC_LS_SETUP_INVALID );
+ push_next_indice( hMetaData, idx_sph, bits_ism[obj] );
+ hIsmMeta[obj]->q_elevation_old = hIsmMeta[obj]->elevation;
+ hIsmMeta[obj]->q_azimuth_old = hIsmMeta[obj]->azimuth;
+ }
+ }
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------*
+ * ivas_merge_masa_transports()
+ *
+ * Merge MASA transport channels
+ *-------------------------------------------------------------------*/
+
+void ivas_merge_masa_transports(
+ float data_in_f1[][L_FRAME48k],
+ float data_in_f2[][L_FRAME48k],
+ float data_out_f[][L_FRAME48k],
+ const int16_t input_frame,
+ const int16_t num_transport_channels )
+{
+ int16_t i, j;
+
+ for ( i = 0; i < num_transport_channels; i++ )
+ {
+ for ( j = 0; j < input_frame; j++ )
+ {
+ data_out_f[i][j] = data_in_f1[i][j] + data_in_f2[i][j];
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c
index 2979a9bdb5621ab83df96f06ec98553b9d99269d..fe4f8e8cfcc54912cb246b4f5eb1ea9f0735537f 100644
--- a/lib_enc/ivas_mc_param_enc.c
+++ b/lib_enc/ivas_mc_param_enc.c
@@ -35,7 +35,9 @@
#include "options.h"
#include "cnst.h"
#include "rom_enc.h"
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
#include "ivas_rom_enc.h"
+#endif
#include "rom_com.h"
#include "prot.h"
#include "ivas_prot.h"
@@ -213,11 +215,13 @@ ivas_error ivas_param_mc_enc_open(
/* Init total/dmx ener factors */
set_f( hParamMC->ener_fac, 0.0f, PARAM_MC_MAX_PARAMETER_BANDS );
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
/* init previous ILDs */
for ( i = 0; i < PARAM_MC_MAX_PARAMETER_BANDS; i++ )
{
set_zero( hParamMC->prev_ilds[i], PARAM_MC_SZ_ILD_MAP );
}
+#endif
st_ivas->hParamMC = hParamMC;
@@ -489,6 +493,10 @@ void ivas_param_mc_enc(
{
hParamMC->hMetadataPMC.attackIndex = 0;
}
+
+#ifndef FIX_580_PARAMMC_ENER_BURSTS
+ band_step = hParamMC->hMetadataPMC.bAttackPresent ? PARAM_MC_TRANSIENT_BAND_STEP : 1;
+#endif
}
break;
#ifdef DEBUGGING
@@ -501,7 +509,9 @@ void ivas_param_mc_enc(
/* parameter estimation*/
ivas_param_mc_param_est_enc( hParamMC, data_f, Cy_sum, Cx_sum, input_frame, nchan_inp, st_ivas->nchan_transport );
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
band_step = hParamMC->hMetadataPMC.bAttackPresent ? PARAM_MC_TRANSIENT_BAND_STEP : 1;
+#endif
/* ILD parameter quantization */
@@ -837,6 +847,7 @@ static void ivas_param_mc_param_est_enc(
}
}
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
if ( !hParamMC->hMetadataPMC.bAttackPresent )
{
const PARAM_MC_ILD_MAPPING *h_ild_mapping;
@@ -892,6 +903,7 @@ static void ivas_param_mc_param_est_enc(
hParamMC->hMetadataPMC.bAttackPresent = 1;
}
}
+#endif
if ( hParamMC->hMetadataPMC.bAttackPresent )
@@ -920,7 +932,11 @@ static void ivas_param_mc_param_est_enc(
for ( ; cur_param_band < num_parameter_bands; cur_param_band += 2 )
{
+#ifdef FIX_563_PARAMMC_LIMITER
if ( cur_param_band < num_parameter_bands )
+#else
+ if ( cur_param_band + 1 < num_parameter_bands )
+#endif
{
for ( ch_idx1 = 0; ch_idx1 < nchan_transport; ++ch_idx1 )
{
@@ -1316,7 +1332,11 @@ static void ivas_param_mc_quantize_ilds(
ener_fac = 10.0f * log10f( ( tot_ener + EPSILON ) / ( dmx_ener + EPSILON ) );
delta_fac = ener_fac - hParamMC->ener_fac[freq_idx];
+#ifdef FIX_563_PARAMMC_LIMITER
if ( !hParamMC->hMetadataPMC.bAttackPresent && ( delta_fac > PARAM_MC_ENER_LIMIT_INTERFRAME ) && ( delta_fac < PARAM_MC_ENER_LIMIT_MAX_DELTA_FAC ) )
+#else
+ if ( !hParamMC->hMetadataPMC.bAttackPresent && ( delta_fac > PARAM_MC_ENER_LIMIT_INTERFRAME ) )
+#endif
{
float limit_fac;
limit_fac = powf( 10.0f, ( ( 0.3f * logf( delta_fac - PARAM_MC_ENER_LIMIT_INTERFRAME + 1.0f ) - ( delta_fac - PARAM_MC_ENER_LIMIT_INTERFRAME ) ) / 10.0f ) );
@@ -1326,11 +1346,13 @@ static void ivas_param_mc_quantize_ilds(
hParamMC->ener_fac[freq_idx] = ener_fac;
+#ifdef FIX_563_PARAMMC_LIMITER
/* update also combined bands ener_fac when in transient frame */
if ( hParamMC->hMetadataPMC.bAttackPresent && ( ( freq_idx + 1 ) < hParamMC->hMetadataPMC.nbands_coded ) )
{
hParamMC->ener_fac[freq_idx + 1] = ener_fac;
}
+#endif
for ( k = 0; k < num_ilds_to_code; ++k )
{
@@ -1344,11 +1366,13 @@ static void ivas_param_mc_quantize_ilds(
ref_ener += Cx[ref_channel_idx][ref_channel_idx];
}
ILD[k] = 10.0f * log10f( ( Nrg[h_ild_mapping->ild_index[k]] + EPSILON ) / ( hParamMC->hMetadataPMC.ild_factors[k] * ref_ener + EPSILON ) );
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
hParamMC->prev_ilds[freq_idx][k] = ILD[k];
if ( hParamMC->hMetadataPMC.bAttackPresent && ( ( freq_idx + 1 ) < hParamMC->hMetadataPMC.nbands_coded ) )
{
hParamMC->prev_ilds[freq_idx + 1][k] = ILD[k];
}
+#endif
}
@@ -1720,6 +1744,7 @@ static void ivas_param_mc_encode_parameter(
if ( hMetadataPMC->bAttackPresent || hMetadataPMC->param_frame_idx == hMetadataPMC->coding_band_mapping[i] )
{
/* LFE ICC/ILDs are always the last ones in coding band 0 */
+#ifdef FIX_578_PARAMMC_ILD_BS
int16_t n_lfe_idx, k;
n_lfe_idx = map_size - map_size_wo_lfe;
for ( k = 0; k < n_lfe_idx; k++ )
@@ -1730,6 +1755,13 @@ static void ivas_param_mc_encode_parameter(
idx_prev = idx;
sz_seq++;
}
+#else
+ idx = quant_idx[( i + 1 ) * map_size - 1];
+ seq[sz_seq] = idx;
+ seq_delta[sz_seq] = idx - idx_prev + idx_offset;
+ idx_prev = idx;
+ sz_seq++;
+#endif
}
}
}
diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c
new file mode 100644
index 0000000000000000000000000000000000000000..aaa4627361c7a006a20bfd648292aa352807f38c
--- /dev/null
+++ b/lib_enc/ivas_omasa_enc.c
@@ -0,0 +1,1170 @@
+/******************************************************************************************************
+
+ (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 "options.h"
+#include
+#include
+#include
+#include "ivas_cnst.h"
+#include "ivas_prot.h"
+#include "prot.h"
+#include "ivas_rom_com.h"
+#include "ivas_rom_enc.h"
+#ifdef DEBUGGING
+#include "debug.h"
+#endif
+#include "wmc_auto.h"
+
+#ifdef MASA_AND_OBJECTS
+
+/*-------------------------------------------------------------------------
+ * Local function prototypes
+ *------------------------------------------------------------------------*/
+
+static void ivas_omasa_param_est_enc( OMASA_ENC_HANDLE hOMasa, MASA_ENCODER_HANDLE hMasa, ISM_METADATA_HANDLE hIsmMeta[], float data_f[][L_FRAME48k], float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float energyRatio[MASA_FREQUENCY_BANDS], float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], float surroundingCoherence[MASA_FREQUENCY_BANDS], float diffuseness_m[MASA_FREQUENCY_BANDS], const int16_t input_frame, const int16_t nchan_inp );
+
+static void ivas_omasa_energy_and_ratio_est( OMASA_ENC_HANDLE hOMasa, MASA_ENCODER_HANDLE hMasa, float data_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_inp );
+
+static void ivas_omasa_dmx( float data_in_f[][L_FRAME48k], float data_out_f[][L_FRAME48k], const int16_t input_frame, const int16_t nchan_transport, const int16_t nchan_ism, ISM_METADATA_HANDLE hIsmMeta[], float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS], const float interpolator[L_FRAME48k] );
+
+static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] );
+
+static void computeReferencePower_omasa( const int16_t *band_grouping, float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], float *reference_power, const int16_t enc_param_start_band, const int16_t num_freq_bands );
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_enc_open()
+ *
+ * Allocate and initialize OMASA handle
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_enc_open(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder handle */
+)
+{
+ int16_t i, j;
+ OMASA_ENC_HANDLE hOMasa;
+ int16_t numAnalysisChannels;
+ int16_t input_frame;
+ ivas_error error;
+
+ error = IVAS_ERR_OK;
+
+ assert( st_ivas->hMasa != NULL && "MASA encoder handle is not present" );
+
+ if ( ( hOMasa = (OMASA_ENC_HANDLE) malloc( sizeof( OMASA_ENC_DATA ) ) ) == NULL )
+ {
+ return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for OMASA encoder\n" ) );
+ }
+
+ numAnalysisChannels = st_ivas->hEncoderConfig->nchan_ism;
+
+ /* open/initialize CLDFB */
+ hOMasa->num_Cldfb_instances = numAnalysisChannels;
+ for ( i = 0; i < hOMasa->num_Cldfb_instances; i++ )
+ {
+ openCldfb( &( hOMasa->cldfbAnaEnc[i] ), CLDFB_ANALYSIS, st_ivas->hEncoderConfig->input_Fs, CLDFB_PROTOTYPE_5_00MS );
+ }
+
+ /* intensity 3-dim */
+ for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
+ {
+ hOMasa->direction_vector_m[i] = (float **) malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( float * ) );
+
+ for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
+ {
+ hOMasa->direction_vector_m[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) );
+ set_zero( hOMasa->direction_vector_m[i][j], MASA_FREQUENCY_BANDS );
+ }
+ }
+
+ for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
+ {
+ for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
+ {
+ hOMasa->buffer_intensity_real[i][j] = (float *) malloc( MASA_FREQUENCY_BANDS * sizeof( float ) );
+ set_zero( hOMasa->buffer_intensity_real[i][j], MASA_FREQUENCY_BANDS );
+ }
+ }
+
+ set_zero( hOMasa->buffer_energy, DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS );
+
+ for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
+ {
+ set_f( hOMasa->prev_object_dm_gains[i], (float) sqrt( 0.5 ), MASA_MAX_TRANSPORT_CHANNELS );
+ }
+ set_zero( hOMasa->broadband_energy_sm, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
+ set_zero( hOMasa->broadband_energy_prev, MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS );
+ hOMasa->prev_selected_object = 0;
+ hOMasa->changing_object = 0;
+
+ input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
+ for ( i = 0; i < input_frame; i++ )
+ {
+ hOMasa->interpolator[i] = ( (float) i ) / ( (float) input_frame );
+ hOMasa->fade_out_gain[i] = ( 1.0f + cosf( ( (float) i ) / ( (float) input_frame ) * EVS_PI ) ) / 2.0f;
+ hOMasa->fade_in_gain[i] = 1.0f - hOMasa->fade_out_gain[i];
+ }
+
+ hOMasa->index_buffer_intensity = 0;
+
+ st_ivas->hOMasa = hOMasa;
+
+ return error;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_enc_close()
+ *
+ * Close OMASA handle
+ *--------------------------------------------------------------------------*/
+
+void ivas_omasa_enc_close(
+ OMASA_ENC_HANDLE *hOMasa /* i/o: encoder OMASA handle */
+)
+{
+ int16_t i, j;
+
+ if ( hOMasa == NULL || *hOMasa == NULL )
+ {
+ return;
+ }
+
+ for ( i = 0; i < ( *hOMasa )->num_Cldfb_instances; i++ )
+ {
+ deleteCldfb( &( ( *hOMasa )->cldfbAnaEnc[i] ) );
+ }
+
+ for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
+ {
+ for ( j = 0; j < MAX_PARAM_SPATIAL_SUBFRAMES; j++ )
+ {
+ free( ( *hOMasa )->direction_vector_m[i][j] );
+ ( *hOMasa )->direction_vector_m[i][j] = NULL;
+ }
+
+ for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
+ {
+ free( ( *hOMasa )->buffer_intensity_real[i][j] );
+ ( *hOMasa )->buffer_intensity_real[i][j] = NULL;
+ }
+
+ free( ( *hOMasa )->direction_vector_m[i] );
+ ( *hOMasa )->direction_vector_m[i] = NULL;
+ }
+
+ free( *hOMasa );
+ ( *hOMasa ) = NULL;
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_enc_config()
+ *
+ * oMASA encoder configuration
+ *--------------------------------------------------------------------------*/
+
+ivas_error ivas_omasa_enc_config(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
+)
+{
+ int16_t k, sce_id, nSCE_old;
+ int32_t ivas_total_brate, ism_total_brate;
+ ENCODER_CONFIG_HANDLE hEncoderConfig;
+ ivas_error error;
+
+ hEncoderConfig = st_ivas->hEncoderConfig;
+ ivas_total_brate = hEncoderConfig->ivas_total_brate;
+ nSCE_old = st_ivas->nSCE;
+
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, hEncoderConfig->nchan_ism );
+ st_ivas->nchan_transport = 2;
+
+ /* reconfiguration in case of bitrate switching */
+ if ( hEncoderConfig->last_ivas_total_brate != ivas_total_brate )
+ {
+ ivas_set_omasa_TC( st_ivas->ism_mode, hEncoderConfig->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
+
+ k = 0;
+ while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
+ {
+ k++;
+ }
+
+ ism_total_brate = 0;
+ for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
+ {
+ ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
+ }
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ if ( ( error = ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->nSCE, NULL, 0, NULL, NULL, NULL, NULL, NULL, 1 ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+
+ /* reconfigure core-coders for ISMs */
+ if ( ( error = ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, 1, 2, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate, MC_MODE_NONE ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ /* re-write IVAS format signalling - actual 'ism_mode' was not known before */
+ if ( st_ivas->nSCE > 0 )
+ {
+ reset_indices_enc( st_ivas->hSCE[0]->hCoreCoder[0]->hBstr, st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
+ }
+ else
+ {
+ reset_indices_enc( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr, st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot );
+ }
+
+ ivas_write_format( st_ivas );
+
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->hOMasa == NULL )
+ {
+ if ( ( error = ivas_omasa_enc_open( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->hOMasa != NULL )
+ {
+ ivas_omasa_enc_close( &( st_ivas->hOMasa ) );
+ st_ivas->hOMasa = NULL;
+ }
+
+ st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
+
+ if ( ivas_total_brate - ism_total_brate >= MIN_BRATE_MDCT_STEREO )
+ {
+ hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+ }
+ else
+ {
+ hEncoderConfig->element_mode_init = IVAS_CPE_DFT;
+ }
+ }
+
+ /* Configure MASA encoder based on frame parameters */
+ if ( ( error = ivas_masa_enc_config( st_ivas ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC )
+ {
+ /* Configure oMASA analysis based on MASA config */
+ ivas_omasa_set_config( st_ivas->hOMasa, st_ivas->hMasa, st_ivas->hEncoderConfig->input_Fs, st_ivas->ism_mode );
+ }
+
+ return IVAS_ERR_OK;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_set_config()
+ *
+ * Frame-by-frame config for oMASA
+ *--------------------------------------------------------------------------*/
+
+void ivas_omasa_set_config(
+ OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
+ MASA_ENCODER_HANDLE hMasa, /* i : MASA encoder handle */
+ const int32_t input_Fs, /* i : Input sample rate */
+ const ISM_MODE ism_mode /* i : ISM mode */
+)
+{
+ uint8_t i, maxBin;
+
+ /* Determine the number of bands */
+ if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* use full resolution for the ISM+MASA merge and reduce later */
+ hOMasa->nbands = 24;
+ }
+ else
+ {
+ hOMasa->nbands = hMasa->config.numCodingBands;
+ }
+
+ hOMasa->nCodingBands = hMasa->config.numCodingBands;
+
+ /* Determine the number of subframes */
+ hOMasa->nSubframes = hMasa->config.joinedSubframes == TRUE ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES;
+
+ /* Determine band grouping */
+ if ( hOMasa->nbands == 24 )
+ {
+ mvs2s( MASA_band_grouping_24, hOMasa->band_grouping, 24 + 1 );
+ }
+ else
+ {
+ for ( i = 0; i < hOMasa->nbands + 1; i++ )
+ {
+ hOMasa->band_grouping[i] = MASA_band_grouping_24[hMasa->data.band_mapping[i]];
+ }
+ }
+
+ maxBin = (uint8_t) ( input_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
+
+ for ( i = 1; i < hOMasa->nbands + 1; i++ )
+ {
+ if ( hOMasa->band_grouping[i] >= maxBin )
+ {
+ hOMasa->band_grouping[i] = maxBin;
+ hOMasa->nbands = i;
+ break;
+ }
+ }
+
+ mvs2s( DirAC_block_grouping, hOMasa->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 );
+ if ( hOMasa->nSubframes == 1 )
+ {
+ hOMasa->block_grouping[1] = hOMasa->block_grouping[MAX_PARAM_SPATIAL_SUBFRAMES];
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_enc()
+ *
+ * Main OMASA encoding function
+ *--------------------------------------------------------------------------*/
+
+void ivas_omasa_enc(
+ OMASA_ENC_HANDLE hOMasa, /* i/o: OMASA encoder handle */
+ MASA_ENCODER_HANDLE hMasa, /* i/o: MASA encoder handle */
+ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handle */
+ float data_in_f[][L_FRAME48k], /* i/o: Input / transport audio signals */
+ const int16_t input_frame, /* i : Input frame size */
+ const int16_t nchan_transport, /* i : Number of transport channels */
+ const int16_t nchan_ism, /* i : Number of objects for parameter analysis */
+ const ISM_MODE ism_mode, /* i : ISM mode */
+ float data_separated_object[L_FRAME48k], /* o : Separated object audio signal */
+ int16_t *idx_separated_object /* o : Index of the separated object */
+)
+{
+ int16_t i, j;
+ float data_out_f[MASA_MAX_TRANSPORT_CHANNELS][L_FRAME48k];
+
+ /* Determine separated object (when applicable) */
+ if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ float broadband_energy[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
+ int16_t loudest_object;
+ int16_t selected_object;
+ int16_t nchan_all_inp;
+ float alpha;
+ uint8_t fade_out_separate_object;
+ uint8_t fade_in_separate_object;
+
+ /* Estimate broadband energies */
+ nchan_all_inp = nchan_ism + nchan_transport;
+ set_zero( broadband_energy, nchan_all_inp );
+ for ( i = 0; i < nchan_all_inp; i++ )
+ {
+ for ( j = 0; j < input_frame; j++ )
+ {
+ broadband_energy[i] += data_in_f[i][j] * data_in_f[i][j];
+ }
+ }
+
+ /* Temporal averaging */
+ alpha = 0.8f;
+ for ( i = 0; i < nchan_all_inp; i++ )
+ {
+ hOMasa->broadband_energy_sm[i] = ( 1.0f - alpha ) * broadband_energy[i] + alpha * hOMasa->broadband_energy_sm[i];
+ }
+
+ /* Determine loudest object */
+ loudest_object = 0;
+ for ( i = 1; i < nchan_ism; i++ )
+ {
+ if ( hOMasa->broadband_energy_sm[i] > hOMasa->broadband_energy_sm[loudest_object] )
+ {
+ loudest_object = i;
+ }
+ }
+
+ /* Determine object to separate */
+ selected_object = hOMasa->prev_selected_object;
+ fade_out_separate_object = 0;
+ fade_in_separate_object = 0;
+ if ( hOMasa->changing_object )
+ {
+ hOMasa->changing_object = 0;
+ selected_object = loudest_object;
+ fade_in_separate_object = 1;
+ }
+ else
+ {
+ if ( loudest_object != hOMasa->prev_selected_object )
+ {
+ float selected_ene;
+ float total_ene;
+ float selected_ratio;
+ float adaptive_threshold_dB;
+ float ratio_objects_dB;
+ float hardswitch_threshold = 0.25f;
+
+ /* Compute the energy of the current and the previous selected object in the current and the previous frame */
+ selected_ene = broadband_energy[loudest_object] + broadband_energy[hOMasa->prev_selected_object] + hOMasa->broadband_energy_prev[loudest_object] + hOMasa->broadband_energy_prev[hOMasa->prev_selected_object];
+
+ /* Compute the energy of all objects and MASA channels in the current and the previous frame */
+ total_ene = 0.0f;
+ for ( i = 0; i < nchan_all_inp; i++ )
+ {
+ total_ene += broadband_energy[i] + hOMasa->broadband_energy_prev[i];
+ }
+
+ /* Compute the ratio */
+ selected_ratio = selected_ene / ( total_ene + EPSILON );
+
+ adaptive_threshold_dB = selected_ratio * 9.0f + 1.0f; /* selected ratio = 0 -> 1 dB, selected ratio = 1 -> 10 dB */
+ ratio_objects_dB = 10.0f * log10f( hOMasa->broadband_energy_sm[loudest_object] / ( hOMasa->broadband_energy_sm[hOMasa->prev_selected_object] + EPSILON ) );
+
+ /* Adaptively determine whether to change the separated object. If they are quiet compared to the total energy, change easier, as other signals mask the change. */
+ if ( ratio_objects_dB > adaptive_threshold_dB )
+ {
+ if ( selected_ratio < hardswitch_threshold ) /* If low level compared to all audio channels, perform hardswitch */
+ {
+ selected_object = loudest_object;
+ }
+ else /* If high level compared to all audio channels, perform switch via fade out fade in */
+ {
+ hOMasa->changing_object = 1;
+ fade_out_separate_object = 1;
+ }
+ }
+ }
+ }
+
+ /* Set values for next frame */
+ for ( i = 0; i < nchan_all_inp; i++ )
+ {
+ hOMasa->broadband_energy_prev[i] = broadband_energy[i];
+ }
+ hOMasa->prev_selected_object = selected_object;
+
+ /* Separate the selected object */
+ *idx_separated_object = selected_object;
+ mvr2r( data_in_f[selected_object], data_separated_object, input_frame );
+ if ( fade_out_separate_object )
+ {
+ v_mult( data_separated_object, hOMasa->fade_out_gain, data_separated_object, input_frame );
+ v_mult( data_in_f[selected_object], hOMasa->fade_in_gain, data_in_f[selected_object], input_frame );
+ }
+ else if ( fade_in_separate_object )
+ {
+ v_mult( data_separated_object, hOMasa->fade_in_gain, data_separated_object, input_frame );
+ v_mult( data_in_f[selected_object], hOMasa->fade_out_gain, data_in_f[selected_object], input_frame );
+ }
+ else
+ {
+ set_zero( data_in_f[selected_object], input_frame );
+ }
+ }
+
+ /* Analysis */
+ if ( ism_mode == ISM_MODE_NONE || ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ OMASA_SPATIAL_META OMasaMeta; /* working memory for the ISM-object MASA-parameters */
+ OMASA_SPATIAL_META_HANDLE hOMasaMeta;
+ uint8_t n_bands_orig, n_subframes_orig;
+ uint8_t numCodingBands_orig, joinedSubframes_orig;
+
+ hOMasaMeta = &OMasaMeta;
+ hOMasaMeta->num_dirs = 1; /* TODO: hard-coding for now */
+
+ /* merge MASA directions before adding ISM to the mixture */
+ if ( hMasa->config.numberOfDirections == 2 )
+ {
+ n_bands_orig = hMasa->config.numCodingBands;
+ hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
+
+ ivas_masa_combine_directions( hMasa );
+
+ hMasa->config.numCodingBands = (int8_t) n_bands_orig;
+ }
+
+ /* force computation into high resolution */
+#ifndef OMASA_FIX_LOW_FS
+ n_bands_orig = hOMasa->nbands;
+#endif
+ n_subframes_orig = hOMasa->nSubframes;
+
+#ifndef OMASA_FIX_LOW_FS
+ hOMasa->nbands = MASA_FREQUENCY_BANDS;
+#endif
+ hOMasa->nSubframes = MAX_PARAM_SPATIAL_SUBFRAMES;
+
+ /* Estimate MASA parameters from the objects */
+ /* NB: only first direction is populated */
+ /* NB2: in energy_ratios and surround_coherence only first sub-frame contains valid data */
+ ivas_omasa_param_est_enc( hOMasa, hMasa, hIsmMeta, data_in_f, hOMasaMeta->directional_meta[0].elevation, hOMasaMeta->directional_meta[0].azimuth, hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].spread_coherence, hOMasaMeta->common_meta.surround_coherence[0],
+ hOMasaMeta->common_meta.diffuse_to_total_ratio[0], input_frame, nchan_ism );
+
+ /* copy energy_ratios and surrCoh from first sub-frame to the remaining ones */
+ for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ )
+ {
+ mvr2r( hOMasaMeta->directional_meta[0].energy_ratio[0], hOMasaMeta->directional_meta[0].energy_ratio[i], MASA_FREQUENCY_BANDS );
+ mvr2r( hOMasaMeta->common_meta.surround_coherence[0], hOMasaMeta->common_meta.surround_coherence[i], MASA_FREQUENCY_BANDS );
+ mvr2r( hOMasaMeta->common_meta.diffuse_to_total_ratio[0], hOMasaMeta->common_meta.diffuse_to_total_ratio[i], MASA_FREQUENCY_BANDS );
+ }
+
+ /* restore resolution parameters */
+#ifndef OMASA_FIX_LOW_FS
+ hOMasa->nbands = n_bands_orig;
+#endif
+ hOMasa->nSubframes = n_subframes_orig;
+
+ /* perform MASA+ISM merge in full resolution */
+ numCodingBands_orig = hMasa->config.numCodingBands;
+ joinedSubframes_orig = hMasa->config.joinedSubframes;
+
+#ifndef OMASA_FIX_LOW_FS
+ hMasa->config.numCodingBands = MASA_FREQUENCY_BANDS;
+#else
+ hMasa->config.numCodingBands = hOMasa->nbands;
+#endif
+ hMasa->config.joinedSubframes = 0;
+
+ ivas_merge_masa_metadata( hMasa, hOMasaMeta ); /* => merge result in hMasa->masaMetadata */
+
+ hMasa->config.numCodingBands = numCodingBands_orig;
+ hMasa->config.joinedSubframes = joinedSubframes_orig;
+ }
+ else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ /* Estimate energies and ratios */
+ ivas_omasa_energy_and_ratio_est( hOMasa, hMasa, data_in_f, input_frame, nchan_ism );
+ }
+
+ /* Move the ISM metadata to the first entry for encoding in the MASA_ONE_OBJ mode */
+ if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ hIsmMeta[0]->azimuth = hIsmMeta[*idx_separated_object]->azimuth;
+ hIsmMeta[0]->elevation = hIsmMeta[*idx_separated_object]->elevation;
+ }
+
+ /* Downmix */
+ ivas_omasa_dmx( data_in_f, data_out_f, input_frame, nchan_transport, nchan_ism, hIsmMeta, hOMasa->prev_object_dm_gains, hOMasa->interpolator );
+
+ /* Merge transport signals */
+ ivas_merge_masa_transports( data_out_f, &( data_in_f[nchan_ism] ), data_in_f, input_frame, nchan_transport );
+
+ return;
+}
+
+
+/*-------------------------------------------------------------------------*
+ * set_ism_importance_interformat()
+ *
+ * Set the importance of particular ISM streams in combined-format coding
+ *-------------------------------------------------------------------------*/
+
+void set_ism_importance_interformat(
+ const int32_t ism_total_brate, /* i/o: ISms total bitrate */
+ const int16_t nchan_transport, /* i : number of transported channels */
+ ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
+ SCE_ENC_HANDLE hSCE[], /* i/o: SCE encoder handles */
+ const float lp_noise_CPE, /* i : LP filtered total noise estimation */
+ int16_t ism_imp[] /* o : ISM importance flags */
+)
+{
+ Encoder_State *st;
+ int16_t ch, ctype, active_flag;
+
+ for ( ch = 0; ch < nchan_transport; ch++ )
+ {
+ st = hSCE[ch]->hCoreCoder[0];
+
+ active_flag = st->vad_flag;
+
+ if ( active_flag == 0 )
+ {
+ if ( st->lp_noise > 15 || lp_noise_CPE - st->lp_noise < 30 )
+ {
+ active_flag = 1;
+ }
+ }
+
+ /* do not use the low-rate core-coder mode at highest bit-rates */
+ if ( ism_total_brate / nchan_transport > IVAS_48k )
+ {
+ active_flag = 1;
+ }
+
+ ctype = hSCE[ch]->hCoreCoder[0]->coder_type_raw;
+
+ st->low_rate_mode = 0;
+ if ( active_flag == 0 )
+ {
+ ism_imp[ch] = ISM_INACTIVE_IMP;
+ st->low_rate_mode = 1;
+ }
+ else if ( ctype == INACTIVE || ctype == UNVOICED )
+ {
+ ism_imp[ch] = ISM_LOW_IMP;
+ }
+ else if ( ctype == VOICED )
+ {
+ ism_imp[ch] = ISM_MEDIUM_IMP;
+ }
+ else /* GENERIC */
+ {
+ ism_imp[ch] = ISM_HIGH_IMP;
+ }
+
+ hIsmMeta[ch]->ism_metadata_flag = active_flag; /* flag is needed for the MD coding */
+ }
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_set_surplus_brate_enc()
+ *
+ * set bit-rate surplus in combined format coding
+ *--------------------------------------------------------------------------*/
+
+void ivas_set_surplus_brate_enc(
+ Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */
+#ifdef DEBUG_MODE_INFO
+ ,
+ const int16_t *nb_bits_metadata /* i : number of metadata bits */
+#endif
+)
+{
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
+ /* note: ISM st->total_brate is iset in ivas_sce_enc() */
+ }
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ /* it is already set in ivas_ism_enc() */
+ }
+ else
+ {
+ st_ivas->hCPE[0]->brate_surplus = 0;
+ }
+
+#ifdef DEBUG_MODE_INFO
+ if ( st_ivas->hSCE[0] != NULL )
+ {
+ int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC );
+ float tmpF = 0;
+
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 );
+ }
+ else
+ {
+ for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ )
+ {
+ tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 );
+ }
+ }
+ tmpF /= 1000.f;
+ dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */
+ tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF;
+ dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */
+ tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f;
+ dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */
+ }
+#endif
+
+ return;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * ivas_omasa_ener_brate()
+ *
+ *
+ *--------------------------------------------------------------------------*/
+
+/*! r: OMASA energy bitrate flag */
+int16_t ivas_omasa_ener_brate(
+ const int16_t nchan_ism, /* i : number of ISMs */
+ const int32_t ivas_total_brate, /* i : IVAS total bitrate */
+ float data_f[][L_FRAME48k], /* i : Input / transport audio signals */
+ const int16_t input_frame /* i : Input frame size */
+)
+{
+ int16_t i, flag_omasa_ener_brate;
+ float energy_ism, energy_masa;
+
+ flag_omasa_ener_brate = 0;
+
+ if ( nchan_ism >= 3 && ivas_total_brate == IVAS_128k )
+ {
+ energy_ism = 0.0f;
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+ energy_ism += sum2_f( data_f[i], input_frame );
+ }
+
+ energy_masa = 0.0f;
+ for ( i = nchan_ism; i < nchan_ism + MASA_MAXIMUM_DIRECTIONS; i++ )
+ {
+ energy_masa += sum2_f( data_f[i], input_frame );
+ }
+
+ energy_ism = energy_ism / ( energy_masa + 1.0f ) * 2.0f / (float) ( nchan_ism );
+
+ if ( energy_ism < 1.0f )
+ {
+ flag_omasa_ener_brate = 1;
+ }
+ }
+
+ return flag_omasa_ener_brate;
+}
+
+
+/*--------------------------------------------------------------------------*
+ * Local functions
+ *--------------------------------------------------------------------------*/
+
+/* Estimate MASA parameters from the objects */
+static void ivas_omasa_param_est_enc(
+ OMASA_ENC_HANDLE hOMasa,
+ MASA_ENCODER_HANDLE hMasa,
+ ISM_METADATA_HANDLE hIsmMeta[],
+ float data_f[][L_FRAME48k],
+ float elevation_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ float azimuth_m_values[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ float energyRatio[MASA_FREQUENCY_BANDS],
+ float spreadCoherence[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
+ float surroundingCoherence[MASA_FREQUENCY_BANDS],
+ float diffuseness_m[MASA_FREQUENCY_BANDS],
+ const int16_t input_frame,
+ const int16_t nchan_ism )
+{
+ float reference_power[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
+ int16_t ts, i, j, d, k;
+ int16_t num_freq_bins, num_freq_bands, index;
+ float dir_v[DIRAC_NUM_DIMS];
+ int16_t l_ts;
+ float Chnl_RealBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
+ float Chnl_ImagBuffer[MCMASA_MAX_ANA_CHANS][CLDFB_NO_CHANNELS_MAX];
+ float Foa_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
+ float Foa_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX];
+ float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
+ float direction_vector[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS];
+ float diffuseness_vector[MASA_FREQUENCY_BANDS];
+ int16_t band_m_idx, block_m_idx;
+ float renormalization_factor_diff[MASA_FREQUENCY_BANDS];
+ float norm_tmp;
+ int16_t mrange[2], brange[2];
+
+ num_freq_bins = hOMasa->cldfbAnaEnc[0]->no_channels;
+ num_freq_bands = hOMasa->nbands;
+ l_ts = input_frame / CLDFB_NO_COL_MAX;
+
+ /* Need to initialize renormalization_factors, and variables to be normalized */
+ set_zero( renormalization_factor_diff, hOMasa->nbands );
+ set_zero( diffuseness_m, hOMasa->nbands );
+
+ /* Compute ISM to FOA matrices */
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+ hOMasa->chnlToFoaMtx[0][i] = 1.0f;
+ hOMasa->chnlToFoaMtx[1][i] = sinf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
+ hOMasa->chnlToFoaMtx[2][i] = sinf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
+ hOMasa->chnlToFoaMtx[3][i] = cosf( ( hIsmMeta[i]->azimuth / 180.0f * EVS_PI ) ) * cosf( ( hIsmMeta[i]->elevation / 180.0f * EVS_PI ) );
+ }
+
+ /* do processing over all CLDFB time slots */
+ for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
+ {
+ mrange[0] = hOMasa->block_grouping[block_m_idx];
+ mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
+
+ for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
+ {
+ hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] = 0.0f;
+ hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] = 0.0f;
+ hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] = 0.0f;
+ }
+
+ set_zero( hMasa->data.energy_ism[block_m_idx], num_freq_bands );
+
+ for ( ts = mrange[0]; ts < mrange[1]; ts++ )
+ {
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+ cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
+ }
+
+ /* Compute energy */
+ for ( i = 0; i < num_freq_bands; i++ )
+ {
+ brange[0] = hOMasa->band_grouping[i];
+ brange[1] = hOMasa->band_grouping[i + 1];
+ for ( j = brange[0]; j < brange[1]; j++ )
+ {
+ for ( k = 0; k < nchan_ism; k++ )
+ {
+ hMasa->data.energy_ism[block_m_idx][i] += Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
+ }
+ }
+ }
+
+ /* Compute FOA */
+ /* W */
+ mvr2r( Chnl_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
+ mvr2r( Chnl_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
+ for ( i = 1; i < nchan_ism; i++ )
+ {
+ v_add( Chnl_RealBuffer[i], Foa_RealBuffer[0], Foa_RealBuffer[0], num_freq_bins );
+ v_add( Chnl_ImagBuffer[i], Foa_ImagBuffer[0], Foa_ImagBuffer[0], num_freq_bins );
+ }
+
+ /* Y */
+ v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_RealBuffer[1], num_freq_bins );
+ v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[1][0], Foa_ImagBuffer[1], num_freq_bins );
+ for ( i = 1; i < nchan_ism; i++ )
+ {
+ v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_RealBuffer[1], num_freq_bins );
+ v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[1][i], Foa_ImagBuffer[1], num_freq_bins );
+ }
+
+ /* Z */
+ v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_RealBuffer[2], num_freq_bins );
+ v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[2][0], Foa_ImagBuffer[2], num_freq_bins );
+ for ( i = 1; i < nchan_ism; i++ )
+ {
+ v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_RealBuffer[2], num_freq_bins );
+ v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[2][i], Foa_ImagBuffer[2], num_freq_bins );
+ }
+
+ /* X */
+ v_multc( Chnl_RealBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_RealBuffer[3], num_freq_bins );
+ v_multc( Chnl_ImagBuffer[0], hOMasa->chnlToFoaMtx[3][0], Foa_ImagBuffer[3], num_freq_bins );
+ for ( i = 1; i < nchan_ism; i++ )
+ {
+ v_multc_acc( Chnl_RealBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_RealBuffer[3], num_freq_bins );
+ v_multc_acc( Chnl_ImagBuffer[i], hOMasa->chnlToFoaMtx[3][i], Foa_ImagBuffer[3], num_freq_bins );
+ }
+
+ /* Direction estimation */
+ computeIntensityVector_enc( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, num_freq_bands, intensity_real );
+ computeDirectionVectors( intensity_real[0], intensity_real[1], intensity_real[2], 0, num_freq_bands, direction_vector[0], direction_vector[1], direction_vector[2] );
+
+ /* Power estimation for diffuseness */
+ computeReferencePower_omasa( hOMasa->band_grouping, Foa_RealBuffer, Foa_ImagBuffer, reference_power[ts], 0, num_freq_bands );
+
+ /* Fill buffers of length "averaging_length" time slots for intensity and energy */
+ hOMasa->index_buffer_intensity = ( hOMasa->index_buffer_intensity % DIRAC_NO_COL_AVG_DIFF ) + 1; /* averaging_length = 32 */
+ index = hOMasa->index_buffer_intensity;
+ for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
+ {
+ /* only real part needed */
+ mvr2r( intensity_real[i], &( hOMasa->buffer_intensity_real[i][index - 1][0] ), num_freq_bands );
+ }
+ mvr2r( reference_power[ts], &( hOMasa->buffer_energy[( index - 1 ) * num_freq_bands] ), num_freq_bands );
+
+ computeDiffuseness( hOMasa->buffer_intensity_real, hOMasa->buffer_energy, num_freq_bands, diffuseness_vector );
+
+ for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
+ {
+ norm_tmp = reference_power[ts][band_m_idx] * ( 1 - diffuseness_vector[band_m_idx] );
+
+ hOMasa->direction_vector_m[0][block_m_idx][band_m_idx] += norm_tmp * direction_vector[0][band_m_idx];
+ hOMasa->direction_vector_m[1][block_m_idx][band_m_idx] += norm_tmp * direction_vector[1][band_m_idx];
+ hOMasa->direction_vector_m[2][block_m_idx][band_m_idx] += norm_tmp * direction_vector[2][band_m_idx];
+
+ diffuseness_m[band_m_idx] += reference_power[ts][band_m_idx] * diffuseness_vector[band_m_idx];
+ renormalization_factor_diff[band_m_idx] += reference_power[ts][band_m_idx];
+ }
+ }
+
+ for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
+ {
+ for ( d = 0; d < DIRAC_NUM_DIMS; d++ )
+ {
+ dir_v[d] = hOMasa->direction_vector_m[d][block_m_idx][band_m_idx];
+ }
+ ivas_qmetadata_direction_vector_to_azimuth_elevation( dir_v, &azimuth_m_values[block_m_idx][band_m_idx], &elevation_m_values[block_m_idx][band_m_idx] );
+ }
+ /* Set coherences to zero, as this mode is used at lowest bit rates where the coherences are not transmitted */
+ for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
+ {
+ spreadCoherence[block_m_idx][band_m_idx] = 0.0f;
+ surroundingCoherence[band_m_idx] = 0.0f;
+ }
+ }
+
+ /* Determine energy ratios */
+ for ( band_m_idx = 0; band_m_idx < hOMasa->nbands; band_m_idx++ )
+ {
+ if ( renormalization_factor_diff[band_m_idx] > EPSILON )
+ {
+ diffuseness_m[band_m_idx] /= renormalization_factor_diff[band_m_idx];
+ }
+ else
+ {
+ diffuseness_m[band_m_idx] = 0.0f;
+ }
+
+ energyRatio[band_m_idx] = 1.0f - diffuseness_m[band_m_idx];
+ }
+
+ return;
+}
+
+
+/* Estimate energies and ratios */
+static void ivas_omasa_energy_and_ratio_est(
+ OMASA_ENC_HANDLE hOMasa,
+ MASA_ENCODER_HANDLE hMasa,
+ float data_f[][L_FRAME48k],
+ const int16_t input_frame,
+ const int16_t nchan_inp )
+{
+ int16_t ts, i, j, k;
+ int16_t num_freq_bands;
+ int16_t l_ts;
+ float Chnl_RealBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+ float Chnl_ImagBuffer[MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+ int16_t block_m_idx;
+ int16_t mrange[2], brange[2];
+ float tftile_energy;
+ float ism_ratio_sum;
+
+ num_freq_bands = hOMasa->nbands;
+ l_ts = input_frame / CLDFB_NO_COL_MAX;
+
+ /* do processing over all CLDFB time slots */
+ for ( block_m_idx = 0; block_m_idx < hOMasa->nSubframes; block_m_idx++ )
+ {
+ mrange[0] = hOMasa->block_grouping[block_m_idx];
+ mrange[1] = hOMasa->block_grouping[block_m_idx + 1];
+
+ /* Reset variable */
+ for ( i = 0; i < hOMasa->nbands; i++ )
+ {
+ set_zero( hMasa->data.energy_ratio_ism[block_m_idx][i], nchan_inp );
+ }
+ set_zero( hMasa->data.energy_ism[block_m_idx], num_freq_bands );
+
+ /* Compute CLDFB */
+ for ( ts = mrange[0]; ts < mrange[1]; ts++ )
+ {
+ for ( i = 0; i < nchan_inp; i++ )
+ {
+ cldfbAnalysis_ts( &( data_f[i][l_ts * ts] ), Chnl_RealBuffer[i], Chnl_ImagBuffer[i], l_ts, hOMasa->cldfbAnaEnc[i] );
+ }
+
+ /* Compute energy */
+ for ( i = 0; i < num_freq_bands; i++ )
+ {
+ brange[0] = hOMasa->band_grouping[i];
+ brange[1] = hOMasa->band_grouping[i + 1];
+ for ( j = brange[0]; j < brange[1]; j++ )
+ {
+ for ( k = 0; k < nchan_inp; k++ )
+ {
+ tftile_energy = Chnl_RealBuffer[k][j] * Chnl_RealBuffer[k][j] + Chnl_ImagBuffer[k][j] * Chnl_ImagBuffer[k][j];
+ hMasa->data.energy_ism[block_m_idx][i] += tftile_energy;
+ hMasa->data.energy_ratio_ism[block_m_idx][i][k] += tftile_energy;
+ }
+ }
+ }
+ }
+
+ /* Compute ISM energy ratios */
+ for ( i = 0; i < num_freq_bands; i++ )
+ {
+ ism_ratio_sum = 0.0f;
+ for ( j = 0; j < nchan_inp; j++ )
+ {
+ hMasa->data.energy_ratio_ism[block_m_idx][i][j] /= ( hMasa->data.energy_ism[block_m_idx][i] + EPSILON );
+ ism_ratio_sum += hMasa->data.energy_ratio_ism[block_m_idx][i][j];
+ }
+
+ if ( ism_ratio_sum == 0.0f )
+ {
+ float temp_ism_ratio = 1.0f / ( (float) nchan_inp );
+ for ( j = 0; j < nchan_inp; j++ )
+ {
+ hMasa->data.energy_ratio_ism[block_m_idx][i][j] = temp_ism_ratio;
+ }
+ }
+ }
+ hMasa->data.nchan_ism = nchan_inp;
+ }
+
+ return;
+}
+
+
+/* Compute downmix */
+static void ivas_omasa_dmx(
+ float data_in_f[][L_FRAME48k],
+ float data_out_f[][L_FRAME48k],
+ const int16_t input_frame,
+ const int16_t nchan_transport,
+ const int16_t nchan_ism,
+ ISM_METADATA_HANDLE hIsmMeta[],
+ float prev_gains[][MASA_MAX_TRANSPORT_CHANNELS],
+ const float interpolator[L_FRAME48k] )
+{
+ int16_t i, j, k;
+ float azimuth, elevation;
+ float gains[MASA_MAX_TRANSPORT_CHANNELS];
+ float g1, g2;
+
+
+ for ( i = 0; i < nchan_transport; i++ )
+ {
+ set_zero( data_out_f[i], input_frame );
+ }
+
+ for ( i = 0; i < nchan_ism; i++ )
+ {
+ azimuth = hIsmMeta[i]->azimuth;
+ elevation = hIsmMeta[i]->elevation;
+
+ ivas_get_stereo_panning_gains( azimuth, elevation, gains );
+
+ /* Downmix using the panning gains */
+ for ( j = 0; j < nchan_transport; j++ )
+ {
+ if ( fabsf( gains[j] ) > 0.0 || fabsf( prev_gains[i][j] ) > 0.0f )
+ {
+ for ( k = 0; k < input_frame; k++ )
+ {
+ g1 = interpolator[k];
+ g2 = 1.0f - g1;
+ data_out_f[j][k] += ( g1 * gains[j] + g2 * prev_gains[i][j] ) * data_in_f[i][k];
+ }
+ }
+ prev_gains[i][j] = gains[j];
+ }
+ }
+
+ return;
+}
+
+
+static void computeIntensityVector_enc(
+ const int16_t *band_grouping,
+ float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
+ float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX],
+ const int16_t num_frequency_bands,
+ float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] )
+{
+ /* Reminder
+ * X = a + ib; Y = c + id
+ * X*Y = ac - bd + i(ad +bc)
+ */
+ int16_t i, j;
+ float real, img;
+ int16_t brange[2];
+
+ for ( i = 0; i < num_frequency_bands; i++ )
+ {
+ brange[0] = band_grouping[i];
+ brange[1] = band_grouping[i + 1];
+
+ intensity_real[0][i] = 0;
+ intensity_real[1][i] = 0;
+ intensity_real[2][i] = 0;
+
+ for ( j = brange[0]; j < brange[1]; j++ )
+ {
+ real = Cldfb_RealBuffer[0][j];
+ img = Cldfb_ImagBuffer[0][j];
+ intensity_real[0][i] += Cldfb_RealBuffer[3][j] * real + Cldfb_ImagBuffer[3][j] * img; /* Intensity is XYZ order, audio is WYZX order. */
+ intensity_real[1][i] += Cldfb_RealBuffer[1][j] * real + Cldfb_ImagBuffer[1][j] * img;
+ intensity_real[2][i] += Cldfb_RealBuffer[2][j] * real + Cldfb_ImagBuffer[2][j] * img;
+ }
+ }
+
+ return;
+}
+
+
+static void computeReferencePower_omasa(
+ const int16_t *band_grouping, /* i : Band grouping for estimation */
+ float Cldfb_RealBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Real part of input signal */
+ float Cldfb_ImagBuffer[FOA_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : Imag part of input signal */
+ float *reference_power, /* o : Estimated power */
+ const int16_t enc_param_start_band, /* i : first band to process */
+ const int16_t num_freq_bands /* i : Number of frequency bands */
+)
+{
+ int16_t brange[2];
+ int16_t ch_idx, i, j;
+
+ for ( i = 0; i < num_freq_bands; i++ )
+ {
+ brange[0] = band_grouping[i + enc_param_start_band];
+ brange[1] = band_grouping[i + enc_param_start_band + 1];
+ reference_power[i] = 0;
+
+ for ( ch_idx = 0; ch_idx < FOA_CHANNELS; ch_idx++ )
+ {
+ /* abs()^2 */
+ for ( j = brange[0]; j < brange[1]; j++ )
+ {
+ reference_power[i] += ( Cldfb_RealBuffer[ch_idx][j] * Cldfb_RealBuffer[ch_idx][j] ) + ( Cldfb_ImagBuffer[ch_idx][j] * Cldfb_ImagBuffer[ch_idx][j] );
+ }
+ }
+ }
+
+ v_multc( reference_power, 0.5f, reference_power, num_freq_bands );
+
+ return;
+}
+
+#endif /* MASA_AND_OBJECTS */
diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c
index 7cf68d677dd3939231d2cd2680cc1bde6285eaa7..a811ed164dfd8f004d842a3fb2930a055429f445 100644
--- a/lib_enc/ivas_qmetadata_enc.c
+++ b/lib_enc/ivas_qmetadata_enc.c
@@ -63,9 +63,15 @@ static int16_t ivas_qmetadata_entropy_encode_dir( BSTR_ENC_HANDLE hMetaData, IVA
static int16_t ivas_qmetadata_raw_encode_dir( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, const int16_t nbands, const int16_t start_band );
-static int16_t ivas_qmetadata_encode_extended_gr_length( const uint16_t value, const uint16_t alphabet_size, const int16_t gr_param );
+#ifndef MASA_AND_OBJECTS
+static
+#endif
+ int16_t
+ ivas_qmetadata_encode_extended_gr_length( const uint16_t value, const uint16_t alphabet_size, const int16_t gr_param );
+#ifndef MASA_AND_OBJECTS
static void ivas_qmetadata_encode_extended_gr( BSTR_ENC_HANDLE hMetaData, const uint16_t value, const uint16_t alphabet_size, const int16_t gr_param );
+#endif
static int16_t ivas_qmetadata_get_optimal_gr_param( uint16_t *unsigned_data, const int16_t count, const int16_t gr_param_count, int16_t *opt_gr_size );
@@ -129,6 +135,14 @@ static void ivas_qmetadata_reorder_2dir_bands_hr( IVAS_QMETADATA_HANDLE hQMetaDa
static int16_t ivas_qmetadata_quantize_coherence_hr_512( IVAS_QMETADATA *hQMetaData, const int16_t idx_d, const int16_t all_coherence_zero, BSTR_ENC_HANDLE hMetaData, const int16_t bits_coh );
+#ifdef MASA_AND_OBJECTS
+static int16_t write_stream_dct_coeffs_omasa( int16_t *q_idx, const int16_t len_stream, BSTR_ENC_HANDLE hMetaData, const int16_t first_line, const int16_t low_bitrate_mode );
+
+static int16_t find_optimal_GR_order( const int16_t *q_idx, const int16_t len, int16_t *GR );
+
+static int16_t find_optimal_GR_orders( const int16_t *q_idx, const int16_t len, const int16_t len_max_GR1, int16_t *GR1, int16_t *GR2, int16_t *i_min );
+#endif
+
/*-----------------------------------------------------------------------*
* ivas_qmetadata_enc_encode()
@@ -759,6 +773,7 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512(
bits_no_dirs_coh +=
#endif
write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands );
+#ifdef FIX_566_2DIR_MASA_384K
d = 0;
for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ )
{
@@ -775,6 +790,7 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512(
d++;
}
}
+#endif
for ( i = hQMetaData->numTwoDirBands; i < hQMetaData->q_direction[0].cfg.nbands; i++ )
{
set_f( hQMetaData->q_direction[1].band_data[i].energy_ratio, 0.0f, hQMetaData->q_direction[1].cfg.nblocks );
@@ -1620,7 +1636,9 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512(
}
}
#else
+#ifdef FIX_566_2DIR_MASA_384K
float ratioSum;
+#endif
for ( j = hQMetaData->q_direction[1].cfg.start_band; j < hQMetaData->q_direction[1].cfg.nbands; ++j )
{
for ( k = 0; k < hQMetaData->q_direction[1].cfg.nblocks; k++ )
@@ -1629,12 +1647,19 @@ static void ivas_qmetadata_quantize_diffuseness_nrg_ratios_hr_512(
push_next_indice( hMetaData, index, MASA_BITS_ER_HR );
hQMetaData->q_direction[1].band_data[j].energy_ratio_index[k] = index;
hQMetaData->q_direction[1].band_data[j].energy_ratio[k] = 1.0f - diffuseness_reconstructions_hr[index];
+#ifdef FIX_566_2DIR_MASA_384K
ratioSum = hQMetaData->q_direction[0].band_data[j].energy_ratio[k] + hQMetaData->q_direction[1].band_data[j].energy_ratio[k];
if ( ratioSum > 1.0f )
{
hQMetaData->q_direction[0].band_data[j].energy_ratio[k] /= ratioSum;
hQMetaData->q_direction[1].band_data[j].energy_ratio[k] /= ratioSum;
}
+#else
+ if ( hQMetaData->q_direction[1].band_data[j].energy_ratio[k] > 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[k] )
+ {
+ hQMetaData->q_direction[1].band_data[j].energy_ratio[k] = 1.0f - hQMetaData->q_direction[0].band_data[j].energy_ratio[k];
+ }
+#endif
needed_bits[1] += MASA_BITS_ER_HR;
hQMetaData->q_direction[1].band_data[j].bits_sph_idx[k] = bits_dir_hr;
}
@@ -3162,10 +3187,14 @@ static int16_t ivas_qmetadata_get_optimal_gr_param(
*
*------------------------------------------------------------------------*/
-static int16_t ivas_qmetadata_encode_extended_gr_length(
- const uint16_t value,
- const uint16_t alphabet_size,
- const int16_t gr_param )
+#ifndef MASA_AND_OBJECTS
+static
+#endif
+ int16_t
+ ivas_qmetadata_encode_extended_gr_length(
+ const uint16_t value,
+ const uint16_t alphabet_size,
+ const int16_t gr_param )
{
uint16_t msb_alphabet_size;
int16_t bits;
@@ -3305,11 +3334,15 @@ static int16_t ivas_qmetadata_reorder_azimuth_index(
*
*------------------------------------------------------------------------*/
-static void ivas_qmetadata_encode_extended_gr(
- BSTR_ENC_HANDLE hMetaData,
- const uint16_t value,
- const uint16_t alphabet_size,
- const int16_t gr_param )
+#ifndef MASA_AND_OBJECTS
+static
+#endif
+ void
+ ivas_qmetadata_encode_extended_gr(
+ BSTR_ENC_HANDLE hMetaData,
+ const uint16_t value,
+ const uint16_t alphabet_size,
+ const int16_t gr_param )
{
uint16_t msb_alphabet_size;
uint16_t msb, lsb, cnt;
@@ -3504,7 +3537,7 @@ static int16_t truncGR0(
*-------------------------------------------------------------------*/
static int16_t truncGR0_chan(
- float *data,
+ const float *data,
float *data_hat,
uint16_t *data_idx,
const int16_t len,
@@ -6057,3 +6090,495 @@ static float direction_distance(
return d / (float) ( dim1 * dim2 );
}
#endif
+
+#ifdef MASA_AND_OBJECTS
+
+static int16_t divide_GR_orders(
+ const int16_t *q_idx,
+ const int16_t GR1,
+ const int16_t GR2,
+ const int16_t len,
+ const int16_t len_max_GR1,
+ int16_t *i_min )
+{
+ int16_t nb_GR_min;
+ int16_t i, j, nb_GR;
+ nb_GR_min = 1000;
+ *i_min = -1;
+ for ( i = 0; i < min( len_max_GR1, len ); i++ )
+ {
+ nb_GR = 0;
+
+ for ( j = 0; j <= i; j++ )
+ {
+ nb_GR += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
+ }
+ for ( j = i + 1; j < len; j++ )
+ {
+ nb_GR += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
+ }
+
+ if ( nb_GR < nb_GR_min )
+ {
+ nb_GR_min = nb_GR;
+ *i_min = i + 1;
+ }
+ }
+
+ return nb_GR_min;
+}
+
+
+static int16_t find_optimal_GR_order(
+ const int16_t *q_idx,
+ const int16_t len,
+ int16_t *GR )
+{
+ int16_t nb_GR_0, nb_GR_1;
+ int16_t i;
+ /* find optimum length of the part encoded with GR2 */
+ nb_GR_0 = 0;
+ nb_GR_1 = 0;
+ for ( i = 0; i < len; i++ )
+ {
+ nb_GR_0 += ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 0 );
+ nb_GR_1 += ivas_qmetadata_encode_extended_gr_length( q_idx[i], 100, 1 );
+ }
+
+ if ( nb_GR_0 < nb_GR_1 )
+ {
+ *GR = 0;
+ return nb_GR_0;
+ }
+ else
+ {
+ *GR = 1;
+
+ return nb_GR_1;
+ }
+}
+
+
+static int16_t find_optimal_GR_orders(
+ const int16_t *q_idx,
+ const int16_t len,
+ const int16_t len_max_GR1,
+ int16_t *GR1,
+ int16_t *GR2,
+ int16_t *i_min )
+{
+ int16_t nb_GR_20, nb_GR_21, nb_GR_10, nb_GR_min;
+ int16_t i_min_20, i_min_21, i_min_10;
+ /* find optimum length of the part encoded with GR2 */
+ nb_GR_20 = divide_GR_orders( q_idx, 2, 0, len, len_max_GR1, &i_min_20 );
+ nb_GR_21 = divide_GR_orders( q_idx, 2, 1, len, len_max_GR1, &i_min_21 );
+ nb_GR_10 = divide_GR_orders( q_idx, 1, 0, len, len_max_GR1, &i_min_10 );
+
+ if ( nb_GR_20 < nb_GR_21 && nb_GR_20 < nb_GR_10 )
+ {
+ *GR1 = 2;
+ *GR2 = 0;
+ nb_GR_min = nb_GR_20;
+ *i_min = i_min_20;
+ }
+ else
+ {
+ if ( nb_GR_21 < nb_GR_20 && nb_GR_21 < nb_GR_10 )
+ {
+ *GR1 = 2;
+ *GR2 = 1;
+ nb_GR_min = nb_GR_21;
+ *i_min = i_min_21;
+ }
+ else
+ {
+ *GR1 = 1;
+ *GR2 = 0;
+ nb_GR_min = nb_GR_10;
+ *i_min = i_min_10;
+ }
+ }
+
+ return nb_GR_min;
+}
+
+
+static int16_t write_stream_dct_coeffs_omasa(
+ int16_t *q_idx, /* i: array of indexes to be written */
+ const int16_t len_stream, /* i: array length */
+ BSTR_ENC_HANDLE hMetaData, /* i/o: metadata bitstream */
+ const int16_t first_line, /* i: is first line of the matrix? 1/0*/
+ const int16_t low_bitrate_mode /* i: is low bitrate mode? if yes, limit the number of bits written */
+)
+{
+ int16_t nb_bits = 0, bits_pos;
+ uint16_t nb_GR_min;
+ int16_t i, j;
+ int16_t changed, update_needed;
+
+ int16_t GR1, GR2, i_min;
+ int16_t max_bits;
+
+ bits_pos = hMetaData->nb_bits_tot;
+ if ( low_bitrate_mode == 1 )
+ {
+ max_bits = 50; /* To do : find optimal allowed value*/
+ }
+ else
+ {
+ max_bits = 1000;
+ }
+ /* write DCT 0 component */
+ /* write sign only if not the very first DCT coeff */
+ if ( first_line == 0 )
+ {
+ if ( q_idx[0] > 0 )
+ {
+ push_next_indice( hMetaData, 1, 1 );
+ push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
+ }
+ else
+ {
+ push_next_indice( hMetaData, 0, 1 );
+ push_next_indice( hMetaData, -q_idx[0], BITS_MASA2TOTTAL_DCT0 );
+ }
+ nb_bits += BITS_MASA2TOTTAL_DCT0 + 1;
+ }
+ else
+ {
+ push_next_indice( hMetaData, q_idx[0], BITS_MASA2TOTTAL_DCT0 );
+ nb_bits += BITS_MASA2TOTTAL_DCT0;
+ }
+
+
+ if ( q_idx[0] != 0 )
+ {
+ i_min = 1;
+ GR2 = 0;
+ if ( len_stream >= 8 )
+ {
+ nb_GR_min = find_optimal_GR_orders( &q_idx[1], len_stream - 1, 15, &GR1, &GR2, &i_min );
+ }
+ else
+ {
+ nb_GR_min = find_optimal_GR_order( &q_idx[1], len_stream - 1, &GR1 );
+ }
+
+ assert( nb_GR_min < 1000 );
+ changed = 1;
+ update_needed = 0;
+ while ( len_stream >= 8 && nb_GR_min > max_bits && changed >= 1 )
+ {
+ update_needed = 1;
+ changed = 0;
+ for ( j = len_stream - 1; j > 6; j-- )
+ {
+ if ( q_idx[j] >= 2 )
+ {
+
+ if ( j > i_min )
+ {
+ changed = 1;
+ nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
+ q_idx[j] -= 2;
+ nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
+ }
+ else
+ {
+ changed = 1;
+ nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
+ q_idx[j] -= 2;
+ nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 );
+ }
+ }
+ else if ( q_idx[j] == 1 )
+ {
+ if ( j > i_min )
+ {
+ changed = 1;
+ nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
+ q_idx[j] -= 1;
+
+ nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR2 );
+ }
+ else
+ {
+ changed = 1;
+ nb_GR_min -= ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, GR1 );
+ q_idx[j] -= 1;
+ nb_GR_min += ivas_qmetadata_encode_extended_gr_length( q_idx[j], 100, 0 );
+ }
+ }
+ if ( nb_GR_min < max_bits )
+ {
+ break;
+ }
+ }
+ }
+ if ( update_needed == 1 )
+ {
+ /* re-calculate */
+ /* find optimum length of the part encoded with GR2 */
+ nb_GR_min = find_optimal_GR_orders( &q_idx[1], len_stream - 1, 15, &GR1, &GR2, &i_min );
+ }
+
+ if ( len_stream >= 8 )
+ {
+ /* write number of indexes encoded with GR2 on 4 bits */
+ push_next_indice( hMetaData, i_min, 4 );
+ nb_bits += 4;
+ /* write GR orders */
+ push_next_indice( hMetaData, GR1 - 1, 1 );
+ nb_bits += 1;
+ if ( GR1 == 2 )
+ {
+ push_next_indice( hMetaData, GR2, 1 );
+ nb_bits += 1;
+ }
+
+ /* write GR data */
+ for ( i = 1; i <= i_min; i++ )
+ {
+ ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 );
+ }
+
+ for ( i = i_min + 1; i < len_stream; i++ )
+ {
+ ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR2 );
+ }
+ }
+ else
+ {
+ /* len_stream <= 8 */
+ /* write GR order */
+ push_next_indice( hMetaData, GR1, 1 );
+ nb_bits += 1;
+ for ( i = 1; i < len_stream; i++ )
+ {
+ ivas_qmetadata_encode_extended_gr( hMetaData, q_idx[i], 100, GR1 );
+ }
+ }
+
+ nb_bits += nb_GR_min;
+
+ assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
+ }
+
+ return nb_bits;
+}
+
+
+/*-------------------------------------------------------------------------
+ * encode_masa_to_total()
+ *
+ *------------------------------------------------------------------------*/
+
+void encode_masa_to_total(
+ IVAS_QMETADATA_HANDLE hQMetaData,
+ BSTR_ENC_HANDLE hMetaData,
+ const int16_t low_bitrate_mode,
+ const int16_t nbands,
+ const int16_t nblocks )
+{
+ int16_t i, j, k;
+ float data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ float q_dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ float step = STEP_M2T;
+ int16_t q_idx[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ float dct_data_tmp[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ float dct_data[MAX_PARAM_SPATIAL_SUBFRAMES * MASA_FREQUENCY_BANDS];
+ int16_t bits_pos, nb_bits;
+ int16_t n_streams, len_stream;
+
+#ifdef DEBUG_MODE_QMETADATA
+ static FILE *pF = NULL;
+ static FILE *pF_ratio = NULL;
+
+ if ( pF == NULL )
+ pF = fopen( "./res/qmetadata_ism_qidx__enc.txt", "w" );
+ if ( pF_ratio == NULL )
+ pF_ratio = fopen( "./res/qmetadata_masa2tot_enc.txt", "w" );
+
+#endif
+
+ bits_pos = hMetaData->nb_bits_tot;
+ k = 0;
+ for ( i = 0; i < nbands; i++ )
+ {
+ for ( j = 0; j < nblocks; j++ )
+ {
+ data[k] = hQMetaData->masa_to_total_energy_ratio[j][i];
+ k++;
+ }
+ }
+
+ /* DCT2 transform */
+ n_streams = 1;
+ len_stream = nbands * nblocks;
+ switch ( len_stream )
+ {
+ case 4:
+ matrix_product( dct4, nblocks, nblocks, 0, data, 1, nblocks, 1, dct_data );
+ n_streams = 1;
+ len_stream = 4;
+ break;
+ case 5:
+ matrix_product( dct5, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
+ n_streams = 1;
+ len_stream = nbands;
+ break;
+ case 8:
+ matrix_product( dct8, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
+ n_streams = 1;
+ len_stream = nbands;
+ break;
+ case 12:
+ matrix_product( dct12, nbands, nbands, 0, data, 1, nbands, 1, dct_data );
+ n_streams = 1;
+ len_stream = nbands;
+ break;
+ case 20:
+ matrix_product( dct5, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 1, dct_data );
+ n_streams = 1;
+ len_stream = nbands * nblocks;
+ break;
+ case 32:
+ matrix_product( dct8, nbands, nbands, 0, data, nblocks, nbands, 1, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 1, dct_data );
+ n_streams = nblocks;
+ len_stream = nbands;
+ break;
+ default:
+ printf( "Incorrect number of coefficients for OMASA.\n" );
+ break;
+ }
+
+ for ( k = 0; k < n_streams; k++ )
+ {
+ j = k * len_stream;
+ /* quantize with fixed common step */
+ q_idx[j] = (int16_t) rintf( dct_data[j] / step );
+
+ if ( q_idx[j] > ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 ) ) /* limit DCT0 to BITS_MASA2TOTTAL_DCT0 bit representation */
+ {
+ q_idx[j] = ( ( 1 << BITS_MASA2TOTTAL_DCT0 ) - 1 );
+ }
+
+ q_dct_data[j] = step * q_idx[j];
+
+ if ( q_idx[j] == 0 )
+ {
+ set_s( &q_idx[j], 0, len_stream );
+ set_zero( &q_dct_data[j], len_stream );
+ }
+ else
+ {
+ for ( i = 1; i < len_stream; i++ )
+ {
+ q_idx[j + i] = (int16_t) rintf( dct_data[j + i] / step );
+ q_dct_data[j + i] = step * q_idx[j + i];
+ if ( q_idx[j + i] <= 0 )
+ {
+ q_idx[j + i] = -2 * q_idx[j + i];
+ }
+ else
+ {
+ q_idx[j + i] = 2 * q_idx[j + i] - 1;
+ }
+ }
+ }
+ }
+
+ /* write data */
+ nb_bits = 0;
+ for ( i = 0; i < n_streams; i++ )
+ {
+ nb_bits += write_stream_dct_coeffs_omasa( &q_idx[i * len_stream], len_stream, hMetaData, ( i == 0 ), low_bitrate_mode );
+ }
+
+ /* reconstruct masa2total */
+ q_dct_data[0] = q_idx[0] * step;
+ for ( i = 1; i < len_stream; i++ )
+ {
+ if ( ( q_idx[i] % 2 ) == 0 )
+ {
+ q_dct_data[i] = -( q_idx[i] >> 1 ) * step;
+ }
+ else
+ {
+ q_dct_data[i] = ( ( q_idx[i] + 1 ) >> 1 ) * step;
+ }
+ }
+
+ /* inverse DCT2 transform */
+ switch ( len_stream )
+ {
+ case 4:
+ matrix_product( dct4, nblocks, nblocks, 1, q_dct_data, nblocks, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nblocks );
+ break;
+ case 5:
+ matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 8:
+ matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 12:
+ matrix_product( dct12, nbands, nbands, 1, q_dct_data, nbands, 1, 0, dct_data_tmp );
+ mvr2r( dct_data_tmp, q_dct_data, nbands );
+ break;
+ case 20:
+ matrix_product( dct5, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data ); /* reuse of variable*/
+ break;
+ case 32:
+ matrix_product( dct8, nbands, nbands, 1, q_dct_data, nbands, nblocks, 0, dct_data_tmp );
+ matrix_product( dct_data_tmp, nbands, nblocks, 0, dct4, nblocks, nblocks, 0, q_dct_data );
+ break;
+ default:
+ printf( "Incorrect number of coefficients for OMASA.\n" );
+ break;
+ }
+
+ k = 0;
+ for ( i = 0; i < nblocks; i++ )
+ {
+ for ( j = 0; j < nbands; j++ )
+ {
+ hQMetaData->masa_to_total_energy_ratio[i][j] = max( 0.0f, q_dct_data[k] );
+ hQMetaData->masa_to_total_energy_ratio[i][j] = min( 1.0f, hQMetaData->masa_to_total_energy_ratio[i][j] );
+ k++;
+ }
+ }
+ assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) );
+
+#ifdef DEBUG_MODE_QMETADATA
+ {
+
+ fprintf( pF, "frame %d: ", frame );
+ fprintf( pF_ratio, "frame %d: ", frame );
+
+
+ /* direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist );*/
+ for ( i = 0; i < nbands; i++ )
+ {
+ for ( j = 0; j < 4; j++ )
+ {
+ fprintf( pF_ratio, " %5.2f ", hQMetaData->masa_to_total_energy_ratio[j][i] );
+ }
+ }
+ for ( i = 0; i < 20; i++ )
+ {
+ fprintf( pF, " %4d ", q_idx[i] );
+ }
+ fprintf( pF, "\n" );
+ fprintf( pF_ratio, "\n" );
+ }
+#endif
+
+ return;
+}
+#endif
diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c
index ce24de702d8382fd4b7d14d8f6d348cc0bd5f891..a031d6df288ee817f891256e8bbb9cd3e1d724d8 100644
--- a/lib_enc/ivas_rom_enc.c
+++ b/lib_enc/ivas_rom_enc.c
@@ -837,11 +837,13 @@ const HUFF_TABLE huff_beta_table[2] =
const int16_t mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3};
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
/*----------------------------------------------------------------------------------*
* ParamMC ROM tables
*----------------------------------------------------------------------------------*/
const float param_mc_ild_diff_threshold[20] = { 8.0f, 8.0f, 10.0f, 20.0f,
20.0f, 20.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 20.0f };
+#endif
/* clang-format on */
diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h
index fa45706cab5082c87232c012f9ce9fcc36602433..170bf3182035352994fe7e57ae24d55cc84bb24f 100644
--- a/lib_enc/ivas_rom_enc.h
+++ b/lib_enc/ivas_rom_enc.h
@@ -130,10 +130,12 @@ extern const HUFF_TABLE huff_alpha_table[2];
extern const HUFF_TABLE huff_beta_table[2];
extern const int16_t mc_paramupmix_fb_remix_order[4];
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
/*----------------------------------------------------------------------------------*
* ParamMC ROM tables
*----------------------------------------------------------------------------------*/
extern const float param_mc_ild_diff_threshold[20];
+#endif
#endif
diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c
index b9e6a85527391784ef7c985671cc7e5977fdef93..07ba653dcde494d05ec9f1389fe07860461b3c1f 100644
--- a/lib_enc/ivas_sce_enc.c
+++ b/lib_enc/ivas_sce_enc.c
@@ -143,7 +143,11 @@ ivas_error ivas_sce_enc(
/* set "bits_frame_nominal" */
if ( st_ivas->hQMetaData != NULL && st_ivas->hSpar == NULL )
{
+#ifdef MASA_AND_OBJECTS
+ if ( ( ( st_ivas->mc_mode == MC_MODE_MCMASA ) && ( st_ivas->hEncoderConfig->ivas_total_brate >= MCMASA_SEPARATE_BRATE ) ) || ( st_ivas->ism_mode >= ISM_MASA_MODE_MASA_ONE_OBJ ) )
+#else
if ( st_ivas->mc_mode == MC_MODE_MCMASA && st_ivas->hEncoderConfig->ivas_total_brate >= MCMASA_SEPARATE_BRATE )
+#endif
{
st->bits_frame_nominal = (int16_t) ( hSCE->element_brate / FRAMES_PER_SEC );
}
@@ -206,6 +210,19 @@ ivas_error ivas_sce_enc(
reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata );
+#ifdef MASA_AND_OBJECTS
+ /*----------------------------------------------------------------*
+ * Combined format coding: get the ISM importance and the bit-rate
+ *----------------------------------------------------------------*/
+
+ if ( ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
+ {
+ set_ism_importance_interformat( hSCE->element_brate, 1, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->hMasa->data.lp_noise_CPE, &st_ivas->hIsmMetaData[0]->ism_imp );
+
+ st->total_brate = ivas_interformat_brate( ISM_MASA_MODE_PARAM_ONE_OBJ, 1, hSCE->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 ) - nb_bits_metadata * FRAMES_PER_SEC;
+ }
+#endif
+
/*----------------------------------------------------------------*
* Write IVAS format signaling in SID frames
*----------------------------------------------------------------*/
@@ -224,6 +241,12 @@ ivas_error ivas_sce_enc(
{
st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->core_brate, 0, 0, -1, -1 );
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st->low_rate_mode )
+ {
+ st->flag_ACELP16k = 0;
+ }
+#endif
else
{
st->flag_ACELP16k = set_ACELP_flag( IVAS_SCE, hSCE->element_brate, st->total_brate, 0, 0, -1, -1 );
@@ -337,6 +360,13 @@ ivas_error create_sce_enc(
copy_encoder_config( st_ivas, st, 1 );
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->hEncoderConfig->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC ) )
+ {
+ st->element_mode = IVAS_SCE;
+ }
+#endif
+
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;
diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c
index 757f772b13a3a4bf4cc956ea90fdfb598f86ea51..e07f51e86c62ad05e951a95725030fa16fe5ce44 100644
--- a/lib_enc/ivas_spar_md_enc.c
+++ b/lib_enc/ivas_spar_md_enc.c
@@ -45,7 +45,7 @@
/*------------------------------------------------------------------------------------------*
* PreProcessor
*------------------------------------------------------------------------------------------*/
-#define IVAS_MAX_MD_BYTES ( 1000 )
+#define IVAS_MAX_MD_BYTES ( 1000 ) // ToDo: not used
static const float pr_boost_range[2] = { 0.1f, 0.4f };
diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h
index 59abb33a0ad56ce2136fcb9716b4ec5bb5b27788..9e97acc5f238ec79b56a8d63bb1ac63179e241c3 100644
--- a/lib_enc/ivas_stat_enc.h
+++ b/lib_enc/ivas_stat_enc.h
@@ -729,7 +729,9 @@ typedef struct ivas_param_mc_enc_data_structure
int16_t lfe_index;
int16_t icc_map_index[PARAM_MC_PARAMETER_FRAMES][PARAM_MC_SZ_ICC_MAP];
int16_t max_param_band_abs_cov;
+#ifdef FIX_580_PARAMMC_ENER_BURSTS
float prev_ilds[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_SZ_ILD_MAP];
+#endif
float ener_fac[PARAM_MC_MAX_PARAMETER_BANDS];
@@ -780,6 +782,16 @@ typedef struct ivas_masa_sync_struct
typedef struct ivas_masa_encoder_data_struct
{
float energy[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
+#ifdef MASA_AND_OBJECTS
+ float energy_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS]; /* TODO Nokia: Make an own MASAISM struct for these, and reserve it only for OMASA */
+ float energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS];
+ int16_t nchan_ism;
+ float lp_noise_CPE; /* LP filterend total noise estimation */
+ int16_t omasa_stereo_sw_cnt;
+ int16_t omasa_stereo_sw_cnt2;
+#endif
+
int16_t num_Cldfb_instances;
HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_ENC_CLDFB_INSTANCES];
int16_t band_mapping[MASA_FREQUENCY_BANDS + 1];
@@ -866,6 +878,46 @@ typedef struct ivas_mcmasa_enc_data_structure
} MCMASA_ENC_DATA, *MCMASA_ENC_HANDLE;
+#ifdef MASA_AND_OBJECTS
+/*----------------------------------------------------------------------------------*
+ * Object MASA (OMASA) encoder structure
+ *----------------------------------------------------------------------------------*/
+
+typedef struct ivas_omasa_enc_data_structure
+{
+ uint8_t nbands;
+ uint8_t nCodingBands;
+ uint8_t nSubframes;
+
+ /* CLDFB analysis */
+ int16_t num_Cldfb_instances;
+ HANDLE_CLDFB_FILTER_BANK cldfbAnaEnc[MAX_NUM_OBJECTS];
+
+ /* DirAC parameter estimation */
+ float **direction_vector_m[DIRAC_NUM_DIMS]; /* Average direction vector */
+ int16_t band_grouping[MASA_FREQUENCY_BANDS + 1];
+ int16_t block_grouping[5];
+
+ /* diffuseness */
+ int16_t index_buffer_intensity;
+ float *buffer_intensity_real[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF];
+ float buffer_energy[DIRAC_NO_COL_AVG_DIFF * MASA_FREQUENCY_BANDS];
+
+ float chnlToFoaMtx[DIRAC_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS];
+
+ float interpolator[L_FRAME48k];
+
+ float prev_object_dm_gains[MAX_NUM_OBJECTS][MASA_MAX_TRANSPORT_CHANNELS];
+ float broadband_energy_sm[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
+ float broadband_energy_prev[MAX_NUM_OBJECTS + MASA_MAX_TRANSPORT_CHANNELS];
+ int16_t prev_selected_object;
+ uint8_t changing_object;
+ float fade_out_gain[L_FRAME48k];
+ float fade_in_gain[L_FRAME48k];
+
+} OMASA_ENC_DATA, *OMASA_ENC_HANDLE;
+#endif
+
/*----------------------------------------------------------------------------------*
* Stereo CNG handle
@@ -934,6 +986,9 @@ typedef struct cpe_enc_data_structure
float *input_mem[CPE_CHANNELS]; /* input channels buffers memory; needed to be up-to-date for TD->DFT stereo switching */
+#ifdef MASA_AND_OBJECTS
+ int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */
+#endif
#ifdef DEBUGGING
int16_t stereo_mode_cmdl; /* stereo mode forced from the commaand-line */
#endif
@@ -1059,6 +1114,9 @@ typedef struct stereo_dmx_evs_enc_data_structure
typedef struct ivas_lfe_enc_data_structure
{
+#ifndef FIX_572_LFE_LPF_ENC
+ ivas_filters_process_state_t filter_state;
+#endif
LFE_WINDOW_HANDLE pWindow_state;
BSTR_ENC_HANDLE hBstr; /* pointer to encoder bitstream handle */
const uint16_t *cum_freq_models[IVAS_MAX_NUM_QUANT_STRATS][IVAS_MAX_NUM_DCT_COEF_GROUPS];
@@ -1160,8 +1218,13 @@ typedef struct
PARAM_MC_ENC_HANDLE hParamMC; /* Parametric MC handle */
MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix; /* MC Param-Upmix handle */
MCMASA_ENC_HANDLE hMcMasa; /* Multi-channel MASA data handle */
+#ifdef MASA_AND_OBJECTS
+ OMASA_ENC_HANDLE hOMasa; /* Object-MASA data handle */
+#endif
LFE_ENC_HANDLE hLFE; /* LFE data handle */
+#ifdef FIX_572_LFE_LPF_ENC
ivas_filters_process_state_t *hLfeLpf; /* low pass filter state for LFE */
+#endif
ISM_MODE ism_mode; /* ISM format mode */
MC_MODE mc_mode; /* MC format mode */
diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c
index 555a27d72566c143ff713b6b23a714e8d3b4c4b6..5d672616fc6dbaa31654e16b8340fec07dfe5313 100644
--- a/lib_enc/ivas_stereo_classifier.c
+++ b/lib_enc/ivas_stereo_classifier.c
@@ -107,8 +107,10 @@ int16_t select_stereo_mode(
/* set binary flag indicating LRTD mode based on unclr/xtalk classifiers' decisions */
hStereoClassif->prev_lrtd_mode = hStereoClassif->lrtd_mode;
+#ifdef FIX_UNCLR_ISSUE
hStereoClassif->unclr_decision = ( hStereoClassif->unclr_decision && hCPE->hCoreCoder[0]->flag_noisy_speech_snr == 0 &&
hCPE->element_brate > IVAS_16k4 );
+#endif
hStereoClassif->lrtd_mode = ( ( hStereoClassif->unclr_decision | hStereoClassif->xtalk_decision ) && is_speech );
stereo_switching_flag = 1;
@@ -121,7 +123,11 @@ int16_t select_stereo_mode(
stereo_switching_flag = 0;
}
+#ifdef MASA_AND_OBJECTS
+ if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO && !( hCPE->element_brate == IVAS_48k && ivas_total_brate == IVAS_32k ) ) /* the second condition for PARAM mode OMASA */
+#else
if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO )
+#endif
{
hStereoClassif->prev_lrtd_mode = 0;
hStereoClassif->lrtd_mode = 0;
@@ -208,8 +214,6 @@ int16_t select_stereo_mode(
set_f( hStereoClassif->xtalk_fv, -1.0f, SSC_MAX_NFEA );
}
}
-
-
#ifdef DEBUG_MODE_TD
dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, L_FRAME16k, "res/unclr_decision.enc" );
dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, L_FRAME16k, "res/xtalk_decision.enc" );
diff --git a/lib_enc/ivas_stereo_eclvq_enc.c b/lib_enc/ivas_stereo_eclvq_enc.c
index f71beece823e102c87ec95b1943e70956685e1e7..71f0bc805fd910a6fc96fe3994022d08a590d8c2 100644
--- a/lib_enc/ivas_stereo_eclvq_enc.c
+++ b/lib_enc/ivas_stereo_eclvq_enc.c
@@ -41,7 +41,11 @@
#include "prot.h"
#include "wmc_auto.h"
/* used only for norm_s in the code_length_from_count function */
+#ifdef FIX_593_STL_INCLUDE
#include "stl.h"
+#else
+#include "basop32.h"
+#endif
/*---------------------------------------------------------------
diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c
index 16970d31db8915cdedbca914fab51b691e6ccdfb..2c428726b25379e24a98229305f67c3707098791 100755
--- a/lib_enc/ivas_stereo_mdct_core_enc.c
+++ b/lib_enc/ivas_stereo_mdct_core_enc.c
@@ -173,6 +173,15 @@ void stereo_mdct_core_enc(
sts[0]->hTcxEnc->tfm_mem = sts[1]->hTcxEnc->tfm_mem = sqrtf( 0.5f * ( sts[0]->hTcxEnc->tfm_mem * sts[0]->hTcxEnc->tfm_mem + sts[1]->hTcxEnc->tfm_mem * sts[1]->hTcxEnc->tfm_mem ) ); /* RMS */
sts[0]->hTcxEnc->tcxltp_norm_corr_past = sts[1]->hTcxEnc->tcxltp_norm_corr_past = 0.5f * ( sts[0]->hTcxEnc->tcxltp_norm_corr_past + sts[1]->hTcxEnc->tcxltp_norm_corr_past );
+
+#if 0
+ if ( sts[0]->bits_frame_channel + sts[1]->bits_frame_channel - meta_bits < 495 )
+ {
+ sts[0]->hTranDet->transientDetector.bIsAttackPresent = 0;
+ sts[1]->hTranDet->transientDetector.bIsAttackPresent = 0;
+ }
+#endif
+
for ( ch = 0; ch < CPE_CHANNELS; ch++ )
{
st = sts[ch];
@@ -449,7 +458,11 @@ void stereo_mdct_core_enc(
sts[ch]->total_brate = ( sts[ch]->bits_frame_channel + sts[ch]->side_bits_frame_channel ) * FRAMES_PER_SEC;
}
stereo_bits += SMDCT_NBBITS_SPLIT_RATIO;
+#ifdef MASA_AND_OBJECTS
+ assert( ( sts[0]->total_brate + sts[1]->total_brate + ( stereo_bits + signal_bits + meta_bits ) * FRAMES_PER_SEC ) == hCPE->element_brate + hCPE->brate_surplus );
+#else
assert( ( sts[0]->total_brate + sts[1]->total_brate + ( stereo_bits + signal_bits + meta_bits ) * FRAMES_PER_SEC ) == hCPE->element_brate );
+#endif
assert( hStereoMdct->split_ratio > 0 && hStereoMdct->split_ratio < SMDCT_BITRATE_RATIO_RANGE );
push_next_indice( hBstr, hStereoMdct->split_ratio, SMDCT_NBBITS_SPLIT_RATIO );
diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc.c
index d959cdba2fc5662d6089185b102fbecde893da9b..3d277e241db16735b4eeb38bb577fdcc08bcb7ab 100755
--- a/lib_enc/ivas_stereo_mdct_stereo_enc.c
+++ b/lib_enc/ivas_stereo_mdct_stereo_enc.c
@@ -1133,15 +1133,29 @@ void initMdctStereoEncData(
set_s( hStereoMdct->mdct_stereo_mode, -1, 2 );
/*Initialize sfb parameteres for TCX20 */
+#ifdef FIX_581_CLANG_OFFSET_TO_NULL
stereo_mdct_init_bands( tcx_coded_lines, TCX_20_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_NORM] : NULL, &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
+#else
+ stereo_mdct_init_bands( tcx_coded_lines, TCX_20_CORE, element_brate, igf, &hIgfGrid[IGF_GRID_LB_NORM], &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
+#endif
/*Initialize sfb parameteres for TCX10 */
+#ifdef FIX_581_CLANG_OFFSET_TO_NULL
stereo_mdct_init_bands( tcx_coded_lines, TCX_10_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_SHORT] : NULL,
&hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
+#else
+ stereo_mdct_init_bands( tcx_coded_lines, TCX_10_CORE, element_brate, igf, &hIgfGrid[IGF_GRID_LB_SHORT],
+ &hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
+#endif
/*Initialize sfb parameteres for transitions */
+#ifdef FIX_581_CLANG_OFFSET_TO_NULL
stereo_mdct_init_bands( tcx_coded_lines, -1, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_TRAN] : NULL,
&hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
+#else
+ stereo_mdct_init_bands( tcx_coded_lines, -1, element_brate, igf, &hIgfGrid[IGF_GRID_LB_TRAN],
+ &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
+#endif
set_s( hStereoMdct->IGFStereoMode, -1, 2 );
diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c
index d2d72c153426b47d40febe4c2079a100de5f2247..8f86f25986666fc103cc62abed98cce81ce7375f 100644
--- a/lib_enc/ivas_stereo_td_analysis.c
+++ b/lib_enc/ivas_stereo_td_analysis.c
@@ -111,6 +111,9 @@ static float Comp_diff_lt_corr( CPE_ENC_HANDLE hCPE, const int16_t IsSideMono, c
*-------------------------------------------------------------------*/
int16_t stereo_tdm_ener_analysis(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+#endif
CPE_ENC_HANDLE hCPE, /* i : CPE structure */
const int16_t input_frame, /* i : Number of samples */
int16_t *tdm_SM_or_LRTD_Pri, /* o : channel combination scheme flag in TD stereo OR LRTD primary channel */
@@ -195,6 +198,17 @@ int16_t stereo_tdm_ener_analysis(
* of L and R needed to create new mono/side signals
*----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == MASA_ISM_FORMAT )
+ {
+
+ if ( ( hCPE->hStereoClassif->lrtd_mode == 1 || hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 1 ) && ( hCPE->element_brate - 50 * FRAMES_PER_SEC + hCPE->brate_surplus + hCPE->brate_surplus < 15000 ) )
+ {
+ hStereoTD->prev_fr_LRTD_TD_dec = 0;
+ }
+ }
+#endif
+
rms_thd = RMS_MIN;
if ( hCPE->hStereoClassif->lrtd_mode == 1 )
{
diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc.c
index a59ac93e49d43a79887e905d9f1fb6f9dfcafa31..858543cf7ee0aa746130dcf986e48e9bd8062b34 100644
--- a/lib_enc/ivas_stereo_td_enc.c
+++ b/lib_enc/ivas_stereo_td_enc.c
@@ -292,8 +292,8 @@ ivas_error stereo_set_tdm(
dbgwrite( &tmp, 2, 1, 320, "res/inst_ratio_L" );
dbgwrite( &ftmp, 4, 1, 320, "res/ratio_L" );
dbgwrite( &tmp, 2, 1, 320, "res/tdm_low_rate_mode" );
- dbgwrite( &tmp, 2, 1, 320, "res/tdm_lp_reuse_flag" );
- dbgwrite( &tmp, 2, 1, 320, "res/mod_ct.enx" );
+ // dbgwrite( &tmp, 2, 1, 320, "res/tdm_lp_reuse_flag" );
+ // dbgwrite( &tmp, 2, 1, 320, "res/mod_ct.enx" );
}
#endif
hCPE->hCoreCoder[0]->tdm_LRTD_flag = 0;
@@ -311,6 +311,10 @@ ivas_error stereo_set_tdm(
*-------------------------------------------------------------------*/
void tdm_configure_enc(
+#ifdef MASA_AND_OBJECTS
+ const int16_t ivas_format, /* i : IVAS format */
+ const int16_t ism_mode, /* i : ISM mode in combined format */
+#endif
CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
const float Etot_last[CPE_CHANNELS], /* i/o: Energy of last frame */
const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */
@@ -426,6 +430,30 @@ void tdm_configure_enc(
sts[1]->coder_type = GENERIC;
}
+#ifdef MASA_AND_OBJECTS
+ if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 12000 )
+ {
+ if ( sts[1]->coder_type == UNVOICED )
+ {
+ sts[1]->coder_type = GENERIC;
+ }
+ hStereoTD->tdm_lp_reuse_flag = 1;
+
+ if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 11000 )
+ {
+ sts[1]->coder_type = INACTIVE;
+ }
+ }
+
+ if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 14700 )
+ {
+ if ( sts[0]->coder_type == TRANSITION )
+ {
+ sts[0]->coder_type = GENERIC;
+ }
+ }
+#endif
+
mod_ct = AUDIO;
if ( hCPE->element_brate < IVAS_24k4 )
{
@@ -459,7 +487,16 @@ void tdm_configure_enc(
* bitbudget distribution between channels (taking into account also metadata bitbudget)
*----------------------------------------------------------------*/
+#ifdef MASA_AND_OBJECTS
+ tdm_bit_alloc( ivas_format,
+ ism_mode,
+ hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus,
+ hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
+ &( hStereoTD->tdm_low_rate_mode ), sts[1]->coder_type, tdm_ratio_bit_alloc_idx, hStereoTD->tdm_Pitch_reuse_flag,
+ sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, hStereoTD->tdm_inst_ratio_idx );
+#else
tdm_bit_alloc( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC, hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ), &( hStereoTD->tdm_low_rate_mode ), sts[1]->coder_type, tdm_ratio_bit_alloc_idx, hStereoTD->tdm_Pitch_reuse_flag, sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, hStereoTD->tdm_inst_ratio_idx );
+#endif
if ( sts[0]->GSC_IVAS_mode > 0 && sts[0]->total_brate <= STEREO_GSC_BIT_RATE_ALLOC )
{
@@ -522,9 +559,9 @@ void tdm_configure_enc(
}
#ifdef DEBUG_MODE_TD
- dbgwrite( &hStereoTD->tdm_low_rate_mode, 2, 1, 320, "res/tdm_low_rate_mode" );
- dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag" );
- dbgwrite( &mod_ct, 2, 1, 320, "res/mod_ct.enx" );
+ dbgwrite( &hStereoTD->tdm_low_rate_mode, 2, 1, 320, "res/tdm_low_rate_mode_c" );
+ dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag_c" );
+ dbgwrite( &mod_ct, 2, 1, 320, "res/mod_ct.enc" );
#endif
/*----------------------------------------------------------------*
@@ -831,4 +868,6 @@ void stereo_tdm_prep_dwnmx(
}
}
}
+
+ return;
}
diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c
index 5e051e41b7eb10875e4f5c57d04e20810e9b4045..83f5e68ee829c02ec2f21d86e1deb5a130869fe3 100644
--- a/lib_enc/lib_enc.c
+++ b/lib_enc/lib_enc.c
@@ -330,6 +330,63 @@ ivas_error IVAS_ENC_ConfigureForStereo(
}
+#ifdef MASA_AND_OBJECTS
+/*---------------------------------------------------------------------*
+ * IVAS_ENC_ConfigureForMASAObjects()
+ *
+ * Configure and initialize the combined MASA and ISM encoder.
+ *---------------------------------------------------------------------*/
+
+ivas_error IVAS_ENC_ConfigureForMASAObjects(
+ IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */
+ const int32_t inputFs, /* i : input sampling frequency */
+ const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */
+ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */
+ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */
+ const uint16_t numObjects, /* i : number of objects to be encoded */
+ const int16_t masaVariant /* i : index specifying the number of MASA transport channels */
+)
+{
+ Encoder_Struct *st_ivas;
+ ivas_error error;
+
+ if ( ( error = doCommonConfigureChecks( hIvasEnc ) ) != IVAS_ERR_OK )
+ {
+ return error;
+ }
+
+ if ( numObjects > MAX_NUM_OBJECTS )
+ {
+ return IVAS_ERR_TOO_MANY_INPUTS;
+ }
+ st_ivas = hIvasEnc->st_ivas;
+ switch ( masaVariant )
+ {
+ case IVAS_ENC_MASA_2CH:
+ st_ivas->hEncoderConfig->nchan_inp = CPE_CHANNELS + numObjects;
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_DFT; /* initialization only, might be changed later based on element_brate */
+ break;
+ case IVAS_ENC_MASA_1CH:
+ st_ivas->hEncoderConfig->nchan_inp = 1 + numObjects;
+ st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_DFT; /* initialization only, might be changed later based on element_brate */
+ break;
+ default:
+ return IVAS_ERR_INVALID_MASA_CONFIG;
+ break;
+ }
+
+ st_ivas = hIvasEnc->st_ivas;
+
+ /* Currently this is true but it is already shown in descriptive metadata that there can be inequality for this. */
+ st_ivas->nchan_transport = st_ivas->hEncoderConfig->nchan_inp - numObjects;
+ st_ivas->hEncoderConfig->ivas_format = MASA_ISM_FORMAT;
+ st_ivas->hEncoderConfig->nchan_ism = numObjects;
+
+ return configureEncoder( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() );
+}
+#endif
+
+
/*---------------------------------------------------------------------*
* IVAS_ENC_ConfigureForObjects()
*
@@ -396,7 +453,11 @@ ivas_error IVAS_ENC_FeedObjectMetadata(
return IVAS_ERR_NOT_CONFIGURED;
}
+#ifdef MASA_AND_OBJECTS
+ if ( hIvasEnc->st_ivas->hEncoderConfig->ivas_format != ISM_FORMAT && hIvasEnc->st_ivas->hEncoderConfig->ivas_format != MASA_ISM_FORMAT )
+#else
if ( hIvasEnc->st_ivas->hEncoderConfig->ivas_format != ISM_FORMAT )
+#endif
{
return IVAS_ERR_METADATA_NOT_EXPECTED;
}
@@ -553,7 +614,11 @@ ivas_error IVAS_ENC_FeedMasaMetadata(
return IVAS_ERR_NOT_CONFIGURED;
}
+#ifdef MASA_AND_OBJECTS
+ if ( hIvasEnc->st_ivas->hEncoderConfig->ivas_format != MASA_FORMAT && hIvasEnc->st_ivas->hEncoderConfig->ivas_format != MASA_ISM_FORMAT )
+#else
if ( hIvasEnc->st_ivas->hEncoderConfig->ivas_format != MASA_FORMAT )
+#endif
{
return IVAS_ERR_METADATA_NOT_EXPECTED;
}
@@ -640,6 +705,9 @@ static ivas_error configureEncoder(
Encoder_Struct *st_ivas;
ENCODER_CONFIG_HANDLE hEncoderConfig;
ivas_error error;
+#ifdef MASA_AND_OBJECTS
+ int32_t cpe_brate;
+#endif
error = IVAS_ERR_OK;
@@ -781,6 +849,23 @@ static ivas_error configureEncoder(
}
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ st_ivas->ism_mode = ivas_omasa_ism_mode_select( st_ivas->hEncoderConfig->ivas_total_brate, hEncoderConfig->nchan_ism );
+
+ cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, st_ivas->hEncoderConfig->ivas_total_brate, hEncoderConfig->nchan_ism );
+
+ /*adapt element_mode according to the bit-rate*/
+ if ( hEncoderConfig->element_mode_init != IVAS_SCE )
+ {
+ if ( cpe_brate >= IVAS_48k )
+ {
+ hEncoderConfig->element_mode_init = IVAS_CPE_MDCT;
+ }
+ }
+ }
+#endif
}
else /* EVS mono */
{
@@ -1580,6 +1665,12 @@ static ivas_error printConfigInfo_enc(
fprintf( stdout, "IVAS mode: Multi-Channel 7.1+4\n" );
}
}
+#ifdef MASA_AND_OBJECTS
+ else if ( hEncoderConfig->ivas_format == MASA_ISM_FORMAT )
+ {
+ fprintf( stdout, "IVAS format: combined ISM and MASA (%i ISM stream(s))\n", hEncoderConfig->nchan_inp - 2 );
+ }
+#endif
if ( hEncoderConfig->is_binaural )
{
@@ -1649,11 +1740,13 @@ static ivas_error printConfigInfo_enc(
{
if ( newBandwidthApi != hEncoderConfig->max_bwidth )
{
+#ifdef ISM_FB
if ( hEncoderConfig->ivas_format == ISM_FORMAT )
{
fprintf( stdout, "\nFB coding not supported below %.2f kbps for %i objects. Switching to SWB.\n", hEncoderConfig->nchan_ism * MIN_BRATE_FB_ISM / 1000.f, hEncoderConfig->nchan_ism );
}
else
+#endif
{
fprintf( stdout, "\nFB coding not supported below %.2f kbps. Switching to SWB.\n", MIN_BRATE_FB_STEREO / 1000.f );
}
@@ -1953,8 +2046,12 @@ static ivas_error sanitizeBandwidth(
}
else
{
+#ifdef ISM_FB
if ( max_bwidth_tmp == FB && ( ( hEncoderConfig->ivas_format != ISM_FORMAT && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO ) ||
( hEncoderConfig->ivas_format == ISM_FORMAT && hEncoderConfig->ivas_total_brate / hEncoderConfig->nchan_ism < MIN_BRATE_FB_ISM ) ) )
+#else
+ if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO )
+#endif
{
max_bwidth_tmp = SWB;
}
diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h
index 9d2578755799653924c3cddb6e5b8d8f176732f5..8c015a99e4c6a74c448d525e589a6a633d316da9 100644
--- a/lib_enc/lib_enc.h
+++ b/lib_enc/lib_enc.h
@@ -50,6 +50,9 @@ typedef enum _IVAS_ENC_INPUT_FORMAT
IVAS_ENC_INPUT_SBA,
IVAS_ENC_INPUT_MASA,
IVAS_ENC_INPUT_MC,
+#ifdef MASA_AND_OBJECTS
+ IVAS_ENC_INPUT_MASA_ISM,
+#endif
IVAS_DEC_INPUT_UNKNOWN = 0xffff
} IVAS_ENC_INPUT_FORMAT;
@@ -101,6 +104,14 @@ typedef enum _IVAS_ENC_COMPLEXITY_LEVEL
IVAS_ENC_COMPLEXITY_LEVEL_THREE = 3
} IVAS_ENC_COMPLEXITY_LEVEL;
+#ifdef MASA_AND_OBJECTS
+typedef enum _IVAS_ENC_COMBINED_FORMAT
+{
+ IVAS_ENC_MASA_ISM = 1,
+ IVAS_ENC_COMBINED_UNDEFINED = 0xffff
+} IVAS_ENC_COMBINED_FORMAT;
+#endif
+
#ifdef DEBUGGING
typedef enum _IVAS_ENC_STEREO_MODE
{
@@ -193,6 +204,19 @@ ivas_error IVAS_ENC_ConfigureForObjects(
const bool ism_extended_metadata /* i : Extended metadata used (true/false), where extended metadata includes radius and orientation */
);
+#ifdef MASA_AND_OBJECTS
+/*! r: encoder error code */
+ivas_error IVAS_ENC_ConfigureForMASAObjects(
+ IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */
+ const int32_t inputFs, /* i : input sampling frequency */
+ const int32_t bitrate, /* i : requested bitrate of the ouput bitstream */
+ const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */
+ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */
+ const uint16_t numObjects, /* i : number of objects to be encoded */
+ const int16_t masaVariant /* i : index specifying the number of MASA transport channels */
+);
+#endif
+
/*! r: error code */
ivas_error IVAS_ENC_ConfigureForAmbisonics(
IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */
diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h
index 34efc3da7f3d9ae45da4015427257f4b4217bddc..45d01ac6cac73baec5e74780732cfa05ce469c6a 100644
--- a/lib_enc/stat_enc.h
+++ b/lib_enc/stat_enc.h
@@ -126,7 +126,11 @@ typedef struct
float firState1;
float firState2;
+#ifdef FIX_583_CLANG_TRANS_DET
uint16_t ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */
+#else
+ int16_t ramp_up_flag; /* bit map flags to indicate a ramp up in beginning of TCX frame */
+#endif
} SubblockEnergies;
diff --git a/lib_enc/transient_detection.c b/lib_enc/transient_detection.c
index 04cf8ea2471a095aede392c3f01641dce49b3c15..3b345b733396d022a2eae591fef15730b7a09238 100644
--- a/lib_enc/transient_detection.c
+++ b/lib_enc/transient_detection.c
@@ -241,7 +241,11 @@ void RunTransientDetection(
UpdateDelayBuffer( filteredInput, length, &hTranDet->delayBuffer );
/* compute ramp up flag */
+#ifdef FIX_583_CLANG_TRANS_DET
pSubblockEnergies->ramp_up_flag = ( ( pSubblockEnergies->ramp_up_flag << 1 ) & 0x0003 );
+#else
+ pSubblockEnergies->ramp_up_flag = pSubblockEnergies->ramp_up_flag << 1;
+#endif
e0 = dotp( filteredInput + length / 2, filteredInput + length / 2, pSubblockEnergies->pDelayBuffer->nSubblockSize / 2 ) + 0.5f * MIN_BLOCK_ENERGY;
e1 = pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4] - e0;
if ( e1 > e0 )
diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c
index 8a3f33b80b1949416653dfb99e889414c3e22b6d..5ca721b331f4f5e518dcb5a7c6ca6536c5cac8c0 100644
--- a/lib_rend/ivas_dirac_dec_binaural_functions.c
+++ b/lib_rend/ivas_dirac_dec_binaural_functions.c
@@ -56,6 +56,10 @@
#define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN ( 2.0f )
#define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN_LOW_BR ( 3.0f )
+#ifdef MASA_AND_OBJECTS
+#define STEREO_PREPROCESS_IIR_FACTOR ( 0.9f )
+#endif
+
/* powf(0.95f, 4.0f) for sub-frame smoothing instead of CLDFB slot */
#define ADAPT_HTPROTO_IIR_FAC 0.81450625f
@@ -64,7 +68,11 @@
#define ADAPT_HTPROTO_ROT_LIM_0 0.4f
#define ADAPT_HTPROTO_ROT_LIM_1 0.8f
+#ifdef MASA_AND_OBJECTS
+#define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */
+#else
#define MAX_GAIN_CACHE_SIZE 6
+#endif
typedef struct hrtfGainCache
{
@@ -74,18 +82,6 @@ typedef struct hrtfGainCache
float shVec[HRTF_SH_CHANNELS];
} PARAMBIN_HRTF_GAIN_CACHE;
-typedef struct parambin_rend_config_data
-{
- int16_t separateCenterChannelRendering;
- IVAS_FORMAT ivas_format;
- MC_MODE mc_mode;
- int32_t ivas_total_brate;
- int16_t nchan_transport;
- float qualityBasedSmFactor;
- int16_t processReverb;
-
-} PARAMBIN_REND_CONFIG, *PARAMBIN_REND_CONFIG_HANDLE;
-
/*-------------------------------------------------------------------------
* Local function prototypes
@@ -93,13 +89,13 @@ typedef struct parambin_rend_config_data
static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t nchan_transport, const int16_t subframe );
-static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] );
+static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_HANDLE hDirAC, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] );
-static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked );
+static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( Decoder_Struct *st_ivas, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked );
-static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, float Rmat[3][3], const int16_t isHeadtracked );
+static void ivas_dirac_dec_binaural_determine_processing_matrices( Decoder_Struct *st_ivas, const int16_t max_band_decorr, float Rmat[3][3], const int16_t isHeadtracked );
-static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe );
+static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t subframe );
static void adaptTransportSignalsHeadtracked( COMBINED_ORIENTATION_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, const int16_t nSlots, float Rmat[3][3] );
@@ -116,69 +112,67 @@ static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Ai
static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] );
-// Todo Tapani refactor: Create separate init & render functions for MASA external renderer. The decoder versions would become too complex if generalized.
-
/*-------------------------------------------------------------------------
* ivas_dirac_dec_init_binaural_data()
*
* Initialize parametric binaural renderer
*------------------------------------------------------------------------*/
-// Todo Tapani refactor: To be moved to lib_dec
ivas_error ivas_dirac_dec_init_binaural_data(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
HRTFS_PARAMBIN_HANDLE hHrtfParambin /* i : HRTF structure for rendering */
)
{
- DIRAC_DEC_BIN_HANDLE hDiracDecBin;
+ DIRAC_DEC_BIN_HANDLE hBinaural;
int16_t nBins;
int32_t output_Fs;
RENDERER_TYPE renderer_type;
int16_t j, k, bin;
float binCenterFreq, tmpFloat;
ivas_error error;
- float frequency_axis[CLDFB_NO_CHANNELS_MAX];
- hDiracDecBin = st_ivas->hDiracDecBin;
+ hBinaural = st_ivas->hDiracDecBin;
- if ( hDiracDecBin == NULL )
+ if ( hBinaural == NULL )
{
- if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL )
+ if ( ( hBinaural = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL )
{
return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC binaural handle " );
}
- hDiracDecBin->hTdDecorr = NULL;
- hDiracDecBin->hReverb = NULL;
- hDiracDecBin->h_freq_domain_decorr_ap_params = NULL;
- hDiracDecBin->h_freq_domain_decorr_ap_state = NULL;
+ hBinaural->hTdDecorr = NULL;
+ hBinaural->hReverb = NULL;
}
+ nBins = st_ivas->hDirAC->num_freq_bands;
output_Fs = st_ivas->hDecoderConfig->output_Fs;
- nBins = st_ivas->hSpatParamRendCom->num_freq_bands;
renderer_type = st_ivas->renderer_type;
for ( j = 0; j < BINAURAL_CHANNELS; j++ )
{
+#ifdef MASA_AND_OBJECTS
+ for ( k = 0; k < BINAURAL_CHANNELS + MAX_NUM_OBJECTS; k++ )
+#else
for ( k = 0; k < BINAURAL_CHANNELS + 1; k++ )
+#endif
{
- set_zero( hDiracDecBin->processMtxRe[j][k], nBins );
- set_zero( hDiracDecBin->processMtxIm[j][k], nBins );
+ set_zero( hBinaural->processMtxRe[j][k], nBins );
+ set_zero( hBinaural->processMtxIm[j][k], nBins );
}
for ( k = 0; k < BINAURAL_CHANNELS; k++ )
{
- set_zero( hDiracDecBin->processMtxDecRe[j][k], nBins );
- set_zero( hDiracDecBin->processMtxDecIm[j][k], nBins );
+ set_zero( hBinaural->processMtxDecRe[j][k], nBins );
+ set_zero( hBinaural->processMtxDecIm[j][k], nBins );
}
- set_zero( hDiracDecBin->ChEnePrev[j], nBins );
- set_zero( hDiracDecBin->ChEneOutPrev[j], nBins );
+ set_zero( hBinaural->ChEnePrev[j], nBins );
+ set_zero( hBinaural->ChEneOutPrev[j], nBins );
}
- set_zero( hDiracDecBin->ChCrossRePrev, nBins );
- set_zero( hDiracDecBin->ChCrossImPrev, nBins );
- set_zero( hDiracDecBin->ChCrossReOutPrev, nBins );
- set_zero( hDiracDecBin->ChCrossImOutPrev, nBins );
- hDiracDecBin->renderStereoOutputInsteadOfBinaural = 0;
+ set_zero( hBinaural->ChCrossRePrev, nBins );
+ set_zero( hBinaural->ChCrossImPrev, nBins );
+ set_zero( hBinaural->ChCrossReOutPrev, nBins );
+ set_zero( hBinaural->ChCrossImOutPrev, nBins );
+ hBinaural->renderStereoOutputInsteadOfBinaural = 0;
for ( bin = 0; bin < nBins; bin++ )
@@ -186,35 +180,35 @@ ivas_error ivas_dirac_dec_init_binaural_data(
binCenterFreq = ( (float) bin + CLDFB_HALF_BIN_FREQUENCY_OFFSET ) / (float) nBins * ( (float) output_Fs / 2.0f );
/* These formulas and values are from Christian Borss's publication for binaural diffuse field coherence */
tmpFloat = max( 0.0f, 1.0f - binCenterFreq / 2700.0f );
- hDiracDecBin->diffuseFieldCoherence[bin] = tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );
+ hBinaural->diffuseFieldCoherence[bin] = tmpFloat * sinf( binCenterFreq * EVS_PI / 550.0f ) / ( binCenterFreq * EVS_PI / 550.0f );
}
for ( bin = 0; bin < BINAURAL_COHERENCE_DIFFERENCE_BINS; bin++ )
{
- hDiracDecBin->diffuseFieldCoherenceX[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceX[bin];
- hDiracDecBin->diffuseFieldCoherenceY[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceY[bin];
- hDiracDecBin->diffuseFieldCoherenceZ[bin] = hDiracDecBin->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceZ[bin];
+ hBinaural->diffuseFieldCoherenceX[bin] = hBinaural->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceX[bin];
+ hBinaural->diffuseFieldCoherenceY[bin] = hBinaural->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceY[bin];
+ hBinaural->diffuseFieldCoherenceZ[bin] = hBinaural->diffuseFieldCoherence[bin] + diffuseFieldCoherenceDifferenceZ[bin];
}
if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC ) /* Indication of binaural rendering without room effect */
{
- set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX );
- hDiracDecBin->hReverb = NULL;
+ set_f( hBinaural->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX );
+ hBinaural->hReverb = NULL;
}
else if ( renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) /* Indication of binaural rendering with room effect */
{
- mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins );
+ mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hBinaural->earlyPartEneCorrection, nBins );
/* reconfiguration needed when Reverb. parameters are changed -> close and open the handle again */
- if ( hDiracDecBin->hReverb != NULL && ( ( hDiracDecBin->hReverb->numBins != nBins ) ||
- ( hDiracDecBin->hReverb->blockSize != CLDFB_SLOTS_PER_SUBFRAME ) ) )
+ if ( hBinaural->hReverb != NULL && ( ( hBinaural->hReverb->numBins != nBins ) ||
+ ( hBinaural->hReverb->blockSize != CLDFB_SLOTS_PER_SUBFRAME ) ) )
{
- ivas_binaural_reverb_close( &( hDiracDecBin->hReverb ) );
+ ivas_binaural_reverb_close( &( hBinaural->hReverb ) );
}
- if ( hDiracDecBin->hReverb == NULL )
+ if ( hBinaural->hReverb == NULL )
{
- if ( ( error = ivas_binaural_reverb_open( &hDiracDecBin->hReverb,
+ if ( ( error = ivas_binaural_reverb_open( &hBinaural->hReverb,
nBins,
CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL,
st_ivas->hIntSetup.output_config,
@@ -229,52 +223,28 @@ ivas_error ivas_dirac_dec_init_binaural_data(
}
else if ( renderer_type == RENDERER_STEREO_PARAMETRIC )
{
- set_f( hDiracDecBin->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX );
- hDiracDecBin->hReverb = NULL;
- hDiracDecBin->renderStereoOutputInsteadOfBinaural = 1;
+ set_f( hBinaural->earlyPartEneCorrection, 1.0f, CLDFB_NO_CHANNELS_MAX );
+ hBinaural->hReverb = NULL;
+ hBinaural->renderStereoOutputInsteadOfBinaural = 1;
}
else /* Not valid renderer type for this renderer */
{
assert( false );
}
- hDiracDecBin->hDiffuseDist = NULL; /* Memory is allocated from stack during runtime when needed */
-
- if ( hDiracDecBin->hTdDecorr == NULL )
+ if ( hBinaural->hTdDecorr == NULL )
{
- hDiracDecBin->useTdDecorr = 0;
+ hBinaural->useTdDecorr = 0;
}
- if ( hDiracDecBin->h_freq_domain_decorr_ap_params != NULL )
- {
- ivas_dirac_dec_decorr_close( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state );
- }
-
- if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hBinaural->hTdDecorr ), &( hBinaural->useTdDecorr ) ) ) != IVAS_ERR_OK )
{
return error;
}
- if ( !hDiracDecBin->useTdDecorr && !( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) )
- {
- ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins );
- if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ),
- &( hDiracDecBin->h_freq_domain_decorr_ap_state ),
- nBins,
- BINAURAL_CHANNELS,
- BINAURAL_CHANNELS,
- DIRAC_SYNTHESIS_PSD_LS,
- frequency_axis,
- BINAURAL_CHANNELS,
- output_Fs ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
-
- hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
+ hBinaural->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate );
- st_ivas->hDiracDecBin = hDiracDecBin;
+ st_ivas->hDiracDecBin = hBinaural;
/* allocate transport channels*/
if ( st_ivas->hDecoderConfig->voip_active == 1 && st_ivas->hTcBuffer == NULL )
@@ -313,10 +283,6 @@ void ivas_dirac_dec_close_binaural_data(
}
ivas_td_decorr_dec_close( &( ( *hBinaural )->hTdDecorr ) );
- if ( ( *hBinaural )->h_freq_domain_decorr_ap_params != NULL )
- {
- ivas_dirac_dec_decorr_close( &( *hBinaural )->h_freq_domain_decorr_ap_params, &( *hBinaural )->h_freq_domain_decorr_ap_state );
- }
free( *hBinaural );
*hBinaural = NULL;
@@ -377,7 +343,6 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs(
*
*------------------------------------------------------------------------*/
-// Todo Tapani refactor: To be moved to lib_dec
void ivas_dirac_dec_binaural_render(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */
@@ -390,13 +355,13 @@ void ivas_dirac_dec_binaural_render(
int16_t slots_to_render, first_sf, last_sf, subframe_idx;
uint16_t slot_size, ch;
uint16_t nchan_out;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
+ DIRAC_DEC_HANDLE hDirAC;
float *output_f_local[MAX_OUTPUT_CHANNELS];
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
+ hDirAC = st_ivas->hDirAC;
nchan_out = BINAURAL_CHANNELS;
#ifdef DEBUGGING
- assert( hSpatParamRendCom );
+ assert( hDirAC );
#endif
for ( ch = 0; ch < nchan_out; ch++ )
{
@@ -405,14 +370,14 @@ void ivas_dirac_dec_binaural_render(
slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
/* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
- slots_to_render = min( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered, nSamplesAsked / slot_size );
+ slots_to_render = min( hDirAC->num_slots - hDirAC->slots_rendered, nSamplesAsked / slot_size );
*nSamplesRendered = slots_to_render * slot_size;
- first_sf = hSpatParamRendCom->subframes_rendered;
+ first_sf = hDirAC->subframes_rendered;
last_sf = first_sf;
while ( slots_to_render > 0 )
{
- slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
+ slots_to_render -= hDirAC->subframe_nbslots[last_sf];
last_sf++;
}
@@ -421,7 +386,7 @@ void ivas_dirac_dec_binaural_render(
#endif
for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
{
- int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe_idx];
+ int16_t n_samples_sf = slot_size * hDirAC->subframe_nbslots[subframe_idx];
ivas_dirac_dec_binaural_internal( st_ivas, st_ivas->hCombinedOrientationData, output_f_local, nchan_transport, subframe_idx );
for ( ch = 0; ch < nchan_out; ch++ )
{
@@ -429,12 +394,12 @@ void ivas_dirac_dec_binaural_render(
}
}
- if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots )
+ if ( hDirAC->slots_rendered == hDirAC->num_slots )
{
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
- *nSamplesAvailable = ( hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered ) * slot_size;
+ *nSamplesAvailable = ( hDirAC->num_slots - hDirAC->slots_rendered ) * slot_size;
return;
}
@@ -442,13 +407,12 @@ void ivas_dirac_dec_binaural_render(
#ifdef FIX_564
/*-------------------------------------------------------------------------
- * ivas_dirac_dec_binaural_sba_gain()
+ * ivas_dirac_dec_binaural_gain()
*
* loudness correction for parametric binaural renderer
*------------------------------------------------------------------------*/
-// Todo Tapani refactor: To be moved to lib_dec
-void ivas_dirac_dec_binaural_sba_gain(
+void ivas_dirac_dec_binaural_gain(
float output[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */
const int16_t nchan_remapped, /* i : num channels after remapping of TCs */
const int16_t output_frame /* i : output frame length */
@@ -482,7 +446,6 @@ void ivas_dirac_dec_binaural_sba_gain(
* Parametric binaural renderer main function
*------------------------------------------------------------------------*/
-// Todo Tapani refactor: To be moved to lib_dec
void ivas_dirac_dec_binaural(
Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */
@@ -491,13 +454,11 @@ void ivas_dirac_dec_binaural(
)
{
int16_t subframe;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
float cng_td_buffer[L_FRAME16k];
float *p_output[MAX_OUTPUT_CHANNELS];
int16_t ch;
int16_t slot_size;
int16_t numInChannels;
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS );
for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ )
@@ -505,10 +466,22 @@ void ivas_dirac_dec_binaural(
p_output[ch] = &output_f[ch][0];
}
numInChannels = nchan_transport;
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->hOutSetup.separateChannelEnabled || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) )
+ {
+ numInChannels++;
+ }
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ numInChannels += (uint8_t) st_ivas->nchan_ism;
+ }
+#else
if ( st_ivas->hOutSetup.separateChannelEnabled )
{
numInChannels++;
}
+#endif
+
for ( ch = 0; ch < numInChannels; ch++ )
{
st_ivas->hTcBuffer->tc[ch] = &output_f[ch][0];
@@ -544,7 +517,7 @@ void ivas_dirac_dec_binaural(
for ( subframe = 0; subframe < MAX_PARAM_SPATIAL_SUBFRAMES; subframe++ )
{
- int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe];
+ int16_t n_samples_sf = slot_size * st_ivas->hDirAC->subframe_nbslots[subframe];
ivas_dirac_dec_binaural_internal( st_ivas, hCombinedOrientationData, p_output, nchan_transport, subframe );
@@ -552,7 +525,7 @@ void ivas_dirac_dec_binaural(
{
p_output[ch] += n_samples_sf;
}
- hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length;
+ st_ivas->hDirAC->dirac_read_idx = ( st_ivas->hDirAC->dirac_read_idx + 1 ) % st_ivas->hDirAC->dirac_md_buffer_length;
}
for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ )
@@ -568,7 +541,7 @@ void ivas_dirac_dec_binaural(
* Local functions
*------------------------------------------------------------------------*/
-// Todo refactor: To be moved to lib_dec
+
static void ivas_dirac_dec_binaural_internal(
Decoder_Struct *st_ivas,
COMBINED_ORIENTATION_HANDLE hCombinedOrientationData,
@@ -576,39 +549,42 @@ static void ivas_dirac_dec_binaural_internal(
const int16_t nchan_transport,
const int16_t subframe )
{
- DIRAC_DEC_BIN_HANDLE hDiracDecBin;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
- PARAMBIN_REND_CONFIG config_data;
+ DIRAC_DEC_HANDLE hDirAC;
int16_t slot, ch, numInChannels;
+#ifdef MASA_AND_OBJECTS
+ float Cldfb_RealBuffer_in[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+ float Cldfb_ImagBuffer_in[6][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+#else
float Cldfb_RealBuffer_in[4][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
float Cldfb_ImagBuffer_in[4][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+#endif
float Rmat[3][3];
int16_t max_band_decorr;
DIFFUSE_DISTRIBUTION_DATA diffuseDistData;
int16_t nBins, offsetSamples;
int16_t i, j;
- hDiracDecBin = st_ivas->hDiracDecBin;
- assert( hDiracDecBin );
- hSpatParamRendCom = st_ivas->hSpatParamRendCom;
- nBins = hSpatParamRendCom->num_freq_bands;
- offsetSamples = hSpatParamRendCom->slots_rendered * nBins;
-
- /* Setuo internal config */
- config_data.separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled;
- config_data.ivas_format = st_ivas->ivas_format;
- config_data.mc_mode = st_ivas->mc_mode;
- config_data.ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
- config_data.nchan_transport = st_ivas->nchan_transport;
- config_data.qualityBasedSmFactor = st_ivas->hMasa != NULL ? st_ivas->hMasa->data.dir_decode_quality : 1.0f;
- config_data.processReverb = st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ? 1 : 0;
+ hDirAC = st_ivas->hDirAC;
+ nBins = hDirAC->num_freq_bands;
+ offsetSamples = hDirAC->slots_rendered * nBins;
/* The input channel number at this processing function (not nchan_transport) */
numInChannels = BINAURAL_CHANNELS;
- if ( config_data.separateCenterChannelRendering )
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->hOutSetup.separateChannelEnabled || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) )
{
numInChannels++;
}
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ numInChannels += (uint8_t) st_ivas->nchan_ism;
+ }
+#else
+ if ( st_ivas->hOutSetup.separateChannelEnabled )
+ {
+ numInChannels++;
+ }
+#endif
Rmat[0][0] = 1.0f;
Rmat[0][1] = 0.0f;
@@ -623,7 +599,7 @@ static void ivas_dirac_dec_binaural_internal(
Rmat[2][2] = 1.0f;
/* CLDFB Analysis of input */
- for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
+ for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe]; slot++ )
{
for ( ch = 0; ch < numInChannels; ch++ )
{
@@ -635,7 +611,7 @@ static void ivas_dirac_dec_binaural_internal(
Cldfb_ImagBuffer_in[ch][slot],
nBins, st_ivas->cldfbAnaDec[ch] );
}
- else if ( config_data.nchan_transport == 2 ) /* Stereo signal transmitted as mono with DFT stereo */
+ else if ( st_ivas->nchan_transport == 2 ) /* Stereo signal transmitted as mono with DFT stereo */
{
/* At mono input duplicate the channel to dual-mono */
mvr2r( Cldfb_RealBuffer_in[0][slot], Cldfb_RealBuffer_in[1][slot], nBins );
@@ -650,7 +626,7 @@ static void ivas_dirac_dec_binaural_internal(
int16_t slotInFrame;
numCoreBands = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->numCoreBands;
- slotInFrame = hSpatParamRendCom->slots_rendered + slot;
+ slotInFrame = hDirAC->slots_rendered + slot;
generate_masking_noise_dirac( st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom,
st_ivas->cldfbAnaDec[1],
@@ -702,7 +678,7 @@ static void ivas_dirac_dec_binaural_internal(
}
}
- if ( hDiracDecBin->useTdDecorr )
+ if ( st_ivas->hDiracDecBin->useTdDecorr )
{
for ( ch = BINAURAL_CHANNELS; ch < ( 2 * BINAURAL_CHANNELS ); ch++ )
{
@@ -712,7 +688,7 @@ static void ivas_dirac_dec_binaural_internal(
Cldfb_ImagBuffer_in[ch][slot],
nBins, st_ivas->cldfbAnaDec[ch] );
- if ( config_data.nchan_transport == 1 && config_data.ivas_format == SBA_FORMAT )
+ if ( st_ivas->nchan_transport == 1 && st_ivas->ivas_format == SBA_FORMAT )
{
v_multc( Cldfb_RealBuffer_in[ch][slot], INV_SQRT_2, Cldfb_RealBuffer_in[ch][slot], nBins );
v_multc( Cldfb_ImagBuffer_in[ch][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[ch][slot], nBins );
@@ -721,15 +697,22 @@ static void ivas_dirac_dec_binaural_internal(
}
}
- if ( config_data.ivas_format == SBA_FORMAT )
+ if ( st_ivas->ivas_format == SBA_FORMAT )
{
- hDiracDecBin->hDiffuseDist = &diffuseDistData;
+ st_ivas->hDirAC->hDiffuseDist = &diffuseDistData;
ivas_spar_param_to_masa_param_mapping( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe );
ivas_sba_prototype_renderer( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe );
}
+#ifdef MASA_AND_OBJECTS
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ )
+ {
+ preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, subframe );
+ }
+#endif
+
if ( hCombinedOrientationData )
{
for ( i = 0; i < 3; i++ )
@@ -742,45 +725,44 @@ static void ivas_dirac_dec_binaural_internal(
if ( nchan_transport == 2 )
{
- adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat );
+ adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hDirAC->subframe_nbslots[subframe], Rmat );
- ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat );
+ ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hDirAC->subframe_nbslots[subframe], Rmat );
}
}
- ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe,
+ ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe,
hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 );
- if ( config_data.ivas_format == ISM_FORMAT )
+ if ( st_ivas->ivas_format == ISM_FORMAT )
{
max_band_decorr = 0;
}
- else if ( hDiracDecBin->useTdDecorr )
+ else if ( st_ivas->hDiracDecBin->useTdDecorr )
{
max_band_decorr = CLDFB_NO_CHANNELS_MAX;
}
else
{
- max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr;
+ max_band_decorr = st_ivas->hDirAC->h_freq_domain_decorr_ap_params->max_band_decorr;
}
- ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat,
+ ivas_dirac_dec_binaural_determine_processing_matrices( st_ivas, max_band_decorr, Rmat,
hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0 );
- ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe );
+ ivas_dirac_dec_binaural_process_output( st_ivas, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, subframe );
- hDiracDecBin->hDiffuseDist = NULL;
+ st_ivas->hDirAC->hDiffuseDist = NULL;
-
- hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe];
- hSpatParamRendCom->subframes_rendered++;
+ // Todo OMASA JBM: This change could have some side effects
+ hDirAC->slots_rendered += hDirAC->subframe_nbslots[subframe];
+ hDirAC->subframes_rendered++;
return;
}
static void ivas_dirac_dec_decorrelate_slot(
- DIRAC_DEC_BIN_HANDLE hDiracDecBin,
- const int16_t num_freq_bands,
+ DIRAC_DEC_HANDLE hDirAC,
const int16_t slot,
float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
@@ -790,39 +772,37 @@ static void ivas_dirac_dec_decorrelate_slot(
int16_t offset, ch, bin;
float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */
float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */
- float protoFrameF[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */
- const int16_t protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 };
/* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- offset = num_freq_bands * BINAURAL_CHANNELS * ch;
- for ( bin = 0; bin < num_freq_bands; bin++ )
+ offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch;
+ for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ )
{
- protoFrameF[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin];
- protoFrameF[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin];
+ hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin];
+ hDirAC->proto_frame_f[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin];
}
}
/* Decorrelate proto signal to decorrelatedFrameInterleaved */
- ivas_dirac_dec_decorr_process( num_freq_bands,
- BINAURAL_CHANNELS,
- BINAURAL_CHANNELS,
- DIRAC_SYNTHESIS_PSD_LS,
+ ivas_dirac_dec_decorr_process( hDirAC->num_freq_bands,
+ hDirAC->num_outputs_diff,
+ hDirAC->num_protos_diff,
+ hDirAC->synthesisConf,
BINAURAL_CHANNELS,
- protoFrameF,
- BINAURAL_CHANNELS,
- protoIndexDir,
+ hDirAC->proto_frame_f,
+ hDirAC->num_protos_diff,
+ hDirAC->proto_index_diff,
decorrelatedFrameInterleaved,
onset_filter,
- hDiracDecBin->h_freq_domain_decorr_ap_params,
- hDiracDecBin->h_freq_domain_decorr_ap_state );
+ hDirAC->h_freq_domain_decorr_ap_params,
+ hDirAC->h_freq_domain_decorr_ap_state );
/* De-interleave decorrelated signals*/
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- offset = num_freq_bands * BINAURAL_CHANNELS * ch;
- for ( bin = 0; bin < num_freq_bands; bin++ )
+ offset = hDirAC->num_freq_bands * BINAURAL_CHANNELS * ch;
+ for ( bin = 0; bin < hDirAC->num_freq_bands; bin++ )
{
decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset];
decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1];
@@ -834,9 +814,7 @@ static void ivas_dirac_dec_decorrelate_slot(
static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices(
- DIRAC_DEC_BIN_HANDLE hDiracDecBin,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
- PARAMBIN_REND_CONFIG_HANDLE hConfig,
+ Decoder_Struct *st_ivas,
float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
float Rmat[3][3],
@@ -844,9 +822,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
const int16_t isHeadtracked )
{
int16_t ch, slot, bin;
- int16_t separateCenterChannelRendering;
+ uint8_t separateCenterChannelRendering;
int16_t nBins, idx;
float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX];
+ DIRAC_DEC_HANDLE hDirAC;
+ DIRAC_DEC_BIN_HANDLE h;
float IIReneLimiterFactor;
float qualityBasedSmFactor;
float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX];
@@ -854,30 +834,25 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
int16_t dirac_read_idx;
float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX];
PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE];
- IVAS_FORMAT ivas_format;
- MC_MODE mc_mode;
- int32_t ivas_total_brate;
- int16_t nchan_transport;
-
- separateCenterChannelRendering = hConfig->separateCenterChannelRendering;
- ivas_format = hConfig->ivas_format;
- mc_mode = hConfig->mc_mode;
- ivas_total_brate = hConfig->ivas_total_brate;
- nchan_transport = hConfig->nchan_transport;
- qualityBasedSmFactor = hConfig->qualityBasedSmFactor;
- qualityBasedSmFactor *= qualityBasedSmFactor;
- nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */
-
- set_zero( hDiracDecBin->ChCrossRe, nBins );
- set_zero( hDiracDecBin->ChCrossIm, nBins );
- set_zero( hDiracDecBin->ChCrossReOut, nBins );
- set_zero( hDiracDecBin->ChCrossImOut, nBins );
+#ifdef MASA_AND_OBJECTS
+ int16_t gainCacheBaseIndex;
+#endif
+
+ hDirAC = st_ivas->hDirAC;
+ h = st_ivas->hDiracDecBin;
+ separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled;
+ nBins = hDirAC->num_freq_bands; /* Actually bins */
+
+ set_zero( h->ChCrossRe, nBins );
+ set_zero( h->ChCrossIm, nBins );
+ set_zero( h->ChCrossReOut, nBins );
+ set_zero( h->ChCrossImOut, nBins );
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- set_zero( hDiracDecBin->ChEne[ch], nBins );
- set_zero( hDiracDecBin->ChEneOut[ch], nBins );
+ set_zero( h->ChEne[ch], nBins );
+ set_zero( h->ChEneOut[ch], nBins );
}
- set_zero( hDiracDecBin->frameMeanDiffuseness, nBins );
+ set_zero( h->frameMeanDiffuseness, nBins );
set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX );
@@ -888,10 +863,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Determine EQ for low bit rates (13.2 and 16.4 kbps) */
applyLowBitRateEQ = 0;
- if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ivas_total_brate < MASA_STEREO_MIN_BITRATE )
+ if ( ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MC_FORMAT ) && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE )
{
applyLowBitRateEQ = 1;
- if ( ivas_total_brate == IVAS_16k4 )
+ if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_16k4 )
{
for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ )
{
@@ -909,10 +884,10 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Formulate input and target covariance matrices for this subframe */
set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX );
- dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe];
+ dirac_read_idx = hDirAC->render_to_md_map[subframe];
/* Calculate input covariance matrix */
- for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
+ for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe]; slot++ )
{
for ( bin = 0; bin < nBins; bin++ )
{
@@ -922,13 +897,13 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
instEne = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] );
instEne += ( inIm[ch][slot][bin] * inIm[ch][slot][bin] );
- hDiracDecBin->ChEne[ch][bin] += instEne;
+ h->ChEne[ch][bin] += instEne;
subFrameTotalEne[bin] += instEne;
}
- hDiracDecBin->ChCrossRe[bin] += inRe[0][slot][bin] * inRe[1][slot][bin];
- hDiracDecBin->ChCrossRe[bin] += inIm[0][slot][bin] * inIm[1][slot][bin];
- hDiracDecBin->ChCrossIm[bin] += inRe[0][slot][bin] * inIm[1][slot][bin];
- hDiracDecBin->ChCrossIm[bin] -= inIm[0][slot][bin] * inRe[1][slot][bin];
+ h->ChCrossRe[bin] += inRe[0][slot][bin] * inRe[1][slot][bin];
+ h->ChCrossRe[bin] += inIm[0][slot][bin] * inIm[1][slot][bin];
+ h->ChCrossIm[bin] += inRe[0][slot][bin] * inIm[1][slot][bin];
+ h->ChCrossIm[bin] -= inIm[0][slot][bin] * inRe[1][slot][bin];
}
}
@@ -947,13 +922,13 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
}
}
- if ( ivas_format == SBA_FORMAT && nchan_transport == 2 )
+ if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport == 2 )
{
float tempRe, tempIm;
set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX );
- for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ )
+ for ( slot = 0; slot < hDirAC->subframe_nbslots[subframe]; slot++ )
{
for ( bin = 0; bin < nBins; bin++ )
{
@@ -967,7 +942,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Determine target covariance matrix containing target binaural properties */
for ( bin = 0; bin < nBins; bin++ )
{
- float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */
+ float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */
+#ifdef MASA_AND_OBJECTS
+ float diffusenessValForDecorrelationReduction = 1.0f;
+ float diffEneValForDecorrelationReduction;
+#endif
float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */
float diffEne, dirEne, meanEnePerCh;
int16_t dirIndex;
@@ -977,26 +956,36 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
* HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match
* the early spectrum of the BRIR data, using the spectral correction data in
* hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */
- meanEnePerCh = hDiracDecBin->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f;
+ meanEnePerCh = h->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f;
/* Determine direct part target covariance matrix (for 1 or 2 directions) */
- for ( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ )
+ for ( dirIndex = 0; dirIndex < hDirAC->numSimultaneousDirections; dirIndex++ )
{
int16_t aziDeg, eleDeg;
float lRealp, lImagp, rRealp, rImagp;
float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp;
float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio;
+#ifdef MASA_AND_OBJECTS
+ uint8_t isIsmDirection = 0;
+#endif
if ( dirIndex == 0 ) /* For first of the two simultaneous directions */
{
- aziDeg = hSpatParamRendCom->azimuth[dirac_read_idx][bin];
- eleDeg = hSpatParamRendCom->elevation[dirac_read_idx][bin];
- ratio = hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin];
- spreadCoh = hSpatParamRendCom->spreadCoherence[dirac_read_idx][bin];
+ aziDeg = hDirAC->azimuth[dirac_read_idx][bin];
+ eleDeg = hDirAC->elevation[dirac_read_idx][bin];
+ ratio = hDirAC->energy_ratio1[dirac_read_idx][bin];
+ spreadCoh = hDirAC->spreadCoherence[dirac_read_idx][bin];
+#ifdef MASA_AND_OBJECTS
+ gainCacheBaseIndex = 0;
+#endif
}
+#ifdef MASA_AND_OBJECTS
+ else if ( st_ivas->ivas_format != MASA_ISM_FORMAT || ( st_ivas->ivas_format == MASA_ISM_FORMAT && dirIndex < hDirAC->numParametricDirections ) ) /* For second of the two simultaneous directions */
+#else
else /* For second of the two simultaneous directions */
+#endif
{
- if ( ( ratio = hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin] ) < 0.001 )
+ if ( ( ratio = hDirAC->energy_ratio2[dirac_read_idx][bin] ) < 0.001 )
{
/* This touches only MASA path where second direction always has smaller ratio and
* for non-2dir it is zero. As the whole direction contribution is multiplied with
@@ -1004,12 +993,53 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
* it is better to save complexity. */
continue;
}
- aziDeg = hSpatParamRendCom->azimuth2[dirac_read_idx][bin];
- eleDeg = hSpatParamRendCom->elevation2[dirac_read_idx][bin];
- spreadCoh = hSpatParamRendCom->spreadCoherence2[dirac_read_idx][bin];
+ aziDeg = hDirAC->azimuth2[dirac_read_idx][bin];
+ eleDeg = hDirAC->elevation2[dirac_read_idx][bin];
+ spreadCoh = hDirAC->spreadCoherence2[dirac_read_idx][bin];
+#ifdef MASA_AND_OBJECTS
+ gainCacheBaseIndex = 3;
+#endif
}
+#ifdef MASA_AND_OBJECTS
+ else /* For object directions of MASA_ISM_FORMAT */
+ {
+ isIsmDirection = 1;
+ uint16_t ismDirIndex;
+ ismDirIndex = dirIndex - hDirAC->numParametricDirections;
+ if ( st_ivas->hMasaIsmData->ism_is_edited[ismDirIndex] )
+ {
+ aziDeg = st_ivas->hMasaIsmData->azimuth_ism_edited[ismDirIndex];
+ eleDeg = st_ivas->hMasaIsmData->elevation_ism_edited[ismDirIndex];
+ }
+ else
+ {
+ aziDeg = st_ivas->hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx];
+ eleDeg = st_ivas->hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx];
+ }
+ ratio = st_ivas->hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin];
+ spreadCoh = 0.0f;
+ gainCacheBaseIndex = 6 + ismDirIndex;
+ }
+#endif
+
diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */
+#ifdef MASA_AND_OBJECTS
+ if ( diffuseness < 0.0f )
+ {
+ diffuseness = 0.0f;
+ }
+ if ( isIsmDirection )
+ {
+ /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */
+ diffusenessValForDecorrelationReduction -= ratio * 0.5f;
+ }
+ else
+ {
+ diffusenessValForDecorrelationReduction -= ratio;
+ }
+#endif
+
if ( separateCenterChannelRendering )
{
/* In masa + mono rendering mode, the center directions originate from phantom sources, so the
@@ -1024,9 +1054,13 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
spreadCoh = max( spreadCoh, altSpreadCoh );
}
- getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 )], isHeadtracked );
+#ifdef MASA_AND_OBJECTS
+ getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked );
+#else
+ getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 )], isHeadtracked );
+#endif
- if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural )
+ if ( h->renderStereoOutputInsteadOfBinaural )
{
/* Synthesizing spread coherence is not needed for stereo loudspeaker output,
* as directional sound is reproduced with two loudspeakers in any case */
@@ -1067,7 +1101,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
rImagp *= centerMul;
/* Apply the gain for the left source of the three coherent sources */
- getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 + 1 )], isHeadtracked );
+#ifdef MASA_AND_OBJECTS
+ getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked );
+#else
+ getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 + 1 )], isHeadtracked );
+#endif
hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp );
lRealp += sidesMul * lRealpTmp;
@@ -1077,7 +1115,11 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Apply the gain for the right source of the three coherent sources.
* -30 degrees to 330 wrapping due to internal functions. */
- getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 + 2 )], isHeadtracked );
+#ifdef MASA_AND_OBJECTS
+ getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked );
+#else
+ getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[( dirIndex * 3 + 2 )], isHeadtracked );
+#endif
hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp );
lRealp += sidesMul * lRealpTmp;
@@ -1105,7 +1147,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
w3 = 2.0f * spreadCoh - 1.0f;
}
- if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) )
+ if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) )
{
idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 );
@@ -1135,60 +1177,92 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Add direct part (1 or 2) covariance matrix */
dirEne = ratio * meanEnePerCh;
- hDiracDecBin->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/
- hDiracDecBin->ChEneOut[1][bin] += dirEne * hrtfEne[1];
- hDiracDecBin->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */
- hDiracDecBin->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */
+ h->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/
+ h->ChEneOut[1][bin] += dirEne * hrtfEne[1];
+ h->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */
+ h->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */
}
/* Add diffuse / ambient part covariance matrix */
diffuseness = max( 0.0f, diffuseness );
diffEne = diffuseness * meanEnePerCh;
- surCoh = hSpatParamRendCom->surroundingCoherence[dirac_read_idx][bin];
- if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) )
+ surCoh = hDirAC->surroundingCoherence[dirac_read_idx][bin];
+
+#ifdef MASA_AND_OBJECTS
+ diffusenessValForDecorrelationReduction = max( 0.0f, diffusenessValForDecorrelationReduction );
+ diffEneValForDecorrelationReduction = diffusenessValForDecorrelationReduction * meanEnePerCh;
+#endif
+
+ if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) )
{
- if ( !hDiracDecBin->renderStereoOutputInsteadOfBinaural )
+ if ( !h->renderStereoOutputInsteadOfBinaural )
{
+#ifdef MASA_AND_OBJECTS
+ float spectrumModVal;
+
+ idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 );
+ /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */
+ spectrumModVal = ( 1.0f - surCoh ) + surCoh * surCohEne[idx];
+ diffEne *= spectrumModVal;
+#else
idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 );
/* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */
diffEne *= ( 1.0f - surCoh ) + surCoh * surCohEne[idx];
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ /* Modify also the value for decorrelation reduction */
+ diffEneValForDecorrelationReduction *= spectrumModVal;
+#endif
}
}
- hDiracDecBin->ChEneOut[0][bin] += diffEne; /* Diff ene part*/
- hDiracDecBin->ChEneOut[1][bin] += diffEne;
+ h->ChEneOut[0][bin] += diffEne; /* Diff ene part*/
+ h->ChEneOut[1][bin] += diffEne;
- if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural )
+ if ( h->renderStereoOutputInsteadOfBinaural )
{
/* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */
- hDiracDecBin->ChCrossReOut[bin] += surCoh * diffEne;
+ h->ChCrossReOut[bin] += surCoh * diffEne;
}
else /* When rendering binaural, ambience has frequency dependent ICC. */
{
- if ( ivas_format == SBA_FORMAT && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS )
+ if ( st_ivas->ivas_format == SBA_FORMAT && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS )
{
float diffuseFieldCoherence;
- diffuseFieldCoherence = hDiracDecBin->hDiffuseDist->diffuseRatioX[bin] * hDiracDecBin->diffuseFieldCoherenceX[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioY[bin] * hDiracDecBin->diffuseFieldCoherenceY[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioZ[bin] * hDiracDecBin->diffuseFieldCoherenceZ[bin];
- hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne;
+ diffuseFieldCoherence = hDirAC->hDiffuseDist->diffuseRatioX[bin] * h->diffuseFieldCoherenceX[bin] + hDirAC->hDiffuseDist->diffuseRatioY[bin] * h->diffuseFieldCoherenceY[bin] + hDirAC->hDiffuseDist->diffuseRatioZ[bin] * h->diffuseFieldCoherenceZ[bin];
+ h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne;
}
else
{
- hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * hDiracDecBin->diffuseFieldCoherence[bin] + surCoh ) * diffEne;
+ h->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * h->diffuseFieldCoherence[bin] + surCoh ) * diffEne;
}
}
/* Store parameters for formulating average diffuseness over frame */
- hDiracDecBin->frameMeanDiffuseness[bin] += diffEne;
+#ifdef MASA_AND_OBJECTS
+ h->frameMeanDiffuseness[bin] += diffEneValForDecorrelationReduction;
+#else
+ h->frameMeanDiffuseness[bin] += diffEne;
+#endif
frameMeanDiffusenessEneWeight[bin] += meanEnePerCh;
}
/* Formulate average diffuseness over frame */
for ( bin = 0; bin < nBins; bin++ )
{
- hDiracDecBin->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] );
+ h->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] );
+ }
+
+ /* Determine encoding quality based additional smoothing factor */
+ qualityBasedSmFactor = 1.0f;
+ if ( st_ivas->hMasa != NULL )
+ {
+ qualityBasedSmFactor = st_ivas->hMasa->data.dir_decode_quality;
+ qualityBasedSmFactor *= qualityBasedSmFactor;
}
- /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */
- if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE )
+ /* Temporal IIR-type smoothing of covariance matrices */
+ if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE )
{
IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor );
}
@@ -1203,41 +1277,41 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
/* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that
* the energy history (IIR) must not be more than double of the current frame energy. This provides more
* robust performance at energy offsets when compared to typical IIR averaging. */
- eneRatio = ( hDiracDecBin->ChEne[0][bin] + hDiracDecBin->ChEne[1][bin] ) / fmaxf( 1e-12f, ( hDiracDecBin->ChEnePrev[0][bin] + hDiracDecBin->ChEnePrev[1][bin] ) );
+ eneRatio = ( h->ChEne[0][bin] + h->ChEne[1][bin] ) / fmaxf( 1e-12f, ( h->ChEnePrev[0][bin] + h->ChEnePrev[1][bin] ) );
IIReneLimiter = fminf( 1.0f, eneRatio * IIReneLimiterFactor );
- hDiracDecBin->ChCrossRe[bin] *= qualityBasedSmFactor;
- hDiracDecBin->ChCrossIm[bin] *= qualityBasedSmFactor;
- hDiracDecBin->ChCrossReOut[bin] *= qualityBasedSmFactor;
- hDiracDecBin->ChCrossImOut[bin] *= qualityBasedSmFactor;
+ h->ChCrossRe[bin] *= qualityBasedSmFactor;
+ h->ChCrossIm[bin] *= qualityBasedSmFactor;
+ h->ChCrossReOut[bin] *= qualityBasedSmFactor;
+ h->ChCrossImOut[bin] *= qualityBasedSmFactor;
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- hDiracDecBin->ChEne[ch][bin] *= qualityBasedSmFactor;
- hDiracDecBin->ChEneOut[ch][bin] *= qualityBasedSmFactor;
+ h->ChEne[ch][bin] *= qualityBasedSmFactor;
+ h->ChEneOut[ch][bin] *= qualityBasedSmFactor;
}
- hDiracDecBin->ChCrossRe[bin] += IIReneLimiter * hDiracDecBin->ChCrossRePrev[bin];
- hDiracDecBin->ChCrossIm[bin] += IIReneLimiter * hDiracDecBin->ChCrossImPrev[bin];
- hDiracDecBin->ChCrossReOut[bin] += IIReneLimiter * hDiracDecBin->ChCrossReOutPrev[bin];
- hDiracDecBin->ChCrossImOut[bin] += IIReneLimiter * hDiracDecBin->ChCrossImOutPrev[bin];
+ h->ChCrossRe[bin] += IIReneLimiter * h->ChCrossRePrev[bin];
+ h->ChCrossIm[bin] += IIReneLimiter * h->ChCrossImPrev[bin];
+ h->ChCrossReOut[bin] += IIReneLimiter * h->ChCrossReOutPrev[bin];
+ h->ChCrossImOut[bin] += IIReneLimiter * h->ChCrossImOutPrev[bin];
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- hDiracDecBin->ChEne[ch][bin] += IIReneLimiter * hDiracDecBin->ChEnePrev[ch][bin];
- hDiracDecBin->ChEneOut[ch][bin] += IIReneLimiter * hDiracDecBin->ChEneOutPrev[ch][bin];
+ h->ChEne[ch][bin] += IIReneLimiter * h->ChEnePrev[ch][bin];
+ h->ChEneOut[ch][bin] += IIReneLimiter * h->ChEneOutPrev[ch][bin];
}
/* Store energy values and coefficients for next round */
- hDiracDecBin->ChCrossRePrev[bin] = hDiracDecBin->ChCrossRe[bin];
- hDiracDecBin->ChCrossImPrev[bin] = hDiracDecBin->ChCrossIm[bin];
- hDiracDecBin->ChCrossReOutPrev[bin] = hDiracDecBin->ChCrossReOut[bin];
- hDiracDecBin->ChCrossImOutPrev[bin] = hDiracDecBin->ChCrossImOut[bin];
+ h->ChCrossRePrev[bin] = h->ChCrossRe[bin];
+ h->ChCrossImPrev[bin] = h->ChCrossIm[bin];
+ h->ChCrossReOutPrev[bin] = h->ChCrossReOut[bin];
+ h->ChCrossImOutPrev[bin] = h->ChCrossImOut[bin];
for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
{
- hDiracDecBin->ChEnePrev[ch][bin] = hDiracDecBin->ChEne[ch][bin];
- hDiracDecBin->ChEneOutPrev[ch][bin] = hDiracDecBin->ChEneOut[ch][bin];
+ h->ChEnePrev[ch][bin] = h->ChEne[ch][bin];
+ h->ChEneOutPrev[ch][bin] = h->ChEneOut[ch][bin];
}
}
@@ -1246,30 +1320,61 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric
static void ivas_dirac_dec_binaural_determine_processing_matrices(
- DIRAC_DEC_BIN_HANDLE hDiracDecBin,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
- PARAMBIN_REND_CONFIG_HANDLE hConfig,
+ Decoder_Struct *st_ivas,
const int16_t max_band_decorr,
float Rmat[3][3],
const int16_t isHeadtracked )
{
int16_t chA, chB, bin;
- int16_t separateCenterChannelRendering;
+ uint8_t separateCenterChannelRendering;
+#ifdef MASA_AND_OBJECTS
+ uint8_t nchanSeparateChannels;
+#endif
int16_t nBins;
+#ifdef MASA_AND_OBJECTS
+ int16_t dirac_read_idx;
+#endif
+ DIRAC_DEC_BIN_HANDLE h;
+#ifdef MASA_AND_OBJECTS
+ PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_NUM_OBJECTS];
+ int16_t idx;
+#else
PARAMBIN_HRTF_GAIN_CACHE gainCache;
- IVAS_FORMAT ivas_format;
- MC_MODE mc_mode;
- int32_t ivas_total_brate;
- int16_t nchan_transport;
-
- separateCenterChannelRendering = hConfig->separateCenterChannelRendering;
- ivas_format = hConfig->ivas_format;
- mc_mode = hConfig->mc_mode;
- ivas_total_brate = hConfig->ivas_total_brate;
- nchan_transport = hConfig->nchan_transport;
- nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */
+#endif
+
+ h = st_ivas->hDiracDecBin;
+#ifdef MASA_AND_OBJECTS
+ separateCenterChannelRendering = 0;
+ nchanSeparateChannels = 0;
+ if ( st_ivas->hOutSetup.separateChannelEnabled || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) )
+ {
+ separateCenterChannelRendering = 1;
+ nchanSeparateChannels = 1;
+ }
+ else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) )
+ {
+ separateCenterChannelRendering = 1;
+ nchanSeparateChannels = (uint8_t) st_ivas->nchan_ism;
+ }
+#else
+ separateCenterChannelRendering = st_ivas->hOutSetup.separateChannelEnabled;
+#endif
+
+ nBins = st_ivas->hDirAC->num_freq_bands; /* Actually bins */
+#ifdef MASA_AND_OBJECTS
+ // Todo OMASA JBM: This is probably not correct now. We should get the index from JBM
+ dirac_read_idx = st_ivas->hDirAC->dirac_read_idx;
+#endif
+
+#ifdef MASA_AND_OBJECTS
+ for ( idx = 0; idx < MAX_NUM_OBJECTS; idx++ )
+ {
+ gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */
+ }
+#else
gainCache.azi = -1000; /* Use -1000 as value for uninitialized cache. */
+#endif
for ( bin = 0; bin < nBins; bin++ )
{
@@ -1285,21 +1390,21 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
CrEneR = 0.0f;
/* Formulate main processing matrix M */
- formulate2x2MixingMatrix( hDiracDecBin->ChEne[0][bin], hDiracDecBin->ChEne[1][bin],
- hDiracDecBin->ChCrossRe[bin], hDiracDecBin->ChCrossIm[bin],
- hDiracDecBin->ChEneOut[0][bin], hDiracDecBin->ChEneOut[1][bin],
- hDiracDecBin->ChCrossReOut[bin], hDiracDecBin->ChCrossImOut[bin],
- prototypeMtx, Mre, Mim, hDiracDecBin->reqularizationFactor );
+ formulate2x2MixingMatrix( h->ChEne[0][bin], h->ChEne[1][bin],
+ h->ChCrossRe[bin], h->ChCrossIm[bin],
+ h->ChEneOut[0][bin], h->ChEneOut[1][bin],
+ h->ChCrossReOut[bin], h->ChCrossImOut[bin],
+ prototypeMtx, Mre, Mim, h->reqularizationFactor );
/* Load estimated covariance matrix to the [2][2] matrix form */
- CxRe[0][0] = hDiracDecBin->ChEne[0][bin];
- CxRe[1][1] = hDiracDecBin->ChEne[1][bin];
- CxRe[1][0] = hDiracDecBin->ChCrossRe[bin];
- CxRe[0][1] = hDiracDecBin->ChCrossRe[bin];
+ CxRe[0][0] = h->ChEne[0][bin];
+ CxRe[1][1] = h->ChEne[1][bin];
+ CxRe[1][0] = h->ChCrossRe[bin];
+ CxRe[0][1] = h->ChCrossRe[bin];
CxIm[0][0] = 0.0f;
CxIm[1][1] = 0.0f;
- CxIm[1][0] = hDiracDecBin->ChCrossIm[bin];
- CxIm[0][1] = -hDiracDecBin->ChCrossIm[bin];
+ CxIm[1][0] = h->ChCrossIm[bin];
+ CxIm[0][1] = -h->ChCrossIm[bin];
/* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */
matrixMul( Mre, Mim, CxRe, CxIm, tmpMtxRe, tmpMtxIm );
@@ -1315,30 +1420,30 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
/* Subtract the resulting covariance matrix from the target covariance matrix to determine
* what signal component is missing. The result is the target covariance matrix for the residual signal, i.e.,
* a residual covariance matrix. */
- CrEneL = max( 0.0f, hDiracDecBin->ChEneOut[0][bin] - resultMtxRe[0][0] );
- CrEneR = max( 0.0f, hDiracDecBin->ChEneOut[1][bin] - resultMtxRe[1][1] );
- CrCrossRe = hDiracDecBin->ChCrossReOut[bin] - resultMtxRe[1][0];
- CrCrossIm = hDiracDecBin->ChCrossImOut[bin] - resultMtxIm[1][0];
+ CrEneL = max( 0.0f, h->ChEneOut[0][bin] - resultMtxRe[0][0] );
+ CrEneR = max( 0.0f, h->ChEneOut[1][bin] - resultMtxRe[1][1] );
+ CrCrossRe = h->ChCrossReOut[bin] - resultMtxRe[1][0];
+ CrCrossIm = h->ChCrossImOut[bin] - resultMtxIm[1][0];
/* The amount of the decorrelated sound is further controlled based on the spatial metadata,
* by determining an energy-suppressed residual covariance matrix that is a control parameter
* that guides the processing of the decorrelated sound to a residual signal.
* The procedure improves quality in e.g. double-talk 2-direction rendering situations.*/
- if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE )
+ if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE )
{
decorrelationReductionFactor = 1.0f;
}
- else if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) || ( ivas_format == MASA_FORMAT && nchan_transport == 1 ) )
+ else if ( ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) || ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 1 ) )
{
- decorrelationReductionFactor = sqrtf( fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] ) );
+ decorrelationReductionFactor = sqrtf( fmaxf( 0.0f, h->frameMeanDiffuseness[bin] ) );
}
- else if ( ivas_format == SBA_FORMAT && nchan_transport == 1 )
+ else if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport == 1 )
{
decorrelationReductionFactor = 1.0f;
}
else
{
- decorrelationReductionFactor = fmaxf( 0.0f, hDiracDecBin->frameMeanDiffuseness[bin] );
+ decorrelationReductionFactor = fmaxf( 0.0f, h->frameMeanDiffuseness[bin] );
}
CrEneL *= decorrelationReductionFactor;
CrEneR *= decorrelationReductionFactor;
@@ -1347,7 +1452,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
/* Determine a residual mixing matrix Mdec for processing the decorrelated signal to obtain
* the residual signal (that has the residual covariance matrix) */
- formulate2x2MixingMatrix( hDiracDecBin->ChEne[0][bin], hDiracDecBin->ChEne[1][bin],
+ formulate2x2MixingMatrix( h->ChEne[0][bin], h->ChEne[1][bin],
0.0f, 0.0f, /* Decorrelated signal has ideally no cross-terms */
CrEneL, CrEneR,
CrCrossRe, CrCrossIm,
@@ -1364,7 +1469,7 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
/* The regularizations at determining mixing matrices cause signal energy to be lost to some degree, which is compensated for here */
realizedOutputEne = CrEneL + CrEneR + resultMtxRe[0][0] + resultMtxRe[1][1];
- targetOutputEne = hDiracDecBin->ChEneOut[0][bin] + hDiracDecBin->ChEneOut[1][bin];
+ targetOutputEne = h->ChEneOut[0][bin] + h->ChEneOut[1][bin];
missingOutputEne = fmaxf( 0.0f, targetOutputEne - realizedOutputEne );
gain = sqrtf( ( resultMtxRe[0][0] + resultMtxRe[1][1] + missingOutputEne ) /
@@ -1385,15 +1490,15 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
{
for ( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
{
- hDiracDecBin->processMtxRePrev[chA][chB][bin] = hDiracDecBin->processMtxRe[chA][chB][bin];
- hDiracDecBin->processMtxImPrev[chA][chB][bin] = hDiracDecBin->processMtxIm[chA][chB][bin];
- hDiracDecBin->processMtxDecRePrev[chA][chB][bin] = hDiracDecBin->processMtxDecRe[chA][chB][bin];
- hDiracDecBin->processMtxDecImPrev[chA][chB][bin] = hDiracDecBin->processMtxDecIm[chA][chB][bin];
-
- hDiracDecBin->processMtxRe[chA][chB][bin] = Mre[chA][chB];
- hDiracDecBin->processMtxIm[chA][chB][bin] = Mim[chA][chB];
- hDiracDecBin->processMtxDecRe[chA][chB][bin] = MdecRe[chA][chB];
- hDiracDecBin->processMtxDecIm[chA][chB][bin] = MdecIm[chA][chB];
+ h->processMtxRePrev[chA][chB][bin] = h->processMtxRe[chA][chB][bin];
+ h->processMtxImPrev[chA][chB][bin] = h->processMtxIm[chA][chB][bin];
+ h->processMtxDecRePrev[chA][chB][bin] = h->processMtxDecRe[chA][chB][bin];
+ h->processMtxDecImPrev[chA][chB][bin] = h->processMtxDecIm[chA][chB][bin];
+
+ h->processMtxRe[chA][chB][bin] = Mre[chA][chB];
+ h->processMtxIm[chA][chB][bin] = Mim[chA][chB];
+ h->processMtxDecRe[chA][chB][bin] = MdecRe[chA][chB];
+ h->processMtxDecIm[chA][chB][bin] = MdecIm[chA][chB];
}
}
@@ -1405,20 +1510,72 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
float gainFactor;
int16_t aziDeg = 0;
int16_t eleDeg = 0;
+#ifdef MASA_AND_OBJECTS
+ uint8_t instantChange = 0;
+
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ gainFactor = 0.7943f * sqrtf( h->earlyPartEneCorrection[bin] ); /* Todo Nokia: Temporary gain for roughly matching the loudness of other processing paths. */
+ }
+ else
+ {
+ gainFactor = 0.8414f * sqrtf( h->earlyPartEneCorrection[bin] );
+ }
+
+ for ( chB = 0; chB < nchanSeparateChannels; chB++ )
+ {
+ if ( st_ivas->ivas_format == MASA_ISM_FORMAT )
+ {
+ if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
+ {
+ aziDeg = st_ivas->hMasaIsmData->azimuth_ism[chB][dirac_read_idx];
+ eleDeg = st_ivas->hMasaIsmData->elevation_ism[chB][dirac_read_idx];
+ }
+ else
+ {
+ aziDeg = st_ivas->hMasaIsmData->azimuth_separated_ism[dirac_read_idx];
+ eleDeg = st_ivas->hMasaIsmData->elevation_separated_ism[dirac_read_idx];
+ instantChange = 1;
+ }
+ }
+
+ for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
+ {
+ h->processMtxRePrev[chA][chB + 2][bin] = h->processMtxRe[chA][chB + 2][bin];
+ h->processMtxImPrev[chA][chB + 2][bin] = h->processMtxIm[chA][chB + 2][bin];
+ }
+
+ getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[chB], isHeadtracked );
- gainFactor = 0.8414f * sqrtf( hDiracDecBin->earlyPartEneCorrection[bin] );
+ h->processMtxRe[0][chB + 2][bin] = lRealp * gainFactor;
+ h->processMtxIm[0][chB + 2][bin] = lImagp * gainFactor;
+ h->processMtxRe[1][chB + 2][bin] = rRealp * gainFactor;
+ h->processMtxIm[1][chB + 2][bin] = rImagp * gainFactor;
+
+ if ( instantChange )
+ {
+ for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
+ {
+ h->processMtxRePrev[chA][chB + 2][bin] = h->processMtxRe[chA][chB + 2][bin];
+ h->processMtxImPrev[chA][chB + 2][bin] = h->processMtxIm[chA][chB + 2][bin];
+ }
+ }
+ }
+#else
+ gainFactor = 0.8414f * sqrtf( h->earlyPartEneCorrection[bin] );
for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
{
- hDiracDecBin->processMtxRePrev[chA][2][bin] = hDiracDecBin->processMtxRe[chA][2][bin];
- hDiracDecBin->processMtxImPrev[chA][2][bin] = hDiracDecBin->processMtxIm[chA][2][bin];
+ h->processMtxRePrev[chA][2][bin] = h->processMtxRe[chA][2][bin];
+ h->processMtxImPrev[chA][2][bin] = h->processMtxIm[chA][2][bin];
}
- getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache, isHeadtracked );
+ getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, h->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache, isHeadtracked );
- hDiracDecBin->processMtxRe[0][2][bin] = lRealp * gainFactor;
- hDiracDecBin->processMtxIm[0][2][bin] = lImagp * gainFactor;
- hDiracDecBin->processMtxRe[1][2][bin] = rRealp * gainFactor;
- hDiracDecBin->processMtxIm[1][2][bin] = rImagp * gainFactor;
+ h->processMtxRe[0][2][bin] = lRealp * gainFactor;
+ h->processMtxIm[0][2][bin] = lImagp * gainFactor;
+ h->processMtxRe[1][2][bin] = rRealp * gainFactor;
+ h->processMtxIm[1][2][bin] = rImagp * gainFactor;
+#endif
}
}
@@ -1427,15 +1584,12 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices(
static void ivas_dirac_dec_binaural_process_output(
- DIRAC_DEC_BIN_HANDLE hDiracDecBin,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom,
- HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS],
+ Decoder_Struct *st_ivas,
float *output_f[],
float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
const int16_t max_band_decorr,
const int16_t numInChannels,
- const int16_t processReverb,
const int16_t subframe )
{
int16_t slot, bin, chA, chB;
@@ -1444,29 +1598,31 @@ static void ivas_dirac_dec_binaural_process_output(
float decSlotRe[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
+ DIRAC_DEC_BIN_HANDLE h;
float interpVal;
float *decSlotRePointer;
float *decSlotImPointer;
int16_t offsetSamples;
int16_t nSlots;
- nBins = hSpatParamRendCom->num_freq_bands;
+ h = st_ivas->hDiracDecBin;
+ nBins = st_ivas->hDirAC->num_freq_bands;
offsetSamples = 0;
- nSlots = hSpatParamRendCom->subframe_nbslots[subframe];
+ nSlots = st_ivas->hDirAC->subframe_nbslots[subframe];
- if ( processReverb )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
{
/* Process second / room effect part of binaural output when needed */
- ivas_binaural_reverb_processSubframe( hDiracDecBin->hReverb, numInChannels, nSlots, inRe, inIm, reverbRe, reverbIm );
+ ivas_binaural_reverb_processSubframe( st_ivas->hDiracDecBin->hReverb, numInChannels, nSlots, inRe, inIm, reverbRe, reverbIm );
}
interpVal = 0.0f;
for ( slot = 0; slot < nSlots; slot++ )
{
interpVal += 1.0f / (float) nSlots;
- if ( !hDiracDecBin->useTdDecorr && max_band_decorr > 0 )
+ if ( !st_ivas->hDiracDecBin->useTdDecorr && max_band_decorr > 0 )
{
- ivas_dirac_dec_decorrelate_slot( hDiracDecBin, nBins, slot, inRe, inIm, decSlotRe, decSlotIm );
+ ivas_dirac_dec_decorrelate_slot( st_ivas->hDirAC, slot, inRe, inIm, decSlotRe, decSlotIm );
}
for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
@@ -1479,7 +1635,7 @@ static void ivas_dirac_dec_binaural_process_output(
/* Processing of the first / HRTF part of the binaural output. */
for ( chB = 0; chB < numInChannels; chB++ )
{
- if ( hDiracDecBin->useTdDecorr )
+ if ( st_ivas->hDiracDecBin->useTdDecorr )
{
decSlotRePointer = inRe[chB + 2][slot];
decSlotImPointer = inIm[chB + 2][slot];
@@ -1495,33 +1651,33 @@ static void ivas_dirac_dec_binaural_process_output(
float gain;
/* Mixing using the formulated processing matrix M */
- gain = ( 1.0f - interpVal ) * hDiracDecBin->processMtxRePrev[chA][chB][bin] +
- interpVal * hDiracDecBin->processMtxRe[chA][chB][bin];
+ gain = ( 1.0f - interpVal ) * h->processMtxRePrev[chA][chB][bin] +
+ interpVal * h->processMtxRe[chA][chB][bin];
outSlotRe[bin] += gain * inRe[chB][slot][bin];
outSlotIm[bin] += gain * inIm[chB][slot][bin];
- gain = ( 1.0f - interpVal ) * hDiracDecBin->processMtxImPrev[chA][chB][bin] +
- interpVal * hDiracDecBin->processMtxIm[chA][chB][bin];
+ gain = ( 1.0f - interpVal ) * h->processMtxImPrev[chA][chB][bin] +
+ interpVal * h->processMtxIm[chA][chB][bin];
outSlotRe[bin] -= gain * inIm[chB][slot][bin];
outSlotIm[bin] += gain * inRe[chB][slot][bin];
/* Mixing decorrelated signals using the formulated residual processing matrix Mdec */
if ( bin < max_band_decorr && chB < 2 )
{
- gain = ( 1.0f - interpVal ) * hDiracDecBin->processMtxDecRePrev[chA][chB][bin] +
- interpVal * hDiracDecBin->processMtxDecRe[chA][chB][bin];
+ gain = ( 1.0f - interpVal ) * h->processMtxDecRePrev[chA][chB][bin] +
+ interpVal * h->processMtxDecRe[chA][chB][bin];
outSlotRe[bin] += gain * decSlotRePointer[bin];
outSlotIm[bin] += gain * decSlotImPointer[bin];
- gain = ( 1.0f - interpVal ) * hDiracDecBin->processMtxDecImPrev[chA][chB][bin] +
- interpVal * hDiracDecBin->processMtxDecIm[chA][chB][bin];
+ gain = ( 1.0f - interpVal ) * h->processMtxDecImPrev[chA][chB][bin] +
+ interpVal * h->processMtxDecIm[chA][chB][bin];
outSlotRe[bin] -= gain * decSlotImPointer[bin];
outSlotIm[bin] += gain * decSlotRePointer[bin];
}
}
}
- if ( processReverb )
+ if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM )
{
/* Combine second (reverb) part with the first (HRTF) part to obtain binaural output signal with room effect */
v_add( outSlotRe, reverbRe[chA][slot], outSlotRe, CLDFB_NO_CHANNELS_MAX );
@@ -1532,7 +1688,7 @@ static void ivas_dirac_dec_binaural_process_output(
outSlotImPr = &( outSlotIm[0] );
/* Inverse filter bank */
- cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] );
+ cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, st_ivas->cldfbSynDec[chA] );
}
}
@@ -2209,10 +2365,7 @@ static void hrtfShGetHrtf(
{
float shVec[HRTF_SH_CHANNELS];
- ivas_dirac_dec_get_response( aziDeg,
- eleDeg,
- shVec,
- HRTF_SH_ORDER );
+ ivas_dirac_dec_get_response( aziDeg, eleDeg, shVec, HRTF_SH_ORDER );
for ( k = 0; k < HRTF_SH_CHANNELS; k++ )
{
@@ -2243,6 +2396,7 @@ float configure_reqularization_factor(
)
{
float reqularizationFactor;
+
reqularizationFactor = 1.0f; /* Default value */
if ( ivas_format == MASA_FORMAT )
@@ -2293,7 +2447,236 @@ float configure_reqularization_factor(
}
}
- /* For SBA and parametric ISM, currently in default value of 1.0f. */
+ /* For SBA and parametric ISM, default value of 1.0f. */
return reqularizationFactor;
}
+
+
+#ifdef MASA_AND_OBJECTS
+/*-------------------------------------------------------------------*
+ * preProcessStereoTransportsForMovedObjects()
+ *
+ *
+ *-------------------------------------------------------------------*/
+// Todo OMASA JBM: This might need further adjustments
+void preProcessStereoTransportsForMovedObjects(
+ Decoder_Struct *st_ivas,
+ float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
+ float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
+ const int16_t nBins,
+ const int16_t subframe )
+{
+ int16_t bin, ch, inCh, outCh, ismDirIndex, slot;
+ DIRAC_DEC_HANDLE hDirAC;
+ MASA_ISM_DATA_HANDLE hMasaIsmData;
+ uint8_t enableCentering;
+ int16_t dirac_read_idx;
+ int16_t nSlots;
+
+ hDirAC = st_ivas->hDirAC;
+ hMasaIsmData = st_ivas->hMasaIsmData;
+
+ if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_HOA2 || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_HOA3 )
+ {
+ enableCentering = 0;
+ }
+ else
+ {
+ enableCentering = 1;
+ }
+
+ /* Bypass processing until first object is moved */
+ if ( hMasaIsmData->objectsMoved == 0 )
+ {
+ for ( ismDirIndex = 0; ismDirIndex < hDirAC->numIsmDirections; ismDirIndex++ )
+ {
+ if ( hMasaIsmData->ism_is_edited[ismDirIndex] )
+ {
+ hMasaIsmData->objectsMoved = 1;
+ }
+ }
+ if ( hMasaIsmData->objectsMoved == 0 )
+ {
+ /* No objects have moved so far */
+ return;
+ }
+ }
+
+ /* Perform object-movement based processing */
+ // Todo OMASA JBM: Fixed but might be still wrong somehow
+ nSlots = st_ivas->hDirAC->subframe_nbslots[subframe];
+ dirac_read_idx = st_ivas->hDirAC->render_to_md_map[subframe];
+
+ for ( bin = 0; bin < nBins; bin++ )
+ {
+ float ismPreprocMtxNew[2][2];
+ float ismPreprocMtxIncrement[2][2];
+ float eneMove[2];
+ float enePreserve[2];
+ float ismRatioAcc;
+ float subframeEne;
+ float normEnes[2];
+ float remainderNormEne;
+
+ set_zero( ismPreprocMtxNew[0], 2 );
+ set_zero( ismPreprocMtxNew[1], 2 );
+ set_zero( ismPreprocMtxIncrement[0], 2 );
+ set_zero( ismPreprocMtxIncrement[1], 2 );
+ set_zero( eneMove, 2 );
+ set_zero( enePreserve, 2 );
+ ismRatioAcc = 0.0f;
+ subframeEne = 0.0f;
+ set_zero( normEnes, 2 );
+
+ /* Determine transport normalized energies and subframe energy */
+ for ( slot = 0; slot < nSlots; slot++ )
+ {
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ normEnes[ch] += inRe[ch][slot][bin] * inRe[ch][slot][bin];
+ normEnes[ch] += inIm[ch][slot][bin] * inIm[ch][slot][bin];
+ }
+ }
+ subframeEne = normEnes[0] + normEnes[1];
+ normEnes[0] /= fmaxf( 1e-12f, subframeEne );
+ normEnes[1] /= fmaxf( 1e-12f, subframeEne );
+
+ /* For each ismDir, formulate a mix-matrix that moves object audio signals between
+ * left and right channels when needed. Make a combined matrix by a ratio-weighted sum */
+ for ( ismDirIndex = 0; ismDirIndex < hDirAC->numIsmDirections; ismDirIndex++ )
+ {
+ float panGainsOut[2];
+ float panGainsIn[2];
+ float ratio;
+ float panEnesOut[2];
+ float panEnesIn[2];
+ float centeringFactor;
+
+ ratio = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin];
+
+ ismRatioAcc += ratio;
+
+ /* Get input and output panning gains */
+ ivas_get_stereo_panning_gains( hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx],
+ hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx],
+ panGainsIn );
+
+ if ( hMasaIsmData->ism_is_edited[ismDirIndex] )
+ {
+ ivas_get_stereo_panning_gains( hMasaIsmData->azimuth_ism_edited[ismDirIndex],
+ hMasaIsmData->elevation_ism_edited[ismDirIndex],
+ panGainsOut );
+ }
+ else
+ {
+ /* When not edited, input and output pan gains are the same */
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ panGainsOut[ch] = panGainsIn[ch];
+ }
+ }
+
+ /* Determine pan enes */
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ panEnesOut[ch] = panGainsOut[ch] * panGainsOut[ch];
+ panEnesIn[ch] = panGainsIn[ch] * panGainsIn[ch];
+ }
+
+ if ( enableCentering )
+ {
+ centeringFactor = fmaxf( 0.0f, 2.0f * fabsf( panEnesIn[0] - panEnesOut[0] ) - 1.0f );
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ panEnesOut[ch] *= ( 1.0f - centeringFactor );
+ panEnesOut[ch] += 0.5f * centeringFactor;
+ }
+ }
+
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ float eneMoveThis;
+ float enePreserveThis;
+ eneMoveThis = fmaxf( 0.0f, panEnesIn[ch] - panEnesOut[ch] );
+ enePreserveThis = panEnesIn[ch] - eneMoveThis;
+
+ eneMove[ch] += ratio * eneMoveThis;
+ enePreserve[ch] += ratio * enePreserveThis;
+
+ /* Subtract object parts from normEnes */
+ normEnes[ch] -= panEnesIn[ch] * ratio;
+ }
+ }
+
+ /* Any remaining (non-object) energy is set to be preserved at both channels */
+ remainderNormEne = fmaxf( 0.0f, ( 1.0f - ismRatioAcc ) - normEnes[0] - normEnes[1] );
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ enePreserve[ch] += fmaxf( 0.0f, normEnes[ch] + remainderNormEne / 2.0f );
+ }
+
+ /* Temporally average energy moving and preserving, and generate the transport signal preprocessing matrix */
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ float normVal;
+ hMasaIsmData->eneMoveIIR[ch][bin] *= STEREO_PREPROCESS_IIR_FACTOR;
+ hMasaIsmData->eneMoveIIR[ch][bin] += eneMove[ch] * subframeEne;
+ hMasaIsmData->enePreserveIIR[ch][bin] *= STEREO_PREPROCESS_IIR_FACTOR;
+ hMasaIsmData->enePreserveIIR[ch][bin] += enePreserve[ch] * subframeEne;
+ normVal = fmaxf( EPSILON, hMasaIsmData->eneMoveIIR[ch][bin] + hMasaIsmData->enePreserveIIR[ch][bin] );
+ ismPreprocMtxNew[ch][ch] = sqrtf( hMasaIsmData->enePreserveIIR[ch][bin] / normVal );
+ ismPreprocMtxNew[1 - ch][ch] = sqrtf( hMasaIsmData->eneMoveIIR[ch][bin] / normVal );
+ }
+
+ /* Get increment value for temporal interpolation */
+ for ( inCh = 0; inCh < 2; inCh++ )
+ {
+ for ( outCh = 0; outCh < 2; outCh++ )
+ {
+ ismPreprocMtxIncrement[outCh][inCh] = ( ismPreprocMtxNew[outCh][inCh] - hMasaIsmData->ismPreprocMatrix[outCh][inCh][bin] ) / (float) nSlots;
+ }
+ }
+
+ /* Mix signals */
+ for ( slot = 0; slot < nSlots; slot++ )
+ {
+ float eqVal;
+ float outSlotRe[2];
+ float outSlotIm[2];
+
+ set_zero( outSlotRe, 2 );
+ set_zero( outSlotIm, 2 );
+
+ for ( outCh = 0; outCh < 2; outCh++ )
+ {
+ for ( inCh = 0; inCh < 2; inCh++ )
+ {
+ hMasaIsmData->ismPreprocMatrix[outCh][inCh][bin] += ismPreprocMtxIncrement[outCh][inCh];
+ outSlotRe[outCh] += inRe[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][bin];
+ outSlotIm[outCh] += inIm[inCh][slot][bin] * hMasaIsmData->ismPreprocMatrix[outCh][inCh][bin];
+ }
+ }
+
+ /* IIR average the energy measures and determine and apply energy-preserving equalizer */
+ hMasaIsmData->preprocEneTarget[bin] *= STEREO_PREPROCESS_IIR_FACTOR;
+ hMasaIsmData->preprocEneRealized[bin] *= STEREO_PREPROCESS_IIR_FACTOR;
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ hMasaIsmData->preprocEneTarget[bin] += inRe[ch][slot][bin] * inRe[ch][slot][bin];
+ hMasaIsmData->preprocEneTarget[bin] += inIm[ch][slot][bin] * inIm[ch][slot][bin];
+ hMasaIsmData->preprocEneRealized[bin] += outSlotRe[ch] * outSlotRe[ch];
+ hMasaIsmData->preprocEneRealized[bin] += outSlotIm[ch] * outSlotIm[ch];
+ }
+ eqVal = fminf( 4.0f, sqrtf( hMasaIsmData->preprocEneTarget[bin] / fmaxf( 1e-12f, hMasaIsmData->preprocEneRealized[bin] ) ) );
+ for ( ch = 0; ch < 2; ch++ )
+ {
+ inRe[ch][slot][bin] = outSlotRe[ch] * eqVal;
+ inIm[ch][slot][bin] = outSlotIm[ch] * eqVal;
+ }
+ }
+ }
+
+ return;
+}
+#endif
diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c
deleted file mode 100644
index 84ce30d1bce60f83798b233d2c0286ef559c9e73..0000000000000000000000000000000000000000
--- a/lib_rend/ivas_dirac_rend.c
+++ /dev/null
@@ -1,2030 +0,0 @@
-/******************************************************************************************************
-
-(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
-#include "cnst.h"
-#include "prot.h"
-#include "ivas_prot.h"
-#include "ivas_prot_rend.h"
-#include "ivas_cnst.h"
-#include "ivas_rom_dec.h"
-#ifdef DEBUGGING
-#include "debug.h"
-#endif
-#include "wmc_auto.h"
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_allocate_parameters()
- *
- * Allocate and initialize DirAC parameters
- *-------------------------------------------------------------------------*/
-
-ivas_error ivas_dirac_allocate_parameters(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */
- const int16_t params_flag /* i : set of parameters flag */
-)
-{
- int16_t i;
-
- if ( params_flag == 1 )
- {
- if ( ( hSpatParamRendCom->azimuth = (int16_t **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->elevation = (int16_t **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->diffuseness_vector = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->energy_ratio1 = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->spreadCoherence = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->surroundingCoherence = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- for ( i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++ )
- {
- if ( ( hSpatParamRendCom->azimuth[i] = (int16_t *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_s( hSpatParamRendCom->azimuth[i], 0, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->elevation[i] = (int16_t *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_s( hSpatParamRendCom->elevation[i], 0, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->diffuseness_vector[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->diffuseness_vector[i], 1.0f, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->energy_ratio1[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->energy_ratio1[i], 0.0f, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->spreadCoherence[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->spreadCoherence[i], 0.0f, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->surroundingCoherence[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->surroundingCoherence[i], 0.0f, hSpatParamRendCom->num_freq_bands );
- }
- }
- else if ( params_flag == 2 )
- {
- if ( ( hSpatParamRendCom->azimuth2 = (int16_t **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->elevation2 = (int16_t **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( int16_t * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->energy_ratio2 = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- if ( ( hSpatParamRendCom->spreadCoherence2 = (float **) malloc( hSpatParamRendCom->dirac_md_buffer_length * sizeof( float * ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
-
- for ( i = 0; i < hSpatParamRendCom->dirac_md_buffer_length; i++ )
- {
- if ( ( hSpatParamRendCom->azimuth2[i] = (int16_t *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_s( hSpatParamRendCom->azimuth2[i], 0, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->elevation2[i] = (int16_t *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( int16_t ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_s( hSpatParamRendCom->elevation2[i], 0, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->energy_ratio2[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->energy_ratio2[i], 0.0f, hSpatParamRendCom->num_freq_bands );
-
- if ( ( hSpatParamRendCom->spreadCoherence2[i] = (float *) malloc( hSpatParamRendCom->num_freq_bands * sizeof( float ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC\n" ) );
- }
- set_f( hSpatParamRendCom->spreadCoherence2[i], 0.0f, hSpatParamRendCom->num_freq_bands );
- }
- }
-
- return IVAS_ERR_OK;
-}
-
-
-ivas_error ivas_spat_hSpatParamRendCom_config(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: IVAS decoder structure */
- const DIRAC_CONFIG_FLAG flag_config_inp, /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
- const int16_t dec_param_estim_flag,
- const IVAS_FORMAT ivas_format,
- const MC_MODE mc_mode,
- const int32_t output_Fs,
- const int16_t hodirac_flag )
-{
- ivas_error error;
- int16_t map_idx;
- DIRAC_CONFIG_FLAG flag_config;
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
-
- flag_config = ( flag_config_inp == DIRAC_RECONFIGURE_MODE ) ? DIRAC_RECONFIGURE : flag_config_inp;
- error = IVAS_ERR_OK;
-
- hSpatParamRendCom = NULL;
-
- if ( flag_config == DIRAC_RECONFIGURE )
- {
- hSpatParamRendCom = *hSpatParamRendCom_out;
- }
- else if ( flag_config == DIRAC_OPEN )
- {
- /*-----------------------------------------------------------------*
- * prepare library opening
- *-----------------------------------------------------------------*/
-
- if ( ( hSpatParamRendCom = (SPAT_PARAM_REND_COMMON_DATA_HANDLE) malloc( sizeof( SPAT_PARAM_REND_COMMON_DATA ) ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for DirAC meta\n" ) );
- }
-
- *hSpatParamRendCom_out = hSpatParamRendCom;
- }
-
-
- if ( flag_config == DIRAC_OPEN )
- {
- hSpatParamRendCom->slot_size = (int16_t) ( ( output_Fs / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );
- set_s( hSpatParamRendCom->subframe_nbslots, 0, MAX_JBM_SUBFRAMES_5MS );
- set_s( hSpatParamRendCom->subframe_nbslots, JBM_CLDFB_SLOTS_IN_SUBFRAME, DEFAULT_JBM_SUBFRAMES_5MS );
- hSpatParamRendCom->nb_subframes = DEFAULT_JBM_SUBFRAMES_5MS;
- hSpatParamRendCom->subframes_rendered = 0;
- hSpatParamRendCom->slots_rendered = 0;
- hSpatParamRendCom->num_slots = DEFAULT_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME;
- hSpatParamRendCom->num_freq_bands = (int16_t) ( output_Fs * INV_CLDFB_BANDWIDTH + 0.5f );
- }
-
- /*-----------------------------------------------------------------*
- * set input parameters
- *-----------------------------------------------------------------*/
-
- if ( ivas_format == SBA_FORMAT && flag_config == DIRAC_RECONFIGURE )
- {
- if ( hodirac_flag && hSpatParamRendCom->azimuth2 == NULL )
- {
- if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 2 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else if ( !hodirac_flag && hSpatParamRendCom->azimuth2 != NULL )
- {
- ivas_dirac_deallocate_parameters( hSpatParamRendCom, 2 );
- }
- }
-
- if ( flag_config == DIRAC_OPEN )
- {
- hSpatParamRendCom->dirac_md_buffer_length = 0;
- hSpatParamRendCom->dirac_bs_md_write_idx = 0;
- hSpatParamRendCom->dirac_read_idx = 0;
- if ( mc_mode == MC_MODE_MCMASA )
- {
- hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES;
-
- set_s( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
- for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
- {
- hSpatParamRendCom->render_to_md_map[map_idx] = map_idx;
- }
- }
- else if ( ivas_format == MASA_FORMAT )
- {
- hSpatParamRendCom->dirac_md_buffer_length = MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR;
- hSpatParamRendCom->dirac_bs_md_write_idx = DELAY_MASA_PARAM_DEC_SFR;
-
- set_s( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
- for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS; map_idx++ )
- {
- hSpatParamRendCom->render_to_md_map[map_idx] = map_idx;
- }
- }
- else
- {
- int16_t num_slots_in_subfr;
- num_slots_in_subfr = dec_param_estim_flag ? CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES : 1;
- hSpatParamRendCom->dirac_md_buffer_length = ( MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_DIRAC_PARAM_DEC_SFR );
- hSpatParamRendCom->dirac_bs_md_write_idx = DELAY_DIRAC_PARAM_DEC_SFR;
- hSpatParamRendCom->dirac_read_idx = 0;
-
- set_s( hSpatParamRendCom->render_to_md_map, 0, MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME );
- for ( map_idx = 0; map_idx < DEFAULT_JBM_SUBFRAMES_5MS * num_slots_in_subfr; map_idx++ )
- {
- hSpatParamRendCom->render_to_md_map[map_idx] = hSpatParamRendCom->dirac_read_idx + map_idx / num_slots_in_subfr;
- }
- }
-
- if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 1 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
-
- if ( ivas_format == MASA_FORMAT || ( ivas_format == SBA_FORMAT && hodirac_flag ) )
- {
- if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 2 ) ) != IVAS_ERR_OK )
- {
- return error;
- }
- }
- else
- {
- hSpatParamRendCom->azimuth2 = NULL;
- hSpatParamRendCom->elevation2 = NULL;
- hSpatParamRendCom->energy_ratio2 = NULL;
- hSpatParamRendCom->spreadCoherence2 = NULL;
- }
- }
-
- return error;
-}
-
-
-void ivas_spat_hSpatParamRendCom_close(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out )
-{
- if ( hSpatParamRendCom_out == NULL || *hSpatParamRendCom_out == NULL )
- {
- return;
- }
-
- ivas_dirac_deallocate_parameters( *hSpatParamRendCom_out, 1 );
- ivas_dirac_deallocate_parameters( *hSpatParamRendCom_out, 2 );
-
- free( *hSpatParamRendCom_out );
- *hSpatParamRendCom_out = NULL;
-
- return;
-}
-
-void ivas_dirac_rend_close(
- DIRAC_REND_HANDLE *hDirACRend_out )
-{
- int16_t i, j;
- DIRAC_REND_HANDLE hDirACRend;
-
- if ( hDirACRend_out == NULL || *hDirACRend_out == NULL )
- {
- return;
- }
-
- hDirACRend = *hDirACRend_out;
-
- /* close Output synthesis sub-module */
- ivas_dirac_dec_output_synthesis_close( hDirACRend );
-
- /* close Decorrelator sub-module */
- if ( hDirACRend->proto_signal_decorr_on )
- {
- ivas_dirac_dec_decorr_close( &hDirACRend->h_freq_domain_decorr_ap_params, &hDirACRend->h_freq_domain_decorr_ap_state );
- }
-
- /* Params */
-
- /* free frequency axis buffer */
- if ( hDirACRend->frequency_axis != NULL )
- {
- free( hDirACRend->frequency_axis );
- hDirACRend->frequency_axis = NULL;
- }
-
- if ( hDirACRend->diffuse_response_function != NULL )
- {
- free( hDirACRend->diffuse_response_function );
- hDirACRend->diffuse_response_function = NULL;
- }
-
- if ( hDirACRend->hoa_encoder != NULL )
- {
- free( hDirACRend->hoa_encoder );
- hDirACRend->hoa_encoder = NULL;
- }
-
- /* prototype indexing */
- if ( hDirACRend->proto_index_dir != NULL )
- {
- free( hDirACRend->proto_index_dir );
- hDirACRend->proto_index_dir = NULL;
- }
-
- if ( hDirACRend->proto_index_diff != NULL )
- {
- free( hDirACRend->proto_index_diff );
- hDirACRend->proto_index_dir = NULL;
- }
-
- /* States */
-
- /* free prototype signal buffers */
- if ( hDirACRend->proto_frame_f != NULL )
- {
- free( hDirACRend->proto_frame_f );
- hDirACRend->proto_frame_f = NULL;
- }
-
- for ( i = 0; i < DIRAC_NUM_DIMS; i++ )
- {
- for ( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
- {
- if ( hDirACRend->buffer_intensity_real[i][j] != NULL )
- {
- free( hDirACRend->buffer_intensity_real[i][j] );
- hDirACRend->buffer_intensity_real[i][j] = NULL;
- }
- }
- }
- if ( hDirACRend->buffer_energy != NULL )
- {
- free( hDirACRend->buffer_energy );
- hDirACRend->buffer_energy = NULL;
- }
-
- if ( hDirACRend->masa_stereo_type_detect != NULL )
- {
- free( hDirACRend->masa_stereo_type_detect );
- hDirACRend->masa_stereo_type_detect = NULL;
- }
-
- ivas_dirac_free_mem( &( hDirACRend->stack_mem ) );
-
- free( *hDirACRend_out );
- *hDirACRend_out = NULL;
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_deallocate_parameters()
- *
- * Deallocate DirAC parameters
- *-------------------------------------------------------------------------*/
-
-void ivas_dirac_deallocate_parameters(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */
- const int16_t params_flag /* i : set of parameters flag */
-)
-{
- int16_t i;
- int16_t md_buffer_length;
-
- if ( hSpatParamRendCom == NULL )
- {
- return;
- }
-
- md_buffer_length = hSpatParamRendCom->dirac_md_buffer_length;
-
- if ( params_flag == 1 )
- {
- if ( hSpatParamRendCom->azimuth != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->azimuth[i] != NULL )
- {
- free( hSpatParamRendCom->azimuth[i] );
- hSpatParamRendCom->azimuth[i] = NULL;
- }
- }
-
- free( hSpatParamRendCom->azimuth );
- hSpatParamRendCom->azimuth = NULL;
- }
-
- if ( hSpatParamRendCom->elevation != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->elevation[i] != NULL )
- {
- free( hSpatParamRendCom->elevation[i] );
- hSpatParamRendCom->elevation[i] = NULL;
- }
- }
-
- free( hSpatParamRendCom->elevation );
- hSpatParamRendCom->elevation = NULL;
- }
-
- if ( hSpatParamRendCom->energy_ratio1 != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->energy_ratio1[i] != NULL )
- {
- free( hSpatParamRendCom->energy_ratio1[i] );
- hSpatParamRendCom->energy_ratio1[i] = NULL;
- }
- }
- free( hSpatParamRendCom->energy_ratio1 );
- hSpatParamRendCom->energy_ratio1 = NULL;
- }
-
- if ( hSpatParamRendCom->diffuseness_vector != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->diffuseness_vector[i] != NULL )
- {
- free( hSpatParamRendCom->diffuseness_vector[i] );
- hSpatParamRendCom->diffuseness_vector[i] = NULL;
- }
- }
-
- free( hSpatParamRendCom->diffuseness_vector );
- hSpatParamRendCom->diffuseness_vector = NULL;
- }
-
- if ( hSpatParamRendCom->spreadCoherence != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->spreadCoherence[i] != NULL )
- {
- free( hSpatParamRendCom->spreadCoherence[i] );
- hSpatParamRendCom->spreadCoherence[i] = NULL;
- }
- }
- free( hSpatParamRendCom->spreadCoherence );
- hSpatParamRendCom->spreadCoherence = NULL;
- }
-
- if ( hSpatParamRendCom->surroundingCoherence != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->surroundingCoherence[i] != NULL )
- {
- free( hSpatParamRendCom->surroundingCoherence[i] );
- hSpatParamRendCom->surroundingCoherence[i] = NULL;
- }
- }
- free( hSpatParamRendCom->surroundingCoherence );
- hSpatParamRendCom->surroundingCoherence = NULL;
- }
- }
- else if ( params_flag == 2 )
- {
- if ( hSpatParamRendCom->azimuth2 != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->azimuth2[i] != NULL )
- {
- free( hSpatParamRendCom->azimuth2[i] );
- hSpatParamRendCom->azimuth2[i] = NULL;
- }
- }
- free( hSpatParamRendCom->azimuth2 );
- hSpatParamRendCom->azimuth2 = NULL;
- }
-
- if ( hSpatParamRendCom->elevation2 != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->elevation2[i] != NULL )
- {
- free( hSpatParamRendCom->elevation2[i] );
- hSpatParamRendCom->elevation2[i] = NULL;
- }
- }
- free( hSpatParamRendCom->elevation2 );
- hSpatParamRendCom->elevation2 = NULL;
- }
-
- if ( hSpatParamRendCom->energy_ratio2 != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->energy_ratio2[i] != NULL )
- {
- free( hSpatParamRendCom->energy_ratio2[i] );
- hSpatParamRendCom->energy_ratio2[i] = NULL;
- }
- }
- free( hSpatParamRendCom->energy_ratio2 );
- hSpatParamRendCom->energy_ratio2 = NULL;
- }
-
- if ( hSpatParamRendCom->spreadCoherence2 != NULL )
- {
- for ( i = 0; i < md_buffer_length; i++ )
- {
- if ( hSpatParamRendCom->spreadCoherence2[i] != NULL )
- {
- free( hSpatParamRendCom->spreadCoherence2[i] );
- hSpatParamRendCom->spreadCoherence2[i] = NULL;
- }
- }
- free( hSpatParamRendCom->spreadCoherence2 );
- hSpatParamRendCom->spreadCoherence2 = NULL;
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_alloc_mem()
- *
- * Allocate stack memory for DirAC renderer
- *------------------------------------------------------------------------*/
-
-ivas_error ivas_dirac_alloc_mem(
- DIRAC_REND_HANDLE hDirACRend,
- const RENDERER_TYPE renderer_type,
- const int16_t num_freq_bands,
- DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem,
- const int16_t hodirac_flag )
-{
- int16_t num_freq_bands_diff, size;
- int16_t size_ho;
- int16_t size_pf;
- int16_t num_outputs_dir, num_outputs_diff;
- int16_t num_protos_dir;
-
- num_protos_dir = hDirACRend->num_protos_dir;
-
- num_freq_bands_diff = hDirACRend->h_output_synthesis_psd_params.max_band_decorr;
-
- num_outputs_dir = hDirACRend->num_outputs_dir;
- num_outputs_diff = hDirACRend->num_outputs_diff;
-
- size = num_freq_bands * num_outputs_dir;
- if ( hodirac_flag )
- {
- size_ho = size * DIRAC_HO_NUMSECTORS;
- size_pf = num_freq_bands * DIRAC_HO_NUMSECTORS;
- }
- else
- {
- size_ho = size;
- size_pf = num_freq_bands;
- }
-
- /* PSD related buffers */
- hDirAC_mem->cy_auto_dir_smooth = NULL;
- hDirAC_mem->proto_power_smooth = NULL;
- hDirAC_mem->proto_power_diff_smooth = NULL;
- hDirAC_mem->direct_responses_square = NULL;
- hDirAC_mem->frame_dec_f = NULL;
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
- {
- if ( ( hDirAC_mem->cy_auto_dir_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->cy_auto_dir_smooth, size );
-
- if ( ( hDirAC_mem->proto_power_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->proto_power_smooth, size );
-
- if ( ( hDirAC_mem->proto_power_diff_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->proto_power_diff_smooth, size );
-
- if ( ( hDirAC_mem->direct_responses_square = (float *) malloc( sizeof( float ) * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->direct_responses_square, size );
- if ( hDirACRend->proto_signal_decorr_on && ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC ) )
- {
- if ( ( hDirAC_mem->frame_dec_f = (float *) malloc( sizeof( float ) * 2 * num_outputs_diff * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
- }
- hDirACRend->h_output_synthesis_psd_state.proto_power_smooth = hDirAC_mem->proto_power_smooth;
- hDirACRend->h_output_synthesis_psd_state.proto_power_diff_smooth = hDirAC_mem->proto_power_diff_smooth;
- hDirACRend->h_output_synthesis_psd_state.cy_auto_dir_smooth = hDirAC_mem->cy_auto_dir_smooth;
- hDirACRend->h_output_synthesis_psd_state.direct_responses_square = hDirAC_mem->direct_responses_square;
-
- /* Target and smoothed nrg factors/gains */
- if ( ( hDirAC_mem->cy_cross_dir_smooth = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->cy_cross_dir_smooth, size );
-
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
- {
- if ( ( hDirAC_mem->cy_auto_diff_smooth = (float *) malloc( sizeof( float ) * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->cy_auto_diff_smooth, size );
- }
- else
- {
- if ( ( hDirAC_mem->cy_auto_diff_smooth = (float *) malloc( sizeof( float ) * num_outputs_diff * num_freq_bands_diff ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->cy_auto_diff_smooth, num_outputs_diff * num_freq_bands_diff );
- }
- hDirACRend->h_output_synthesis_psd_state.cy_cross_dir_smooth = hDirAC_mem->cy_cross_dir_smooth;
- hDirACRend->h_output_synthesis_psd_state.cy_auto_diff_smooth = hDirAC_mem->cy_auto_diff_smooth;
-
- /*Responses (gains/factors)*/
- if ( ( hDirAC_mem->direct_responses = (float *) malloc( sizeof( float ) * size_ho ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- set_zero( hDirAC_mem->direct_responses, size );
-
-
- hDirACRend->h_output_synthesis_psd_state.direct_responses = hDirAC_mem->direct_responses;
-
- /* Prototypes */
- hDirAC_mem->proto_direct_buffer_f = NULL;
- hDirAC_mem->proto_diffuse_buffer_f = NULL;
- if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
- {
- if ( ( hDirAC_mem->proto_direct_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_protos_dir * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
-
- if ( hDirACRend->proto_signal_decorr_on )
- {
- if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_PSD_SHD )
- {
- if ( ( hDirAC_mem->proto_diffuse_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * size ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
- else
- {
- if ( ( hDirAC_mem->proto_diffuse_buffer_f = (float *) malloc( sizeof( float ) * 2 * MAX_PARAM_SPATIAL_SUBFRAMES * num_outputs_diff * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
- }
- }
- hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f = hDirAC_mem->proto_direct_buffer_f;
- hDirACRend->h_output_synthesis_psd_state.proto_diffuse_buffer_f = hDirAC_mem->proto_diffuse_buffer_f;
-
- /* Gains/power factors*/
- hDirAC_mem->direct_power_factor = NULL;
- hDirAC_mem->diffuse_power_factor = NULL;
-
- if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
- {
- if ( ( hDirAC_mem->direct_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- if ( ( hDirAC_mem->diffuse_power_factor = (float *) malloc( sizeof( float ) * size_pf ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
-
- hDirACRend->h_output_synthesis_psd_state.direct_power_factor = hDirAC_mem->direct_power_factor;
- hDirACRend->h_output_synthesis_psd_state.diffuse_power_factor = hDirAC_mem->diffuse_power_factor;
-
- hDirAC_mem->reference_power = NULL;
- hDirAC_mem->onset_filter = NULL;
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_GAIN_SHD )
- {
- if ( renderer_type != RENDERER_BINAURAL_PARAMETRIC && renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && renderer_type != RENDERER_STEREO_PARAMETRIC )
- {
- if ( ( hDirAC_mem->reference_power = (float *) malloc( sizeof( float ) * 2 * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- if ( hDirACRend->proto_signal_decorr_on )
- {
- if ( ( hDirAC_mem->onset_filter = (float *) malloc( sizeof( float ) * num_outputs_diff * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
- }
- }
- else
- {
- if ( num_protos_dir > 2 )
- {
- if ( ( hDirAC_mem->reference_power = (float *) malloc( sizeof( float ) * 5 * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
-
- if ( hDirACRend->proto_signal_decorr_on )
- {
- if ( ( hDirAC_mem->onset_filter = (float *) malloc( sizeof( float ) * 2 * num_freq_bands ) ) == NULL )
- {
- return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate stack memory for DirAC\n" ) );
- }
- }
- }
-
- return IVAS_ERR_OK;
-}
-
-
-void ivas_dirac_free_mem(
- DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem )
-{
- if ( hDirAC_mem->cy_auto_dir_smooth != NULL )
- {
- free( hDirAC_mem->cy_auto_dir_smooth );
- }
- if ( hDirAC_mem->proto_power_smooth != NULL )
- {
- free( hDirAC_mem->proto_power_smooth );
- }
- if ( hDirAC_mem->proto_power_diff_smooth != NULL )
- {
- free( hDirAC_mem->proto_power_diff_smooth );
- }
- if ( hDirAC_mem->direct_responses_square != NULL )
- {
- free( hDirAC_mem->direct_responses_square );
- }
- if ( hDirAC_mem->frame_dec_f != NULL )
- {
- free( hDirAC_mem->frame_dec_f );
- }
- if ( hDirAC_mem->cy_cross_dir_smooth != NULL )
- {
- free( hDirAC_mem->cy_cross_dir_smooth );
- }
- if ( hDirAC_mem->cy_auto_diff_smooth != NULL )
- {
- free( hDirAC_mem->cy_auto_diff_smooth );
- }
- if ( hDirAC_mem->direct_responses != NULL )
- {
- free( hDirAC_mem->direct_responses );
- }
- if ( hDirAC_mem->proto_direct_buffer_f != NULL )
- {
- free( hDirAC_mem->proto_direct_buffer_f );
- }
- if ( hDirAC_mem->proto_diffuse_buffer_f != NULL )
- {
- free( hDirAC_mem->proto_diffuse_buffer_f );
- }
- if ( hDirAC_mem->direct_power_factor != NULL )
- {
- free( hDirAC_mem->direct_power_factor );
- }
- if ( hDirAC_mem->diffuse_power_factor != NULL )
- {
- free( hDirAC_mem->diffuse_power_factor );
- }
- if ( hDirAC_mem->reference_power != NULL )
- {
- free( hDirAC_mem->reference_power );
- }
- if ( hDirAC_mem->onset_filter != NULL )
- {
- free( hDirAC_mem->onset_filter );
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * compute_hoa_encoder_mtx()
- *
- *
- *------------------------------------------------------------------------*/
-
-void compute_hoa_encoder_mtx(
- const float *azimuth,
- const float *elevation,
- float *response,
- const int16_t num_responses,
- const int16_t ambisonics_order )
-{
- int16_t k, num_sh;
-
- num_sh = ivas_sba_get_nchan( ambisonics_order, 0 );
-
- for ( k = 0; k < num_responses; k++ )
- {
- ivas_dirac_dec_get_response( (const int16_t) azimuth[k], (const int16_t) elevation[k], &response[k * num_sh], ambisonics_order );
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_dec_get_frequency_axis()
- *
- * DirAC decoding initialization
- *------------------------------------------------------------------------*/
-
-void ivas_dirac_dec_get_frequency_axis(
- float *frequency_axis,
- const int32_t output_Fs,
- const int16_t num_freq_bands )
-{
- int16_t k;
- float const_part;
-
- /* calc cldfb frequency axis */
- const_part = (float) output_Fs / ( 2.0f * (float) num_freq_bands );
- for ( k = 0; k < num_freq_bands; ++k )
- {
- frequency_axis[k] = ( (float) k + 0.5f ) * const_part;
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * Local functions
- *-------------------------------------------------------------------------*/
-
-void initDiffuseResponses(
- float *diffuse_response_function,
- const int16_t num_channels,
- AUDIO_CONFIG output_config,
- IVAS_OUTPUT_SETUP hOutSetup,
- const int16_t ambisonics_order,
- const IVAS_FORMAT ivas_format,
- int16_t *num_ele_spk_no_diffuse_rendering,
- AUDIO_CONFIG transport_config )
-{
- int16_t i, l, k, idx, num_horizontal_speakers;
- *num_ele_spk_no_diffuse_rendering = 0;
-
- if ( output_config == AUDIO_CONFIG_MONO )
- {
- diffuse_response_function[0] = 1.0f;
- diffuse_response_function[1] = inv_sqrt( 3.0f );
- }
- else if ( !( output_config == AUDIO_CONFIG_FOA || output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_HOA3 ) )
- {
- /* set diffuse response function */
- if ( ivas_format == MC_FORMAT && ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 ) && output_config == AUDIO_CONFIG_5_1_4 )
- {
- num_horizontal_speakers = num_channels - NUM_ELEVATED_SPEAKERS;
-
- mvr2r( diffuse_response_CICP6, diffuse_response_function, num_horizontal_speakers );
- set_zero( &diffuse_response_function[num_horizontal_speakers], NUM_ELEVATED_SPEAKERS );
- *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
- }
- else if ( ivas_format == MC_FORMAT && ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 ) && output_config == AUDIO_CONFIG_7_1_4 )
- {
- num_horizontal_speakers = num_channels - NUM_ELEVATED_SPEAKERS;
-
- set_f( diffuse_response_function, sqrtf( 1.f / ( (float) num_horizontal_speakers ) ), num_horizontal_speakers );
- set_zero( &diffuse_response_function[num_horizontal_speakers], NUM_ELEVATED_SPEAKERS );
- *num_ele_spk_no_diffuse_rendering = NUM_ELEVATED_SPEAKERS;
- }
- else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && output_config == AUDIO_CONFIG_5_1 && num_channels == 5 )
- {
- mvr2r( diffuse_response_CICP6, diffuse_response_function, num_channels );
- }
- else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && output_config == AUDIO_CONFIG_5_1_2 && num_channels == 7 )
- {
- mvr2r( diffuse_response_CICP14, diffuse_response_function, num_channels );
- }
- else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_5_1_4 ) && ( num_channels == 9 ) )
- {
- mvr2r( diffuse_response_CICP16, diffuse_response_function, num_channels );
- }
- else if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ( output_config == AUDIO_CONFIG_LS_CUSTOM ) )
- {
- if ( transport_config == AUDIO_CONFIG_5_1 || transport_config == AUDIO_CONFIG_7_1 )
- {
- /* Detect loudspeakers with elevation */
- for ( i = 0, num_horizontal_speakers = 0; i < num_channels; i++ )
- {
- if ( fabsf( hOutSetup.ls_elevation[i] ) <= 5.f )
- {
- num_horizontal_speakers++;
- diffuse_response_function[i] = 1.f;
- }
- else
- {
- *num_ele_spk_no_diffuse_rendering += 1;
- diffuse_response_function[i] = 0.f;
- }
- }
- /* Diffuse only to horizontal plane if enough loudspeakers */
- if ( num_horizontal_speakers > 2 )
- {
- for ( i = 0; i < num_channels; i++ )
- {
- diffuse_response_function[i] *= sqrtf( 1.f / (float) num_horizontal_speakers );
- }
- }
- else
- {
- *num_ele_spk_no_diffuse_rendering = 0;
- set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
- }
- }
- else
- {
- set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
- }
- }
- else
- {
- set_f( diffuse_response_function, sqrtf( 1.f / (float) num_channels ), num_channels );
- }
- }
- else
- {
- idx = 0;
- for ( l = 0; l <= ambisonics_order; l++ )
- {
- for ( k = 0; k < ( 2 * l + 1 ); k++ )
- {
- diffuse_response_function[idx++] = inv_sqrt( 2.0f * l + 1.0f );
- }
- }
- }
-
- return;
-}
-
-
-void protoSignalComputation_shd(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_direct_buffer_f,
- float *proto_diffuse_buffer_f,
- float *reference_power,
- const int16_t slot_index,
- const int16_t num_inputs,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands,
- float *p_Rmat )
-{
- int16_t l, k;
- float *p_proto_direct_buffer;
- float *p_proto_diffuse_buffer;
- int16_t Rmat_k[4];
- float W_real, W_imag;
- float Y_real, Y_imag;
- float *p_k[4];
-
- k = 0; /* to avoid compilation warning */
-
- p_proto_direct_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * num_inputs;
- p_proto_diffuse_buffer = proto_diffuse_buffer_f + slot_index * 2 * num_freq_bands * num_outputs_diff;
-
- if ( num_inputs == 1 )
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- p_proto_direct_buffer[2 * l] = RealBuffer[0][0][l];
- p_proto_direct_buffer[2 * l + 1] = ImagBuffer[0][0][l];
- }
- }
- else if ( num_inputs == 2 )
- {
- if ( p_Rmat != 0 )
- {
- assert( num_inputs == 4 && "This code block should never be run with num_inputs != 4!" );
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- W_real = RealBuffer[0][0][l] + RealBuffer[1][0][l];
- W_imag = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
-
- Y_real = RealBuffer[0][0][l] - RealBuffer[1][0][l];
- Y_imag = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
-
- p_proto_direct_buffer[2 * l] = W_real;
- p_proto_direct_buffer[2 * l + 1] = W_imag;
- p_proto_direct_buffer[2 * num_freq_bands + 2 * l] = p_Rmat[0] * Y_real;
- p_proto_direct_buffer[2 * num_freq_bands + 2 * l + 1] = p_Rmat[0] * Y_imag;
- }
- }
- else
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- W_real = RealBuffer[0][0][l] + RealBuffer[1][0][l];
- W_imag = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
-
- p_proto_direct_buffer[2 * l] = W_real;
- p_proto_direct_buffer[2 * l + 1] = W_imag;
- {
- p_proto_direct_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
- p_proto_direct_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
- }
- }
- }
- }
- else if ( num_inputs >= 4 )
- {
- p_k[0] = p_proto_direct_buffer;
- p_k[1] = p_proto_direct_buffer + 2 * num_freq_bands;
- p_k[2] = p_proto_direct_buffer + 4 * num_freq_bands;
- p_k[3] = p_proto_direct_buffer + 6 * num_freq_bands;
- Rmat_k[0] = 0;
- Rmat_k[1] = 1;
- Rmat_k[2] = 2;
- Rmat_k[3] = 0;
-
- if ( p_Rmat != 0 )
- {
- assert( num_inputs == 4 && "This code block should never be run with num_inputs != 4!" );
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- *( p_k[0] ) = RealBuffer[0][0][l];
- reference_power[l + num_freq_bands] = *( p_k[0] ) * *( p_k[0] );
- p_k[0]++;
- *( p_k[0] ) = ImagBuffer[0][0][l];
- reference_power[l + num_freq_bands] += *( p_k[0] ) * *( p_k[0] );
- p_k[0]++;
- reference_power[l] = 0.5f * reference_power[l + num_freq_bands];
-
- for ( k = 1; k < 4; k++ )
- {
- *( p_k[k] ) = p_Rmat[3 * Rmat_k[k] + 1] * RealBuffer[1][0][l] + p_Rmat[3 * Rmat_k[k] + 2] * RealBuffer[2][0][l] + p_Rmat[3 * Rmat_k[k] + 0] * RealBuffer[3][0][l];
- reference_power[l + ( k + 1 ) * num_freq_bands] = *( p_k[k] ) * *( p_k[k] );
- p_k[k]++;
- *( p_k[k] ) = p_Rmat[3 * Rmat_k[k] + 1] * ImagBuffer[1][0][l] + p_Rmat[3 * Rmat_k[k] + 2] * ImagBuffer[2][0][l] + p_Rmat[3 * Rmat_k[k] + 0] * ImagBuffer[3][0][l];
- reference_power[l + ( k + 1 ) * num_freq_bands] += *( p_k[k] ) * *( p_k[k] );
- p_k[k]++;
- reference_power[l] += 0.5f * ( reference_power[l + ( k + 1 ) * num_freq_bands] );
- }
-
- for ( k = 1; k < 4; k++ )
- {
- RealBuffer[k][0][l] = p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l];
- ImagBuffer[k][0][l] = p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1];
- }
- }
- }
- else
- {
- set_zero( reference_power, num_freq_bands );
- for ( k = 0; k < 4; k++ )
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l] = RealBuffer[k][0][l];
- p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1] = ImagBuffer[k][0][l];
- reference_power[l + ( k + 1 ) * num_freq_bands] = RealBuffer[k][0][l] * RealBuffer[k][0][l] + ImagBuffer[k][0][l] * ImagBuffer[k][0][l];
- reference_power[l] += 0.5f * ( reference_power[l + ( k + 1 ) * num_freq_bands] );
- }
- }
- }
-
- /* Additional transport channels = planar SBA components of degree higher than 1*/
- for ( ; k < num_inputs; k++ )
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l] = RealBuffer[k][0][l];
- p_proto_direct_buffer[k * 2 * num_freq_bands + 2 * l + 1] = ImagBuffer[k][0][l];
- }
- }
- }
-
-
- /*Copy direct to diffuse proto*/
- mvr2r( p_proto_direct_buffer, p_proto_diffuse_buffer, 2 * num_freq_bands * min( num_outputs_diff, num_inputs ) );
-
- if ( num_inputs == 1 )
- {
- /* Add comfort noise addition (CNA) to diffuse proto only*/
- for ( l = 0; l < num_freq_bands; l++ )
- {
- p_proto_diffuse_buffer[2 * l] += RealBuffer[1][0][l];
- p_proto_diffuse_buffer[2 * l + 1] += ImagBuffer[1][0][l];
- }
- }
-
- return;
-}
-
-
-void protoSignalComputation1(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t slot_index,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands )
-{
- int16_t l, k;
- float *p_proto_buffer;
-
- p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands;
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- reference_power[l] = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- proto_power_smooth[l] += reference_power[l];
- p_proto_buffer[2 * l] = RealBuffer[0][0][l];
- p_proto_buffer[2 * l + 1] = ImagBuffer[0][0][l];
-
- for ( k = 0; k < num_outputs_diff; k++ )
- {
- proto_frame_f[2 * k * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
- proto_frame_f[2 * k * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
- }
- }
-
- return;
-}
-
-
-void protoSignalComputation2(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t isloudspeaker,
- const int16_t slot_index,
- const int16_t num_freq_bands,
- MASA_STEREO_TYPE_DETECT *stereo_type_detect )
-{
- int16_t l;
- float *p_proto_buffer;
- float Real_aux, Imag_aux;
-
- float left_bb_power, right_bb_power, total_bb_power, lr_bb_power;
- float lr_total_bb_ratio;
- float a, b;
-
- float left_hi_power, right_hi_power, total_hi_power, lr_hi_power;
- float lr_total_hi_ratio;
- float a2, b2;
-
- float sum_power;
- float sum_total_ratio[MASA_SUM_FREQ_RANGE_BINS];
- float min_sum_total_ratio;
- float min_sum_total_ratio_db;
-
- float RealSubtract, ImagSubtract;
-
- float interpolatorSpaced = 0.0f;
- float interpolatorDmx = 1.0f;
-
- int16_t dipole_freq_range[2];
- float tempSpaced, tempDmx;
-
- if ( isloudspeaker )
- {
- p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 3;
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- float Left_power;
- float Right_power;
- Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
- Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
-
- Left_power = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- Right_power = RealBuffer[1][0][l] * RealBuffer[1][0][l] + ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
-
- reference_power[l] = Left_power + Right_power;
- proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
-
- p_proto_buffer[2 * l] = Real_aux;
- p_proto_buffer[2 * l + 1] = Imag_aux;
- proto_power_smooth[l + num_freq_bands] += RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
-
- proto_power_smooth[l + 2 * num_freq_bands] += RealBuffer[1][0][l] * RealBuffer[1][0][l];
- proto_power_smooth[l + 2 * num_freq_bands] += ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
- p_proto_buffer[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
- p_proto_buffer[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
-
- proto_frame_f[2 * l] = Real_aux;
- proto_frame_f[2 * l + 1] = Imag_aux;
-
- proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
- proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
- }
- }
- else if ( stereo_type_detect != NULL )
- {
- p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 2;
-
- left_bb_power = 0.0f;
- right_bb_power = 0.0f;
- total_bb_power = 0.0f;
-
- left_hi_power = 0.0f;
- right_hi_power = 0.0f;
- total_hi_power = 0.0f;
-
- dipole_freq_range[0] = stereo_type_detect->dipole_freq_range[0];
- dipole_freq_range[1] = stereo_type_detect->dipole_freq_range[1];
-
- a = 0.01f; /* Temporal smoothing coefficient */
- b = 1.0f - a; /* Temporal smoothing coefficient */
- a2 = 0.1f; /* Temporal smoothing coefficient */
- b2 = 1.0f - a2; /* Temporal smoothing coefficient */
-
- if ( stereo_type_detect->interpolator > 0 )
- {
- if ( stereo_type_detect->type_change_direction == MASA_STEREO_SPACED_MICS )
- {
- interpolatorSpaced = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS );
- interpolatorDmx = 1.0f - interpolatorSpaced;
- }
- else
- {
- interpolatorDmx = ( (float) ( stereo_type_detect->interpolator ) ) / ( (float) MASA_STEREO_INTERPOLATION_SLOTS );
- interpolatorSpaced = 1.0f - interpolatorDmx;
- }
- }
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- float Left_power;
- float Right_power;
-
- /* Compute sum signal */
- Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
- Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
-
- /* Compute reference power */
- Left_power = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- Right_power = RealBuffer[1][0][l] * RealBuffer[1][0][l] + ImagBuffer[1][0][l] * ImagBuffer[1][0][l];
-
- reference_power[l] = Left_power + Right_power;
-
- left_bb_power += Left_power;
- right_bb_power += Right_power;
- total_bb_power += reference_power[l];
-
- if ( l > MASA_HI_FREQ_START_BIN )
- {
- left_hi_power += Left_power;
- right_hi_power += Right_power;
- total_hi_power += reference_power[l];
- }
-
- if ( l < min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ) )
- {
- sum_power = Real_aux * Real_aux + Imag_aux * Imag_aux;
-
- stereo_type_detect->sum_power[l] = a * sum_power + b * stereo_type_detect->sum_power[l];
- stereo_type_detect->total_power[l] = a * reference_power[l] + b * stereo_type_detect->total_power[l];
-
- sum_total_ratio[l] = stereo_type_detect->sum_power[l] / ( stereo_type_detect->total_power[l] + EPSILON );
- }
-
- if ( l == 0 )
- {
- RealSubtract = RealBuffer[0][0][l] - RealBuffer[1][0][l];
- ImagSubtract = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
- stereo_type_detect->subtract_power_y += RealSubtract * RealSubtract + ImagSubtract * ImagSubtract;
- }
-
- /* Compute protos (and their power) for direct sound rendering */
-
- /* W prototype */
- if ( stereo_type_detect->interpolator > 0 )
- {
- if ( l < ( dipole_freq_range[1] - 1 ) || l >= MASA_SUM_PROTO_START_BIN )
- {
- Real_aux = interpolatorSpaced * 0.5f * Real_aux + interpolatorDmx * Real_aux;
- Imag_aux = interpolatorSpaced * 0.5f * Imag_aux + interpolatorDmx * Imag_aux;
- proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
- p_proto_buffer[2 * l] = Real_aux;
- p_proto_buffer[2 * l + 1] = Imag_aux;
- }
- else
- {
- tempSpaced = RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- tempDmx = Real_aux * Real_aux + Imag_aux * Imag_aux;
- proto_power_smooth[l] += interpolatorSpaced * tempSpaced + interpolatorDmx * tempDmx;
- p_proto_buffer[2 * l] = interpolatorSpaced * RealBuffer[0][0][l] + interpolatorDmx * Real_aux;
- p_proto_buffer[2 * l + 1] = interpolatorSpaced * ImagBuffer[0][0][l] + interpolatorDmx * Imag_aux;
- }
- }
- else if ( stereo_type_detect->masa_stereo_type == MASA_STEREO_SPACED_MICS )
- {
- if ( l < ( dipole_freq_range[1] - 1 ) || l >= MASA_SUM_PROTO_START_BIN )
- {
- Real_aux *= 0.5f;
- Imag_aux *= 0.5f;
- proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
- p_proto_buffer[2 * l] = Real_aux;
- p_proto_buffer[2 * l + 1] = Imag_aux;
- }
- else
- {
- proto_power_smooth[l] += RealBuffer[0][0][l] * RealBuffer[0][0][l] + ImagBuffer[0][0][l] * ImagBuffer[0][0][l];
- p_proto_buffer[2 * l] = RealBuffer[0][0][l];
- p_proto_buffer[2 * l + 1] = ImagBuffer[0][0][l];
- }
- }
- else
- {
- proto_power_smooth[l] += Real_aux * Real_aux + Imag_aux * Imag_aux;
- p_proto_buffer[2 * l] = Real_aux;
- p_proto_buffer[2 * l + 1] = Imag_aux;
- }
-
- /* Y prototype */
- if ( stereo_type_detect->interpolator > 0 )
- {
- if ( l < ( dipole_freq_range[0] ) )
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * p_proto_buffer[2 * l] + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * p_proto_buffer[2 * l + 1] + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
- }
- else if ( l < ( dipole_freq_range[1] ) )
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] ) + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * ( -( RealBuffer[0][0][l] - RealBuffer[1][0][l] ) ) + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
- }
- else
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = interpolatorSpaced * p_proto_buffer[2 * l] + interpolatorDmx * ( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = interpolatorSpaced * p_proto_buffer[2 * l + 1] + interpolatorDmx * ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
- }
- proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
- }
- else if ( stereo_type_detect->masa_stereo_type == MASA_STEREO_SPACED_MICS )
- {
- if ( l < ( dipole_freq_range[0] ) ) /* proto = W */
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = p_proto_buffer[2 * l];
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = p_proto_buffer[2 * l + 1];
- proto_power_smooth[l + num_freq_bands] = proto_power_smooth[l];
- }
- else if ( l < ( dipole_freq_range[1] ) ) /* proto = -i * (x1-x2) * eq */
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = ( ImagBuffer[0][0][l] - ImagBuffer[1][0][l] );
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = -( RealBuffer[0][0][l] - RealBuffer[1][0][l] );
- proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
- }
- else /* proto = W */
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = p_proto_buffer[2 * l];
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = p_proto_buffer[2 * l + 1];
- proto_power_smooth[l + num_freq_bands] = proto_power_smooth[l];
- }
- }
- else
- {
- p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
- proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
- }
-
- /* Compute protos for decorrelation */
- proto_frame_f[2 * l] = Real_aux;
- proto_frame_f[2 * l + 1] = Imag_aux;
- proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
- proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
- }
-
- if ( stereo_type_detect->interpolator > 0 )
- {
- stereo_type_detect->interpolator++;
- if ( stereo_type_detect->interpolator == MASA_STEREO_INTERPOLATION_SLOTS )
- {
- stereo_type_detect->interpolator = 0;
- stereo_type_detect->current_stereo_type = stereo_type_detect->type_change_direction;
- }
- }
-
- stereo_type_detect->left_bb_power = a * left_bb_power + b * stereo_type_detect->left_bb_power;
- stereo_type_detect->right_bb_power = a * right_bb_power + b * stereo_type_detect->right_bb_power;
- stereo_type_detect->total_bb_power = a * total_bb_power + b * stereo_type_detect->total_bb_power;
-
- lr_bb_power = ( stereo_type_detect->left_bb_power < stereo_type_detect->right_bb_power ) ? stereo_type_detect->left_bb_power : stereo_type_detect->right_bb_power;
- lr_bb_power *= 2.0f;
- lr_total_bb_ratio = 10.0f * log10f( lr_bb_power / ( stereo_type_detect->total_bb_power + EPSILON ) );
-
- stereo_type_detect->left_hi_power = a2 * left_hi_power + b2 * stereo_type_detect->left_hi_power;
- stereo_type_detect->right_hi_power = a2 * right_hi_power + b2 * stereo_type_detect->right_hi_power;
- stereo_type_detect->total_hi_power = a2 * total_hi_power + b2 * stereo_type_detect->total_hi_power;
-
- lr_hi_power = ( stereo_type_detect->left_hi_power < stereo_type_detect->right_hi_power ) ? stereo_type_detect->left_hi_power : stereo_type_detect->right_hi_power;
- lr_hi_power *= 2.0f;
- lr_total_hi_ratio = 10.0f * log10f( lr_hi_power / ( stereo_type_detect->total_hi_power + EPSILON ) );
-
- minimum( sum_total_ratio, min( num_freq_bands, MASA_SUM_FREQ_RANGE_BINS ), &min_sum_total_ratio );
- min_sum_total_ratio_db = 10.0f * log10f( min_sum_total_ratio );
-
- stereo_type_detect->lr_total_bb_ratio_db = lr_total_bb_ratio;
- stereo_type_detect->lr_total_hi_ratio_db = lr_total_hi_ratio;
- stereo_type_detect->min_sum_total_ratio_db = min_sum_total_ratio_db;
-
- ivas_masa_stereotype_detection( stereo_type_detect );
- }
- else
- {
- p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * 2;
-
- for ( l = 0; l < num_freq_bands; l++ )
- {
- Real_aux = RealBuffer[0][0][l] + RealBuffer[1][0][l];
- Imag_aux = ImagBuffer[0][0][l] + ImagBuffer[1][0][l];
-
- reference_power[l] = Real_aux * Real_aux + Imag_aux * Imag_aux;
- proto_power_smooth[l] += reference_power[l];
- p_proto_buffer[2 * l] = Real_aux;
- p_proto_buffer[2 * l + 1] = Imag_aux;
-
- p_proto_buffer[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l] - RealBuffer[1][0][l];
- p_proto_buffer[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l] - ImagBuffer[1][0][l];
- proto_power_smooth[l + num_freq_bands] += p_proto_buffer[2 * num_freq_bands + 2 * l] * p_proto_buffer[2 * num_freq_bands + 2 * l] + p_proto_buffer[2 * num_freq_bands + 2 * l + 1] * p_proto_buffer[2 * num_freq_bands + 2 * l + 1];
-
- proto_frame_f[2 * l] = Real_aux;
- proto_frame_f[2 * l + 1] = Imag_aux;
-
- proto_frame_f[2 * num_freq_bands + 2 * l] = RealBuffer[0][0][l];
- proto_frame_f[2 * num_freq_bands + 2 * l + 1] = ImagBuffer[0][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l] = RealBuffer[1][0][l];
- proto_frame_f[4 * num_freq_bands + 2 * l + 1] = ImagBuffer[1][0][l];
- }
- }
-
- return;
-}
-
-
-void protoSignalComputation4(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t slot_index,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands,
- const float *mtx_hoa_decoder,
- const int16_t nchan_transport,
- const int16_t *sba_map_tc_ind )
-{
- int16_t k, l;
- int16_t n;
- float sq_tmp;
- float *p_proto_buffer;
-
- set_zero( reference_power, num_freq_bands );
- for ( k = 0; k < 4; k++ )
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- sq_tmp = RealBuffer[k][0][l] * RealBuffer[k][0][l] + ImagBuffer[k][0][l] * ImagBuffer[k][0][l];
- reference_power[l] += 0.5f * sq_tmp;
- }
- }
-
- /*For decorrelated diffuseness*/
- for ( l = 0; l < num_outputs_diff; l++ )
- {
- for ( k = 0; k < num_freq_bands; k++ )
- {
- proto_frame_f[2 * l * num_freq_bands + 2 * k] = 0.f;
- proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] = 0.f;
- for ( n = 0; n < nchan_transport; n++ )
- {
- proto_frame_f[2 * l * num_freq_bands + 2 * k] += RealBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]];
- proto_frame_f[2 * l * num_freq_bands + 2 * k + 1] += ImagBuffer[n][0][k] * mtx_hoa_decoder[l * 16 + sba_map_tc_ind[n]];
- }
- }
- }
-
- p_proto_buffer = proto_direct_buffer_f + slot_index * 2 * num_freq_bands * num_outputs_diff;
- for ( k = 0; k < num_outputs_diff; k++ )
- {
- for ( l = 0; l < num_freq_bands; l++ )
- {
- sq_tmp = proto_frame_f[k * 2 * num_freq_bands + 2 * l] * proto_frame_f[k * 2 * num_freq_bands + 2 * l] + proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1] * proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1];
- proto_power_smooth[l + k * num_freq_bands] += sq_tmp;
- p_proto_buffer[k * 2 * num_freq_bands + 2 * l] = proto_frame_f[k * 2 * num_freq_bands + 2 * l];
- p_proto_buffer[k * 2 * num_freq_bands + 2 * l + 1] = proto_frame_f[k * 2 * num_freq_bands + 2 * l + 1];
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_dirac_dec_compute_diffuse_proto()
- *
- * Compute diffuse prototype buffer and smooth power, only for decorrelated bands
- *------------------------------------------------------------------------*/
-
-void ivas_dirac_dec_compute_diffuse_proto(
- DIRAC_REND_HANDLE hDirACRend,
- const int16_t num_freq_bands,
- const int16_t slot_idx /* i : slot index */
-)
-{
- int16_t k, l;
- int16_t num_freq_bands_diff;
- float *p_diff_buffer, *p_diff_buffer_1;
- float *p_proto_diff, *p_power_smooth, *proto_frame_dec_f;
- DIRAC_OUTPUT_SYNTHESIS_PARAMS *h_dirac_output_synthesis_params;
- DIRAC_OUTPUT_SYNTHESIS_STATE *h_dirac_output_synthesis_state;
- int16_t m;
- float *p_hoa_enc;
-
- proto_frame_dec_f = hDirACRend->proto_frame_dec_f;
- h_dirac_output_synthesis_params = &( hDirACRend->h_output_synthesis_psd_params );
- h_dirac_output_synthesis_state = &( hDirACRend->h_output_synthesis_psd_state );
-
- num_freq_bands_diff = h_dirac_output_synthesis_params->max_band_decorr;
-
- p_diff_buffer = h_dirac_output_synthesis_state->proto_diffuse_buffer_f + slot_idx * 2 * num_freq_bands_diff * hDirACRend->hOutSetup.nchan_out_woLFE;
- p_diff_buffer_1 = p_diff_buffer + 1;
- p_power_smooth = h_dirac_output_synthesis_state->proto_power_diff_smooth;
-
- if ( hDirACRend->synthesisConf != DIRAC_SYNTHESIS_PSD_SHD )
- {
- for ( k = 0; k < hDirACRend->hOutSetup.nchan_out_woLFE; k++ )
- {
- p_proto_diff = proto_frame_dec_f + k * 2 * num_freq_bands;
- for ( l = 0; l < num_freq_bands_diff; l++ )
- {
- *p_diff_buffer = *( p_proto_diff++ );
- *p_diff_buffer_1 = *( p_proto_diff++ );
- *( p_power_smooth++ ) += ( *p_diff_buffer ) * ( *p_diff_buffer ) + ( *p_diff_buffer_1 ) * ( *p_diff_buffer_1 );
- p_diff_buffer += 2;
- p_diff_buffer_1 += 2;
- }
- }
- }
- else
- {
- /*DIRAC_SYNTHESIS_PSD_SHD: Virtual LS->HOA encoding*/
- for ( k = 0; k < hDirACRend->hOutSetup.nchan_out_woLFE; k++ )
- {
- for ( l = 0; l < num_freq_bands_diff; l++ )
- {
- p_hoa_enc = hDirACRend->hoa_encoder + k;
- p_proto_diff = proto_frame_dec_f + 2 * l;
-
- *p_diff_buffer = 0.f;
- *p_diff_buffer_1 = 0.f;
-
- /*LS to HOA*/
- for ( m = 0; m < hDirACRend->num_outputs_diff; m++ )
- {
- *p_diff_buffer += ( *p_hoa_enc ) * ( *p_proto_diff );
- *p_diff_buffer_1 += ( *p_hoa_enc ) * ( *( p_proto_diff + 1 ) );
- p_hoa_enc += hDirACRend->hOutSetup.nchan_out_woLFE;
- p_proto_diff += 2 * num_freq_bands;
- }
-
- *( p_power_smooth++ ) += ( *p_diff_buffer ) * ( *p_diff_buffer ) + ( *p_diff_buffer_1 ) * ( *p_diff_buffer_1 );
- p_diff_buffer += 2;
- p_diff_buffer_1 += 2;
- }
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * computeDirectionAngles()
- *
- *------------------------------------------------------------------------*/
-
-void computeDirectionAngles(
- float *intensity_real_x,
- float *intensity_real_y,
- float *intensity_real_z,
- const int16_t num_frequency_bands,
- int16_t *azimuth,
- int16_t *elevation )
-{
- int16_t k;
- float intensityNorm;
- float x, y, z, radius;
-
- for ( k = 0; k < num_frequency_bands; ++k )
-
- {
- intensityNorm = *( intensity_real_x ) * *( intensity_real_x ) +
- *( intensity_real_y ) * *( intensity_real_y ) +
- *( intensity_real_z ) * *( intensity_real_z );
-
- if ( intensityNorm <= EPSILON )
- {
- intensityNorm = 1.0f;
- x = 1.0f;
- y = 0.0f;
- z = 0.0f;
- intensity_real_x++;
- intensity_real_y++;
- intensity_real_z++;
- }
- else
- {
- intensityNorm = sqrtf( 1.f / intensityNorm );
- x = *( intensity_real_x++ ) * intensityNorm;
- y = *( intensity_real_y++ ) * intensityNorm;
- z = *( intensity_real_z++ ) * intensityNorm;
- }
- radius = sqrtf( x * x + y * y );
- azimuth[k] = (int16_t) ( max( -180.0f, min( 180.0f, atan2f( y, x ) / EVS_PI * 180.0f ) ) + 0.5f );
- elevation[k] = (int16_t) ( max( -90.0f, min( 180.0f, atan2f( z, radius ) / EVS_PI * 180.0f ) ) + 0.5f );
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_masa_init_stereotype_detection()
- *
- * Initialize stereo transport signal type detection
- *------------------------------------------------------------------------*/
-
-void ivas_masa_init_stereotype_detection(
- MASA_STEREO_TYPE_DETECT *stereo_type_detect )
-{
- stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
- stereo_type_detect->current_stereo_type = MASA_STEREO_DOWNMIX;
- stereo_type_detect->type_change_direction = MASA_STEREO_DOWNMIX;
-
- stereo_type_detect->counter = 0;
- stereo_type_detect->interpolator = 0;
-
- stereo_type_detect->dipole_freq_range[0] = 1;
- stereo_type_detect->dipole_freq_range[1] = 3;
-
- stereo_type_detect->left_bb_power = 0.0f; /* Broadband estimates */
- stereo_type_detect->right_bb_power = 0.0f;
- stereo_type_detect->total_bb_power = 0.0f;
-
- stereo_type_detect->left_hi_power = 0.0f; /* High-frequency estimates */
- stereo_type_detect->right_hi_power = 0.0f;
- stereo_type_detect->total_hi_power = 0.0f;
-
- set_zero( stereo_type_detect->sum_power, MASA_SUM_FREQ_RANGE_BINS );
- set_zero( stereo_type_detect->total_power, MASA_SUM_FREQ_RANGE_BINS );
-
- stereo_type_detect->subtract_power_y = 0.0f;
- stereo_type_detect->subtract_power_y_smooth = 0.0f;
- stereo_type_detect->target_power_y_smooth = 0.0f;
-
- stereo_type_detect->lr_total_bb_ratio_db = 0.0f;
- stereo_type_detect->lr_total_hi_ratio_db = 0.0f;
- stereo_type_detect->min_sum_total_ratio_db = 0.0f;
- stereo_type_detect->subtract_target_ratio_db = 0.0f;
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_masa_stereotype_detection()
- *
- * Detect the type of the transport audio signals
- *------------------------------------------------------------------------*/
-
-void ivas_masa_stereotype_detection(
- MASA_STEREO_TYPE_DETECT *stereo_type_detect )
-{
- float lr_total_bb_ratio_db = stereo_type_detect->lr_total_bb_ratio_db;
- float lr_total_hi_ratio_db = stereo_type_detect->lr_total_hi_ratio_db;
- float min_sum_total_ratio_db = stereo_type_detect->min_sum_total_ratio_db;
- float subtract_target_ratio_db = stereo_type_detect->subtract_target_ratio_db;
- float change_to_spaced;
- int16_t change_to_spaced_selection;
- float change_to_downmix;
- float change_to_downmix2;
- int16_t change_to_downmix_selection;
- float subtract_temp;
- float min_sum_temp;
- float lr_total_bb_temp;
- float lr_total_hi_temp;
-
- /* Determine if the determined features match the spaced mic type */
- change_to_spaced_selection = 0;
- if ( subtract_target_ratio_db < -3.0f )
- {
- subtract_temp = ( -subtract_target_ratio_db - 3.0f ) / 3.0f;
- min_sum_temp = max( -min_sum_total_ratio_db / 6.0f, 0.0f );
- lr_total_bb_temp = lr_total_bb_ratio_db / 6.0f;
-
- change_to_spaced = subtract_temp + min_sum_temp + lr_total_bb_temp;
-
- if ( change_to_spaced >= 1.0f )
- {
- change_to_spaced_selection = 1;
- }
- }
-
- /* Determine if the determined features match the downmix type, according to a metric */
- change_to_downmix_selection = 0;
- if ( subtract_target_ratio_db > 0.0f )
- {
- subtract_temp = subtract_target_ratio_db / 3.0f;
- min_sum_temp = ( min_sum_total_ratio_db + 1.0f ) / 6.0f;
- lr_total_bb_temp = -lr_total_bb_ratio_db / 6.0f;
-
- change_to_downmix = subtract_temp + min_sum_temp + lr_total_bb_temp;
-
- if ( change_to_downmix >= 1.0f )
- {
- change_to_downmix_selection = 1;
- }
- }
-
- /* Determine if the determined features match the downmix type, according to another metric */
- if ( lr_total_hi_ratio_db < -12.0f )
- {
- subtract_temp = ( subtract_target_ratio_db + 4.0f ) / 3.0f;
- min_sum_temp = min_sum_total_ratio_db / 6.0f;
- lr_total_hi_temp = ( -lr_total_hi_ratio_db - 12.0f ) / 3.0f;
-
- change_to_downmix2 = subtract_temp + min_sum_temp + lr_total_hi_temp;
-
- if ( change_to_downmix2 >= 1.0f )
- {
- change_to_downmix_selection = 1;
- }
- }
-
- if ( stereo_type_detect->counter < 400 )
- {
- stereo_type_detect->counter++;
- }
- else
- {
- if ( change_to_spaced_selection == 1 )
- {
- stereo_type_detect->masa_stereo_type = MASA_STEREO_SPACED_MICS;
- }
- else if ( change_to_downmix_selection == 1 )
- {
- stereo_type_detect->masa_stereo_type = MASA_STEREO_DOWNMIX;
- }
- }
-
- if ( stereo_type_detect->interpolator == 0 )
- {
- if ( stereo_type_detect->current_stereo_type != stereo_type_detect->masa_stereo_type )
- {
- stereo_type_detect->interpolator = 1;
- stereo_type_detect->type_change_direction = stereo_type_detect->masa_stereo_type;
- }
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * computeIntensityVector_dec()
- *
- *
- *------------------------------------------------------------------------*/
-
-void computeIntensityVector_dec(
- float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- const int16_t num_frequency_bands,
- float *intensity_real_x,
- float *intensity_real_y,
- float *intensity_real_z )
-{
- /*
- * W = a + ib; Y = c + id
- * real(W*Y') = ac + bd
- */
- int16_t i;
- float real, img;
-
- for ( i = 0; i < num_frequency_bands; ++i )
- {
- real = Cldfb_RealBuffer[0][0][i];
- img = Cldfb_ImagBuffer[0][0][i];
- intensity_real_x[i] = Cldfb_RealBuffer[3][0][i] * real + Cldfb_ImagBuffer[3][0][i] * img;
- intensity_real_y[i] = Cldfb_RealBuffer[1][0][i] * real + Cldfb_ImagBuffer[1][0][i] * img;
- intensity_real_z[i] = Cldfb_RealBuffer[2][0][i] * real + Cldfb_ImagBuffer[2][0][i] * img;
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * ivas_lfe_synth_with_cldfb()
- *
- *
- *------------------------------------------------------------------------*/
-
-void ivas_lfe_synth_with_cldfb(
- MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth,
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float RealBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- const int16_t slot_index,
- const int16_t subframe_index,
- const int16_t nchan_transport )
-{
- float lfeGain;
- float transportGain;
- float protoLfeReal, protoLfeImag;
- int16_t i;
- float transportEne, protoLfeEne, targetEneLfe, targetEneTrans;
-
- set_zero( RealBufferLfe[slot_index], CLDFB_NO_CHANNELS_MAX );
- set_zero( ImagBufferLfe[slot_index], CLDFB_NO_CHANNELS_MAX );
-
- protoLfeReal = RealBuffer[0][0][0];
- protoLfeImag = ImagBuffer[0][0][0];
- transportEne = RealBuffer[0][0][0] * RealBuffer[0][0][0] + ImagBuffer[0][0][0] * ImagBuffer[0][0][0];
- for ( i = 1; i < nchan_transport; i++ )
- {
- protoLfeReal += RealBuffer[i][0][0];
- protoLfeImag += ImagBuffer[i][0][0];
- transportEne += RealBuffer[i][0][0] * RealBuffer[i][0][0] + ImagBuffer[i][0][0] * ImagBuffer[i][0][0];
- }
- protoLfeEne = protoLfeReal * protoLfeReal + protoLfeImag * protoLfeImag;
-
- targetEneLfe = transportEne * hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index];
- targetEneTrans = transportEne * max( ( 1.0f - hMasaLfeSynth->lfeToTotalEnergyRatio[subframe_index] ), 0.01f );
-
- hMasaLfeSynth->transportEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
- hMasaLfeSynth->protoLfeEneSmooth *= MCMASA_LFE_SYNTH_ALPHA;
- hMasaLfeSynth->targetEneLfeSmooth *= MCMASA_LFE_SYNTH_ALPHA;
- hMasaLfeSynth->targetEneTransSmooth *= MCMASA_LFE_SYNTH_ALPHA;
-
- hMasaLfeSynth->transportEneSmooth += transportEne;
- hMasaLfeSynth->protoLfeEneSmooth += protoLfeEne;
- hMasaLfeSynth->targetEneLfeSmooth += targetEneLfe;
- hMasaLfeSynth->targetEneTransSmooth += targetEneTrans;
-
- lfeGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneLfeSmooth / ( EPSILON + hMasaLfeSynth->protoLfeEneSmooth ) ) );
- transportGain = min( 1.0f, sqrtf( hMasaLfeSynth->targetEneTransSmooth / ( EPSILON + hMasaLfeSynth->transportEneSmooth ) ) );
-
- RealBufferLfe[slot_index][0] = protoLfeReal * lfeGain;
- ImagBufferLfe[slot_index][0] = protoLfeImag * lfeGain;
-
- RealBuffer[0][0][0] *= transportGain;
- ImagBuffer[0][0][0] *= transportGain;
- for ( i = 1; i < nchan_transport; i++ )
- {
- RealBuffer[i][0][0] *= transportGain;
- ImagBuffer[i][0][0] *= transportGain;
- }
-
- return;
-}
-
-
-/*-------------------------------------------------------------------------
- * rotateAziEle_DirAC()
- *
- * Apply rotation to DirAC DOAs
- *------------------------------------------------------------------------*/
-
-void rotateAziEle_DirAC(
- int16_t *azi, /* i/o: array of azimuth values */
- int16_t *ele, /* i/o: array of elevation values */
- const int16_t band1, /* i : bands to work on (lower limit) */
- const int16_t band2, /* i : bands to work on (upper bound) */
- const float *p_Rmat /* i : pointer to real-space rotation matrix */
-)
-{
- int16_t b;
- float dv_0, dv_1, dv_2;
- float dv_r_0, dv_r_1, dv_r_2;
- float w;
-
- push_wmops( "rotateAziEle_DirAC" );
-
- for ( b = band1; b < band2; b++ )
- {
-
- /*Conversion spherical to cartesian coordinates*/
- w = cosf( ele[b] * PI_OVER_180 );
- dv_0 = w * cosf( azi[b] * PI_OVER_180 );
- dv_1 = w * sinf( azi[b] * PI_OVER_180 );
- dv_2 = sinf( ele[b] * PI_OVER_180 );
-
- dv_r_0 = p_Rmat[0] * dv_0 + p_Rmat[1] * dv_1 + p_Rmat[2] * dv_2;
- dv_r_1 = p_Rmat[3] * dv_0 + p_Rmat[4] * dv_1 + p_Rmat[5] * dv_2;
- dv_r_2 = p_Rmat[6] * dv_0 + p_Rmat[7] * dv_1 + p_Rmat[8] * dv_2;
-
- /*Conversion spherical to cartesian coordinates*/
- azi[b] = (int16_t) ( atan2f( dv_r_1, dv_r_0 ) * _180_OVER_PI );
- ele[b] = (int16_t) ( atan2f( dv_r_2, sqrtf( dv_r_0 * dv_r_0 + dv_r_1 * dv_r_1 ) ) * _180_OVER_PI );
- }
-
- pop_wmops();
-
- return;
-}
diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c
index 9748fe835b2ffc7e085d139aaf5d43a33cafd35f..0a6938254ac491fc1f80541c9681521d32d1a455 100644
--- a/lib_rend/ivas_objectRenderer.c
+++ b/lib_rend/ivas_objectRenderer.c
@@ -193,7 +193,12 @@ ivas_error ivas_td_binaural_open_unwrap(
TDREND_MIX_SRC_SetDirAtten( pBinRendTd, nS, DirAtten_p );
}
}
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format == ISM_FORMAT || ivas_format == MASA_ISM_FORMAT )
+#else
if ( ivas_format == ISM_FORMAT )
+#endif
{
DirAtten_p = pBinRendTd->DirAtten_p;
if ( NULL == directivity )
@@ -216,7 +221,15 @@ ivas_error ivas_td_binaural_open_unwrap(
}
*hBinRendererTd = pBinRendTd;
+
+#ifdef MASA_AND_OBJECTS
+ if ( ivas_format != MASA_ISM_FORMAT )
+ {
+ *binaural_latency_ns = (int32_t) ( ( *hBinRendererTd )->HrFiltSet_p->latency_s * 1000000000.f );
+ }
+#else
*binaural_latency_ns = (int32_t) ( ( *hBinRendererTd )->HrFiltSet_p->latency_s * 1000000000.f );
+#endif
return error;
}
@@ -495,7 +508,11 @@ void TDREND_Update_object_positions(
/* For each source, write the frame data to the source object*/
for ( nS = 0; nS < num_src; nS++ )
{
+#ifdef MASA_AND_OBJECTS
+ if ( in_format == ISM_FORMAT || in_format == MASA_ISM_FORMAT )
+#else
if ( in_format == ISM_FORMAT )
+#endif
{
/* Update the source positions */
/* Source position and direction */
diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h
index 2b2915d1941d192d3042e448df98735daca9f6d7..e64fdce77a4a23d07f8d2961a3b5e02ce997966d 100644
--- a/lib_rend/ivas_prot_rend.h
+++ b/lib_rend/ivas_prot_rend.h
@@ -37,7 +37,6 @@
#include "options.h"
#include "ivas_error.h"
#include "lib_rend.h"
-#include "ivas_stat_rend.h"
#include "ivas_stat_dec.h" // Note: needed until #156 is resolved
/* clang-format off */
@@ -134,7 +133,7 @@ void efap_determine_gains(
/*----------------------------------------------------------------------------------*
- * DirAC/MASA rendering
+ * SBA rendering
*----------------------------------------------------------------------------------*/
void ivas_sba_prototype_renderer(
@@ -152,7 +151,7 @@ ivas_error ivas_sba_get_hoa_dec_matrix(
#ifdef FIX_564
-void ivas_dirac_dec_binaural_sba_gain(
+void ivas_dirac_dec_binaural_gain(
float output[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */
const int16_t nchan_remapped, /* i : num channels after remapping of TCs */
const int16_t output_frame /* i : output frame length */
@@ -188,323 +187,6 @@ ivas_error ivas_dirac_dec_binaural_copy_hrtfs(
HRTFS_PARAMBIN_HANDLE *hHrtfParambin /* i/o: HRTF structure for rendering */
);
-/*! r: Configured reqularization factor value */
-float configure_reqularization_factor(
- const IVAS_FORMAT ivas_format, /* i : IVAS format */
- const int32_t ivas_total_brate /* i : total IVAS bitrate */
-);
-
-ivas_error ivas_dirac_alloc_mem(
- DIRAC_REND_HANDLE hDirACRend,
- const RENDERER_TYPE renderer_type,
- const int16_t num_freq_bands,
- DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem,
- const int16_t hodirac_flag
-);
-
-void ivas_dirac_free_mem(
- DIRAC_DEC_STACK_MEM_HANDLE hDirAC_mem
-);
-
-void initDiffuseResponses(
- float *diffuse_response_function,
- const int16_t num_channels,
- AUDIO_CONFIG output_config,
- IVAS_OUTPUT_SETUP hOutSetup,
- const int16_t ambisonics_order,
- const IVAS_FORMAT ivas_format,
- int16_t *num_ele_spk_no_diffuse_rendering,
- AUDIO_CONFIG transport_config
-);
-
-void computeIntensityVector_dec(
- float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float Cldfb_ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- const int16_t num_frequency_bands,
- float *intensity_real_x,
- float *intensity_real_y,
- float *intensity_real_z
-);
-
-void protoSignalComputation_shd(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_direct_buffer_f,
- float *proto_diffuse_buffer_f,
- float *reference_power,
- const int16_t slot_index,
- const int16_t num_inputs,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands,
- float *p_Rmat
-);
-
-void protoSignalComputation1(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t slot_index,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands
-);
-
-void protoSignalComputation2(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t isloudspeaker,
- const int16_t slot_index,
- const int16_t num_freq_bands,
- MASA_STEREO_TYPE_DETECT *stereo_type_detect
-);
-
-void protoSignalComputation4(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float *proto_frame_f,
- float *proto_direct_buffer_f,
- float *reference_power,
- float *proto_power_smooth,
- const int16_t slot_index,
- const int16_t num_outputs_diff,
- const int16_t num_freq_bands,
- const
- float *mtx_hoa_decoder,
- const int16_t nchan_transport,
- const int16_t *sba_map_tc_ind
-);
-
-void ivas_dirac_dec_compute_diffuse_proto(
- DIRAC_REND_HANDLE hDirACRend,
- const int16_t num_freq_bands,
- const int16_t slot_idx
-);
-
-void computeDirectionAngles(
- float *intensity_real_x,
- float *intensity_real_y,
- float *intensity_real_z,
- const int16_t num_frequency_bands,
- int16_t *azimuth,
- int16_t *elevation
-);
-
-void ivas_masa_init_stereotype_detection(
- MASA_STEREO_TYPE_DETECT *stereo_type_detect
-);
-
-void ivas_masa_stereotype_detection(
- MASA_STEREO_TYPE_DETECT *stereo_type_detect
-);
-
-void ivas_lfe_synth_with_cldfb(
- MCMASA_LFE_SYNTH_DATA_HANDLE hMasaLfeSynth,
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float RealBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- float ImagBufferLfe[MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],
- const int16_t slot_index,
- const int16_t subframe_index,
- const int16_t nchan_transport
-);
-
-void rotateAziEle_DirAC(
- int16_t *azi,
- int16_t *ele,
- const int16_t band1,
- const int16_t band2,
- const float *p_Rmat
-);
-
-ivas_error ivas_dirac_dec_onset_detection_open(
- const int16_t num_channels,
- const int16_t num_freq_bands,
- const int16_t max_band_decorr,
- DIRAC_ONSET_DETECTION_PARAMS *ph_dirac_onset_detection_params,
- DIRAC_ONSET_DETECTION_STATE *ph_dirac_onset_detection_state
-);
-
-void ivas_dirac_dec_onset_detection_process(
- const float *input_power_f,
- float *onset_filter,
- const int16_t num_protos_diff,
- DIRAC_ONSET_DETECTION_PARAMS h_dirac_onset_detection_params,
- DIRAC_ONSET_DETECTION_STATE h_dirac_onset_detection_state
-);
-
-ivas_error ivas_dirac_dec_decorr_open(
- DIRAC_DECORR_PARAMS **ph_freq_domain_decorr_ap_params,
- DIRAC_DECORR_STATE **ph_freq_domain_decorr_ap_state,
- const int16_t num_freq_bands,
- int16_t num_outputs_diff,
- const int16_t num_protos_diff,
- const DIRAC_SYNTHESIS_CONFIG synthesisConf,
- float *frequency_axis,
- const int16_t nchan_transport, /* i : number of transport channels */
- const int32_t output_Fs /* i : output sampling rate */
-);
-
-void ivas_dirac_dec_decorr_process(
- const int16_t num_freq_bands,
- int16_t num_channels,
- const int16_t num_protos_diff,
- const DIRAC_SYNTHESIS_CONFIG synthesisConf,
- const int16_t nchan_transport, /* i : number of transport channels */
- const float *input_frame_f,
- const int16_t num_protos_dir,
- const int16_t *proto_index_dir,
- float *frame_dec_f,
- float *onset_filter,
- HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params,
- HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state
-);
-
-void ivas_dirac_dec_decorr_close(
- HANDLE_DIRAC_DECORR_PARAMS *ph_dirac_decorr_params,
- HANDLE_DIRAC_DECORR_STATE *ph_dirac_decorr_state
-);
-
-ivas_error ivas_dirac_dec_output_synthesis_open(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const RENDERER_TYPE renderer_type, /* i : renderer type */
- const int16_t nchan_transport, /* i : number of transport channels */
- const int32_t output_Fs, /* i : output sampling rate */
- const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
-);
-
-void ivas_dirac_dec_output_synthesis_init(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const int16_t nchan_out_woLFE, /* i : number of output audio channels without LFE */
- const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
-);
-
-void ivas_dirac_dec_output_synthesis_close(
- DIRAC_REND_HANDLE hDirACRend /* i/o: DirAC handle */
-);
-
-void ivas_dirac_dec_output_synthesis_process_slot(
- const float *reference_power, /* i : Estimated power */
- const float *onset, /* i : onset filter */
- const int16_t *azimuth,
- const int16_t *elevation,
- const float *diffuseness,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const int16_t sh_rot_max_order,
- const float *p_Rmat, /* i : rotation matrix */
- const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
- const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */
- const int16_t nchan_transport, /* i : number of transport channels */
- const int16_t ind_slot, /* i : index of the slot to be added to the input covariance */
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */
-);
-
-void ivas_dirac_dec_output_synthesis_process_subframe_gain_shd(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const int16_t nchan_transport, /* i : number of transport channels */
- const int16_t nbslots, /* i : number of slots to process */
- const float *onset_filter,
- float *diffuseness,
- const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */
- const int16_t dec_param_estim /* i : flag to indicate parameter estimation mode */
-);
-
-void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls(
- float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
- float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX],/* i : LS signals */
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const int16_t nbslots, /* i : number of slots to process */
- float *diffuseness_vector, /* i : diffuseness (needed for direction smoothing)*/
- float *reference_power_smooth,
- float qualityBasedSmFactor,
- const int16_t enc_param_start_band
-);
-
-void compute_hoa_encoder_mtx(
- const float *azimuth,
- const float *elevation,
- float *response,
- const int16_t num_responses,
- const int16_t ambisonics_order );
-
-void ivas_dirac_dec_compute_gain_factors(
- const int16_t num_freq_bands,
- const float *diffuseness,
- const int16_t max_band_decorr,
- float *direct_gain_factor,
- float *diffuse_gain_factor
-);
-
-void ivas_dirac_dec_compute_power_factors(
- const int16_t num_freq_bands,
- const float *diffuseness,
- const int16_t max_band_decorr,
- float *direct_power_factor,
- float *diffuse_power_factor
-);
-
-void ivas_dirac_dec_compute_directional_responses(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */
- DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */
- const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */
- const MASA_DECODER_HANDLE hMasa, /* i : MASA decoder structure */
- const int16_t *azimuth,
- const int16_t *elevation,
- const int16_t md_idx,
- const float *surCohRatio,
- const int16_t shd_rot_max_order, /* i : split-order rotation method */
- const float *p_Rmat, /* i : rotation matrix */
- const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
-);
-
-void ivas_dirac_dec_get_frequency_axis(
- float *frequency_axis, /* o : array of center frequencies of a real filter bank */
- const int32_t output_Fs, /* i : sampling frequency */
- const int16_t num_freq_bands /* i : number of frequency bands */
-);
-
-ivas_error ivas_spat_hSpatParamRendCom_config(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out, /* i/o: IVAS decoder structure */
- const DIRAC_CONFIG_FLAG flag_config_inp, /* i/ : Flag determining if we open or reconfigure the DirAC decoder */
- const int16_t dec_param_estim_flag,
- const IVAS_FORMAT ivas_format,
- const MC_MODE mc_mode,
- const int32_t output_Fs,
- const int16_t hodirac_flag
-);
-
-void ivas_spat_hSpatParamRendCom_close(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE *hSpatParamRendCom_out
-);
-
-void ivas_dirac_rend_close(
- DIRAC_REND_HANDLE *hDirACRend_out
-);
-
-ivas_error ivas_dirac_allocate_parameters(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */
- const int16_t params_flag /* i : set of parameters flag */
-);
-
-void ivas_dirac_deallocate_parameters(
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common data for spatial parametric rendering */
- const int16_t params_flag /* i : set of parameters flag */
-);
-
-
/*----------------------------------------------------------------------------------*
* HRTF
diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c
index c7d372d65d5ae08c6bbd7103f35008dfed804224..a3bf1f1d922f322aa99982283455a58a7c8d5cb7 100644
--- a/lib_rend/ivas_rotation.c
+++ b/lib_rend/ivas_rotation.c
@@ -225,11 +225,17 @@ void Quat2EulerDegree(
{
if ( quat.w != -3.0 )
{
+#ifdef EULER2QUAT_FIX
float p;
+#endif
*yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) );
+#ifdef EULER2QUAT_FIX
p = 2 * ( quat.w * quat.y - quat.z * quat.x );
p = max( -1.0f, min( 1.0f, p ) );
*pitch = asinf( p );
+#else
+ *pitch = asinf( 2 * ( quat.w * quat.y - quat.z * quat.x ) );
+#endif
*roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) );
*yaw *= _180_OVER_PI;
*pitch *= _180_OVER_PI;
diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h
index 36c4a1783654583e146ceeaa66ccc38ad58840d6..40d8127437311b9047e668ef0f2940471676e652 100644
--- a/lib_rend/ivas_stat_rend.h
+++ b/lib_rend/ivas_stat_rend.h
@@ -47,7 +47,6 @@
#include "ivas_lc3plus_dec.h"
#endif
-//#include "ivas_stat_dec.h"
/*----------------------------------------------------------------------------------*
* Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...)
@@ -73,348 +72,6 @@ typedef struct ivas_output_setup_structure
} IVAS_OUTPUT_SETUP, *IVAS_OUTPUT_SETUP_HANDLE;
-/*----------------------------------------------------------------------------------*
- * Spatial parametric rendering common structures
- *----------------------------------------------------------------------------------*/
-
-/*Onset detector*/
-typedef struct dirac_onset_detection_params_structure
-{
- int16_t num_freq_bands;
- int16_t max_band_decorr;
-
-} DIRAC_ONSET_DETECTION_PARAMS;
-
-typedef struct dirac_onset_detection_state_structure
-{
- float *onset_detector_1;
- float *onset_detector_2;
-
-} DIRAC_ONSET_DETECTION_STATE;
-
-/*Decorrelator*/
-typedef struct dirac_decorr_params_structure
-{
- int16_t max_band_decorr;
- int16_t max_frequency;
-
- int16_t *pre_delay;
- int16_t *filter_length;
- float *filter_coeff_num_real;
- float *filter_coeff_den_real;
- float *phase_coeff_real;
- float *phase_coeff_imag;
- int16_t *split_frequency_bands;
- int16_t num_split_frequency_bands;
-
- int16_t use_ducker;
- int16_t add_back_onsets_on;
-
- DIRAC_ONSET_DETECTION_PARAMS h_onset_detection_power_params;
-
-} DIRAC_DECORR_PARAMS, *HANDLE_DIRAC_DECORR_PARAMS;
-
-typedef struct dirac_decorr_state_structure
-{
- float *decorr_buffer;
- float *direct_energy_smooth;
- float *reverb_energy_smooth;
-
- DIRAC_ONSET_DETECTION_STATE h_onset_detection_power_state;
-
-} DIRAC_DECORR_STATE, *HANDLE_DIRAC_DECORR_STATE;
-
-typedef struct ivas_spatial_parametric_rend_common_data_structure
-{
- int16_t slot_size;
- int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS];
- int16_t subframes_rendered;
- int16_t slots_rendered;
- int16_t num_slots;
- int16_t render_to_md_map[MAX_JBM_SUBFRAMES_5MS * JBM_CLDFB_SLOTS_IN_SUBFRAME];
- int16_t nb_subframes;
-
- int16_t num_freq_bands;
- int16_t numSimultaneousDirections; /* 1 or 2 */
-
- int16_t **azimuth;
- int16_t **elevation;
- int16_t **azimuth2;
- int16_t **elevation2;
-
- float **diffuseness_vector;
- float **energy_ratio1;
- float **energy_ratio2;
-
- float **spreadCoherence;
- float **spreadCoherence2;
- float **surroundingCoherence;
-
- /* Metadata access indices and buffer size */
- int16_t dirac_bs_md_write_idx;
- int16_t dirac_read_idx;
- int16_t dirac_md_buffer_length;
-
-} SPAT_PARAM_REND_COMMON_DATA, *SPAT_PARAM_REND_COMMON_DATA_HANDLE;
-
-
-/*----------------------------------------------------------------------------------*
- * DirAC rendering structures
- *----------------------------------------------------------------------------------*/
-
-typedef struct dirac_dec_stack_mem
-{
- /*Decorrelator*/
- float *frame_dec_f;
-
- /*Prototypes*/
- float *proto_direct_buffer_f;
- float *proto_diffuse_buffer_f;
-
- /*Prototype NRGs*/
- float *proto_power_smooth;
- float *proto_power_diff_smooth;
-
- /*Gain or power factors for directional and diffuse streams*/
- float *direct_power_factor;
- float *diffuse_power_factor;
-
- /*Directional responses (gains & Nrg)*/
- float *direct_responses;
- float *direct_responses_square;
-
- /* Target co-variance mtx */
- float *cy_auto_dir_smooth;
- float *cy_cross_dir_smooth;
- float *cy_auto_diff_smooth;
-
- float *reference_power;
- float *onset_filter;
-
-} DIRAC_DEC_STACK_MEM, *DIRAC_DEC_STACK_MEM_HANDLE;
-
-/*Output synthesis*/
-typedef struct dirac_output_synthesis_params_structure
-{
- int16_t max_band_decorr;
-
- int16_t use_onset_filters;
-
- float *interpolator;
- float *alpha_synthesis;
- float *alpha_synthesis_fast;
- int16_t numAlphas;
- int16_t numAlphasFast;
-
- float *proto_matrix;
-
- float diffuse_compensation_factor;
- float diffuse_compensation_factor_decorr;
-
-} DIRAC_OUTPUT_SYNTHESIS_PARAMS;
-
-typedef struct dirac_output_synthesis_state_structure
-{
- /* only pointer to local buffers */
- float *direct_responses; /* direct responses for DOA of current frame. Size: num_freq_bands*num_channels. */
- float *direct_responses_square;
- float *diffuse_responses_square; /* squared diffuse responses. Size: num_channels. */
-
- /* only pointer to local buffers */
- float *direct_power_factor;
- float *diffuse_power_factor;
-
- float *proto_power_smooth; /* Smoothed power of the prototype signals. Size: num_freq_bands*num_channels. */
- float *proto_power_smooth_prev; /* Smoothed power of the prototype signals of the previous synthesis block. Size: num_freq_bands*num_channels. */
-
- float *proto_power_diff_smooth;
- float *proto_power_diff_smooth_prev;
-
- /* only pointer to local buffers */
- float *proto_direct_buffer_f; /* Buffer for direct sound prototype signals. Size: 2*num_freq_bands*num_channels*buffer_length (complex interleaved). */
- float *proto_diffuse_buffer_f; /* Buffer for diffuse sound prototype signals. Size: 2*num_freq_bands*num_channels*buffer_length (complex interleaved). */
-
- /* Output gain memories */
- float *gains_dir_prev; /* Direct sound gains of current synthesis block. Size: num_freq_bands*num_channel. */
- float *gains_diff_prev; /* Diffuse sound gains of previous synthesis block. Size: num_freq_bands*num_channel. */
-
- /* only pointer to local buffers */
- float *cy_auto_dir_smooth; /* Target auto PSD of direct sound. Size: num_freq_bands*num_channels. */
- float *cy_cross_dir_smooth; /* Target cross PSD of direct sound. Size: num_freq_bands*num_channels. */
- float *cy_auto_diff_smooth; /* Target auto PSD of diffuse sound. Size: num_freq_bands*num_channels. */
-
- /* PSD memories */
- float *cy_auto_dir_smooth_prev; /* Target auto PSD of direct sound of previous synthesis block. Size: num_freq_bands*num_channels. */
- float *cy_cross_dir_smooth_prev; /* Target cross PSD of direct sound of previous synthesis block. Size: num_freq_bands*num_channels. */
- float *cy_auto_diff_smooth_prev; /* Target auto PSD of diffuse sound of previous synthesis block. Size: num_freq_bands*num_channels. */
-
- const float *onset_filter;
-
- /* Temporal smoothing memories */
- float *reference_power_smooth_prev;
- float *direction_smoothness_prev;
-
-} DIRAC_OUTPUT_SYNTHESIS_STATE;
-
-/* MASA stereo transport signal type detection structure */
-typedef struct
-{
- MASA_TRANSPORT_SIGNAL_TYPE masa_stereo_type;
- MASA_TRANSPORT_SIGNAL_TYPE current_stereo_type;
- MASA_TRANSPORT_SIGNAL_TYPE type_change_direction;
-
- int16_t dipole_freq_range[2];
-
- float left_bb_power;
- float right_bb_power;
- float total_bb_power;
-
- float left_hi_power;
- float right_hi_power;
- float total_hi_power;
-
- float sum_power[MASA_SUM_FREQ_RANGE_BINS];
- float total_power[MASA_SUM_FREQ_RANGE_BINS];
-
- float subtract_power_y;
- float subtract_power_y_smooth;
- float target_power_y_smooth;
-
- float lr_total_bb_ratio_db;
- float lr_total_hi_ratio_db;
- float min_sum_total_ratio_db;
- float subtract_target_ratio_db;
-
- int16_t counter;
- int16_t interpolator;
-
-} MASA_STEREO_TYPE_DETECT;
-
-/* McMASA LFE synthesis structure */
-typedef struct ivas_mcmasa_lfe_synth_struct
-{
- float lfeToTotalEnergyRatio[MAX_PARAM_SPATIAL_SUBFRAMES];
- int16_t lfeGainPrevIndex;
- float transportEneSmooth;
- float protoLfeEneSmooth;
- float targetEneLfeSmooth;
- float targetEneTransSmooth;
-
- float *lfeSynthRingBuffer;
- int16_t ringBufferLoPointer;
- int16_t ringBufferHiPointer;
- float lowpassSum;
- int16_t ringBufferSize;
-
- float *lfeSynthRingBuffer2;
- int16_t ringBufferLoPointer2;
- float lowpassSum2;
- int16_t ringBufferSize2;
-
- float *delayBuffer_syncLp;
- int16_t delayBuffer_syncLp_size;
-
- float *delayBuffer_syncDirAC;
- int16_t delayBuffer_syncDirAC_size;
-
- float lfeGainPrev;
- float transportGainPrev;
- float interpolator[CLDFB_NO_CHANNELS_MAX];
-
-} MCMASA_LFE_SYNTH_DATA, *MCMASA_LFE_SYNTH_DATA_HANDLE;
-
-/* DirAC renderer main structure */
-typedef struct ivas_dirac_rend_data_structure
-{
- IVAS_OUTPUT_SETUP hOutSetup;
-
- /*Parameter estimation*/
- int16_t index_buffer_intensity;
- float *buffer_intensity_real[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF];
- float *buffer_energy;
-
- float *frequency_axis;
- float *diffuse_response_function;
- float *hoa_encoder;
- const float *hoa_decoder;
-
- /*Decoder parameters */
- /*Prototypes*/
- int16_t num_outputs_dir;
- int16_t num_outputs_diff;
- int16_t num_protos_dir;
- int16_t num_protos_diff;
- int16_t num_protos_ambi;
- DIRAC_SYNTHESIS_CONFIG synthesisConf;
- DIRAC_PANNING_CONFIG panningConf;
-
- /* prototype computing */
- int16_t *proto_index_dir;
- int16_t *proto_index_diff;
-
- int16_t proto_signal_decorr_on;
-
- /*Decoder states=memories*/
- float *proto_frame_f;
- float *proto_frame_dec_f;
-
- DIRAC_DEC_STACK_MEM stack_mem;
- MASA_STEREO_TYPE_DETECT *masa_stereo_type_detect;
-
- int16_t num_ele_spk_no_diffuse_rendering;
-
- const int16_t *sba_map_tc;
-
- DIRAC_OUTPUT_SYNTHESIS_PARAMS h_output_synthesis_psd_params;
- DIRAC_OUTPUT_SYNTHESIS_STATE h_output_synthesis_psd_state;
-
- HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params;
- HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state;
-
-} DIRAC_REND_DATA, *DIRAC_REND_HANDLE;
-
-
-/*----------------------------------------------------------------------------------*
- * VBAP structures
- *----------------------------------------------------------------------------------*/
-
-/* Defines a single virtual surface triplet of loudspeakers
- * with a precalculated inverse matrix */
-typedef struct vbap_vs_triplet_structure
-{
- uint8_t speaker_node[3];
- float inverse_matrix[3][3];
-
-} VBAP_VS_TRIPLET;
-
-
-/* Storage structure for fast runtime triplet search */
-typedef struct triplet_search_structure
-{
- VBAP_VS_TRIPLET *triplets;
- int16_t num_triplets;
- int16_t initial_search_indices[VBAP_NUM_SEARCH_SECTORS];
-
-} VBAP_SEARCH_STRUCT;
-
-
-/* VBAP data structure. Contains the formed virtual surface arrangement * and supporting data. */
-typedef struct vbap_data_structure
-{
- VBAP_SEARCH_STRUCT search_struct[2]; /* Default to max two groups in this implementation */
- int16_t num_search_structs;
- int16_t num_speaker_nodes;
- int16_t num_speaker_nodes_internal;
- int16_t top_virtual_speaker_node_index; /* These indices can be negative */
- int16_t bottom_virtual_speaker_node_index;
- int16_t back_virtual_speaker_node_index;
- float *bottom_virtual_speaker_node_division_gains;
- float *top_virtual_speaker_node_division_gains;
- float *back_virtual_speaker_node_division_gains;
-
-} VBAP_DATA, *VBAP_HANDLE;
-
-
/*----------------------------------------------------------------------------------*
* Binaural FastConv Rendering structure
*----------------------------------------------------------------------------------*/
@@ -457,17 +114,6 @@ typedef struct ivas_binaural_reverb_struct
} REVERB_STRUCT, *REVERB_STRUCT_HANDLE;
-
-/* Diffuse sound directional distribution data structure */
-typedef struct ivas_diffuse_distribution_data_structure
-{
- float diffuseRatioX[CLDFB_NO_CHANNELS_MAX];
- float diffuseRatioY[CLDFB_NO_CHANNELS_MAX];
- float diffuseRatioZ[CLDFB_NO_CHANNELS_MAX];
-
-} DIFFUSE_DISTRIBUTION_DATA, *DIFFUSE_DISTRIBUTION_HANDLE;
-
-
/* Parametric binaural data structure */
typedef struct ivas_dirac_dec_binaural_data_structure
{
@@ -483,8 +129,13 @@ typedef struct ivas_dirac_dec_binaural_data_structure
float ChEneOut[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
float ChCrossReOut[CLDFB_NO_CHANNELS_MAX];
float ChCrossImOut[CLDFB_NO_CHANNELS_MAX];
+#ifdef MASA_AND_OBJECTS
+ float processMtxRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+ float processMtxIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+#else
float processMtxRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX]; /* +1 refers to SeparateChannel */
float processMtxIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX];
+#endif
float processMtxDecRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
float processMtxDecIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
float diffuseFieldCoherence[CLDFB_NO_CHANNELS_MAX];
@@ -495,19 +146,20 @@ typedef struct ivas_dirac_dec_binaural_data_structure
REVERB_STRUCT_HANDLE hReverb;
uint8_t renderStereoOutputInsteadOfBinaural;
float frameMeanDiffuseness[CLDFB_NO_CHANNELS_MAX];
+#ifdef MASA_AND_OBJECTS
+ float processMtxRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+ float processMtxImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_CHANNELS_MAX];
+#else
float processMtxRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX];
float processMtxImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS + 1][CLDFB_NO_CHANNELS_MAX];
+#endif
float processMtxDecRePrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
float processMtxDecImPrev[BINAURAL_CHANNELS][BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX];
+ uint16_t useSubframeMode; /* 0 = process in 20 ms frames, 1 = process in 5 ms subframes */
uint16_t useTdDecorr;
ivas_td_decorr_state_t *hTdDecorr;
float reqularizationFactor;
- DIFFUSE_DISTRIBUTION_HANDLE hDiffuseDist;
-
- HANDLE_DIRAC_DECORR_PARAMS h_freq_domain_decorr_ap_params;
- HANDLE_DIRAC_DECORR_STATE h_freq_domain_decorr_ap_state;
-
} DIRAC_DEC_BIN_DATA, *DIRAC_DEC_BIN_HANDLE;
typedef struct ivas_binaural_rendering_conv_module_struct
diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c
index 9509f11bc5b13bb8adbce9f8c08ea5b0b702fd20..6ad462c7114122d02f0c86467a4563fb94397862 100644
--- a/lib_rend/lib_rend.c
+++ b/lib_rend/lib_rend.c
@@ -57,9 +57,13 @@
/* Maximum buffer length (total) in samples. */
#ifdef SPLIT_REND_WITH_HEAD_ROT
+#ifdef REND_STATIC_MEM_OPT
#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS )
+#else /* REND_STATIC_MEM_OPT */
+#define MAX_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
+#endif /* REND_STATIC_MEM_OPT */
#else
#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS )
@@ -120,6 +124,9 @@ typedef struct
IVAS_REND_AudioConfig inConfig;
IVAS_REND_InputId id;
IVAS_REND_AudioBuffer inputBuffer;
+#ifndef REND_STATIC_MEM_OPT
+ float bufferData[MAX_BUFFER_LENGTH];
+#endif
float gain; /* Linear, not in dB */
rendering_context ctx;
int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */
@@ -137,7 +144,9 @@ typedef struct
#ifdef SPLIT_REND_WITH_HEAD_ROT
TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */
#endif
+#ifdef REND_STATIC_MEM_OPT
float *bufferData;
+#endif
int16_t nonDiegeticPan;
float nonDiegeticPanGain;
OMASA_ANA_HANDLE hOMasa;
@@ -174,7 +183,9 @@ typedef struct
int16_t nonDiegeticPan;
float nonDiegeticPanGain;
lfe_routing lfeRouting;
+#ifdef REND_STATIC_MEM_OPT
float *bufferData;
+#endif
MCMASA_ANA_HANDLE hMcMasa;
} input_mc;
@@ -192,7 +203,9 @@ typedef struct
rotation_gains rot_gains_prev;
#endif
+#ifdef REND_STATIC_MEM_OPT
float *bufferData;
+#endif
DIRAC_ANA_HANDLE hDirAC;
} input_sba;
@@ -201,7 +214,9 @@ typedef struct
{
input_base base;
SPLIT_POST_REND_WRAPPER splitPostRendWrapper;
+#ifdef REND_STATIC_MEM_OPT
float *bufferData;
+#endif
} input_split_post_rend;
#endif
@@ -215,7 +230,9 @@ typedef struct
DecoderDummy *decDummy;
MASA_METADATA_FRAME masaMetadata;
bool metadataHasBeenFed;
+#ifdef REND_STATIC_MEM_OPT
float *bufferData;
+#endif
MASA_PREREND_HANDLE hMasaPrerend;
} input_masa;
@@ -264,6 +281,7 @@ struct IVAS_REND
* Local functions
*-------------------------------------------------------------------*/
+#ifdef REND_STATIC_MEM_OPT
static ivas_error allocateInputBaseBufferData( float **data, const int16_t data_size )
{
*data = (float *) malloc( data_size * sizeof( float ) );
@@ -285,6 +303,7 @@ static void freeInputBaseBufferData( float **data )
return;
}
+#endif
static IVAS_QUATERNION quaternionInit(
void )
@@ -1201,9 +1220,13 @@ static void initRendInputBase(
input_base *inputBase,
const IVAS_REND_AudioConfig inConfig,
const IVAS_REND_InputId id,
- const rendering_context rendCtx,
+ const rendering_context rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
float *dataBuf,
- const int16_t dataBufSize )
+ const int16_t dataBufSize
+#endif
+)
{
inputBase->inConfig = inConfig;
inputBase->id = id;
@@ -1213,11 +1236,17 @@ static void initRendInputBase(
inputBase->inputBuffer.config.numSamplesPerChannel = 0;
inputBase->inputBuffer.config.numChannels = 0;
+#ifndef REND_STATIC_MEM_OPT
+ inputBase->inputBuffer.data = inputBase->bufferData;
+
+ set_zero( inputBase->bufferData, MAX_BUFFER_LENGTH );
+#else
inputBase->inputBuffer.data = dataBuf;
if ( inputBase->inputBuffer.data != NULL )
{
set_zero( inputBase->inputBuffer.data, dataBufSize );
}
+#endif
return;
}
@@ -1357,12 +1386,18 @@ static ivas_error setRendInputActiveIsm(
return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED;
}
+#ifdef REND_STATIC_MEM_OPT
if ( ( error = allocateInputBaseBufferData( &inputIsm->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{
return error;
}
- initRendInputBase( &inputIsm->base, inConfig, id, rendCtx,
- inputIsm->bufferData, MAX_BUFFER_LENGTH );
+#endif
+ initRendInputBase( &inputIsm->base, inConfig, id, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ inputIsm->bufferData, MAX_BUFFER_LENGTH
+#endif
+ );
inputIsm->currentPos = defaultObjectPosition();
inputIsm->previousPos = defaultObjectPosition();
@@ -1462,9 +1497,15 @@ static void clearInputIsm(
rendCtx = inputIsm->base.ctx;
+#ifdef REND_STATIC_MEM_OPT
freeInputBaseBufferData( &inputIsm->base.inputBuffer.data );
- initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
- NULL, 0 );
+#endif
+ initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
/* Free input's internal handles */
@@ -2367,12 +2408,18 @@ static ivas_error setRendInputActiveMc(
return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED;
}
+#ifdef REND_STATIC_MEM_OPT
if ( ( error = allocateInputBaseBufferData( &inputMc->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{
return error;
}
- initRendInputBase( &inputMc->base, inConfig, id, rendCtx,
- inputMc->bufferData, MAX_BUFFER_LENGTH );
+#endif
+ initRendInputBase( &inputMc->base, inConfig, id, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ inputMc->bufferData, MAX_BUFFER_LENGTH
+#endif
+ );
setZeroPanMatrix( inputMc->panGains );
inputMc->customLsInput = defaultCustomLs();
inputMc->tdRendWrapper = defaultTdRendWrapper();
@@ -2425,9 +2472,15 @@ static void clearInputMc(
rendCtx = inputMc->base.ctx;
+#ifdef REND_STATIC_MEM_OPT
freeInputBaseBufferData( &inputMc->bufferData );
- initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
- NULL, 0 );
+#endif
+ initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
/* Free input's internal handles */
if ( inputMc->efapInWrapper.hEfap != NULL )
@@ -2724,12 +2777,18 @@ static ivas_error setRendInputActiveSplitPostRend(
rendCtx = inputSplitPostRend->base.ctx;
outConfig = *rendCtx.pOutConfig;
+#ifdef REND_STATIC_MEM_OPT
if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{
return error;
}
- initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx,
- inputSplitPostRend->bufferData, MAX_BIN_BUFFER_LENGTH );
+#endif
+ initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ inputSplitPostRend->bufferData, MAX_BIN_BUFFER_LENGTH
+#endif
+ );
if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK )
{
@@ -2783,6 +2842,7 @@ static ivas_error setRendInputActiveSba(
return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED;
}
+#ifdef REND_STATIC_MEM_OPT
#ifdef SPLIT_REND_WITH_HEAD_ROT
if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
#else
@@ -2796,6 +2856,9 @@ static ivas_error setRendInputActiveSba(
#else
initRendInputBase( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData, MAX_BUFFER_LENGTH );
#endif /* SPLIT_REND_WITH_HEAD_ROT */
+#else /* REND_STATIC_MEM_OPT */
+ initRendInputBase( &inputSba->base, inConfig, id, rendCtx );
+#endif /* REND_STATIC_MEM_OPT */
setZeroPanMatrix( inputSba->hoaDecMtx );
#ifdef SPLIT_REND_WITH_HEAD_ROT
inputSba->crendWrapper = NULL;
@@ -2833,9 +2896,15 @@ static void clearInputSplitRend(
rendCtx = inputSplitRend->base.ctx;
+#ifdef REND_STATIC_MEM_OPT
freeInputBaseBufferData( &inputSplitRend->bufferData );
- initRendInputBase( &inputSplitRend->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
- NULL, 0 );
+#endif
+ initRendInputBase( &inputSplitRend->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL )
{
ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend );
@@ -2860,9 +2929,15 @@ static void clearInputSba(
rendCtx = inputSba->base.ctx;
+#ifdef REND_STATIC_MEM_OPT
freeInputBaseBufferData( &inputSba->bufferData );
- initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
- NULL, 0 );
+#endif
+ initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
/* Free input's internal handles */
#ifdef SPLIT_REND_WITH_HEAD_ROT
@@ -2919,11 +2994,11 @@ static ivas_error initMasaDummyDecForMcOut(
}
decDummy->hQMetaData->coherence_flag = 1;
- if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK )
{
return error;
}
- decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0;
+ decDummy->hDirAC->dirac_bs_md_write_idx = 0;
if ( decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
@@ -2997,11 +3072,11 @@ static ivas_error initMasaDummyDecForSbaOut(
}
decDummy->hQMetaData->coherence_flag = 1;
- if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK )
{
return error;
}
- decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0;
+ decDummy->hDirAC->dirac_bs_md_write_idx = 0;
numCldfbAnalyses = decDummy->nchan_transport;
numCldfbSyntheses = decDummy->hDecoderConfig->nchan_out;
@@ -3071,11 +3146,11 @@ static ivas_error initMasaDummyDecForBinauralOut(
decDummy->ivas_format = MASA_FORMAT;
decDummy->transport_config = AUDIO_CONFIG_INVALID;
- if ( ( error = ivas_dirac_dec_config( decDummy, DIRAC_OPEN ) ) != IVAS_ERR_OK )
+ if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK )
{
return error;
}
- decDummy->hSpatParamRendCom->dirac_bs_md_write_idx = 0;
+ decDummy->hDirAC->dirac_bs_md_write_idx = 0;
if ( ( error = ivas_dirac_dec_binaural_copy_hrtfs( &decDummy->hHrtfParambin ) ) != IVAS_ERR_OK )
{
@@ -3170,8 +3245,6 @@ static DecoderDummy *initDecoderDummy(
decDummy->hVBAPdata = NULL; // note: not used at the moment
decDummy->hMasa = NULL;
decDummy->hDiracDecBin = NULL;
- decDummy->hDirACRend = NULL;
- decDummy->hSpatParamRendCom = NULL;
decDummy->hQMetaData = NULL;
decDummy->hHrtfParambin = NULL;
decDummy->hHeadTrackData = NULL;
@@ -3266,12 +3339,18 @@ static ivas_error setRendInputActiveMasa(
return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED;
}
+#ifdef REND_STATIC_MEM_OPT
if ( ( error = allocateInputBaseBufferData( &inputMasa->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK )
{
return error;
}
- initRendInputBase( &inputMasa->base, inConfig, id, rendCtx,
- inputMasa->bufferData, MAX_BUFFER_LENGTH );
+#endif
+ initRendInputBase( &inputMasa->base, inConfig, id, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ inputMasa->bufferData, MAX_BUFFER_LENGTH
+#endif
+ );
if ( ( error = getAudioConfigNumChannels( inConfig, &numInChannels ) ) != IVAS_ERR_OK )
{
@@ -3353,8 +3432,6 @@ static void freeDecoderDummy(
}
/* DirAC handle */
- ivas_dirac_rend_close( &( pDecDummy->hDirACRend ) );
- ivas_spat_hSpatParamRendCom_close( &( pDecDummy->hSpatParamRendCom ) );
ivas_dirac_dec_close( &( pDecDummy->hDirAC ) );
/* Qmetadata handle */
@@ -3370,9 +3447,6 @@ static void freeDecoderDummy(
pDecDummy->hoa_dec_mtx = NULL;
}
- /* Parametric binaural renderer HRTF structure */
- free( pDecDummy->hHrtfParambin );
-
/* Parametric binaural renderer handle */
ivas_dirac_dec_close_binaural_data( &pDecDummy->hDiracDecBin );
@@ -3392,11 +3466,17 @@ static void clearInputMasa(
rendCtx = inputMasa->base.ctx;
+#ifdef REND_STATIC_MEM_OPT
freeInputBaseBufferData( &inputMasa->bufferData );
+#endif
masaPrerendClose( &inputMasa->hMasaPrerend );
- initRendInputBase( &inputMasa->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx,
- NULL, 0 );
+ initRendInputBase( &inputMasa->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
freeDecoderDummy( &inputMasa->decDummy );
return;
@@ -3547,8 +3627,12 @@ ivas_error IVAS_REND_Open(
for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i )
{
- initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ),
- NULL, 0 );
+ initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend )
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
hIvasRend->inputsIsm[i].crendWrapper = NULL;
hIvasRend->inputsIsm[i].hReverb = NULL;
hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL;
@@ -3559,7 +3643,9 @@ ivas_error IVAS_REND_Open(
hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hHrtfTD = NULL;
}
#endif
+#ifdef REND_STATIC_MEM_OPT
hIvasRend->inputsIsm[i].bufferData = NULL;
+#endif
hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan;
hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain;
hIvasRend->inputsIsm[i].hOMasa = NULL;
@@ -3567,13 +3653,19 @@ ivas_error IVAS_REND_Open(
for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i )
{
- initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ),
- NULL, 0 );
+ initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend )
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL;
hIvasRend->inputsMc[i].crendWrapper = NULL;
hIvasRend->inputsMc[i].hReverb = NULL;
hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL;
+#ifdef REND_STATIC_MEM_OPT
hIvasRend->inputsMc[i].bufferData = NULL;
+#endif
hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan;
hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain;
hIvasRend->inputsMc[i].hMcMasa = NULL;
@@ -3588,24 +3680,36 @@ ivas_error IVAS_REND_Open(
for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i )
{
- initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ),
- NULL, 0 );
+ initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend )
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
hIvasRend->inputsSba[i].crendWrapper = NULL;
#ifdef SPLIT_REND_WITH_HEAD_ROT
hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend = NULL;
hIvasRend->inputsSba[i].cldfbRendWrapper.hHrtfFastConv = NULL;
#endif
+#ifdef REND_STATIC_MEM_OPT
hIvasRend->inputsSba[i].bufferData = NULL;
+#endif
hIvasRend->inputsSba[i].hDirAC = NULL;
}
for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i )
{
- initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ),
- NULL, 0 );
+ initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend )
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
hIvasRend->inputsMasa[i].decDummy = NULL;
hIvasRend->inputsMasa[i].metadataHasBeenFed = false;
+#ifdef REND_STATIC_MEM_OPT
hIvasRend->inputsMasa[i].bufferData = NULL;
+#endif
hIvasRend->inputsMasa[i].hMasaPrerend = NULL;
}
#ifdef SPLIT_REND_WITH_HEAD_ROT
@@ -3614,13 +3718,20 @@ ivas_error IVAS_REND_Open(
initRendInputBase( &hIvasRend->inputsSplitPost[i].base,
IVAS_REND_AUDIO_CONFIG_UNKNOWN,
0,
- getRendCtx( hIvasRend ),
- NULL, 0 );
+ getRendCtx( hIvasRend )
+#ifdef REND_STATIC_MEM_OPT
+ ,
+ NULL, 0
+#endif
+ );
ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper );
#ifdef SPLIT_REND_WITH_HEAD_ROT
hIvasRend->splitRendBFI = 0;
#endif
+#ifdef REND_STATIC_MEM_OPT
hIvasRend->inputsSplitPost[i].bufferData = NULL;
+
+#endif
}
#endif
@@ -4982,7 +5093,11 @@ ivas_error IVAS_REND_SetHeadRotation(
( hIvasRend->inputsSplitPost[0].base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ||
( hIvasRend->inputsSplitPost[0].base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
{
+#ifndef EULER2QUAT_FIX
+ rotQuat = headRot[i]; /* TODO: temp change until Euler2Quat() is fixed*/
+#else
Euler2Quat( deg2rad( headRot[i].x ), deg2rad( headRot[i].y ), deg2rad( headRot[i].z ), &rotQuat );
+#endif
}
else
#endif
@@ -5471,13 +5586,19 @@ static ivas_error rotateFrameSba(
int16_t m1, m2;
int16_t shd_rot_max_order;
int16_t subframe_idx, subframe_len;
+#ifdef SBA_CREND_ROT_OPT
float *writePtr;
+#else
+ float *readPtr, *writePtr;
+#endif
rotation_matrix Rmat;
float tmpRot[2 * HEADROT_ORDER + 1];
rotation_gains gains;
ivas_error error;
+#ifdef SBA_CREND_ROT_OPT
int16_t idx;
float val, cf, oneminuscf;
+#endif
push_wmops( "rotateFrameSba" );
@@ -5518,9 +5639,11 @@ static ivas_error rotateFrameSba(
for ( i = 0; i < subframe_len; i++ )
{
+#ifdef SBA_CREND_ROT_OPT
idx = subframe_idx * subframe_len + i;
cf = headRotData->crossfade[i];
oneminuscf = 1 - cf;
+#endif
/* As the rotation matrix becomes block diagonal in a SH basis, we can*/
/* apply each angular-momentum block individually to save complexity. */
@@ -5536,9 +5659,16 @@ static ivas_error rotateFrameSba(
for ( m = m1; m < m2; m++ )
{
+#ifdef SBA_CREND_ROT_OPT
val = inAudio.data[m * inAudio.config.numSamplesPerChannel + idx];
/* crossfade with previous rotation gains */
tmpRot[n - m1] += ( cf * gains[n][m] * val + oneminuscf * gains_prev[n][m] * val );
+#else
+ readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i );
+ /* crossfade with previous rotation gains */
+ tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) +
+ ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr );
+#endif
}
}
/* write back the result */
@@ -5754,7 +5884,6 @@ static ivas_error renderIsmToBinauralRoom(
return IVAS_ERR_OK;
}
-
static ivas_error renderIsmToBinauralReverb(
input_ism *ismInput,
IVAS_REND_AudioBuffer outAudio )
@@ -7692,41 +7821,44 @@ static ivas_error renderActiveInputsSba(
static void copyMasaMetadataToDiracRenderer(
MASA_METADATA_FRAME *meta,
- SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom )
+ DIRAC_DEC_HANDLE hDirAC )
{
int16_t band, sf, bin;
int16_t meta_write_index;
- hSpatParamRendCom->numSimultaneousDirections = meta->descriptive_meta.numberOfDirections + 1;
+#ifdef MASA_AND_OBJECTS
+ hDirAC->numParametricDirections = meta->descriptive_meta.numberOfDirections + 1;
+#endif
+ hDirAC->numSimultaneousDirections = meta->descriptive_meta.numberOfDirections + 1;
for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
{
- meta_write_index = ( hSpatParamRendCom->dirac_bs_md_write_idx + sf ) % hSpatParamRendCom->dirac_md_buffer_length;
+ meta_write_index = ( hDirAC->dirac_bs_md_write_idx + sf ) % hDirAC->dirac_md_buffer_length;
for ( band = 0; band < MASA_MAXIMUM_CODING_SUBBANDS; band++ )
{
for ( bin = MASA_band_grouping_24[band]; bin < MASA_band_grouping_24[band + 1]; bin++ )
{
- hSpatParamRendCom->azimuth[meta_write_index][bin] = (int16_t) meta->directional_meta[0].azimuth[sf][band];
- hSpatParamRendCom->elevation[meta_write_index][bin] = (int16_t) meta->directional_meta[0].elevation[sf][band];
- hSpatParamRendCom->energy_ratio1[meta_write_index][bin] = meta->directional_meta[0].energy_ratio[sf][band];
- hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] = 1.0f - meta->directional_meta[0].energy_ratio[sf][band];
- hSpatParamRendCom->spreadCoherence[meta_write_index][bin] = meta->directional_meta[0].spread_coherence[sf][band];
- hSpatParamRendCom->surroundingCoherence[meta_write_index][bin] = meta->common_meta.surround_coherence[sf][band];
-
- if ( hSpatParamRendCom->numSimultaneousDirections == 2 )
+ hDirAC->azimuth[meta_write_index][bin] = (int16_t) meta->directional_meta[0].azimuth[sf][band];
+ hDirAC->elevation[meta_write_index][bin] = (int16_t) meta->directional_meta[0].elevation[sf][band];
+ hDirAC->energy_ratio1[meta_write_index][bin] = meta->directional_meta[0].energy_ratio[sf][band];
+ hDirAC->diffuseness_vector[meta_write_index][bin] = 1.0f - meta->directional_meta[0].energy_ratio[sf][band];
+ hDirAC->spreadCoherence[meta_write_index][bin] = meta->directional_meta[0].spread_coherence[sf][band];
+ hDirAC->surroundingCoherence[meta_write_index][bin] = meta->common_meta.surround_coherence[sf][band];
+
+ if ( hDirAC->numSimultaneousDirections == 2 )
{
- hSpatParamRendCom->azimuth2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].azimuth[sf][band];
- hSpatParamRendCom->elevation2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].elevation[sf][band];
- hSpatParamRendCom->energy_ratio2[meta_write_index][bin] = meta->directional_meta[1].energy_ratio[sf][band];
- hSpatParamRendCom->diffuseness_vector[meta_write_index][bin] -= meta->directional_meta[1].energy_ratio[sf][band];
- hSpatParamRendCom->spreadCoherence2[meta_write_index][bin] = meta->directional_meta[1].spread_coherence[sf][band];
+ hDirAC->azimuth2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].azimuth[sf][band];
+ hDirAC->elevation2[meta_write_index][bin] = (int16_t) meta->directional_meta[1].elevation[sf][band];
+ hDirAC->energy_ratio2[meta_write_index][bin] = meta->directional_meta[1].energy_ratio[sf][band];
+ hDirAC->diffuseness_vector[meta_write_index][bin] -= meta->directional_meta[1].energy_ratio[sf][band];
+ hDirAC->spreadCoherence2[meta_write_index][bin] = meta->directional_meta[1].spread_coherence[sf][band];
}
}
}
}
- hSpatParamRendCom->dirac_bs_md_write_idx = ( hSpatParamRendCom->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length;
+ hDirAC->dirac_bs_md_write_idx = ( hDirAC->dirac_bs_md_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hDirAC->dirac_md_buffer_length;
return;
}
@@ -7738,7 +7870,7 @@ static void renderMasaToMc(
float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer );
- copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom );
+ copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC );
if ( masaInput->decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC )
{
@@ -7761,7 +7893,7 @@ static void renderMasaToSba(
float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer );
- copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom );
+ copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC );
ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels );
@@ -7777,7 +7909,7 @@ static void renderMasaToBinaural(
float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k];
copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer );
- copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hSpatParamRendCom );
+ copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC );
ivas_dirac_dec_binaural( masaInput->decDummy, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, masaInput->base.inputBuffer.config.numChannels );
diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm
index f0b30c28cf9395f3df439267b6f33d4d69905baa..a4e3fd041f833e25084ed69b4973f0742ed42d72 100644
--- a/scripts/config/self_test.prm
+++ b/scripts/config/self_test.prm
@@ -754,22 +754,6 @@
../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit
../IVAS_dec HOA3 48 bit testv/stv3OA48c.wav_sw_48-48_HOA3.tst
-// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, MONO out
-../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit
-../IVAS_dec MONO 48 bit testv/stv3OA48c.wav_sw_48-48_MONO.tst
-
-// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, STEREO out
-../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit
-../IVAS_dec STEREO 48 bit testv/stv3OA48c.wav_sw_48-48_STEREO.tst
-
-// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out
-../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit
-../IVAS_dec BINAURAL 48 bit testv/stv3OA48c.wav_sw_48-48_BINAURAL.tst
-
-// SBA 3OA bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, FOA out
-../IVAS_cod -sba 3 ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv3OA48c.wav bit
-../IVAS_dec FOA 48 bit testv/stv3OA48c.wav_sw_48-48_FOA.tst
-
// SBA planar 3OA bitrate switching from 24.4 kbps to 256 kbps, 48kHz in, 48kHz out, 7_1_4 out
../IVAS_cod -sba -3 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv3OA48c.wav bit
../IVAS_dec 7_1_4 48 bit testv/stv3OA48c.wav_sw_48-48_7_1_4.tst
@@ -944,43 +928,10 @@
../IVAS_cod -masa 1 testv/stv1MASA1TC48n.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv1MASA1TC48n.wav bit
../IVAS_dec 5_1 48 bit testv/stv1MASA1TC48n.wav_sw_48-48_5_1.tst
-// MASA 1dir 1TC bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, STEREO out
-../IVAS_cod -masa 1 testv/stv1MASA1TC48n.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv1MASA1TC48n.wav bit
-../IVAS_dec STEREO 48 bit testv/stv1MASA1TC48n.wav_sw_48-48_STEREO.tst
-
-// MASA 1dir 1TC bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, BINAURAL out
-../IVAS_cod -masa 1 testv/stv1MASA1TC48n.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv1MASA1TC48n.wav bit
-../IVAS_dec BINAURAL 48 bit testv/stv1MASA1TC48n.wav_sw_48-48_BINAURAL.tst
-
-// MASA 1dir 1TC bitrate switching from 13.2 kbps to 128 kbps, 48kHz in, 48kHz out, FOA out
-../IVAS_cod -masa 1 testv/stv1MASA1TC48n.met ../scripts/switchPaths/sw_13k2_to_128k_10fr.bin 48 testv/stv1MASA1TC48n.wav bit
-../IVAS_dec FOA 48 bit testv/stv1MASA1TC48n.wav_sw_48-48_FOA.tst
-
// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out
../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit
../IVAS_dec BINAURAL 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_BINAURAL.tst
-// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, MONO out
-../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit
-../IVAS_dec MONO 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_MONO.tst
-
-// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, 7_1 out
-../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit
-../IVAS_dec 7_1 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_7_1.tst
-
-// MASA 1dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, MONO out
-../IVAS_cod -masa 2 testv/stv1MASA2TC48n.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv1MASA2TC48n.wav bit
-../IVAS_dec MONO 48 bit testv/stv1MASA2TC48n.wav_sw_48-48_MONO.tst
-
-// MASA 2dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, 7_1 out
-../IVAS_cod -masa 2 testv/stv2MASA2TC48c.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv2MASA2TC48c.wav bit
-../IVAS_dec 7_1 48 bit testv/stv2MASA2TC48c.wav_sw_48-48_7_1.tst
-
-// MASA 2dir 2TC bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out
-../IVAS_cod -masa 2 testv/stv2MASA2TC48c.met ../scripts/switchPaths/sw_13k2_512k.bin 48 testv/stv2MASA2TC48c.wav bit
-../IVAS_dec BINAURAL 48 bit testv/stv2MASA2TC48c.wav_sw_48-48_BINAURAL.tst
-
-
// Multi-channel 5_1 at 13.2 kbps, 48kHz in, 48kHz out
@@ -1187,10 +1138,6 @@
../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_24k4_256k.bin 48 testv/stv714MC48c.wav bit
../IVAS_dec -FEC 5 STEREO 32 bit testv/stv714MC48c.wav_sw_48-32_stereo.tst
-// Multi-channel 7_1_4 bitrate switching from 13.2 kbps to 512 kbps, 48kHz in, 48kHz out, BINAURAL out
-../IVAS_cod -mc 7_1_4 ../scripts/switchPaths/sw_mctech_5fr.bin 48 testv/stv714MC48c.wav bit
-../IVAS_dec BINAURAL 48 bit testv/stv51MC48c.wav_sw_48-48_BINAURAL.tst
-
// Multi-channel 5_1_4 at 512 kbps, 48kHz in, 16kHz out, BINAURAL_ROOM out (Model from file)
../IVAS_cod -mc 5_1_4 512000 48 testv/stv514MC48c.wav bit
diff --git a/tests/codec_be_on_mr_selection/__init__.py b/tests/codec_be_on_mr_selection/__init__.py
index b7f4cd8efeffaff30d451bb9d0eb49945f68a47d..34a307a7393396bbb6aa614f4d496e25c2757bc2 100644
--- a/tests/codec_be_on_mr_selection/__init__.py
+++ b/tests/codec_be_on_mr_selection/__init__.py
@@ -35,7 +35,6 @@ import filecmp
from pathlib import Path
import subprocess
from .constants import OUTPUT_MODES_AND_OPTIONS_FOR_EXPERIMENT, DTX_ON, FER_5PERC
-from ..testconfig import MD5_REF_DICT
HERE = Path(__file__).parent
# set environment variables in CI job
@@ -99,20 +98,8 @@ def apply_error_pattern_on_bitstream(
subprocess.run(cmd)
-def is_be_to_ref(dut_file):
- """
- Check bitexactness either by comparing files directly or by comparing MD5 sums
- """
- if MD5_REF_DICT == dict():
- ref_file = REF_PATH.joinpath(dut_file.name)
- is_be = filecmp.cmp(dut_file, ref_file)
- else:
- md5_ref = MD5_REF_DICT[dut_file.name]
- cmd = f"powershell.exe (Get-FileHash {str(dut_file)} -Algorithm MD5).Hash"
- md5_dut = subprocess.check_output(cmd, shell=True).decode().splitlines()[-1]
- is_be = md5_ref == md5_dut
-
- return is_be
+def files_equal(dut_file, ref_file):
+ return filecmp.cmp(dut_file, ref_file)
def run_check(
@@ -126,7 +113,6 @@ def run_check(
decoder_frontend,
is_ref_creation,
input_file_num=None,
- keep_files=True,
):
sampling_rate = 48
output_mode, options = OUTPUT_MODES_AND_OPTIONS_FOR_EXPERIMENT[experiment]
@@ -161,8 +147,9 @@ def run_check(
add_option_list=options + [str(f) for f in metadata],
)
- if not is_be_to_ref(dut_bitstream):
- pytest.fail(f"Bitstream file differs from reference")
+ ref_bitstream = REF_PATH.joinpath(dut_bitstream.name)
+ if not is_ref_creation and not files_equal(dut_bitstream, ref_bitstream):
+ pytest.fail("Bitstream file differs from reference")
dut_bitstream_to_decoder = dut_bitstream
if error_pattern is not None:
@@ -181,15 +168,12 @@ def run_check(
# this should not be a problem as both the reference and the tdut output was generated by the codec, so
# diverging headers should also indicate a problem - still, keep in mind if something bogus happens
if not is_ref_creation:
- if not is_be_to_ref(dut_output):
+ ref_output = REF_PATH.joinpath(dut_output.name)
+ if not files_equal(dut_output, ref_output):
pytest.fail("Decoder output differs from reference")
- elif not keep_files:
- os.remove(dut_output)
- os.remove(dut_bitstream)
for md in metadata:
md_suffix = "".join(md.suffixes)
dut_md = DUT_PATH.joinpath(dut_output.with_suffix(md_suffix).name)
- if not is_be_to_ref(dut_md):
+ ref_md = REF_PATH.joinpath(dut_output.with_suffix(md_suffix).name)
+ if not files_equal(dut_md, ref_md):
pytest.fail("Metadata file {md.name} differs from reference")
- elif not keep_files:
- os.remove(dut_md)
diff --git a/tests/codec_be_on_mr_selection/test_experiments.py b/tests/codec_be_on_mr_selection/test_experiments.py
index 5b2f51689342117c2e543442a974bce6714ff6fc..a0a4aa780a757cf887e6b80e72a8a48eed00899d 100644
--- a/tests/codec_be_on_mr_selection/test_experiments.py
+++ b/tests/codec_be_on_mr_selection/test_experiments.py
@@ -52,7 +52,6 @@ def test_p800(
dut_encoder_frontend,
dut_decoder_frontend,
update_ref,
- keep_files,
):
run_check(
experiment,
@@ -64,7 +63,6 @@ def test_p800(
dut_encoder_frontend,
dut_decoder_frontend,
update_ref == 1,
- keep_files=keep_files,
)
@@ -81,7 +79,6 @@ def test_bs1534_no_masa(
dut_encoder_frontend,
dut_decoder_frontend,
update_ref,
- keep_files,
):
category = ""
run_check(
@@ -95,7 +92,6 @@ def test_bs1534_no_masa(
dut_decoder_frontend,
update_ref == 1,
input_file_num=input_file_num,
- keep_files=keep_files,
)
@@ -115,7 +111,6 @@ def test_bs1534_masa(
dut_encoder_frontend,
dut_decoder_frontend,
update_ref,
- keep_files,
):
run_check(
experiment,
@@ -128,5 +123,4 @@ def test_bs1534_masa(
dut_decoder_frontend,
update_ref == 1,
input_file_num=input_file_num,
- keep_files=keep_files,
)
diff --git a/tests/conftest.py b/tests/conftest.py
index e4de453b0ea6698f9600076ded65a53a1a2b7d51..12b62caccd9d49cd003b204cfe8ce7e307674a24 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -133,12 +133,6 @@ def pytest_addoption(parser):
" Use --keep_files to prevent these deletions.",
)
- parser.addoption(
- "--selection_be_md5_file",
- type=Path,
- help="Path to file with md5 sums for the reference signals of the selection-BE test"
- )
-
@pytest.fixture(scope="session", autouse=True)
def update_ref(request):
@@ -519,9 +513,3 @@ def pytest_configure(config):
)
if config.option.param_file:
testconfig.PARAM_FILE = config.option.param_file
- if config.option.selection_be_md5_file:
- md5_file_path = config.option.selection_be_md5_file
- if not platform.system() == "Windows":
- raise NotImplementedError("MD5 comparison is currently hardcoded for windows")
- with open(md5_file_path) as f:
- testconfig.MD5_REF_DICT = {line.split()[0]: line.split()[1] for line in f.readlines()}
diff --git a/tests/testconfig.py b/tests/testconfig.py
index 1dbfbb840343801460f1548b4e8b662d9ce96e6e..12d170ba8db49171e16add1f827a590ffcb09bd3 100644
--- a/tests/testconfig.py
+++ b/tests/testconfig.py
@@ -35,5 +35,3 @@ To configure test modules.
"""
PARAM_FILE = "scripts/config/self_test.prm"
-
-MD5_REF_DICT = dict()
\ No newline at end of file