diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f99f6ce010582508e14f91be322609ad886e6e11..c4a429c75d2ac2ff575d112a2aeea6ada7c1c4d7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -717,7 +717,6 @@ codec-comparison-on-main-push: stage: test tags: - sanitizer_test_main - timeout: "2 hours" artifacts: name: "$CI_JOB_NAME--main--sha-$CI_COMMIT_SHORT_SHA" when: always @@ -726,150 +725,168 @@ codec-comparison-on-main-push: # second wildcard is necessary to get encoder and no-PLC run logs - "CLANG*/logs*" +### --- sanitizer schedule A --- + +.sanitizer-test-schedule-A: + extends: + - .sanitizer-test-template + timeout: 2 hours 30 minutes + + sanitizer-test-mono: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py mono mono --tests $SANITIZER_TESTS sanitizer-test-stereo: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 1 hour + start_in: 2 hours 30 minutes script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS sanitizer-test-stereodmxevs: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 2 hours + start_in: 5 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py StereoDmxEVS mono --tests $SANITIZER_TESTS sanitizer-test-ism1: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 3 hours + start_in: 7 hours 30 minutes script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS sanitizer-test-ism2: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 4 hours + start_in: 10 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS sanitizer-test-ism3: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 6 hours + start_in: 12 hours 30 minutes script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS sanitizer-test-ism4: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 8 hours + start_in: 15 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS -sanitizer-test-mc-5_1: - extends: .sanitizer-test-template +sanitizer-test-masa: + extends: .sanitizer-test-schedule-A rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_A when: delayed - start_in: 10 hours + start_in: 17 hours 30 minutes + script: + - *update-ltv-repo + - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +### --- sanitizer schedule B --- + +.sanitizer-test-schedule-B: + extends: + - .sanitizer-test-template + timeout: 3 hours + +sanitizer-test-mc-5_1: + extends: .sanitizer-test-schedule-B + rules: + - if: $SANITIZER_SCHEDULE_B script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS sanitizer-test-mc-5_1_2: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-B rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_B when: delayed - start_in: 12 hours + start_in: 3 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS sanitizer-test-mc-5_1_4: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-B rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_B when: delayed - start_in: 14 hours + start_in: 6 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS sanitizer-test-mc-7_1: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-B rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_B when: delayed - start_in: 16 hours + start_in: 9 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS sanitizer-test-mc-7_1_4: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-B rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_B when: delayed - start_in: 18 hours + start_in: 12 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS -sanitizer-test-masa: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 20 hours - script: - - *update-ltv-repo - - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS +### --- sanitizer schedule C --- + +.sanitizer-test-schedule-C: + extends: + - .sanitizer-test-template + timeout: 6 hours sanitizer-test-sba: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-C rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 22 hours + - if: $SANITIZER_SCHEDULE_C script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py SBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS sanitizer-test-planarsba: - extends: .sanitizer-test-template + extends: .sanitizer-test-schedule-C rules: - - if: $IS_SANITIZER_TEST_RUN + - if: $SANITIZER_SCHEDULE_C when: delayed - start_in: 24 hours + start_in: 6 hours script: - *update-ltv-repo - python3 ci/run_scheduled_sanitizer_test.py PlanarSBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS diff --git a/CMakeLists.txt b/CMakeLists.txt index a048f400a67e211190f73c7a5e41f2014ab20224..317274ddce0b47fa97ce1455dc0715671aa6dd95 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -145,7 +145,7 @@ target_link_libraries(lib_enc lib_com lib_debug) file(GLOB libRendSrcs "lib_rend/*.c") file(GLOB libRendHeaders "lib_rend/*.h") add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) -target_link_libraries(lib_rend lib_com lib_debug) +target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") diff --git a/Makefile b/Makefile index 9514e9a582437a1e60735a29b3a0d5c637d560c0..141a607b075279da49e4530e701a7f5453303bb0 100644 --- a/Makefile +++ b/Makefile @@ -184,8 +184,8 @@ $(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(L $(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) -$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) $(CLI_UTESTS_CREND): $(OBJS_CLI_UTESTS_CREND) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_UTESTS_CREND) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND) diff --git a/apps/decoder.c b/apps/decoder.c index 968dc79ec2b69bcff8bc225c0203931c3f9ccb9f..e8d8019e00570346abc1e130a938217d38de4f7c 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -105,20 +105,22 @@ typedef struct bool hrtfReaderEnabled; char *hrtfFileName; IVAS_DEC_INPUT_FORMAT inputFormat; -#ifdef DEBUGGING - bool forceSubframeBinauralization; - IVAS_DEC_FORCED_REND_MODE forcedRendMode; -#endif bool customLsOutputEnabled; char *customLsSetupFilename; int16_t orientation_tracking; float no_diegetic_pan; bool renderConfigEnabled; char *renderConfigFilename; + +#ifdef DEBUGGING + bool forceSubframeBinauralization; + IVAS_DEC_FORCED_REND_MODE forcedRendMode; #ifdef DEBUG_FOA_AGC FILE *agcBitstream; /* temporary */ #endif +#endif + } DecArguments; @@ -128,12 +130,10 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -#ifdef DEBUGGING -static int16_t app_own_random( int16_t *seed ); -#endif static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, HeadRotFileReader *headRotReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); #ifdef DEBUGGING +static int16_t app_own_random( int16_t *seed ); static IVAS_DEC_FORCED_REND_MODE parseForcedRendModeDec( char *forcedRendModeChar ); #endif @@ -582,10 +582,10 @@ cleanup: printf( "\n" ); } +#ifdef DEBUGGING #ifdef DEBUG_SBA_AUDIO_DUMP ivas_close_sba_decoder_debug_files( arg.output_Fs, numOutChannels, numTransportChannels, pca_ingest_channels ); #endif -#ifdef DEBUGGING dbgclose(); #endif @@ -689,6 +689,9 @@ static bool parseCmdlIVAS_dec( arg->forcedRendMode = IVAS_DEC_FORCE_REND_UNFORCED; arg->forceSubframeBinauralization = false; +#ifdef DEBUG_FOA_AGC + arg->agcBitstream = NULL; +#endif #endif arg->output_Fs = 48000; arg->outputFormat = IVAS_DEC_OUTPUT_MONO; @@ -720,9 +723,6 @@ static bool parseCmdlIVAS_dec( arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->no_diegetic_pan = 0.f; -#ifdef DEBUG_FOA_AGC - arg->agcBitstream = NULL; -#endif /*-----------------------------------------------------------------* * Initialization @@ -791,21 +791,6 @@ static bool parseCmdlIVAS_dec( arg->jbmOffsetFilename = argv[i]; i++; } -#ifdef DEBUGGING - else if ( strcmp( argv_to_upper, "-FEC" ) == 0 ) - { - ftmp = 0.0f; - if ( sscanf( argv[i + 1], "%f", &ftmp ) != 1 ) - { - arg->FEPatterFileName = argv[i + 1]; - } - else - { - arg->FER = ftmp; - } - i += 2; - } -#endif else if ( strcmp( argv_to_upper, "-Q" ) == 0 ) { arg->quietModeEnabled = true; @@ -827,6 +812,19 @@ static bool parseCmdlIVAS_dec( } } #ifdef DEBUGGING + else if ( strcmp( argv_to_upper, "-FEC" ) == 0 ) + { + ftmp = 0.0f; + if ( sscanf( argv[i + 1], "%f", &ftmp ) != 1 ) + { + arg->FEPatterFileName = argv[i + 1]; + } + else + { + arg->FER = ftmp; + } + i += 2; + } else if ( strcmp( argv_to_upper, "-FORCE" ) == 0 ) { i++; @@ -837,6 +835,11 @@ static bool parseCmdlIVAS_dec( i++; } } + else if ( strcmp( argv_to_upper, "-FORCE_SUBFRAME_BIN" ) == 0 ) /* Force binauralization to subframe (5 ms) resolution */ + { + arg->forceSubframeBinauralization = true; + i++; + } #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK /*-----------------------------------------------------------------* @@ -948,13 +951,6 @@ static bool parseCmdlIVAS_dec( } i++; } -#ifdef DEBUGGING - else if ( strcmp( argv_to_upper, "-FORCE_SUBFRAME_BIN" ) == 0 ) /* Force binauralization to subframe (5 ms) resolution */ - { - arg->forceSubframeBinauralization = true; - i++; - } -#endif /*-----------------------------------------------------------------* * Option not recognized diff --git a/apps/encoder.c b/apps/encoder.c index 7d2de90dd07c2f6b6d1ab5e5d7fbd6450cb0cd0a..e9325ded5945c2f368a97517505d7a862e9da9c6 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -72,6 +72,7 @@ typedef union _EncInputFormatConfig { /* MONO details */ bool stereoToMonoDownmix; + #ifdef DEBUGGING /* STEREO details */ IVAS_ENC_STEREO_MODE stereoMode; @@ -83,16 +84,20 @@ typedef union _EncInputFormatConfig int16_t numObjects; const char *metadataFiles[IVAS_MAX_NUM_OBJECTS]; } ism; + /* SBA details */ struct EncSbaConfig { IVAS_ENC_SBA_ORDER order; bool isPlanar; } sba; + /* MASA details */ IVAS_ENC_MASA_VARIANT masaVariant; + /* MC details */ IVAS_ENC_MC_LAYOUT mcLayout; + } EncInputFormatConfig; /* Struct for storing cmdln arguments */ @@ -112,24 +117,24 @@ typedef struct bool quietModeEnabled; bool delayCompensationEnabled; const char *masaMetadataFile; -#ifdef DEBUGGING - IVAS_ENC_FORCED_MODE forcedMode; - const char *forcedModeFile; -#endif IVAS_ENC_CHANNEL_AWARE_CONFIG caConfig; const char *ca_config_file; bool mimeOutput; +#ifdef DEBUGGING + IVAS_ENC_FORCED_MODE forcedMode; + const char *forcedModeFile; #ifdef DEBUG_AGC_ENCODER_CMD_OPTION IVAS_ENC_AGC agc; #endif - bool pca; #ifdef DEBUG_FOA_AGC FILE *agcBitstream; /* temporary */ #endif #ifdef DEBUG_SBA const char *dbg_file_tag; #endif +#endif + bool pca; } EncArguments; @@ -214,17 +219,13 @@ int main( int16_t *pcmBuf = NULL; #ifdef DEBUGGING FILE *f_forcedModeProfile = NULL; -#endif - #ifdef DEBUG_SBA int16_t numTransportChannels = 1; #endif - -#ifdef WMOPS - size_t SRAM_size = 0; #endif #ifdef WMOPS + size_t SRAM_size = 0; reset_wmops(); reset_stack(); #endif @@ -826,13 +827,6 @@ cleanup: fclose( f_bitrateProfile ); } -#ifdef DEBUGGING - if ( f_forcedModeProfile ) - { - fclose( f_forcedModeProfile ); - } -#endif - IVAS_ENC_Close( &hIvasEnc ); #ifdef RAM_COUNTING_TOOL @@ -848,13 +842,18 @@ cleanup: #ifdef DEBUGGING dbgclose(); -#endif + + if ( f_forcedModeProfile ) + { + fclose( f_forcedModeProfile ); + } #ifdef DEBUG_SBA ivas_close_sba_encoder_debug_files(); #ifdef DEBUG_AGC ivas_close_agc_debug_files(); #endif +#endif #endif return mainFailed ? -1 : 0; @@ -884,24 +883,24 @@ static void initArgStruct( EncArguments *arg ) arg->quietModeEnabled = false; arg->delayCompensationEnabled = true; arg->masaMetadataFile = NULL; -#ifdef DEBUGGING - arg->forcedMode = IVAS_ENC_FORCE_UNFORCED; - arg->forcedModeFile = NULL; -#endif arg->caConfig = IVAS_ENC_GetDefaultChannelAwareConfig(); arg->ca_config_file = NULL; arg->mimeOutput = false; +#ifdef DEBUGGING + arg->forcedMode = IVAS_ENC_FORCE_UNFORCED; + arg->forcedModeFile = NULL; #ifdef DEBUG_AGC_ENCODER_CMD_OPTION arg->agc = IVAS_ENC_AGC_UNDEFINED; #endif - arg->pca = false; #ifdef DEBUG_FOA_AGC arg->agcBitstream = NULL; #endif #ifdef DEBUG_SBA arg->dbg_file_tag = NULL; #endif +#endif + arg->pca = false; return; } @@ -1063,6 +1062,54 @@ static bool parseCmdlIVAS_enc( } #endif /* #ifdef DEBUG_MODE_INFO_TWEAK */ #endif /* #ifdef DEBUG_MODE_INFO */ + +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + /*-----------------------------------------------------------------* + * IVAS SPAR AGC option + *-----------------------------------------------------------------*/ + else if ( strcmp( argv_to_upper, "-AGC" ) == 0 ) + { + i++; + if ( i < argc - 4 ) + { + arg->agc = ( atoi( argv[i] ) ) ? IVAS_ENC_AGC_ENABLED : IVAS_ENC_AGC_DISABLED; + if ( argv[i] == NULL || atoi( argv[i] ) < 0 || atoi( argv[i] ) > 1 ) + { + fprintf( stderr, "Error: wrong adaptive gain control option specified (%d), expected 0 or 1\n\n", (int32_t) atoi( argv[i] ) ); + usage_enc(); + return false; + } + i++; + } + else + { + fprintf( stderr, "Error: unspecified adaptive gain control option\n\n" ); + usage_enc(); + return false; + } + } +#endif + +#ifdef DEBUG_SBA + /*-----------------------------------------------------------------* + * IVAS SPAR debug files tag + *-----------------------------------------------------------------*/ + else if ( strcmp( argv_to_upper, "-TAG" ) == 0 ) + { + i++; + if ( i < argc - 4 ) + { + arg->dbg_file_tag = argv[i]; + ++i; + } + else + { + fprintf( stderr, "Error: [IVAS SPAR Encoder] unspecified tag value \n\n" ); + usage_enc(); + return false; + } + } +#endif #endif /* #ifdef DEBUGGING */ /*-----------------------------------------------------------------* @@ -1400,29 +1447,6 @@ static bool parseCmdlIVAS_enc( arg->inputFormatConfig.stereoToMonoDownmix = true; i++; } -#ifdef DEBUG_AGC_ENCODER_CMD_OPTION - else if ( strcmp( argv_to_upper, "-AGC" ) == 0 ) - { - i++; - if ( i < argc - 4 ) - { - arg->agc = ( atoi( argv[i] ) ) ? IVAS_ENC_AGC_ENABLED : IVAS_ENC_AGC_DISABLED; - if ( argv[i] == NULL || atoi( argv[i] ) < 0 || atoi( argv[i] ) > 1 ) - { - fprintf( stderr, "Error: wrong adaptive gain control option specified (%d), expected 0 or 1\n\n", (int32_t) atoi( argv[i] ) ); - usage_enc(); - return false; - } - i++; - } - else - { - fprintf( stderr, "Error: unspecified adaptive gain control option\n\n" ); - usage_enc(); - return false; - } - } -#endif else if ( strcmp( argv_to_upper, "-BYPASS" ) == 0 ) // VE: should be renamed to "-pca" { i++; @@ -1456,26 +1480,6 @@ static bool parseCmdlIVAS_enc( return false; } } -#ifdef DEBUG_SBA - /*-----------------------------------------------------------------* - * IVAS SPAR debug files tag - *-----------------------------------------------------------------*/ - else if ( strcmp( argv_to_upper, "-TAG" ) == 0 ) - { - i++; - if ( i < argc - 4 ) - { - arg->dbg_file_tag = argv[i]; - ++i; - } - else - { - fprintf( stderr, "Error: [IVAS SPAR Encoder] unspecified tag value \n\n" ); - usage_enc(); - return false; - } - } -#endif /*-----------------------------------------------------------------* * Option not recognized @@ -1659,6 +1663,10 @@ static void usage_enc( void ) fprintf( stdout, " The encoder produces TS26.445 Annex.2.6 Mime Storage Format, (not RFC4867 Mime Format).\n" ); fprintf( stdout, " default output bitstream file format is G.192\n" ); + fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" ); +#ifdef DEBUGGING + fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); + fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" ); #ifdef DEBUG_SBA fprintf( stdout, "-tag : Tag name for intermediate debug files\n" ); #endif @@ -1667,11 +1675,6 @@ static void usage_enc( void ) fprintf( stdout, " By default op is 1 (activated) for bitrates between 24400 and 32000,\n" ); fprintf( stdout, " otherwise it is 0 (deactivated) for all other bitrates\n" ); #endif - - fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" ); -#ifdef DEBUGGING - fprintf( stdout, "-force T : Force specific mode, T = (speech, music, ACELP, GSC, TCX, HQ),\n" ); - fprintf( stdout, " alternatively, T can be a text file where each line contains \"nb_frames T\"\n" ); #ifdef DEBUG_MODE_INFO #ifdef DEBUG_MODE_INFO_TWEAK fprintf( stdout, "-info : specify subfolder name for debug output\n" ); diff --git a/apps/renderer.c b/apps/renderer.c index 8097424cec34869269043c7360a1a457fed15216..44423014660c583340551cb4353bfc17e0287de0 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -424,7 +424,12 @@ static int16_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], - IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) + IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + , + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] +#endif +) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -479,6 +484,25 @@ static int16_t getTotalNumInChannels( totalNumInChannels += numInputChannels; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + if ( masaIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, masaIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } +#endif + return totalNumInChannels; } @@ -651,6 +675,9 @@ int main( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] = { 0 }; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] = { 0 }; +#endif if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) { @@ -759,7 +786,29 @@ int main( } } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) + { + if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, masaIds[i], args.inputGainGlobal * dBToLin( args.inConfig.masaBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } +#endif + +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); +#else const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); +#endif + if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) ) { @@ -855,6 +904,7 @@ int main( } #endif +#ifndef NOKIA_MASA_EXTERNAL_RENDERER for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { if ( masaReaders[i] != NULL ) @@ -865,6 +915,7 @@ int main( (void) hMasaMetadata; } } +#endif ObjectPositionBuffer mtdBuffer; IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); @@ -930,6 +981,37 @@ int main( } } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) + { + int16_t numChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, masaIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.masaBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, masaIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( masaReaders[i] != NULL ) + { + /* This will update data in hMasaMetadata[i] */ + MasaFileReader_readNextFrame( masaReaders[i] ); + + if ( ( error = IVAS_REND_FeedInputMasaMetadata( hIvasRend, masaIds[i], hMasaMetadata[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } +#endif + IVAS_REND_GetSamples( hIvasRend, outBuffer ); int16_t num_out_channels; @@ -1307,6 +1389,8 @@ static IVAS_REND_AudioConfig parseAudioConfig( switch ( charBuf[4] ) { case '1': + fprintf(stderr, "1TC MASA support is not functional and is pending on DirAC renderer refactoring.\n"); + exit(EXIT_FAILURE); return IVAS_REND_AUDIO_CONFIG_MASA1; case '2': return IVAS_REND_AUDIO_CONFIG_MASA2; diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py index d2483627dfccf573d371eb349c125b76eb8313d4..644051a79bbc8165b10d91ca3c8c6d7f49773532 100644 --- a/ci/run_scheduled_sanitizer_test.py +++ b/ci/run_scheduled_sanitizer_test.py @@ -6,7 +6,7 @@ import subprocess import pathlib -DURATION = "30" +DURATION = "120" CFG = "ci_linux_ltv.json" SUPPORTED_TESTS = ["CLANG1", "CLANG2", "CLANG3", "VALGRIND"] EP_FILE = "ep_015.g192" diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index fdf03190dec3689c577357dd56a31e8027f0361d..fdc7a1502df931a6e4e08151525d141169808540 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -63,6 +63,9 @@ typedef enum IVAS_ERR_TOO_MANY_INPUTS, #else IVAS_ERR_TOO_MANY_OBJECT_INPUTS, +#endif +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + IVAS_ERR_MISSING_METADATA, #endif IVAS_ERR_INDEX_OUT_OF_BOUNDS, IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, @@ -84,21 +87,14 @@ typedef enum IVAS_ERR_INVALID_INDEX, IVAS_ERR_NOT_SUPPORTED_OPTION, IVAS_ERR_NOT_IMPLEMENTED, -#ifdef DEBUGGING - IVAS_ERR_INVALID_FORCE_MODE, -#endif IVAS_ERR_FILE_READER_TIMESTAMP_MISMATCH, IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT, IVAS_ERR_INVALID_MASA_FORMAT_METADATA_FILE, -#ifdef EXT_RENDERER - IVAS_ERR_NUM_CHANNELS_UNKNOWN, - IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT, - IVAS_ERR_INVALID_INPUT_ID, - IVAS_ERR_WRONG_NUM_CHANNELS, - IVAS_ERR_INVALID_BUFFER_SIZE, -#endif +#ifdef DEBUGGING + IVAS_ERR_INVALID_FORCE_MODE, #ifdef DEBUG_AGC_ENCODER_CMD_OPTION IVAS_ERR_INVALID_AGC, +#endif #endif /*----------------------------------------* @@ -129,6 +125,18 @@ typedef enum IVAS_ERR_BITSTREAM_READER_INVALID_DATA, IVAS_ERR_BITSTREAM_READER_INVALID_FORMAT, +#ifdef EXT_RENDERER + /*----------------------------------------* + * renderer (lib_rend only) * + *----------------------------------------*/ + + IVAS_ERR_NUM_CHANNELS_UNKNOWN, + IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT, + IVAS_ERR_INVALID_INPUT_ID, + IVAS_ERR_WRONG_NUM_CHANNELS, + IVAS_ERR_INVALID_BUFFER_SIZE, +#endif + /*----------------------------------------* * unknown error * *----------------------------------------*/ diff --git a/lib_com/options.h b/lib_com/options.h index 7e32d9532610d0415339b679707f8207c924e119..3d9f3fad7282e4a6061d2a0a6f4cb877f487b245 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,6 +146,7 @@ #define FIX_I1_113 /* under review : MCT bit distribution optimization for SBA high bitrates*/ #define PRINT_SBA_ORDER /* Issue 179: print-out also the SBA order of IVAS SBA format to stdout */ #define EXT_RENDERER /* FhG: external renderer library and standalone application */ +#define NOKIA_MASA_EXTERNAL_RENDERER /* Nokia: MASA support for external renderer */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ #define FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS /* Issue 124: do not allocate unused plc struct in IVAS modes which is only used in EVS mono */ #define FIX_MCT_PLC_RECOVERY /* Issue 184: scale the old synthesis part correctly in the first good frame after lost frames in MCT modes - to be activated after previous switch is merged */ @@ -153,6 +154,7 @@ #define FIX_AGC_WINFUNC_MEMORY /* Issue 62: lower agc_com.winFunc memory consumption */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 8207336b82d67e466aac9da00d0aa2f1d1949f8f..f39f2b81485a638cf53fba3df79041cf41fe741a 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -59,24 +59,12 @@ extern FILE *agcOut; static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState ); #endif -#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_get_flag() * - * This function determines if AGC should be enabled or disabled. - * If agc_configuration is not undefined, then this value decides on the state of - * enablement, otherwise AGC is enabled only if there is one transport channel. - * + * This function determines if AGC is enabled or disabled. *-----------------------------------------------------------------------------------------*/ -#else -/*-----------------------------------------------------------------------------------------* - * Function ivas_agc_enc_get_flag() - * - * This function determines if AGC should be enabled or disabled. - * AGC is enabled only if there is one transport channel. - * - *-----------------------------------------------------------------------------------------*/ -#endif /*! r: AGC enable flag */ int16_t ivas_agc_enc_get_flag( @@ -86,15 +74,21 @@ int16_t ivas_agc_enc_get_flag( int16_t nchan_transport /* i : number of transport channels */ ) { + int16_t agc_flag; + + /* AGC is enabled only if there is one transport channel. */ + agc_flag = (int16_t) ( nchan_transport == 1 ); + #ifdef DEBUG_AGC_ENCODER_CMD_OPTION - return (int16_t) ( ( agc_configuration == SBA_AGC_DEFAULT ) - ? ( nchan_transport == 1 ) - : agc_configuration ); -#else - return (int16_t) ( nchan_transport == 1 ); + /* If agc_configuration is not undefined, then this value decides on the state of * enablement, + otherwise AGC is enabled only if there is one transport channel. */ + agc_flag = ( agc_configuration != SBA_AGC_DEFAULT ) ? agc_configuration : agc_flag; #endif + + return agc_flag; } + /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_init() * diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 9d04506d7991230ff2d7d799c79befbd92b29c9f..0644fcd918e5216b40cd1610449e190ba5cd352b 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -999,9 +999,6 @@ typedef struct encoder_config_structure int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ /* temp. development parameters */ -#ifdef DEBUG_AGC_ENCODER_CMD_OPTION - int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ -#endif int16_t Opt_PCA_ON; /* flag indicating PCA operation in SBA */ #ifdef DEBUGGING @@ -1009,6 +1006,9 @@ typedef struct encoder_config_structure int16_t stereo_mode_cmdl; /* stereo mode forced from the command-line */ int16_t force; /* parameter to force specific "core" of the Core-Coder*/ int16_t mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ +#endif #endif diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 04e9ed4233af7927e5202ff7d921f81812263f29..68a465a5bcc42b9a4b6f7244b8c4ab45dc258b7a 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -892,7 +892,6 @@ static ivas_error configureEncoder( } #endif - if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); @@ -1513,6 +1512,7 @@ static ivas_error printConfigInfo_enc( { fprintf( stdout, "- PCA configured with signal adaptive decision " ); } + #ifdef DEBUG_AGC_ENCODER_CMD_OPTION switch ( hEncoderConfig->Opt_AGC_ON ) { @@ -1529,8 +1529,6 @@ static ivas_error printConfigInfo_enc( fprintf( stdout, "- AGC unknown " ); break; } -#else - fprintf( stdout, "- AGC default mode " ); #endif fprintf( stdout, "\n" ); } @@ -2065,6 +2063,12 @@ static ivas_error bandwidthApiToInternal( } #ifdef DEBUG_AGC_ENCODER_CMD_OPTION +/*---------------------------------------------------------------------* + * agcAPIToInternal() + * + * + *---------------------------------------------------------------------*/ + static ivas_error agcAPIToInternal( const IVAS_ENC_AGC agcOption, int16_t *internalAGCOption ) @@ -2214,17 +2218,17 @@ static void init_encoder_config( hEncoderConfig->rf_fec_indicator = 1; hEncoderConfig->interval_SID = FIXED_SID_RATE; hEncoderConfig->var_SID_rate_flag = 1; -#ifdef DEBUGGING - hEncoderConfig->stereo_mode_cmdl = 0; - hEncoderConfig->force = -1; - hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; -#endif hEncoderConfig->mc_input_setup = MC_LS_SETUP_INVALID; hEncoderConfig->stereo_dmx_evs = 0; hEncoderConfig->sba_order = 0; hEncoderConfig->sba_planar = 0; +#ifdef DEBUGGING + hEncoderConfig->stereo_mode_cmdl = 0; + hEncoderConfig->force = -1; + hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; #ifdef DEBUG_AGC_ENCODER_CMD_OPTION hEncoderConfig->Opt_AGC_ON = SBA_AGC_DEFAULT; +#endif #endif hEncoderConfig->Opt_PCA_ON = 0; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index fd0a4adfa2cba4785fada406fcc3d2b10a8f141f..dbcb21c9897449b671635fff3ccf2cf8ab6846fd 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -71,19 +71,6 @@ typedef struct _IVAS_ENC_DTX_CONFIG int16_t SID_interval; } IVAS_ENC_DTX_CONFIG; -#ifdef DEBUGGING -typedef enum _IVAS_ENC_STEREO_MODE -{ - IVAS_ENC_STEREO_MODE_UNIFIED, - IVAS_ENC_STEREO_MODE_DFT, - IVAS_ENC_STEREO_MODE_TD, - IVAS_ENC_STEREO_MODE_MDCT_DECISION, - IVAS_ENC_STEREO_MODE_MDCT_FORCE_LR, - IVAS_ENC_STEREO_MODE_MDCT_FORCE_MS, - IVAS_ENC_STEREO_MODE_UNDEFINED = 0xffff -} IVAS_ENC_STEREO_MODE; -#endif /* DEBUGGING */ - typedef enum _IVAS_ENC_SBA_ORDER { IVAS_ENC_SBA_FOA = 1, @@ -110,6 +97,17 @@ typedef enum _IVAS_ENC_MASA_VARIANT } IVAS_ENC_MASA_VARIANT; #ifdef DEBUGGING +typedef enum _IVAS_ENC_STEREO_MODE +{ + IVAS_ENC_STEREO_MODE_UNIFIED, + IVAS_ENC_STEREO_MODE_DFT, + IVAS_ENC_STEREO_MODE_TD, + IVAS_ENC_STEREO_MODE_MDCT_DECISION, + IVAS_ENC_STEREO_MODE_MDCT_FORCE_LR, + IVAS_ENC_STEREO_MODE_MDCT_FORCE_MS, + IVAS_ENC_STEREO_MODE_UNDEFINED = 0xffff +} IVAS_ENC_STEREO_MODE; + typedef enum _IVAS_ENC_FORCED_MODE { IVAS_ENC_FORCE_SPEECH, @@ -121,7 +119,6 @@ typedef enum _IVAS_ENC_FORCED_MODE IVAS_ENC_FORCE_UNFORCED, IVAS_ENC_FORCE_UNDEFINED = 0xffff } IVAS_ENC_FORCED_MODE; -#endif #ifdef DEBUG_AGC_ENCODER_CMD_OPTION typedef enum _IVAS_ENC_AGC @@ -131,6 +128,7 @@ typedef enum _IVAS_ENC_AGC IVAS_ENC_AGC_UNDEFINED = 0xffff } IVAS_ENC_AGC; #endif +#endif /*---------------------------------------------------------------------* * Encoder structures diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ef38d00c19e3513c9d6a00e66740cfcc1647e68e..be6e672ce79fdc6f3cbd7d3f017a2bbad1933184 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -140,6 +140,20 @@ typedef struct rotation_gains rot_gains_prev; } input_sba; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER +/* Due to API of some rendering methods, the renderer has to use the decoder struct. + Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ +typedef Decoder_Struct DecoderDummy; + +typedef struct +{ + input_base base; + DecoderDummy *decDummy; + MASA_METADATA_FRAME masaMetadata; + bool metadataHasBeenFed; +} input_masa; +#endif + struct IVAS_REND { int32_t sampleRateOut; @@ -152,6 +166,9 @@ struct IVAS_REND input_ism inputsIsm[RENDERER_MAX_ISM_INPUTS]; input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; +#endif /* TODO @Philips - inputConfig should not be stored here, but read from e.g. input_mc->input_base.inConfig, please remove this */ IVAS_REND_AudioConfig inputConfig; @@ -383,11 +400,13 @@ ivas_error getAudioConfigNumChannels( { case IVAS_REND_AUDIO_CONFIG_MONO: case IVAS_REND_AUDIO_CONFIG_OBJECT: + case IVAS_REND_AUDIO_CONFIG_MASA1: *numChannels = 1; break; case IVAS_REND_AUDIO_CONFIG_STEREO: case IVAS_REND_AUDIO_CONFIG_BINAURAL: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + case IVAS_REND_AUDIO_CONFIG_MASA2: *numChannels = 2; break; case IVAS_REND_AUDIO_CONFIG_FOA: @@ -1849,6 +1868,426 @@ static void clearInputSba( return; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER +static ivas_error initMasaDummyDecForMcOut( input_masa *inputMasa, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + int16_t numCldfbAnalyses; + int16_t numCldfbSyntheses; + int16_t i; + AUDIO_CONFIG output_config; + DecoderDummy *decDummy; + decDummy = inputMasa->decDummy; + + output_config = rendAudioConfigToIvasAudioConfig( outConfig ); + decDummy->hDecoderConfig->output_config = output_config; + + decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ + decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ + decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ + + ivas_output_init( &( decDummy->hOutSetup ), output_config ); + ivas_output_init( &( decDummy->hIntSetup ), output_config ); + + decDummy->renderer_type = RENDERER_DIRAC; + if ( output_config == AUDIO_CONFIG_STEREO ) + { + decDummy->renderer_type = RENDERER_STEREO_PARAMETRIC; + } + + decDummy->ivas_format = MASA_FORMAT; + decDummy->transport_config = AUDIO_CONFIG_INVALID; + + /* Todo refactor: Access to qmetadata is not required by the algorithm. */ + if ( ( error = ivas_qmetadata_open( &( decDummy->hQMetaData ) ) ) != IVAS_ERR_OK ) + { + return error; + } + decDummy->hQMetaData->coherence_flag = 1; + + if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + if ( ( error = ivas_dirac_dec_init_binaural_data( decDummy ) ) != IVAS_ERR_OK ) + { + return error; + } + decDummy->hDiracDecBin->useSubframeMode = 0; /* Todo Nokia: This will disappear in later work but needs to be this now. */ + } + + numCldfbAnalyses = decDummy->nchan_transport; + numCldfbSyntheses = decDummy->hDecoderConfig->nchan_out; + + for ( i = 0; i < numCldfbAnalyses; i++ ) + { + if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_INTERN_CHANNELS; i++ ) + { + decDummy->cldfbAnaDec[i] = NULL; + } + + for ( i = 0; i < numCldfbSyntheses; i++ ) + { + if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + { + decDummy->cldfbSynDec[i] = NULL; + } + + return IVAS_ERR_OK; +} + +static ivas_error initMasaDummyDecForSbaOut( input_masa *inputMasa, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + int16_t numCldfbAnalyses; + int16_t numCldfbSyntheses; + int16_t i; + AUDIO_CONFIG output_config; + DecoderDummy *decDummy; + + decDummy = inputMasa->decDummy; + + output_config = rendAudioConfigToIvasAudioConfig( outConfig ); + decDummy->hDecoderConfig->output_config = output_config; + + decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ + decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ + decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ + + ivas_output_init( &( decDummy->hOutSetup ), output_config ); + ivas_output_init( &( decDummy->hIntSetup ), output_config ); + decDummy->renderer_type = RENDERER_DIRAC; + decDummy->ivas_format = MASA_FORMAT; + decDummy->transport_config = AUDIO_CONFIG_INVALID; + + /* Todo refactor: Access to qmetadata is not required by the algorithm. */ + if ( ( error = ivas_qmetadata_open( &( decDummy->hQMetaData ) ) ) != IVAS_ERR_OK ) + { + return error; + } + decDummy->hQMetaData->coherence_flag = 1; + + if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK ) + { + return error; + } + + numCldfbAnalyses = decDummy->nchan_transport; + numCldfbSyntheses = decDummy->hDecoderConfig->nchan_out; + + for ( i = 0; i < numCldfbAnalyses; i++ ) + { + if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_INTERN_CHANNELS; i++ ) + { + decDummy->cldfbAnaDec[i] = NULL; + } + + for ( i = 0; i < numCldfbSyntheses; i++ ) + { + if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + { + decDummy->cldfbSynDec[i] = NULL; + } + + return IVAS_ERR_OK; +} + +static ivas_error initMasaDummyDecForBinauralOut( input_masa *inputMasa, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + + int16_t i; + AUDIO_CONFIG output_config; + DecoderDummy *decDummy; + + decDummy = inputMasa->decDummy; + + output_config = rendAudioConfigToIvasAudioConfig( outConfig ); + decDummy->hDecoderConfig->output_config = output_config; + + output_config = decDummy->hDecoderConfig->output_config; + + decDummy->hDecoderConfig->ivas_total_brate = IVAS_512k; /* Todo Nokia: This is preventing initialization of 2TC as 1TC, should be fixed properly in ivas_dirac_dec_config() */ + decDummy->sba_mode = SBA_MODE_NONE; /* Todo Nokia: This is done to prevent ivas_dirac_dec_config() to not use uninitialized value. It could be considered if this should not be even accessed when not in SBA. */ + decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ + + ivas_output_init( &( decDummy->hOutSetup ), output_config ); + if ( output_config == AUDIO_CONFIG_BINAURAL ) + { + decDummy->renderer_type = RENDERER_BINAURAL_PARAMETRIC; + } + else + { + decDummy->renderer_type = RENDERER_BINAURAL_PARAMETRIC_ROOM; + } + decDummy->ivas_format = MASA_FORMAT; + decDummy->transport_config = AUDIO_CONFIG_INVALID; +#ifdef DEBUGGING + decDummy->hDecoderConfig->forceSubframeBinauralization = 0; +#endif + + if ( ( error = ivas_dirac_dec_open( decDummy ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = ivas_dirac_dec_init_binaural_data( decDummy ) ) != IVAS_ERR_OK ) + { + return error; + } + + decDummy->hDiracDecBin->useSubframeMode = 0; /* Todo Nokia: This will disappear in later work but needs to be this now. */ + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + if ( ( error = openCldfb( &( decDummy->cldfbAnaDec[i] ), CLDFB_ANALYSIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = openCldfb( &( decDummy->cldfbSynDec[i] ), CLDFB_SYNTHESIS, decDummy->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_INTERN_CHANNELS; i++ ) + { + decDummy->cldfbAnaDec[i] = NULL; + decDummy->cldfbSynDec[i] = NULL; + } + + return IVAS_ERR_OK; +} + +static ivas_error updateMasaDummyDec( input_masa *inputMasa, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = initMasaDummyDecForMcOut( inputMasa, outConfig ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = initMasaDummyDecForSbaOut( inputMasa, outConfig ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + error = initMasaDummyDecForBinauralOut( inputMasa, outConfig ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static DecoderDummy *initDecoderDummy( int32_t sampleRate, int16_t numTransChannels, IVAS_REND_AudioConfig outConfig, const uint8_t enableRenderConfig ) +{ + ivas_error error; + int16_t i; + int16_t numOutChannels; + DecoderDummy *decDummy; + + if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + { + /* Checking error with assert is enough, this function is only temporary anyway */ + assert(error == IVAS_ERR_OK); + } + + decDummy = count_malloc( sizeof( DecoderDummy ) ); + decDummy->hDecoderConfig = count_malloc( sizeof( DECODER_CONFIG ) ); + decDummy->hDecoderConfig->output_Fs = sampleRate; + decDummy->hDecoderConfig->nchan_out = (int16_t)numOutChannels; + decDummy->hDecoderConfig->Opt_Headrotation = 0; + + decDummy->hBinRenderer = NULL; + decDummy->hEFAPdata = NULL; + decDummy->hHrtf = NULL; + decDummy->hHrtfTD = NULL; + decDummy->hSpar = NULL; + decDummy->hoa_dec_mtx = NULL; + decDummy->hVBAPdata = NULL; + decDummy->hMasa = NULL; + decDummy->hDiracDecBin = NULL; + decDummy->hQMetaData = NULL; + decDummy->hDecoderConfig->output_config = rendAudioConfigToIvasAudioConfig(outConfig); + decDummy->nchan_transport = numTransChannels; + + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + decDummy->hHeadTrackData = count_malloc( sizeof( HEAD_TRACK_DATA ) ); + /* Initialise Rmat_prev to I, Rmat will be computed later */ + for ( i = 0; i < 3; i++ ) + { + set_zero( decDummy->hHeadTrackData->Rmat_prev[i], 3 ); + decDummy->hHeadTrackData->Rmat_prev[i][i] = 1.0f; + } + + decDummy->hHeadTrackData->num_quaternions = 0; + decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; + decDummy->hHeadTrackData->lrSwitchedCurrent = 0; + decDummy->hHeadTrackData->lrSwitchedNext = 0; + } + else + { + decDummy->hHeadTrackData = NULL; + } + + if ( enableRenderConfig ) + { + ivas_render_config_open( &decDummy->hRenderConfig ); + decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; + decDummy->hRenderConfig->roomAcoustics.use_brir = 0; + } + else + { + decDummy->hRenderConfig = NULL; + } + + decDummy->renderer_type = RENDERER_DISABLE; + + return decDummy; +} + +static ivas_error setRendInputActiveMasa( + void *input, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRendCfg ) /* Todo: This is not used at all within MASA. Support might be better to do after refactoring. */ +{ + ivas_error error; + rendering_context rendCtx; + IVAS_REND_AudioConfig outConfig; + input_masa *inputMasa; + int16_t numInChannels; + + inputMasa = (input_masa *) input; + rendCtx = inputMasa->base.ctx; + outConfig = *rendCtx.pOutConfig; + + initRendInputBase( &inputMasa->base, inConfig, id, rendCtx ); + + if ( ( error = getAudioConfigNumChannels( inConfig, &numInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + inputMasa->decDummy = initDecoderDummy( *rendCtx.pOutSampleRate, (int16_t)numInChannels, outConfig, 0 ); + inputMasa->metadataHasBeenFed = false; + + if ( ( error = updateMasaDummyDec( inputMasa, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static void freeDecoderDummy( DecoderDummy **ppDecDummy ) +{ + int16_t i; + DecoderDummy *pDecDummy; + + if ( ppDecDummy == NULL || *ppDecDummy == NULL ) + { + return; + } + pDecDummy = *ppDecDummy; + + if ( pDecDummy->hDecoderConfig != NULL ) + { + count_free( pDecDummy->hDecoderConfig ); + } + if ( pDecDummy->hHeadTrackData != NULL ) + { + count_free( pDecDummy->hHeadTrackData ); + } + ivas_render_config_close( &pDecDummy->hRenderConfig ); + +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + /* CLDFB handles */ + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) + { + if ( pDecDummy->cldfbAnaDec[i] != NULL ) + { + deleteCldfb( &( pDecDummy->cldfbAnaDec[i] ) ); + pDecDummy->cldfbAnaDec[i] = NULL; + } + } + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + if ( pDecDummy->cldfbSynDec[i] != NULL ) + { + deleteCldfb( &( pDecDummy->cldfbSynDec[i] ) ); + pDecDummy->cldfbSynDec[i] = NULL; + } + } + + /* DirAC handle */ + if ( pDecDummy->hDirAC != NULL ) + { + ivas_dirac_dec_close( pDecDummy->hDirAC ); + pDecDummy->hDirAC = NULL; + } + + /* Qmetadata handle */ + ivas_qmetadata_close( &pDecDummy->hQMetaData ); + + /* VBAP handle */ + vbap_free_data( &( pDecDummy->hVBAPdata ) ); + + /* HOA decoder matrix */ + if ( pDecDummy->hoa_dec_mtx != NULL ) + { + count_free( pDecDummy->hoa_dec_mtx ); + pDecDummy->hoa_dec_mtx = NULL; + } + + /* Parametric binaural renderer handle */ + ivas_dirac_dec_close_binaural_data( &pDecDummy->hDiracDecBin ); +#endif + + count_free( pDecDummy ); + pDecDummy = NULL; +} + +static void clearInputMasa( input_masa *inputMasa ) +{ + rendering_context rendCtx; + + rendCtx = inputMasa->base.ctx; + + initRendInputBase( &inputMasa->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); + freeDecoderDummy( &inputMasa->decDummy ); +} +#endif + ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, const int32_t outputSampleRate, @@ -1925,6 +2364,17 @@ ivas_error IVAS_REND_Open( initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsSba[i].crendWrapper.hCrend = NULL; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsMasa[i].base, + IVAS_REND_AUDIO_CONFIG_UNKNOWN, + 0, + getRendCtx( hIvasRend ) ); + hIvasRend->inputsMasa[i].decDummy = NULL; + hIvasRend->inputsMasa[i].metadataHasBeenFed = false; + } +#endif return IVAS_ERR_OK; } @@ -2145,6 +2595,15 @@ static ivas_error getInputById( } pInputBase = &hIvasRend->inputsSba[inputIndex].base; break; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + if ( inputIndex > RENDERER_MAX_MASA_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMasa[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -2203,6 +2662,15 @@ static ivas_error getConstInputById( } pInputBase = &hIvasRend->inputsSba[inputIndex].base; break; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + if ( inputIndex > RENDERER_MAX_MASA_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMasa[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -2226,7 +2694,7 @@ static ivas_error findFreeInputSlot( int32_t *inputIndex ) { /* Using a void pointer and a separately provided size is a hack for this function - to be reusable for arrays of any input type (input_ism, input_mc, input_sba). + to be reusable for arrays of any input type (input_ism, input_mc, input_sba, input_masa). Assumptions: - input_base is always the first member in the input struct - provided size is correct @@ -2301,6 +2769,14 @@ ivas_error IVAS_REND_AddInput( inputStructSize = sizeof( *hIvasRend->inputsSba ); activateInput = setRendInputActiveSba; break; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + maxNumInputsOfType = RENDERER_MAX_MASA_INPUTS; + inputsArray = hIvasRend->inputsMasa; + inputStructSize = sizeof( *hIvasRend->inputsMasa ); + activateInput = setRendInputActiveMasa; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -2495,6 +2971,11 @@ ivas_error IVAS_REND_RemoveInput( case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: clearInputSba( (input_sba *) inputBase ); break; +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: + clearInputMasa( (input_masa *) inputBase ); + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -2585,6 +3066,17 @@ ivas_error IVAS_REND_GetDelay( } } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) + { + if ( hIvasRend->inputsMasa[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + latency_ns = NS2SA( hIvasRend->sampleRateOut, (int32_t) ( (float) IVAS_FB_DEC_DELAY_NS + 0.5f ) ); + *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); + } + } +#endif + return IVAS_ERR_OK; } @@ -2676,6 +3168,42 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( return IVAS_ERR_OK; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER +ivas_error IVAS_REND_FeedInputMasaMetadata( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + IVAS_MASA_METADATA_HANDLE masaMetadata ) +{ + ivas_error error; + input_base *inputBase; + input_masa *inputMasa; + + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( getAudioConfigType( inputBase->inConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) + { + /* MASA metadata should only be fed for MASA inputs */ + return IVAS_ERR_METADATA_NOT_EXPECTED; + } + + inputMasa = (input_masa *) inputBase; + inputMasa->masaMetadata = *masaMetadata; + inputMasa->metadataHasBeenFed = true; + + return IVAS_ERR_OK; +} +#endif + ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, bool rendererConfigEnabled ) { @@ -4011,6 +4539,178 @@ static ivas_error renderActiveInputsSba( return IVAS_ERR_OK; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER +static void copyMasaMetadataToDiracRenderer( MASA_METADATA_FRAME *meta, DIRAC_DEC_HANDLE hDirAC ) +{ + int16_t band, sf, bin; + + hDirAC->numSimultaneousDirections = meta->descriptive_meta.numberOfDirections + 1; + + for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + for ( band = 0; band < MASA_MAXIMUM_CODING_SUBBANDS; band++ ) + { + for ( bin = MASA_band_grouping_24[band]; bin < MASA_band_grouping_24[band + 1]; bin++ ) + { + hDirAC->azimuth[sf][bin] = (int16_t) meta->directional_meta[0].azimuth[sf][band]; + hDirAC->elevation[sf][bin] = (int16_t) meta->directional_meta[0].elevation[sf][band]; + hDirAC->energy_ratio1[sf][bin] = meta->directional_meta[0].energy_ratio[sf][band]; + hDirAC->diffuseness_vector[sf][bin] = 1.0f - meta->directional_meta[0].energy_ratio[sf][band]; + hDirAC->spreadCoherence[sf][bin] = meta->directional_meta[0].spread_coherence[sf][band]; + hDirAC->surroundingCoherence[sf][bin] = meta->common_meta.surround_coherence[sf][band]; + + if ( hDirAC->numSimultaneousDirections == 2 ) + { + hDirAC->azimuth2[sf][bin] = (int16_t) meta->directional_meta[1].azimuth[sf][band]; + hDirAC->elevation2[sf][bin] = (int16_t) meta->directional_meta[1].elevation[sf][band]; + hDirAC->energy_ratio2[sf][bin] = meta->directional_meta[1].energy_ratio[sf][band]; + hDirAC->diffuseness_vector[sf][bin] -= meta->directional_meta[1].energy_ratio[sf][band]; + hDirAC->spreadCoherence2[sf][bin] = meta->directional_meta[1].spread_coherence[sf][band]; + } + } + } + } +} + +static ivas_error renderMasaToMc( input_masa *masaInput, IVAS_REND_AudioBuffer outAudio ) +{ + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); + + /* TODO(sgi): Remove code duplication w.r.t. MASA rendering to other output configs */ + if ( masaInput->decDummy->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + } + else + { + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, NULL, NULL, -1 ); + } + + accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); + + return IVAS_ERR_OK; +} + +static ivas_error renderMasaToSba( input_masa *masaInput, IVAS_REND_AudioBuffer outAudio ) +{ + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); + + ivas_dirac_dec( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels, NULL, NULL, -1 ); + + accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); + + return IVAS_ERR_OK; +} + +static ivas_error renderMasaToBinaural( input_masa *masaInput, IVAS_REND_AudioBuffer outAudio ) +{ + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + copyBufferTo2dArray( masaInput->base.inputBuffer, tmpBuffer ); + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->decDummy->hDirAC ); + + ivas_dirac_dec_binaural( masaInput->decDummy, tmpBuffer, masaInput->base.inputBuffer.config.numChannels ); + + accumulate2dArrayToBuffer( tmpBuffer, &outAudio ); + + return IVAS_ERR_OK; +} + +static ivas_error renderInputMasa( + input_masa *masaInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + if ( !masaInput->metadataHasBeenFed ) + { + return IVAS_ERR_MISSING_METADATA; + } + + inAudio = masaInput->base.inputBuffer; + + if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) + { + /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + masaInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, + masaInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = renderMasaToMc( masaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = renderMasaToSba( masaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = renderMasaToBinaural( masaInput, outAudio ); + break; + /* ToDo */ + // case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + // error = renderMasaToBinauralRoom( masaInput, outConfig, outAudio ); + // break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static ivas_error renderActiveInputsMasa( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int32_t i; + input_masa *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsMasa; i < RENDERER_MAX_MASA_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + /* Skip inactive inputs */ + continue; + } + if ( ( error = renderInputMasa( pCurrentInput, + hIvasRend->outputConfig, + outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} +#endif + ivas_error IVAS_REND_GetSamples( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) @@ -4064,6 +4764,12 @@ ivas_error IVAS_REND_GetSamples( { return error; } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + if ( ( error = renderActiveInputsMasa( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif #ifdef DEBUGGING hIvasRend->numClipping += @@ -4107,6 +4813,12 @@ void IVAS_REND_Close( { clearInputSba( &hIvasRend->inputsSba[i] ); } +#ifdef NOKIA_MASA_EXTERNAL_RENDERER + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + clearInputMasa( &hIvasRend->inputsMasa[i] ); + } +#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 99d4b7af25f6079d0b29367129ef6d5b99af4f06..225e9121cdac46fb76afc3ee297e2b0905502839 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -229,14 +229,22 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( const IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ ); +#ifdef NOKIA_MASA_EXTERNAL_RENDERER +ivas_error IVAS_REND_FeedInputMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_MASA_METADATA_HANDLE masaMetadata /* i : MASA metadata frame */ +); +#else /* Support for MASA input will be added in the future. */ ivas_error IVAS_REND_FeedInputMasaMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_InputId inputId, /* i : ID of the input */ void* TODO ); +#endif -ivas_error IVAS_REND_InitConfig( +ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, /* i/o: Renderer handle */ bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ ); diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/.vs/ivas_crend_unit_test/v16/Solution.VC.db-wal b/scripts/ivas_pytests/tests/unit_tests/crend/.vs/ivas_crend_unit_test/v16/Solution.VC.db-wal deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.sln b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.sln index e3a6f0a4e8bf73509cad28ac29bbc69c646adef4..549ec510760386ba415bcd04e6ebc33b2fd1009f 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.sln +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31911.196 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.1500 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ivas_crend_unit_test", "ivas_crend_unit_test.vcxproj", "{32354377-ACA7-40F9-9A0E-87FC956F0B78}" EndProject @@ -13,32 +13,51 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "..\..\..\..\.. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "..\..\..\..\..\Workspace_msvc\lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "..\..\..\..\..\Workspace_msvc\lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Release|Win32 = Release|Win32 + Unittests|Win32 = Unittests|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|Win32.ActiveCfg = Debug|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|Win32.Build.0 = Debug|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|Win32.ActiveCfg = Release|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|Win32.Build.0 = Release|Win32 + {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|Win32.ActiveCfg = Release|Win32 + {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Unittests|Win32.Build.0 = Release|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.ActiveCfg = Debug|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.Build.0 = Debug|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.ActiveCfg = Release|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.Build.0 = Unittests|Win32 {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.ActiveCfg = Debug|Win32 {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.Build.0 = Debug|Win32 {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.ActiveCfg = Release|Win32 {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Unittests|Win32.Build.0 = Unittests|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.ActiveCfg = Debug|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.Build.0 = Debug|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.ActiveCfg = Release|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Unittests|Win32.Build.0 = Unittests|Win32 {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32 {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32 {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.ActiveCfg = Release|Win32 {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Unittests|Win32.Build.0 = Unittests|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.Build.0 = Unittests|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj index 3d8e7ab07f968b37bee7eb46cb7ed36fbc9c6a62..2b0527648d4345855bcafcb3267decce7a1bb265 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj @@ -17,6 +17,9 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + {2fa8f384-0775-f3b7-f8c3-85209222fc70} @@ -97,7 +100,7 @@ Neither false false - ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) + ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_rend;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) UNIT_TEST_CREND_TD_BINAURAL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true @@ -143,7 +146,7 @@ Disabled - ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) + ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_rend;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;%(PreprocessorDefinitions) EnableFastChecks diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index cb2d580ec3ecc9342019975a424245feae2653e0..68b40a9454586ce231028669f4448d6a42f45042 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -188,40 +188,6 @@ FORMAT_TO_METADATA_FILES = { "MASA2": [str(TESTV_DIR.joinpath("stv_IVASMASA_2dir2TC.met"))], } -FORMAT_TO_IVAS = { - "MONO": ["", ""], - "STEREO": ["-stereo", ""], - "FOA": ["-sba", "1"], - "HOA2": ["-sba", "2"], - "HOA3": ["-sba", "3"], - "5_1": ["-mc", "5_1"], - "7_1": ["-mc", "7_1"], - "5_1_2": ["-mc", "5_1_2"], - "5_1_4": ["-mc", "5_1_4"], - "7_1_4": ["-mc", "7_1_4"], - "ISM1": ["-ism", "1"], - "ISM2": ["-ism", "2"], - "ISM3": ["-ism", "3"], - "ISM4": ["-ism", "4"], -} - -FORMAT_TO_IVAS_BR = { - "MONO": "128000", - "STEREO": "256000", - "FOA": "512000", - "HOA2": "512000", - "HOA3": "512000", - "5_1": "512000", - "7_1": "512000", - "5_1_2": "512000", - "5_1_4": "512000", - "7_1_4": "512000", - "ISM1": "256000", - "ISM2": "256000", - "ISM3": "256000", - "ISM4": "256000", -} - FORMAT_TO_CREND_FORMAT = { "MONO": "0", "STEREO": "1", @@ -241,7 +207,7 @@ FORMAT_TO_CREND_FORMAT = { INPUT_FORMATS_AMBI = ["FOA", "HOA2", "HOA3"] INPUT_FORMATS_MC = ["MONO", "STEREO", "5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] INPUT_FORMATS_ISM = ["ISM1", "ISM2", "ISM3", "ISM4"] -INPUT_FORMATS_MASA = ["MASA1", "MASA2"] +INPUT_FORMATS_MASA = ["MASA2"] #["MASA1", "MASA2"] # Disable MASA1 tests until MASA1 can be implemented properly """ Non binaural / parametric output formats """ OUTPUT_FORMATS = [ diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index 9660910afc8f4ad057e84279e0ac9172bce3a473..97ccf03c940374d2c9a0deaa6365d83df843bcae 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -156,13 +156,15 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): """ MASA """ -# # MASA inputs not supported yet -# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -# @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) -# def test_masa(test_info, in_fmt, out_fmt): -# # TODO: implement MASA in Python, compare BE -# compare_renderer_vs_pyscripts( test_info, in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] -# ) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) +def test_masa(test_info, in_fmt, out_fmt): + # # TODO: implement MASA in Python, compare BE + # compare_renderer_vs_pyscripts( test_info, in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] + # ) + run_renderer(in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt]) # MASA inputs not supported yet